diff --git a/SRU2023-9/_data/gradle.yml b/SRU2023-9/_data/gradle.yml index 077f9e350..fde334778 100644 --- a/SRU2023-9/_data/gradle.yml +++ b/SRU2023-9/_data/gradle.yml @@ -3,9 +3,9 @@ docsVersionTitle: SRU2023-9.4.x coreVersion: SRU2023-9.4.16 iso20022Version: SRU2023-9.4.5 sdkVersion: SRU2023-9.4.25 -validationVersion: SRU2023-9.4.23 -translationsVersion: SRU2023-9.4.39 -myformatVersion: SRU2023-9.4.5 +validationVersion: SRU2023-9.4.24 +translationsVersion: SRU2023-9.4.40 +myformatVersion: SRU2023-9.4.6 cbprVersion: SRU2023-9.4.2 sepaVersion: SRU2023-9.4.0 sicVersion: SRU2023-9.4.1 diff --git a/SRU2023-9/integrator/cbpr/index.html b/SRU2023-9/integrator/cbpr/index.html index 79d64c327..c4b26d2ea 100644 --- a/SRU2023-9/integrator/cbpr/index.html +++ b/SRU2023-9/integrator/cbpr/index.html @@ -2189,7 +2189,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/mule/index.html b/SRU2023-9/integrator/mule/index.html index af580a1a9..6667da798 100644 --- a/SRU2023-9/integrator/mule/index.html +++ b/SRU2023-9/integrator/mule/index.html @@ -1999,7 +1999,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/myformat/myformat-config/index.html b/SRU2023-9/integrator/myformat/myformat-config/index.html index 02687fb6b..bcce02f33 100644 --- a/SRU2023-9/integrator/myformat/myformat-config/index.html +++ b/SRU2023-9/integrator/myformat/myformat-config/index.html @@ -2189,7 +2189,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/myformat/myformat-csv/index.html b/SRU2023-9/integrator/myformat/myformat-csv/index.html index 4bd7e45b5..296bc7291 100644 --- a/SRU2023-9/integrator/myformat/myformat-csv/index.html +++ b/SRU2023-9/integrator/myformat/myformat-csv/index.html @@ -2295,7 +2295,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/myformat/myformat-engine/index.html b/SRU2023-9/integrator/myformat/myformat-engine/index.html index 134d04aad..bdcbef313 100644 --- a/SRU2023-9/integrator/myformat/myformat-engine/index.html +++ b/SRU2023-9/integrator/myformat/myformat-engine/index.html @@ -2053,7 +2053,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/myformat/myformat-fin/index.html b/SRU2023-9/integrator/myformat/myformat-fin/index.html index 9aa17d625..58de33762 100644 --- a/SRU2023-9/integrator/myformat/myformat-fin/index.html +++ b/SRU2023-9/integrator/myformat/myformat-fin/index.html @@ -2067,7 +2067,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/myformat/myformat-fixed/index.html b/SRU2023-9/integrator/myformat/myformat-fixed/index.html index 0fb0e35f2..0eab69456 100644 --- a/SRU2023-9/integrator/myformat/myformat-fixed/index.html +++ b/SRU2023-9/integrator/myformat/myformat-fixed/index.html @@ -2255,7 +2255,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/myformat/myformat-json/index.html b/SRU2023-9/integrator/myformat/myformat-json/index.html index fc5af580b..5549ee0c2 100644 --- a/SRU2023-9/integrator/myformat/myformat-json/index.html +++ b/SRU2023-9/integrator/myformat/myformat-json/index.html @@ -2053,7 +2053,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/myformat/myformat-rule/index.html b/SRU2023-9/integrator/myformat/myformat-rule/index.html index 729c2b2fc..327b9714d 100644 --- a/SRU2023-9/integrator/myformat/myformat-rule/index.html +++ b/SRU2023-9/integrator/myformat/myformat-rule/index.html @@ -2095,7 +2095,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/myformat/myformat-setup-commands/index.html b/SRU2023-9/integrator/myformat/myformat-setup-commands/index.html index e9dd57a68..1eb69448a 100644 --- a/SRU2023-9/integrator/myformat/myformat-setup-commands/index.html +++ b/SRU2023-9/integrator/myformat/myformat-setup-commands/index.html @@ -1979,7 +1979,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/myformat/myformat-sql-table/index.html b/SRU2023-9/integrator/myformat/myformat-sql-table/index.html index 367ede51f..681ddf4bc 100644 --- a/SRU2023-9/integrator/myformat/myformat-sql-table/index.html +++ b/SRU2023-9/integrator/myformat/myformat-sql-table/index.html @@ -2067,7 +2067,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/myformat/myformat-transformations/index.html b/SRU2023-9/integrator/myformat/myformat-transformations/index.html index 0df26a90f..1646d4ed1 100644 --- a/SRU2023-9/integrator/myformat/myformat-transformations/index.html +++ b/SRU2023-9/integrator/myformat/myformat-transformations/index.html @@ -2135,7 +2135,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/myformat/myformat-xml/index.html b/SRU2023-9/integrator/myformat/myformat-xml/index.html index 288220216..f12b672fc 100644 --- a/SRU2023-9/integrator/myformat/myformat-xml/index.html +++ b/SRU2023-9/integrator/myformat/myformat-xml/index.html @@ -2067,7 +2067,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/score/index.html b/SRU2023-9/integrator/score/index.html index 81dc87541..c3e3eff72 100644 --- a/SRU2023-9/integrator/score/index.html +++ b/SRU2023-9/integrator/score/index.html @@ -2079,7 +2079,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/sdk/sdk-bicdirectory/index.html b/SRU2023-9/integrator/sdk/sdk-bicdirectory/index.html index a1b61268e..5b6f9f1b1 100644 --- a/SRU2023-9/integrator/sdk/sdk-bicdirectory/index.html +++ b/SRU2023-9/integrator/sdk/sdk-bicdirectory/index.html @@ -2067,7 +2067,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/sdk/sdk-datapdu/index.html b/SRU2023-9/integrator/sdk/sdk-datapdu/index.html index dcdd12571..e3215cc61 100644 --- a/SRU2023-9/integrator/sdk/sdk-datapdu/index.html +++ b/SRU2023-9/integrator/sdk/sdk-datapdu/index.html @@ -2175,7 +2175,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/sdk/sdk-lau/index.html b/SRU2023-9/integrator/sdk/sdk-lau/index.html index aa2165573..d8b441511 100644 --- a/SRU2023-9/integrator/sdk/sdk-lau/index.html +++ b/SRU2023-9/integrator/sdk/sdk-lau/index.html @@ -2217,7 +2217,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/sdk/sdk-mtpath/index.html b/SRU2023-9/integrator/sdk/sdk-mtpath/index.html index d21208763..0deaf2f58 100644 --- a/SRU2023-9/integrator/sdk/sdk-mtpath/index.html +++ b/SRU2023-9/integrator/sdk/sdk-mtpath/index.html @@ -2107,7 +2107,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/sdk/sdk-printout/index.html b/SRU2023-9/integrator/sdk/sdk-printout/index.html index 17b721ff3..5b594943d 100644 --- a/SRU2023-9/integrator/sdk/sdk-printout/index.html +++ b/SRU2023-9/integrator/sdk/sdk-printout/index.html @@ -2133,7 +2133,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/sdk/sdk-schemes/index.html b/SRU2023-9/integrator/sdk/sdk-schemes/index.html index ef8fba908..6883a01c4 100644 --- a/SRU2023-9/integrator/sdk/sdk-schemes/index.html +++ b/SRU2023-9/integrator/sdk/sdk-schemes/index.html @@ -2067,7 +2067,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/sepa/index.html b/SRU2023-9/integrator/sepa/index.html index 7ba3d7a5e..9ece2e7c1 100644 --- a/SRU2023-9/integrator/sepa/index.html +++ b/SRU2023-9/integrator/sepa/index.html @@ -2201,7 +2201,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/sic/index.html b/SRU2023-9/integrator/sic/index.html index cbe158b0f..61acf1b82 100644 --- a/SRU2023-9/integrator/sic/index.html +++ b/SRU2023-9/integrator/sic/index.html @@ -2133,7 +2133,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/translations/translations-avail/index.html b/SRU2023-9/integrator/translations/translations-avail/index.html index 40d9f6d1e..681336bde 100644 --- a/SRU2023-9/integrator/translations/translations-avail/index.html +++ b/SRU2023-9/integrator/translations/translations-avail/index.html @@ -2245,7 +2245,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/translations/translations-factory/index.html b/SRU2023-9/integrator/translations/translations-factory/index.html index d4eec5e42..0b1745b7e 100644 --- a/SRU2023-9/integrator/translations/translations-factory/index.html +++ b/SRU2023-9/integrator/translations/translations-factory/index.html @@ -2187,7 +2187,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/translations/translations-general/index.html b/SRU2023-9/integrator/translations/translations-general/index.html index e5397f7c1..dffefc777 100644 --- a/SRU2023-9/integrator/translations/translations-general/index.html +++ b/SRU2023-9/integrator/translations/translations-general/index.html @@ -2243,7 +2243,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/translations/translations-mt2mx/index.html b/SRU2023-9/integrator/translations/translations-mt2mx/index.html index f1552f9f4..8606845fa 100644 --- a/SRU2023-9/integrator/translations/translations-mt2mx/index.html +++ b/SRU2023-9/integrator/translations/translations-mt2mx/index.html @@ -2053,7 +2053,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/translations/translations-mx2mt/index.html b/SRU2023-9/integrator/translations/translations-mx2mt/index.html index 3844d931e..21340f7e0 100644 --- a/SRU2023-9/integrator/translations/translations-mx2mt/index.html +++ b/SRU2023-9/integrator/translations/translations-mx2mt/index.html @@ -2067,7 +2067,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/validation/validation-bic/index.html b/SRU2023-9/integrator/validation/validation-bic/index.html index 20c513f3c..a4474d2b8 100644 --- a/SRU2023-9/integrator/validation/validation-bic/index.html +++ b/SRU2023-9/integrator/validation/validation-bic/index.html @@ -2025,7 +2025,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/validation/validation-mt/index.html b/SRU2023-9/integrator/validation/validation-mt/index.html index 0a2c2c451..f5bc75648 100644 --- a/SRU2023-9/integrator/validation/validation-mt/index.html +++ b/SRU2023-9/integrator/validation/validation-mt/index.html @@ -2163,7 +2163,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/validation/validation-mx/index.html b/SRU2023-9/integrator/validation/validation-mx/index.html index f2ad07685..807a0a5ae 100644 --- a/SRU2023-9/integrator/validation/validation-mx/index.html +++ b/SRU2023-9/integrator/validation/validation-mx/index.html @@ -2163,7 +2163,7 @@ - +

Restricted content

diff --git a/SRU2023-9/integrator/validation/validation-process/index.html b/SRU2023-9/integrator/validation/validation-process/index.html index 16f9655bc..8b105df73 100644 --- a/SRU2023-9/integrator/validation/validation-process/index.html +++ b/SRU2023-9/integrator/validation/validation-process/index.html @@ -2121,7 +2121,7 @@ - +

Restricted content

diff --git a/SRU2023-9/release-notes/changelog-consolidated/index.html b/SRU2023-9/release-notes/changelog-consolidated/index.html index b648028de..f2a9215fd 100644 --- a/SRU2023-9/release-notes/changelog-consolidated/index.html +++ b/SRU2023-9/release-notes/changelog-consolidated/index.html @@ -2050,15 +2050,15 @@

Bill of materials (BOM)

Prowide Integrator Validation -SRU2023-9.4.23 +SRU2023-9.4.24 Prowide Integrator Translations -SRU2023-9.4.39 +SRU2023-9.4.40 Prowide Integrator MyFormat -SRU2023-9.4.5 +SRU2023-9.4.6 Prowide Integrator CBPR+ diff --git a/SRU2023-9/release-notes/changelog-myformat/index.html b/SRU2023-9/release-notes/changelog-myformat/index.html index 2642045d9..87bedeb13 100644 --- a/SRU2023-9/release-notes/changelog-myformat/index.html +++ b/SRU2023-9/release-notes/changelog-myformat/index.html @@ -1871,8 +1871,8 @@
  • - - 9.4.6 - SNAPSHOT + + 9.4.6 - June 2024
  • @@ -2395,8 +2395,8 @@
    • - - 9.4.6 - SNAPSHOT + + 9.4.6 - June 2024
    • @@ -2808,7 +2808,7 @@

      Prowide Integrator MyFormat - CHANGELOG

      -

      9.4.6 - SNAPSHOT

      +

      9.4.6 - June 2024

      • Added a convenient write method with default write mode in the MessageWriter interface
      diff --git a/SRU2023-9/release-notes/changelog-translations/index.html b/SRU2023-9/release-notes/changelog-translations/index.html index 32f1648e2..2374bc2ba 100644 --- a/SRU2023-9/release-notes/changelog-translations/index.html +++ b/SRU2023-9/release-notes/changelog-translations/index.html @@ -1857,8 +1857,8 @@
      • - - 9.4.40 - SNAPSHOT + + 9.4.40 - June 2024
      • @@ -3102,8 +3102,8 @@
        • - - 9.4.40 - SNAPSHOT + + 9.4.40 - June 2024
        • @@ -4222,9 +4222,12 @@

          Prowide Integrator Translations - CHANGELOG

          -

          9.4.40 - SNAPSHOT

          +

          9.4.40 - June 2024

            +
          • (PW-1897) CBPR+ camt.052.001.08 -> MT941/942: using account currency for fields 90C and 90D when entry currency is not present
          • +
          • (PW-1896) CBPR+ MT200/202/205 -> pacs.009.001.08: create a new UETR for PaymentIdentification\UETR when block3\121 is missing
          • pacs.010.001.03 -> MT204: fixed mappings for fields 58A and 58D
          • +
          • (PW-1859) Added new ISO translator: pain.001.001.09 -> MT103

          9.4.39 - May 2024

            diff --git a/SRU2023-9/search/search_index.json b/SRU2023-9/search/search_index.json index c4852c510..844a26538 100644 --- a/SRU2023-9/search/search_index.json +++ b/SRU2023-9/search/search_index.json @@ -1 +1 @@ -{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"","title":"Home"},{"location":"getting-started/","text":"Getting Started The Open Source section covers the Prowide open source libraries for FIN MT and ISO 20022. The Prowide Integrator section covers the complemetary licensed libraries and tools. Other content in this section provides general information about the standards, and also references for the libraries impementation and maintenance policies. Download The open source libraries are available at Maven Central. The following links provide the coordinates for each libraries: Download coordinates Download Prowide Core Download Prowide ISO 20022 The Prowide Integrator is licensed software, thus download and usage is restricted to licensed customers. To see the changelog of each release, check the release notes section. All libraries are compatible with Java 8+ . Learn by example The online examples at GitHub cover key features of each library. For the open source projects you can just checkout the example project and start running the examples in your IDE. Each example cover a specific feature and is self contained, so you can just run the main method of each example class. The default setup uses Gradle . For the Prowide Integrator, in order to compile and run the examples you need either a production or trial distribution of the required libraries. Examples Prowide Core examples Prowide ISO 20022 examples Prowide Integrator examples Compile and Run The primary intention of the examples is to show code. Most of them produce some kind of output though. All example classes have a main method that you can easily run in your IDE. This project can serve as a template for your own, allowing you to copy and customize examples to fit your requirements. To leverage this, you must incorporate Prowide libraries into your project. There are two main approaches to integrate Prowide dependencies: 1) Direct Use of JARs from Your Local Environment: This approach suits projects that manually manage dependencies. Obtain the JARs by downloading the open-source libraries from core and iso20022 , or by extracting them from a Prowide-provided zip file. Follow these steps to use this method: After downloading the necessary JAR files, copy them to your project's lib folder. In the root directory of the prowide integrator examples project, find the lib folder containing a put_your_jars_here.txt placeholder. Replace this file with the JAR files you've downloaded, ensuring they're placed at the same level as the placeholder. This placeholder file lists example JAR names for reference. For Maven projects, start with the mvn local pom.xml example as a template and customize it as needed. For Gradle projects, begin with the build.gradle example and modify accordingly. If not using Maven or Gradle, directly include all necessary JARs in your classpath. 2) Accessing Libraries via Prowide's Remote Repository: : Most projects benefit from this method, as it simplifies dependency management and ensures access to the latest library versions. Configure your project to use the Prowide Nexus repository. We offer templates for both Maven and Gradle to facilitate this process. This method also applies if you have local access to the libraries and wish to copy them to your local repository. For Maven projects: Use the pom.xml example as a starting template and adapt it to your project. Incorporate settings from our settings.xml example into your Maven settings file to configure Nexus repository access. For Gradle projects: Start with the build.gradle example and adjust as necessary. Ensure to include the gradle.properties example in your Gradle settings for proper Nexus repository configuration. These guidelines help you effectively incorporate Prowide libraries into your project, whether by direct JAR integration or through remote repository access. Each of these methods offers a different approach to managing dependencies, so select the one that aligns best with your project setup and management preferences. Important Note on Library Versions Prowide regularly releases new versions of its libraries. As such, the versions of the libraries you use may need to be updated over time. To check the latest versions and relevant changes, please visit the Prowide Release Notes . It is recommended to regularly review this page and update your project's library versions accordingly to ensure compatibility and access to the latest features and fixes. Learn by reading If you prefer to learn concepts step by step, our developer guides is the best place to start. Every chapter cover a specific feature and it is no necesarry built on the knowledge introduced in the previous chapters, so you can freely navigate to the sections you are interested in. Most of the online examples are also covered in the developer guides, so if you rather use the documentation pages you will not be missing anything. The developer guides are a permament reference you can reach at any time, while starting your journey with the libraries or when you need additional knowledge about a specific feature in an advance stage. Notice the Prowide Integrator developer guides are not public. A password is required to access the full content. The guides are constantly updated and improved, so you can always check for new content. Documentation Prowide Core developer guide Prowide ISO 20022 developer guide Prowide Integrator developer guides API reference The Javadoc is the reference for the API of each library. It is automatically generated from the source code and it is available online. Javadoc Prowide Core Javadoc Prowide ISO 20022 Javadoc Prowide Integrator SDK Javadoc SRU2023-9.4.x Prowide Integrator Validation Javadoc SRU2023-9.4.x Prowide Integrator Translations Javadoc SRU2023-9.4.x Prowide Integrator MyFormat Javadoc SRU2023-9.4.x Prowide Integrator CBPR+ Javadoc SRU2023-9.4.x Prowide Integrator SEPA Javadoc SRU2023-9.4.x Prowide Integrator SIC Javadoc SRU2023-9.4.x Prowide Integrator SCORE Javadoc SRU2023-9.4.x Note the Prowide Integrator Javadoc is not public. A password is required to access. SWIFT Resources The development documentation assumes some familiarity with the SWIFT MT and ISO 20022 standards. You don\u2019t have to be an expert, but it\u2019s harder to learn how to use the libraries API without the fundamental ideas of the message structures it handles. The About SWIFT section provides a brief introduction to the standards, and links to the official SWIFT documentation. Issues For open source users, you can post Issues or questions at the relevant GitHub repositories: Issues Prowide Core Issues Prowide ISO 20022 Issues Please check the existing opened and closed tickets first before posting a new one. A Prowide developer or any other community user would normally reverts back within a few days. Prowide Integrator customers For commercial customers, please use the support email or Jira portal for your inquiries. Notice that request from non-registered email address are not catched by the Service Desk, and thus ignored.","title":"Getting Started"},{"location":"getting-started/#getting-started","text":"The Open Source section covers the Prowide open source libraries for FIN MT and ISO 20022. The Prowide Integrator section covers the complemetary licensed libraries and tools. Other content in this section provides general information about the standards, and also references for the libraries impementation and maintenance policies.","title":"Getting Started"},{"location":"getting-started/#download","text":"The open source libraries are available at Maven Central. The following links provide the coordinates for each libraries: Download coordinates Download Prowide Core Download Prowide ISO 20022 The Prowide Integrator is licensed software, thus download and usage is restricted to licensed customers. To see the changelog of each release, check the release notes section. All libraries are compatible with Java 8+ .","title":"Download"},{"location":"getting-started/#learn-by-example","text":"The online examples at GitHub cover key features of each library. For the open source projects you can just checkout the example project and start running the examples in your IDE. Each example cover a specific feature and is self contained, so you can just run the main method of each example class. The default setup uses Gradle . For the Prowide Integrator, in order to compile and run the examples you need either a production or trial distribution of the required libraries. Examples Prowide Core examples Prowide ISO 20022 examples Prowide Integrator examples","title":"Learn by example"},{"location":"getting-started/#compile-and-run","text":"The primary intention of the examples is to show code. Most of them produce some kind of output though. All example classes have a main method that you can easily run in your IDE. This project can serve as a template for your own, allowing you to copy and customize examples to fit your requirements. To leverage this, you must incorporate Prowide libraries into your project. There are two main approaches to integrate Prowide dependencies: 1) Direct Use of JARs from Your Local Environment: This approach suits projects that manually manage dependencies. Obtain the JARs by downloading the open-source libraries from core and iso20022 , or by extracting them from a Prowide-provided zip file. Follow these steps to use this method: After downloading the necessary JAR files, copy them to your project's lib folder. In the root directory of the prowide integrator examples project, find the lib folder containing a put_your_jars_here.txt placeholder. Replace this file with the JAR files you've downloaded, ensuring they're placed at the same level as the placeholder. This placeholder file lists example JAR names for reference. For Maven projects, start with the mvn local pom.xml example as a template and customize it as needed. For Gradle projects, begin with the build.gradle example and modify accordingly. If not using Maven or Gradle, directly include all necessary JARs in your classpath. 2) Accessing Libraries via Prowide's Remote Repository: : Most projects benefit from this method, as it simplifies dependency management and ensures access to the latest library versions. Configure your project to use the Prowide Nexus repository. We offer templates for both Maven and Gradle to facilitate this process. This method also applies if you have local access to the libraries and wish to copy them to your local repository. For Maven projects: Use the pom.xml example as a starting template and adapt it to your project. Incorporate settings from our settings.xml example into your Maven settings file to configure Nexus repository access. For Gradle projects: Start with the build.gradle example and adjust as necessary. Ensure to include the gradle.properties example in your Gradle settings for proper Nexus repository configuration. These guidelines help you effectively incorporate Prowide libraries into your project, whether by direct JAR integration or through remote repository access. Each of these methods offers a different approach to managing dependencies, so select the one that aligns best with your project setup and management preferences. Important Note on Library Versions Prowide regularly releases new versions of its libraries. As such, the versions of the libraries you use may need to be updated over time. To check the latest versions and relevant changes, please visit the Prowide Release Notes . It is recommended to regularly review this page and update your project's library versions accordingly to ensure compatibility and access to the latest features and fixes.","title":"Compile and Run"},{"location":"getting-started/#learn-by-reading","text":"If you prefer to learn concepts step by step, our developer guides is the best place to start. Every chapter cover a specific feature and it is no necesarry built on the knowledge introduced in the previous chapters, so you can freely navigate to the sections you are interested in. Most of the online examples are also covered in the developer guides, so if you rather use the documentation pages you will not be missing anything. The developer guides are a permament reference you can reach at any time, while starting your journey with the libraries or when you need additional knowledge about a specific feature in an advance stage. Notice the Prowide Integrator developer guides are not public. A password is required to access the full content. The guides are constantly updated and improved, so you can always check for new content. Documentation Prowide Core developer guide Prowide ISO 20022 developer guide Prowide Integrator developer guides","title":"Learn by reading"},{"location":"getting-started/#api-reference","text":"The Javadoc is the reference for the API of each library. It is automatically generated from the source code and it is available online. Javadoc Prowide Core Javadoc Prowide ISO 20022 Javadoc Prowide Integrator SDK Javadoc SRU2023-9.4.x Prowide Integrator Validation Javadoc SRU2023-9.4.x Prowide Integrator Translations Javadoc SRU2023-9.4.x Prowide Integrator MyFormat Javadoc SRU2023-9.4.x Prowide Integrator CBPR+ Javadoc SRU2023-9.4.x Prowide Integrator SEPA Javadoc SRU2023-9.4.x Prowide Integrator SIC Javadoc SRU2023-9.4.x Prowide Integrator SCORE Javadoc SRU2023-9.4.x Note the Prowide Integrator Javadoc is not public. A password is required to access.","title":"API reference"},{"location":"getting-started/#swift-resources","text":"The development documentation assumes some familiarity with the SWIFT MT and ISO 20022 standards. You don\u2019t have to be an expert, but it\u2019s harder to learn how to use the libraries API without the fundamental ideas of the message structures it handles. The About SWIFT section provides a brief introduction to the standards, and links to the official SWIFT documentation.","title":"SWIFT Resources"},{"location":"getting-started/#issues","text":"For open source users, you can post Issues or questions at the relevant GitHub repositories: Issues Prowide Core Issues Prowide ISO 20022 Issues Please check the existing opened and closed tickets first before posting a new one. A Prowide developer or any other community user would normally reverts back within a few days. Prowide Integrator customers For commercial customers, please use the support email or Jira portal for your inquiries. Notice that request from non-registered email address are not catched by the Service Desk, and thus ignored.","title":"Issues"},{"location":"getting-started/deprecation/","text":"Deprecation Policy Description of Prowide policy to deprecate API and workaround for backward compatibility Version 1.0 April 2016 Introduction Deprecation and eventual deletion of pieces of code are an essential part of evolution. It's impossible to evolve efficiently without discarding some obsolete or non functional pieces that are naturally left behind in the process of evolving. The main question we address with this policy is how to make this evolution process smooth to our users. If you are facing a blocking issue with some deprecated API check the compatible mode switch below Phases Our deprecation policy consists of a set of phases, from a java deprecation mark for start and throwing an exception at the last phase. Each phase will last at least one year. A method may be retained in a deprecation phase for more time if required. Users are welcome to provide us feedback and comments about deprecation decisions. Phase 1: Initial deprecation In the initial deprecation phase elements are annotated as deprecated. Javadoc explains how to replace that code and why the deprecation occurred. Period: at least 1 year Source Level Compatible: Yes , source code that uses deprecated elements will still compile without modification during this phase. Runtime Level Compatible: Yes , compiled artifacts that use deprecated elements will still execute without modification during this phase. Phase 2: Warn and delay In the second phase a log is printed each time a deprecated method is called. The log explains the replacement that should be used and any specific information related to that API. In order to make sure this log is visible a small pause is made to enable casual revisions to be alert of the situation. This delay is not compulsive and can be turned off by means of an environment variable . Period: at least 2 years from deprecation mark Source Level Compatible: * Yes**, source code that uses deprecated elements will still compile without modification during this phase. Runtime Level Compatible: Yes , compiled artifacts that use deprecated elements will still execute without modification during this phase. However, there will be a visible impact on the runtime due to the log being printed and the pause introduced. Phase 3: Runtime exception In the third phase a runtime exception is thrown each time a deprecated method is called. The exception message explains the replacement that should be used and any specific information related to that API. This exception throwing can be turned off by means of an environment variable in order to enable old behavior. Period: at least 3 years from deprecation mark Source Level Compatible: Yes , source code that uses deprecated elements will still compile without modification during this phase. Runtime Level Compatible: No , a runtime exception will be thrown each time a deprecated method is called, which can break the execution of compiled artifacts that use those elements. However, this impact can be turned off by means of an environment variable. Phase 4: Delete The forth phase involves deleting the deprecated API. This is done only in situations where the code cleaning is justified in order to have a more understandable API. Also note that this would be done at least 4 years after the initial deprecation mark. Period: at least 4 years from deprecation mark Source Level Compatible: No , deprecated elements will be deleted and will no longer be available, so source code that uses those elements will no longer compile without modification. Runtime Level Compatible: No , compiled artifacts that use deprecated elements will no longer execute without modification, since those elements will have been deleted. Compatible mode switch Both phase 2 and phase 3 of deprecation have a visible impact on the runtime. This impact can be turned off in case of emergency, or if for some reason the code can not be adapted to the new API. In order to bypass the deprecation and preserve the old behaviour set the environment variable: PW_DEPRECATED=[nolog][,nodelay][,noexception] For convenience this can also be set directly from Java, adding the following line within your application initialization: DeprecationUtils.setEnv(EnvironmentVariableKey.NODELAY, EnvironmentVariableKey.NOEXCEPTION); Definitions Compatibility is a wide concept, so we'll refine it here: Source Level Compatibility (SLC): means that our software may be upgraded without modification of existing source code that uses it. Note that source level compatibility does not exempt from recompilation, and that's why we also specify the next level of compatibility, which includes this. Runtime Level Compatibility (RLC): means that our software may be upgraded by just replacing the artifacts in a runtime environment without need for recompilation. For example: void setFoo(String) Foo setFoo(String) L1 and L2 are SLC but not RLC. For this type of changes we'll add, if necessary, the practice of creating a new package and using the newer version classes from the new package. For the old classes/packages, we handle what we believe is very important for long term software, a clear deprecation/deletion policy.","title":"Deprecation policy"},{"location":"getting-started/deprecation/#deprecation-policy","text":"Description of Prowide policy to deprecate API and workaround for backward compatibility Version 1.0 April 2016","title":"Deprecation Policy"},{"location":"getting-started/deprecation/#introduction","text":"Deprecation and eventual deletion of pieces of code are an essential part of evolution. It's impossible to evolve efficiently without discarding some obsolete or non functional pieces that are naturally left behind in the process of evolving. The main question we address with this policy is how to make this evolution process smooth to our users. If you are facing a blocking issue with some deprecated API check the compatible mode switch below","title":"Introduction"},{"location":"getting-started/deprecation/#phases","text":"Our deprecation policy consists of a set of phases, from a java deprecation mark for start and throwing an exception at the last phase. Each phase will last at least one year. A method may be retained in a deprecation phase for more time if required. Users are welcome to provide us feedback and comments about deprecation decisions.","title":"Phases"},{"location":"getting-started/deprecation/#phase-1-initial-deprecation","text":"In the initial deprecation phase elements are annotated as deprecated. Javadoc explains how to replace that code and why the deprecation occurred. Period: at least 1 year Source Level Compatible: Yes , source code that uses deprecated elements will still compile without modification during this phase. Runtime Level Compatible: Yes , compiled artifacts that use deprecated elements will still execute without modification during this phase.","title":"Phase 1: Initial deprecation"},{"location":"getting-started/deprecation/#phase-2-warn-and-delay","text":"In the second phase a log is printed each time a deprecated method is called. The log explains the replacement that should be used and any specific information related to that API. In order to make sure this log is visible a small pause is made to enable casual revisions to be alert of the situation. This delay is not compulsive and can be turned off by means of an environment variable . Period: at least 2 years from deprecation mark Source Level Compatible: * Yes**, source code that uses deprecated elements will still compile without modification during this phase. Runtime Level Compatible: Yes , compiled artifacts that use deprecated elements will still execute without modification during this phase. However, there will be a visible impact on the runtime due to the log being printed and the pause introduced.","title":"Phase 2: Warn and delay"},{"location":"getting-started/deprecation/#phase-3-runtime-exception","text":"In the third phase a runtime exception is thrown each time a deprecated method is called. The exception message explains the replacement that should be used and any specific information related to that API. This exception throwing can be turned off by means of an environment variable in order to enable old behavior. Period: at least 3 years from deprecation mark Source Level Compatible: Yes , source code that uses deprecated elements will still compile without modification during this phase. Runtime Level Compatible: No , a runtime exception will be thrown each time a deprecated method is called, which can break the execution of compiled artifacts that use those elements. However, this impact can be turned off by means of an environment variable.","title":"Phase 3: Runtime exception"},{"location":"getting-started/deprecation/#phase-4-delete","text":"The forth phase involves deleting the deprecated API. This is done only in situations where the code cleaning is justified in order to have a more understandable API. Also note that this would be done at least 4 years after the initial deprecation mark. Period: at least 4 years from deprecation mark Source Level Compatible: No , deprecated elements will be deleted and will no longer be available, so source code that uses those elements will no longer compile without modification. Runtime Level Compatible: No , compiled artifacts that use deprecated elements will no longer execute without modification, since those elements will have been deleted.","title":"Phase 4: Delete"},{"location":"getting-started/deprecation/#compatible-mode-switch","text":"Both phase 2 and phase 3 of deprecation have a visible impact on the runtime. This impact can be turned off in case of emergency, or if for some reason the code can not be adapted to the new API. In order to bypass the deprecation and preserve the old behaviour set the environment variable: PW_DEPRECATED=[nolog][,nodelay][,noexception] For convenience this can also be set directly from Java, adding the following line within your application initialization: DeprecationUtils.setEnv(EnvironmentVariableKey.NODELAY, EnvironmentVariableKey.NOEXCEPTION);","title":"Compatible mode switch"},{"location":"getting-started/deprecation/#definitions","text":"Compatibility is a wide concept, so we'll refine it here: Source Level Compatibility (SLC): means that our software may be upgraded without modification of existing source code that uses it. Note that source level compatibility does not exempt from recompilation, and that's why we also specify the next level of compatibility, which includes this. Runtime Level Compatibility (RLC): means that our software may be upgraded by just replacing the artifacts in a runtime environment without need for recompilation. For example: void setFoo(String) Foo setFoo(String) L1 and L2 are SLC but not RLC. For this type of changes we'll add, if necessary, the practice of creating a new package and using the newer version classes from the new package. For the old classes/packages, we handle what we believe is very important for long term software, a clear deprecation/deletion policy.","title":"Definitions"},{"location":"getting-started/download-core/","text":"Prowide Core Download Information to grab the library from Maven central repository or download. Gradle compile group: 'com.prowidesoftware' , name: 'pw-swift-core' , version: 'SRU2023-9.4.16' Maven com.prowidesoftware pw-swift-core SRU2023-9.4.16 You can also check out our listing at https://mvnrepository.com/artifact/com.prowidesoftware/pw-swift-core Zip archive For non-maven projects you need to download the full distribution zip and setup your IDE to include the pw-swift-core-SRU2023-9.4.16.jar and the external dependencies in your project classpath. The downloaded package is always a single zip file with the full distribution including: pw-swift-core-SRU2023-9.4.16.jar: the library itself pw-swift-core-SRU2023-9.4.16-javadoc.jar: the javadoc, also available online pw-swift-core-SRU2023-9.4.16-sources.jar: the source code, also available at GitHub lib: required dependency jar files Download SRU2023-9.4.16","title":"Download Core"},{"location":"getting-started/download-core/#prowide-core-download","text":"Information to grab the library from Maven central repository or download.","title":"Prowide Core Download"},{"location":"getting-started/download-core/#gradle","text":"compile group: 'com.prowidesoftware' , name: 'pw-swift-core' , version: 'SRU2023-9.4.16'","title":"Gradle"},{"location":"getting-started/download-core/#maven","text":" com.prowidesoftware pw-swift-core SRU2023-9.4.16 You can also check out our listing at https://mvnrepository.com/artifact/com.prowidesoftware/pw-swift-core","title":"Maven"},{"location":"getting-started/download-core/#zip-archive","text":"For non-maven projects you need to download the full distribution zip and setup your IDE to include the pw-swift-core-SRU2023-9.4.16.jar and the external dependencies in your project classpath. The downloaded package is always a single zip file with the full distribution including: pw-swift-core-SRU2023-9.4.16.jar: the library itself pw-swift-core-SRU2023-9.4.16-javadoc.jar: the javadoc, also available online pw-swift-core-SRU2023-9.4.16-sources.jar: the source code, also available at GitHub lib: required dependency jar files Download SRU2023-9.4.16","title":"Zip archive"},{"location":"getting-started/download-iso20022/","text":"Prowide ISO 20022 Download Information to grab the library from Maven central repository or download. Gradle compile group: 'com.prowidesoftware' , name: 'pw-iso20022' , version: 'SRU2023-9.4.5' Maven com.prowidesoftware pw-iso20022 SRU2023-9.4.5 You can also check out our listing at https://mvnrepository.com/artifact/com.prowidesoftware/pw-iso20022 Zip archive For non-maven projects you need to download the full distribution zip and setup your IDE to include the pw-iso20022-SRU2023-9.4.5.jar and the external dependencies in your project classpath. The downloaded package is always a single zip file with the full distribution including: pw-iso20022-SRU2023-9.4.5.jar: the library itself pw-iso20022-SRU2023-9.4.5-javadoc.jar: the javadoc, also available online pw-iso20022-SRU2023-9.4.5-sources.jar: the source code, also available at GitHub lib: required dependency jar files Download SRU2023-9.4.5","title":"Download ISO 20022"},{"location":"getting-started/download-iso20022/#prowide-iso-20022-download","text":"Information to grab the library from Maven central repository or download.","title":"Prowide ISO 20022 Download"},{"location":"getting-started/download-iso20022/#gradle","text":"compile group: 'com.prowidesoftware' , name: 'pw-iso20022' , version: 'SRU2023-9.4.5'","title":"Gradle"},{"location":"getting-started/download-iso20022/#maven","text":" com.prowidesoftware pw-iso20022 SRU2023-9.4.5 You can also check out our listing at https://mvnrepository.com/artifact/com.prowidesoftware/pw-iso20022","title":"Maven"},{"location":"getting-started/download-iso20022/#zip-archive","text":"For non-maven projects you need to download the full distribution zip and setup your IDE to include the pw-iso20022-SRU2023-9.4.5.jar and the external dependencies in your project classpath. The downloaded package is always a single zip file with the full distribution including: pw-iso20022-SRU2023-9.4.5.jar: the library itself pw-iso20022-SRU2023-9.4.5-javadoc.jar: the javadoc, also available online pw-iso20022-SRU2023-9.4.5-sources.jar: the source code, also available at GitHub lib: required dependency jar files Download SRU2023-9.4.5","title":"Zip archive"},{"location":"getting-started/versioning/","text":"Prowide versioning All Prowide artifacts are versioned using a semantic version with an SRU prefix. SRU stands for SWIFT Standard release Update, and it refers to the yearly updates of the MT and MX standards. The new release specification is normally available in the first quarter of the year, entering production by late November. All participants have to upgrade their systems the same day, and there is one and only one version of the standards per year. Since Prowide artifacts are packaged for a specific version of the standard; the SRU is part of the artifacts version, for example: SRU2021-7.8.9 The first part indicates the yearly standard the artifact is compliant to, and the second part uses the traditional format of http://semver.org/ with the following semantic features: The major version number is only changed when we do a big breaking change, just as upgrading the required Java version for the library products. The minnor number, although it is for minor version, we are aligning it to the SRUs. That is, it is increased annually so that the version alone also has the version of the standard implicit. If SRU2021 is 7.8, then SRU2022 is 7.9, and so forth. Meaning the minor version is redundant with the SRU prefix. The patch number is the one we actually change on all intermediate releases. Depending on the product this could be monthly or weekly. Which version should I use? Normally, from January to late November you should use for production the SRU matching the previous calendar year. Since that would be the version of the standards that is live in the network. Prowide mades available the upcoming SRU packages for the general public by late October, one month before production. And six months in advance, by May, for commercial customers. You can check the SWIFT standard releases schedule at https://www.swift.com/standards/standards-releases","title":"Versioning"},{"location":"getting-started/versioning/#prowide-versioning","text":"All Prowide artifacts are versioned using a semantic version with an SRU prefix. SRU stands for SWIFT Standard release Update, and it refers to the yearly updates of the MT and MX standards. The new release specification is normally available in the first quarter of the year, entering production by late November. All participants have to upgrade their systems the same day, and there is one and only one version of the standards per year. Since Prowide artifacts are packaged for a specific version of the standard; the SRU is part of the artifacts version, for example: SRU2021-7.8.9 The first part indicates the yearly standard the artifact is compliant to, and the second part uses the traditional format of http://semver.org/ with the following semantic features: The major version number is only changed when we do a big breaking change, just as upgrading the required Java version for the library products. The minnor number, although it is for minor version, we are aligning it to the SRUs. That is, it is increased annually so that the version alone also has the version of the standard implicit. If SRU2021 is 7.8, then SRU2022 is 7.9, and so forth. Meaning the minor version is redundant with the SRU prefix. The patch number is the one we actually change on all intermediate releases. Depending on the product this could be monthly or weekly.","title":"Prowide versioning"},{"location":"getting-started/versioning/#which-version-should-i-use","text":"Normally, from January to late November you should use for production the SRU matching the previous calendar year. Since that would be the version of the standards that is live in the network. Prowide mades available the upcoming SRU packages for the general public by late October, one month before production. And six months in advance, by May, for commercial customers. You can check the SWIFT standard releases schedule at https://www.swift.com/standards/standards-releases","title":"Which version should I use?"},{"location":"getting-started/swift/","text":"About SWIFT This information is provided as a quick introduction to the SWIFT standard and the MT format. For detail information please check out www.swift.com The acronym stands for Society for Worldwide Interbank Financial Telecommunications. SWIFT is a cooperative society under Belgian law and it is owned by its member financial institutions. It has offices around the world, and SWIFT headquarters are in La Hulpe, Belgium, near Brussels. It mainly provides a network that enables financial institutions worldwide to send and receive information about financial transactions in a secure, standardized and reliable environment. The term SWIFT is normally used indistinctly to reference the society, the network, the system, and the message protocol. Each financial institution, to exchange banking transactions, must have a banking relationship by either being a bank or affiliating itself with one (or more). The organizations types that can access the service are: Banks, Trading Institutions, Money Brokers, Securities Broker Dealers, Investment Management Institutions, Clearing Systems and Central Depositories, Recognised Exchanges, Trust and Fiduciary Service Companies, Subsidiary Providers of Custody and Nominees, Treasury Counterparties, Treasury ETC Service Providers and Corporates. SWIFT has become the industry standard for syntax in financial messages. Messages formatted to SWIFT standards can be read by, and processed by, many well-known financial processing systems, whether or not the message traveled over the SWIFT network. The SWIFT network support two message standards: MT (ISO 15022): standard based on a proprietary format, composed of boundary delimited blocks, also knonw as FIN MX (ISO 20022): the new standard based on XML syntax and XSD schemas.","title":"About SWIFT"},{"location":"getting-started/swift/#about-swift","text":"This information is provided as a quick introduction to the SWIFT standard and the MT format. For detail information please check out www.swift.com The acronym stands for Society for Worldwide Interbank Financial Telecommunications. SWIFT is a cooperative society under Belgian law and it is owned by its member financial institutions. It has offices around the world, and SWIFT headquarters are in La Hulpe, Belgium, near Brussels. It mainly provides a network that enables financial institutions worldwide to send and receive information about financial transactions in a secure, standardized and reliable environment. The term SWIFT is normally used indistinctly to reference the society, the network, the system, and the message protocol. Each financial institution, to exchange banking transactions, must have a banking relationship by either being a bank or affiliating itself with one (or more). The organizations types that can access the service are: Banks, Trading Institutions, Money Brokers, Securities Broker Dealers, Investment Management Institutions, Clearing Systems and Central Depositories, Recognised Exchanges, Trust and Fiduciary Service Companies, Subsidiary Providers of Custody and Nominees, Treasury Counterparties, Treasury ETC Service Providers and Corporates. SWIFT has become the industry standard for syntax in financial messages. Messages formatted to SWIFT standards can be read by, and processed by, many well-known financial processing systems, whether or not the message traveled over the SWIFT network. The SWIFT network support two message standards: MT (ISO 15022): standard based on a proprietary format, composed of boundary delimited blocks, also knonw as FIN MX (ISO 20022): the new standard based on XML syntax and XSD schemas.","title":"About SWIFT"},{"location":"getting-started/swift/swift-mt/","text":"SWIFT MT The following section describes the MT message structure and key concepts of the standard. Message Types FIN MT messages are identified by a 3-digit number, the first digit representing the Category and the following two representing the specific message inside the category. The categories are: Category Description Prowide Model classes 0 System Messages MT0nn 1 Customer Payments MT1nn 2 Financial Institution Transfers MT2nn 3 MT3nn - FX, Money Market & Derivatives MT3nn 4 Collections and cash letters MT4nn 5 Securities Markets MT5nn 6 Precious Metals & Syndications MT6nn 7 Documentary Credits & Guarantees MT7nn 8 Travellers Cheques MT8nn 9 Cash Management & Customer Status MT9nn For example MT103 is a Single Customer Credit Transfer, while MT202 is a General Financial Institution Transfer. There are several hundred of message types in total. MT Message Block Structure FIN MT messages consist of five blocks of data including three headers, message content, and a trailer. {1: Basic Header Block}{2: Application Header Block}{3: User Header Block} {4: Text Block or body} {5: Trailer Block} All blocks have the same basic format: {n:...}. The curly braces indicate the beginning and end of a block and n is the block identifier (between 1 and 5). There is no carriage return or line feed between blocks. Blocks 3, 4, and 5 may contain sub-blocks or fields delimited by field tags. Block 3 is optional. {1: Basic Header Block} The basic header block is fixed-length and continuous with no field delimiters. It includes the following fields: Application ID (F for financial application, A for general purpose application or L for login and session management) Service ID (01 = FIN/GPA, 21 = ACK/NAK) Logical terminal (LT) address. It is fixed at 12 characters; it must not have X in position 9. Example BANKBEBBAXXX. Session number (four digits) and Sequence number (six digits). {2: Application Header Block} There are two types of application headers: Input and Output (from the network perspective). Both are fixed-length and continuous with no field delimiters. Input Used in outgoing messages, when a message is input to the SWIFT network. It includes the following fields: I = Input Message type Receiver's address with X in position 9/ It is padded with Xs if no branch is required. Example: BANKDEFFXXXX The message priority (S = System, N = Normal, U = Urgent) Delivery monitoring (1 = Non delivery warning, 2 = Delivery notification, 3 = Both valid Obsolescence period. It specifies when a non-delivery notification (003 - 15 minutes, 020 - 100 minutes) Output Used in incoming messages, when a message is output from the SWIFT network. It includes the following fields; for example: O 101 1200 220112 BANKBEBBAXXX 2222 123456 220112 1201 N O = Output 101 = Message type 1200 = Input time with respect to the sender 220112 = the MIR date (message input reference) in YYMMDD format BANKBEBBAXXX = 12 characters containing the logical terminal field of the MIR (address of the sender of the message) 2222 = 4 characters containing the session number field of the MIR 123456 = 6 characters containing the sequence number field of the MIR 220112 = String of 6 characters containing the Output date local to the receiver, written in the following format: YYMMDD 1201 = 4 characters containing the Output time local to the receiver, written in the following format: HHMM N = Priority The Message Input Reference (MIR) is sometimes confusing because it is an output block with an input reference. The important thing to understand here is that the MIR information is related to the original sender of the message that has been received. {3: User Header Block} This is an optional block and can include several tags, being the most common: 113:xxxx = Optional banking priority code The Message User Reference (MUR) used by applications for reconciliation with ACK. {4: Text Block or body} This block is where the actual message content. The format, which is variable length and requires use of CRLF as a field delimiter, is as follows: {4: [CRLF] :20:PAYREFTB54302 [CRLF] :32A:970103BEF1000000, [CRLF] :50:CUSTOMER NAME [CRLF] AND ADDRESS [CRLF] :59:/123-456-789 [CRLF] BENEFICIARY NAME [CRLF] AND ADDRESS [CRLF] -} Where the CRLF is the carriage return and line feed and is the mandatory fields delimiter. The content of the text block is a collection of ordered fields in the order specified for the message type. For some message types, the fields are logically grouped into sequences. Sequences can be mandatory or optional, and can repeat. Sequences also can be divided into subsequences. In addition, single fields and groups of consecutive fields can repeat. {5: Trailer Block} This block is mostly for SWIFT system use and contains a number of fields that are denoted by keywords and put into curly braces, for example: {5: {MAC:12345678}{CHK:123456789ABC}} The most common fields used in the trailer block are MAC: Message Authentication Code calculated based on the entire contents of the message using a pre exchanged key and a secret algorithm. CHK: Checksum calculated for all message types. PDE: Possible Duplicate Emission added if user thinks the same message was sent previously. DLM: Added by SWIFT if an urgent message (U) has not been delivered within 15 minutes, or a normal message (N) within 100 minutes. MIR and MOR MIR (message input reference) and MOR (message output reference) are messages unique identifiers containing the date, logical terminal (including branch code), session and sequence numbers. Nevertheless this identifiers can be confusing sometimes because they must be thought from SWIFT perspective. A message created by the sender user/application is considered an INPUT message, because it gets into the SWIFT network. When the message is delivered and gets out of the network it is considered an OUTPUT message. Therefore the headers of a sent message are not exactly the same as the headers of the received message at the destination party. Analogous the headers of a message that the receiving user/application gets from SWIFT are not exactly the same as the headers when the message was created and sent by the sending party. The usage of MIR and MOR are clear when analyzing system messages. A non delivery warning for example, includes the original MIR of the sent message, but not the MOR because the message was not delivered yet. But a delivery confirmation on the other hand, includes both, the sender's MIR and the receiver's MOR. System messages provide MIR/MOR information using fields 106 and 107 respectively. SCORE Standardised CORporate Environment (SCORE) is a SWIFT standard for the exchange of financial information between corporate customers and their banks. For MT messages, it is based on exchanges of the MT798 proprietary envelop message with many sub-message types. Some of the inner payloads are MT messages, but other are proprietary messages defined just for SCORE. The Prowide Core library contains several helper API to handle the MT798 envelop and the inner messages. And the Prowide Integrator library complements that, by adding a set of specific model classes for each SCORE message such as the MT798<745>, 798<760>, 798<726>, etc... along the full structure validation of the envelop and the inner messages.","title":"SWIFT MT"},{"location":"getting-started/swift/swift-mt/#swift-mt","text":"The following section describes the MT message structure and key concepts of the standard.","title":"SWIFT MT"},{"location":"getting-started/swift/swift-mt/#message-types","text":"FIN MT messages are identified by a 3-digit number, the first digit representing the Category and the following two representing the specific message inside the category. The categories are: Category Description Prowide Model classes 0 System Messages MT0nn 1 Customer Payments MT1nn 2 Financial Institution Transfers MT2nn 3 MT3nn - FX, Money Market & Derivatives MT3nn 4 Collections and cash letters MT4nn 5 Securities Markets MT5nn 6 Precious Metals & Syndications MT6nn 7 Documentary Credits & Guarantees MT7nn 8 Travellers Cheques MT8nn 9 Cash Management & Customer Status MT9nn For example MT103 is a Single Customer Credit Transfer, while MT202 is a General Financial Institution Transfer. There are several hundred of message types in total.","title":"Message Types"},{"location":"getting-started/swift/swift-mt/#mt-message-block-structure","text":"FIN MT messages consist of five blocks of data including three headers, message content, and a trailer. {1: Basic Header Block}{2: Application Header Block}{3: User Header Block} {4: Text Block or body} {5: Trailer Block} All blocks have the same basic format: {n:...}. The curly braces indicate the beginning and end of a block and n is the block identifier (between 1 and 5). There is no carriage return or line feed between blocks. Blocks 3, 4, and 5 may contain sub-blocks or fields delimited by field tags. Block 3 is optional.","title":"MT Message Block Structure"},{"location":"getting-started/swift/swift-mt/#1-basic-header-block","text":"The basic header block is fixed-length and continuous with no field delimiters. It includes the following fields: Application ID (F for financial application, A for general purpose application or L for login and session management) Service ID (01 = FIN/GPA, 21 = ACK/NAK) Logical terminal (LT) address. It is fixed at 12 characters; it must not have X in position 9. Example BANKBEBBAXXX. Session number (four digits) and Sequence number (six digits).","title":"{1: Basic Header Block}"},{"location":"getting-started/swift/swift-mt/#2-application-header-block","text":"There are two types of application headers: Input and Output (from the network perspective). Both are fixed-length and continuous with no field delimiters.","title":"{2: Application Header Block}"},{"location":"getting-started/swift/swift-mt/#input","text":"Used in outgoing messages, when a message is input to the SWIFT network. It includes the following fields: I = Input Message type Receiver's address with X in position 9/ It is padded with Xs if no branch is required. Example: BANKDEFFXXXX The message priority (S = System, N = Normal, U = Urgent) Delivery monitoring (1 = Non delivery warning, 2 = Delivery notification, 3 = Both valid Obsolescence period. It specifies when a non-delivery notification (003 - 15 minutes, 020 - 100 minutes)","title":"Input"},{"location":"getting-started/swift/swift-mt/#output","text":"Used in incoming messages, when a message is output from the SWIFT network. It includes the following fields; for example: O 101 1200 220112 BANKBEBBAXXX 2222 123456 220112 1201 N O = Output 101 = Message type 1200 = Input time with respect to the sender 220112 = the MIR date (message input reference) in YYMMDD format BANKBEBBAXXX = 12 characters containing the logical terminal field of the MIR (address of the sender of the message) 2222 = 4 characters containing the session number field of the MIR 123456 = 6 characters containing the sequence number field of the MIR 220112 = String of 6 characters containing the Output date local to the receiver, written in the following format: YYMMDD 1201 = 4 characters containing the Output time local to the receiver, written in the following format: HHMM N = Priority The Message Input Reference (MIR) is sometimes confusing because it is an output block with an input reference. The important thing to understand here is that the MIR information is related to the original sender of the message that has been received.","title":"Output"},{"location":"getting-started/swift/swift-mt/#3-user-header-block","text":"This is an optional block and can include several tags, being the most common: 113:xxxx = Optional banking priority code The Message User Reference (MUR) used by applications for reconciliation with ACK.","title":"{3: User Header Block}"},{"location":"getting-started/swift/swift-mt/#4-text-block-or-body","text":"This block is where the actual message content. The format, which is variable length and requires use of CRLF as a field delimiter, is as follows: {4: [CRLF] :20:PAYREFTB54302 [CRLF] :32A:970103BEF1000000, [CRLF] :50:CUSTOMER NAME [CRLF] AND ADDRESS [CRLF] :59:/123-456-789 [CRLF] BENEFICIARY NAME [CRLF] AND ADDRESS [CRLF] -} Where the CRLF is the carriage return and line feed and is the mandatory fields delimiter. The content of the text block is a collection of ordered fields in the order specified for the message type. For some message types, the fields are logically grouped into sequences. Sequences can be mandatory or optional, and can repeat. Sequences also can be divided into subsequences. In addition, single fields and groups of consecutive fields can repeat.","title":"{4: Text Block or body}"},{"location":"getting-started/swift/swift-mt/#5-trailer-block","text":"This block is mostly for SWIFT system use and contains a number of fields that are denoted by keywords and put into curly braces, for example: {5: {MAC:12345678}{CHK:123456789ABC}} The most common fields used in the trailer block are MAC: Message Authentication Code calculated based on the entire contents of the message using a pre exchanged key and a secret algorithm. CHK: Checksum calculated for all message types. PDE: Possible Duplicate Emission added if user thinks the same message was sent previously. DLM: Added by SWIFT if an urgent message (U) has not been delivered within 15 minutes, or a normal message (N) within 100 minutes.","title":"{5: Trailer Block}"},{"location":"getting-started/swift/swift-mt/#mir-and-mor","text":"MIR (message input reference) and MOR (message output reference) are messages unique identifiers containing the date, logical terminal (including branch code), session and sequence numbers. Nevertheless this identifiers can be confusing sometimes because they must be thought from SWIFT perspective. A message created by the sender user/application is considered an INPUT message, because it gets into the SWIFT network. When the message is delivered and gets out of the network it is considered an OUTPUT message. Therefore the headers of a sent message are not exactly the same as the headers of the received message at the destination party. Analogous the headers of a message that the receiving user/application gets from SWIFT are not exactly the same as the headers when the message was created and sent by the sending party. The usage of MIR and MOR are clear when analyzing system messages. A non delivery warning for example, includes the original MIR of the sent message, but not the MOR because the message was not delivered yet. But a delivery confirmation on the other hand, includes both, the sender's MIR and the receiver's MOR. System messages provide MIR/MOR information using fields 106 and 107 respectively.","title":"MIR and MOR"},{"location":"getting-started/swift/swift-mt/#score","text":"Standardised CORporate Environment (SCORE) is a SWIFT standard for the exchange of financial information between corporate customers and their banks. For MT messages, it is based on exchanges of the MT798 proprietary envelop message with many sub-message types. Some of the inner payloads are MT messages, but other are proprietary messages defined just for SCORE. The Prowide Core library contains several helper API to handle the MT798 envelop and the inner messages. And the Prowide Integrator library complements that, by adding a set of specific model classes for each SCORE message such as the MT798<745>, 798<760>, 798<726>, etc... along the full structure validation of the envelop and the inner messages.","title":"SCORE"},{"location":"getting-started/swift/swift-mx/","text":"ISO 20022 The ISO 20022 is a framework for the electronic exchange of financial information, composed by a catalog of items and message types, structured as XML payloads. The framework allows communities of users and message development organizations to define message sets according to an internationally agreed approach using internationally agreed business semantics. By creating a common language and model for payments data, ISO 20022 significantly improves the quality of data across the payments ecosystem. ISO 20022 creates a common language and model for payments data, ISO 20022 significantly improves the quality of data across the payments ecosystem. Richer, structured, meaningful data enable new client experiences, while improving compliance and efficiency. ISO 20022 defines many message categories, including: Payments and Cash Management: Messages supporting cash account management, payments initiation, clearing and settlement, and cash management, etc. Securities: Messages supporting pre-trade, trade, post-trade, clearing and settlement, securities management, securities account management, reconciliation, asset servicing, collateral management, etc. Trade Services: Messages supporting procurement, trade finance products and services, forecasting, reconciliation, accounting, remittance information, etc. Card Payments: Messages supporting card transactions between acceptor and acquirer, acquirer and issuer, sale system and POI, terminal management, clearing and settlement, fee collection, etc. Foreign Exchange: Messages supporting pre-trade, trade, post-trade, notification, clearing and settlement, reporting and reconciliation of FX products. MX An MX is an XML message definition for use on the SWIFT network. Documentation is only provided for base messages developed by SWIFT. Most MX messages are also ISO 20022 messages. Other ISO 20022 messages are published on www.iso20022.org. Within our libraries implementatino we use the terns ISO 20022 and MX interchangeably. CBPR+ Cross-border Payments and Reporting Plus(CBPR+) specification define how ISO 20022 should be used for cross-border payments and cash reporting on the SWIFT network. Conformance to CBPR+ specification is validated by the SWIFT message service, so it imperative that users implement the specification correctly. The CBPR+ specification includes a set of restricted ISO 20022 message schemas, along a set of rules that payment message must follow. CBPR+ also includes standardized rules that define translation from the MT standard to CBPR+ ISO 20022 and from CBPR+ ISO 20022 to MT. The Prowide Integrator libraries, contain comprehensive support for the CBPR+ restricted model, parser, validators and translators to and from MT. SEPA Developed by the European Payments Council (EPC), the Single Euro Payments Area (SEPA) is a payment-integration and payment standardization initiative that aims to facilitate and harmonize payments in EURO across the SEPA zone. ISO 20022 XML is mandatory for the exchange of SEPA payments between Banks and for the Client-to-Bank instructions. Thus it can be seen as a restricted version of ISO 20022, or as an implementation of the ISO 20022 framework. The Prowide Integrator libraries, contain comprehensive support for the SEPA restricted model, parser and validator. SIC Swiss Interbank Clearing (SIC) is the Swiss RGTS in which the participating financial institutions process their large-value payments as well as a part of their retail payments in Swiss francs. While SIC is also based on the ISO20022 framework, the namespace is different used by the XSD schemas are different. The Prowide Integrator libraries, contain a specific model for SIC messages, as well as some specific translations between MT and SIC.","title":"ISO 20022"},{"location":"getting-started/swift/swift-mx/#iso-20022","text":"The ISO 20022 is a framework for the electronic exchange of financial information, composed by a catalog of items and message types, structured as XML payloads. The framework allows communities of users and message development organizations to define message sets according to an internationally agreed approach using internationally agreed business semantics. By creating a common language and model for payments data, ISO 20022 significantly improves the quality of data across the payments ecosystem. ISO 20022 creates a common language and model for payments data, ISO 20022 significantly improves the quality of data across the payments ecosystem. Richer, structured, meaningful data enable new client experiences, while improving compliance and efficiency. ISO 20022 defines many message categories, including: Payments and Cash Management: Messages supporting cash account management, payments initiation, clearing and settlement, and cash management, etc. Securities: Messages supporting pre-trade, trade, post-trade, clearing and settlement, securities management, securities account management, reconciliation, asset servicing, collateral management, etc. Trade Services: Messages supporting procurement, trade finance products and services, forecasting, reconciliation, accounting, remittance information, etc. Card Payments: Messages supporting card transactions between acceptor and acquirer, acquirer and issuer, sale system and POI, terminal management, clearing and settlement, fee collection, etc. Foreign Exchange: Messages supporting pre-trade, trade, post-trade, notification, clearing and settlement, reporting and reconciliation of FX products.","title":"ISO 20022"},{"location":"getting-started/swift/swift-mx/#mx","text":"An MX is an XML message definition for use on the SWIFT network. Documentation is only provided for base messages developed by SWIFT. Most MX messages are also ISO 20022 messages. Other ISO 20022 messages are published on www.iso20022.org. Within our libraries implementatino we use the terns ISO 20022 and MX interchangeably.","title":"MX"},{"location":"getting-started/swift/swift-mx/#cbpr","text":"Cross-border Payments and Reporting Plus(CBPR+) specification define how ISO 20022 should be used for cross-border payments and cash reporting on the SWIFT network. Conformance to CBPR+ specification is validated by the SWIFT message service, so it imperative that users implement the specification correctly. The CBPR+ specification includes a set of restricted ISO 20022 message schemas, along a set of rules that payment message must follow. CBPR+ also includes standardized rules that define translation from the MT standard to CBPR+ ISO 20022 and from CBPR+ ISO 20022 to MT. The Prowide Integrator libraries, contain comprehensive support for the CBPR+ restricted model, parser, validators and translators to and from MT.","title":"CBPR+"},{"location":"getting-started/swift/swift-mx/#sepa","text":"Developed by the European Payments Council (EPC), the Single Euro Payments Area (SEPA) is a payment-integration and payment standardization initiative that aims to facilitate and harmonize payments in EURO across the SEPA zone. ISO 20022 XML is mandatory for the exchange of SEPA payments between Banks and for the Client-to-Bank instructions. Thus it can be seen as a restricted version of ISO 20022, or as an implementation of the ISO 20022 framework. The Prowide Integrator libraries, contain comprehensive support for the SEPA restricted model, parser and validator.","title":"SEPA"},{"location":"getting-started/swift/swift-mx/#sic","text":"Swiss Interbank Clearing (SIC) is the Swiss RGTS in which the participating financial institutions process their large-value payments as well as a part of their retail payments in Swiss francs. While SIC is also based on the ISO20022 framework, the namespace is different used by the XSD schemas are different. The Prowide Integrator libraries, contain a specific model for SIC messages, as well as some specific translations between MT and SIC.","title":"SIC"},{"location":"integrator/","text":"Prowide Integrator - Overview Prowide Integrator is a set of complementary Java libraries built on top of the open source. These libraries are licensed software , thus download and usage is restricted to licensed customers. Libraries stack The SDK is the cornerstone library. It provides a set of APIs to interact with SWIFT networks and services, such as SWIFT Alliance Access (SAA). And also extended model classes for specific sub-standards such as CBPR+, SEPA, SIC and SCORE. Complementing the SDK, each additional library provides specific features for standard compliance validation, MT/MX automatic translations and conversions to proprietary formats. Getting a license If you are interested on the Prowide Integrator libraries and features contact Prowide by using the online contact form . Info More information regarding Prowide solutions at www.prowidesoftware.com","title":"Prowide Integrator - Overview"},{"location":"integrator/#prowide-integrator-overview","text":"Prowide Integrator is a set of complementary Java libraries built on top of the open source. These libraries are licensed software , thus download and usage is restricted to licensed customers.","title":"Prowide Integrator - Overview"},{"location":"integrator/#libraries-stack","text":"The SDK is the cornerstone library. It provides a set of APIs to interact with SWIFT networks and services, such as SWIFT Alliance Access (SAA). And also extended model classes for specific sub-standards such as CBPR+, SEPA, SIC and SCORE. Complementing the SDK, each additional library provides specific features for standard compliance validation, MT/MX automatic translations and conversions to proprietary formats.","title":"Libraries stack"},{"location":"integrator/#getting-a-license","text":"If you are interested on the Prowide Integrator libraries and features contact Prowide by using the online contact form . Info More information regarding Prowide solutions at www.prowidesoftware.com","title":"Getting a license"},{"location":"integrator/cbpr/","text":"Prowide Integrator CBPR+ Overview The key feature provided by the CBPR+ extension is the specific model implementation for the Cross Border Payments Reporting Plus specification messages. This is a restricted ISO 20022 version with a subset of messages with specific constraints. The supported schemas and guidelines version is 2.1 effective November 2022. Supported message schemes The following table includes all the supported message types: camt_029_001_09 camt_052_001_08 camt_053_001_08 camt_054_001_08 camt_056_001_08 camt_057_001_06 camt_060_001_05 pacs_002_001_10 pacs_004_001_09 pacs_008_001_08 pacs_008_001_08_STP pacs_009_001_08 pacs_009_001_08_ADV pacs_009_001_08_COV pacs_010_001_03 pain_001_001_09 pain_002_001_10 Message model For each of the described message types, a specific implementation message class is provided, into a single common package: com . prowidesoftware . swift . model . mx . cbpr The CBPR+ message subset uses the same namespaces as the ISO standard. Unknown message type parsing To facilitate message type detection and parsing, a CBPR message factory is included in the package: AbstractMX mx = CbprMessageFactory . createMessage ( xmlContent ); The createMessage method accepts a plain string with the whole XML content. The specific message type is detected using information from the AppHdr element. In particular, using the: pacs.009.001.08 swift.cbprplus.adv.02 Notice the BAH v2 header is mandatory for CBPR+ messages, as well as the BizSvc. If the message is detected as a CBPR+ the method returns its content parsed into a specific model object such as: com.prowidesoftware.swift.model.mx.cbpr.MxPacs00900108ADV The parent class AbstractMX is still as in the generic ISO 20022 model messages, however the specific model for CBPR+ is a class within the cbpr package. Known message type parsing When you already know the message type to parse, you can use the specific model class directly. MxPacs00900108ADV mx = MxPacs00900108ADV . parse ( xmlContent ); The parser imposes no restriction on the validity of the message, just the namespace in the Document must match. And it will fill the model object with all the corresponding elements read from the XML content. The xml could be just the clean payload, or it could also contain any type of wrapper/envelope content that will be silently ignored. Since the class name of the CBPR messages is the same as the class name of the standard ISO 20022 message model, make sure your source code is importing the model class within the cbpr package . Building a message The creation of a new CBPR+ message is similar to the creation of any standard ISO message. You just populate the Java object and the model will already include the constraints from the CBPR+ schema. For example: MxPacs00800108 mx = new MxPacs00800108 (); mx . setFIToFICstmrCdtTrf ( new FIToFICustomerCreditTransferV08 ()); mx . getFIToFICstmrCdtTrf (). setGrpHdr ( new GroupHeader931Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setMsgId ( \"1234\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setCreDtTm ( now ()); // include timezone here mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setNbOfTxs ( \"1\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setSttlmInf ( new SettlementInstruction71Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getSttlmInf (). setSttlmMtd ( SettlementMethod1Code1Pacs008 . INDA ); mx . getFIToFICstmrCdtTrf (). setCdtTrfTxInf ( new CreditTransferTransaction391 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setPmtId ( new PaymentIdentification71 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtId (). setInstrId ( \"REF\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtId (). setEndToEndId ( \"gwwg8dluwzG\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtId (). setTxId ( \"bbbb\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtId (). setUETR ( \"8a562c67-ca16-48ba-b074-65581be6f011\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setPmtTpInf ( new PaymentTypeInformation281 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtTpInf (). setLclInstrm ( new LocalInstrument2Choice1 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtTpInf (). getLclInstrm (). setCd ( \"FOO\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setIntrBkSttlmAmt ( new CBPRAmount1 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getIntrBkSttlmAmt (). setCcy ( \"EUR\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getIntrBkSttlmAmt (). setValue ( new BigDecimal ( \"1234.56\" )); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setChrgBr ( ChargeBearerType1Code1 . CRED ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setDbtr ( new PartyIdentification1352Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getDbtr (). setNm ( \"Foo1\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setDbtrAgt ( new BranchAndFinancialInstitutionIdentification61Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getDbtrAgt (). setFinInstnId ( new FinancialInstitutionIdentification181 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getDbtrAgt (). getFinInstnId (). setBICFI ( \"AAAAUSXXXXX\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setCdtr ( new PartyIdentification1353Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getCdtr (). setNm ( \"Foo2\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setCdtrAgt ( new BranchAndFinancialInstitutionIdentification62Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getCdtrAgt (). setFinInstnId ( new FinancialInstitutionIdentification181 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getCdtrAgt (). getFinInstnId (). setBICFI ( \"AAAAUSXXXXX\" ); String xml = mx . message (); As a small remark, beware when creating date and time objects that the XMLGregorianCalendar object used in the setter should have the time zone set. This is because for CBPR+ the timezone is mandatory. So when creating the object for the setter you should do something like this: LocalDateTime localDate = LocalDateTime . now (); XMLGregorianCalendar cal = DatatypeFactory . newInstance (). newXMLGregorianCalendar ( localDate . toString ()); cal . setTimezone ( - 3 ); Message types enumeration An enumeration CbprMessageType is provided with the list of supported CBPR+ messages. This enumeration implements the internal SchemaProvider interface, so it can be used with the Prowide Integrator Validator library to run the CBPR+ validation for an XML. The enum also includes a few helper methods, for example to detect the specific type from an AppHdr. CBPR+ validation Only available if you have a license of the Prowide Integrator Validation module. Along the standard ISO 20022 model, the Validation module provides an out-of-the-box validation for CBPR+ messages. There are two possible scenarios: * You are validating a message created by you in your application with the message model. * You are validating a message created externally and received in XML format. The main entry point to validate CBPR+ messages is the CbprValidationEngine class. The class provides an entry point using the plain XML content, and also an entry if you already have a model object from the com.prowidesoftware.swift.model.mx.cbpr package, such as MxPain00800108 . This specific validation engine implementation will already apply the CBPR+ specific schema and on top of the standard ISO 20022 and cross-element validations it will check the CBPR+ UG rules. When your source content is already the XML it is always recommended to use the XML as parameter for the validation. If you parse the XML into an MX object first, and then call the validation using the parsed message as parameter, some errors may not be detected. The validation call with the model object is only intended for scenarios where you are building the message using the model API. CBPR+ translations Only available if you have a license of the Prowide Integrator MT/MX Translations module. Along the standard ISO 20022 model, the MT/MX translations module provides out-of-the-box translations for CBPR+ messages. Specific translation classes are provided in the com.prowidesoftware.swift.translations.cbpr Automatic translation Since there are several translation options depending on the message type, a CBPR+ translation factory is provided. AbstractMX mx = CbprMessageFactory . createMessage ( xmlContent ); Translator translator = CbprTranslatorFactory . getTranslator ( mx ); if ( translator == null ) { AbstractMT mt = ( AbstractMT ) translator . translate ( mx ); } First thing is to parse the source XML into a CBPR+ model object. When the message type is unknown, you can do that with ease with the CBPR message factory. The parsed object is then passed to the translator factory. The factory checks the specific message type and in some cases the message content, and determines automatically which translation to apply. If a translator is found, meaning the source message has been detected and satisfies the translation preconditions, the specific translator is returned. All translator classes implement a common interface with the translate method, that given the MX input returns the corresponding MT model output. Analogously, to run a translation from MT to CBPR+, the factory provides an entry to pass the MT model as parameter. This translation procedure is the same as in the ISO 20022 translations, with the only difference being the implementation classes package. Specific translations When the message types are known, the specific translation classes can be used directly. The class name reflects the specific source and target message type, including the available variant combinations. For example, the class MxPacs00400109_MT103_Translation is used to translate a pacs.004 payment return into an MT103 return message. Once the class is identified, the main entry for the translation is the translate method. This method has several options, where the most simple expects the source message as parameter and returns the target message model as output. This translation procedure is the same as in the ISO 20022 translations, with the only difference being the implementation classes package. Javadoc Online javadoc Prowide Integrator CBPR+ Javadoc SRU2023-9.4.x","title":"CBPR+"},{"location":"integrator/cbpr/#prowide-integrator-cbpr","text":"","title":"Prowide Integrator CBPR+"},{"location":"integrator/cbpr/#overview","text":"The key feature provided by the CBPR+ extension is the specific model implementation for the Cross Border Payments Reporting Plus specification messages. This is a restricted ISO 20022 version with a subset of messages with specific constraints. The supported schemas and guidelines version is 2.1 effective November 2022.","title":"Overview"},{"location":"integrator/cbpr/#supported-message-schemes","text":"The following table includes all the supported message types: camt_029_001_09 camt_052_001_08 camt_053_001_08 camt_054_001_08 camt_056_001_08 camt_057_001_06 camt_060_001_05 pacs_002_001_10 pacs_004_001_09 pacs_008_001_08 pacs_008_001_08_STP pacs_009_001_08 pacs_009_001_08_ADV pacs_009_001_08_COV pacs_010_001_03 pain_001_001_09 pain_002_001_10","title":"Supported message schemes"},{"location":"integrator/cbpr/#message-model","text":"For each of the described message types, a specific implementation message class is provided, into a single common package: com . prowidesoftware . swift . model . mx . cbpr The CBPR+ message subset uses the same namespaces as the ISO standard.","title":"Message model"},{"location":"integrator/cbpr/#unknown-message-type-parsing","text":"To facilitate message type detection and parsing, a CBPR message factory is included in the package: AbstractMX mx = CbprMessageFactory . createMessage ( xmlContent ); The createMessage method accepts a plain string with the whole XML content. The specific message type is detected using information from the AppHdr element. In particular, using the: pacs.009.001.08 swift.cbprplus.adv.02 Notice the BAH v2 header is mandatory for CBPR+ messages, as well as the BizSvc. If the message is detected as a CBPR+ the method returns its content parsed into a specific model object such as: com.prowidesoftware.swift.model.mx.cbpr.MxPacs00900108ADV The parent class AbstractMX is still as in the generic ISO 20022 model messages, however the specific model for CBPR+ is a class within the cbpr package.","title":"Unknown message type parsing"},{"location":"integrator/cbpr/#known-message-type-parsing","text":"When you already know the message type to parse, you can use the specific model class directly. MxPacs00900108ADV mx = MxPacs00900108ADV . parse ( xmlContent ); The parser imposes no restriction on the validity of the message, just the namespace in the Document must match. And it will fill the model object with all the corresponding elements read from the XML content. The xml could be just the clean payload, or it could also contain any type of wrapper/envelope content that will be silently ignored. Since the class name of the CBPR messages is the same as the class name of the standard ISO 20022 message model, make sure your source code is importing the model class within the cbpr package .","title":"Known message type parsing"},{"location":"integrator/cbpr/#building-a-message","text":"The creation of a new CBPR+ message is similar to the creation of any standard ISO message. You just populate the Java object and the model will already include the constraints from the CBPR+ schema. For example: MxPacs00800108 mx = new MxPacs00800108 (); mx . setFIToFICstmrCdtTrf ( new FIToFICustomerCreditTransferV08 ()); mx . getFIToFICstmrCdtTrf (). setGrpHdr ( new GroupHeader931Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setMsgId ( \"1234\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setCreDtTm ( now ()); // include timezone here mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setNbOfTxs ( \"1\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setSttlmInf ( new SettlementInstruction71Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getSttlmInf (). setSttlmMtd ( SettlementMethod1Code1Pacs008 . INDA ); mx . getFIToFICstmrCdtTrf (). setCdtTrfTxInf ( new CreditTransferTransaction391 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setPmtId ( new PaymentIdentification71 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtId (). setInstrId ( \"REF\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtId (). setEndToEndId ( \"gwwg8dluwzG\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtId (). setTxId ( \"bbbb\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtId (). setUETR ( \"8a562c67-ca16-48ba-b074-65581be6f011\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setPmtTpInf ( new PaymentTypeInformation281 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtTpInf (). setLclInstrm ( new LocalInstrument2Choice1 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtTpInf (). getLclInstrm (). setCd ( \"FOO\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setIntrBkSttlmAmt ( new CBPRAmount1 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getIntrBkSttlmAmt (). setCcy ( \"EUR\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getIntrBkSttlmAmt (). setValue ( new BigDecimal ( \"1234.56\" )); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setChrgBr ( ChargeBearerType1Code1 . CRED ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setDbtr ( new PartyIdentification1352Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getDbtr (). setNm ( \"Foo1\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setDbtrAgt ( new BranchAndFinancialInstitutionIdentification61Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getDbtrAgt (). setFinInstnId ( new FinancialInstitutionIdentification181 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getDbtrAgt (). getFinInstnId (). setBICFI ( \"AAAAUSXXXXX\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setCdtr ( new PartyIdentification1353Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getCdtr (). setNm ( \"Foo2\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setCdtrAgt ( new BranchAndFinancialInstitutionIdentification62Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getCdtrAgt (). setFinInstnId ( new FinancialInstitutionIdentification181 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getCdtrAgt (). getFinInstnId (). setBICFI ( \"AAAAUSXXXXX\" ); String xml = mx . message (); As a small remark, beware when creating date and time objects that the XMLGregorianCalendar object used in the setter should have the time zone set. This is because for CBPR+ the timezone is mandatory. So when creating the object for the setter you should do something like this: LocalDateTime localDate = LocalDateTime . now (); XMLGregorianCalendar cal = DatatypeFactory . newInstance (). newXMLGregorianCalendar ( localDate . toString ()); cal . setTimezone ( - 3 );","title":"Building a message"},{"location":"integrator/cbpr/#message-types-enumeration","text":"An enumeration CbprMessageType is provided with the list of supported CBPR+ messages. This enumeration implements the internal SchemaProvider interface, so it can be used with the Prowide Integrator Validator library to run the CBPR+ validation for an XML. The enum also includes a few helper methods, for example to detect the specific type from an AppHdr.","title":"Message types enumeration"},{"location":"integrator/cbpr/#cbpr-validation","text":"Only available if you have a license of the Prowide Integrator Validation module. Along the standard ISO 20022 model, the Validation module provides an out-of-the-box validation for CBPR+ messages. There are two possible scenarios: * You are validating a message created by you in your application with the message model. * You are validating a message created externally and received in XML format. The main entry point to validate CBPR+ messages is the CbprValidationEngine class. The class provides an entry point using the plain XML content, and also an entry if you already have a model object from the com.prowidesoftware.swift.model.mx.cbpr package, such as MxPain00800108 . This specific validation engine implementation will already apply the CBPR+ specific schema and on top of the standard ISO 20022 and cross-element validations it will check the CBPR+ UG rules. When your source content is already the XML it is always recommended to use the XML as parameter for the validation. If you parse the XML into an MX object first, and then call the validation using the parsed message as parameter, some errors may not be detected. The validation call with the model object is only intended for scenarios where you are building the message using the model API.","title":"CBPR+ validation"},{"location":"integrator/cbpr/#cbpr-translations","text":"Only available if you have a license of the Prowide Integrator MT/MX Translations module. Along the standard ISO 20022 model, the MT/MX translations module provides out-of-the-box translations for CBPR+ messages. Specific translation classes are provided in the com.prowidesoftware.swift.translations.cbpr","title":"CBPR+ translations"},{"location":"integrator/cbpr/#automatic-translation","text":"Since there are several translation options depending on the message type, a CBPR+ translation factory is provided. AbstractMX mx = CbprMessageFactory . createMessage ( xmlContent ); Translator translator = CbprTranslatorFactory . getTranslator ( mx ); if ( translator == null ) { AbstractMT mt = ( AbstractMT ) translator . translate ( mx ); } First thing is to parse the source XML into a CBPR+ model object. When the message type is unknown, you can do that with ease with the CBPR message factory. The parsed object is then passed to the translator factory. The factory checks the specific message type and in some cases the message content, and determines automatically which translation to apply. If a translator is found, meaning the source message has been detected and satisfies the translation preconditions, the specific translator is returned. All translator classes implement a common interface with the translate method, that given the MX input returns the corresponding MT model output. Analogously, to run a translation from MT to CBPR+, the factory provides an entry to pass the MT model as parameter. This translation procedure is the same as in the ISO 20022 translations, with the only difference being the implementation classes package.","title":"Automatic translation"},{"location":"integrator/cbpr/#specific-translations","text":"When the message types are known, the specific translation classes can be used directly. The class name reflects the specific source and target message type, including the available variant combinations. For example, the class MxPacs00400109_MT103_Translation is used to translate a pacs.004 payment return into an MT103 return message. Once the class is identified, the main entry for the translation is the translate method. This method has several options, where the most simple expects the source message as parameter and returns the target message model as output. This translation procedure is the same as in the ISO 20022 translations, with the only difference being the implementation classes package.","title":"Specific translations"},{"location":"integrator/cbpr/#javadoc","text":"Online javadoc Prowide Integrator CBPR+ Javadoc SRU2023-9.4.x","title":"Javadoc"},{"location":"integrator/mule/","text":"Prowide MULE Connector The Prowide Mule Connector for Mule 4 facilitates an out-of-the-box integration of key features from the Prowide libraries in MULE applications. The key features enable validation and translation of SWIFT messages in Mule flows. Including operations for the legacy SWIFT MT standard and the ISO 20022 MX standard. Current implementation implements the following operations: Validate MT messages Validate ISO 20022 (MX) messages Validate CBPR+ messages Translate MT to ISO 20022 (MX) Translate ISO 20022 (MX) to MT Translate CBPR+ to MT Additional operations might be included in future releases. Application/Service Version Mule Runtime 4.0.1 Java 8+ Requirements The Prowide Integrator is a set of licensed Java libraries that complements the open source libraries Prowide Core and Prowide ISO 20022. Thus in order to use the Prowide Mule connector, you need to have a valid license and access to the Prowide Integrator libraries distribution. More information about the Prowide Integrator can be found in the Prowide Integrator product page. Installation The Prowide Mule connector is hosted in Mule Exchange and can be installed from the Exchange UI or from the Exchange API. https://www.anypoint.mulesoft.com/exchange/ Add this dependency to your application pom.xml org.mule.modules.prowide-integrator mule-prowide-integrator-connector 1.0.0 mule-plugin Configuration The Prowide Mule connector requires a valid license to be able to use the Prowide Integrator libraries. The license is provided as a file in the Prowide Integrator distribution. The license file must be placed in the Mule application classpath. The Prowide Mule connector can be configured in the Mule application configuration file or in the Mule application properties file. Check the Prowide Integrator developer guides for additional information. Usage","title":"Prowide MULE Connector"},{"location":"integrator/mule/#prowide-mule-connector","text":"The Prowide Mule Connector for Mule 4 facilitates an out-of-the-box integration of key features from the Prowide libraries in MULE applications. The key features enable validation and translation of SWIFT messages in Mule flows. Including operations for the legacy SWIFT MT standard and the ISO 20022 MX standard. Current implementation implements the following operations: Validate MT messages Validate ISO 20022 (MX) messages Validate CBPR+ messages Translate MT to ISO 20022 (MX) Translate ISO 20022 (MX) to MT Translate CBPR+ to MT Additional operations might be included in future releases. Application/Service Version Mule Runtime 4.0.1 Java 8+","title":"Prowide MULE Connector"},{"location":"integrator/mule/#requirements","text":"The Prowide Integrator is a set of licensed Java libraries that complements the open source libraries Prowide Core and Prowide ISO 20022. Thus in order to use the Prowide Mule connector, you need to have a valid license and access to the Prowide Integrator libraries distribution. More information about the Prowide Integrator can be found in the Prowide Integrator product page.","title":"Requirements"},{"location":"integrator/mule/#installation","text":"The Prowide Mule connector is hosted in Mule Exchange and can be installed from the Exchange UI or from the Exchange API. https://www.anypoint.mulesoft.com/exchange/ Add this dependency to your application pom.xml org.mule.modules.prowide-integrator mule-prowide-integrator-connector 1.0.0 mule-plugin ","title":"Installation"},{"location":"integrator/mule/#configuration","text":"The Prowide Mule connector requires a valid license to be able to use the Prowide Integrator libraries. The license is provided as a file in the Prowide Integrator distribution. The license file must be placed in the Mule application classpath. The Prowide Mule connector can be configured in the Mule application configuration file or in the Mule application properties file. Check the Prowide Integrator developer guides for additional information.","title":"Configuration"},{"location":"integrator/mule/#usage","text":"","title":"Usage"},{"location":"integrator/score/","text":"Prowide Integrator SCORE Overview The key feature provided by the SCORE extension is the specific model implementation for SWIFT for Corporate message structures. Which is a combination of sub-message types enclosed within an MT798 envelop. Parsing For message parsing, specific model classes are provided for each SWIFT for Corporates message type. For example, the 763 sub-message type, letter of credit, Customer to Bank, type can be parsed like this: MT798_763_LC_C2B mt = MT798_763_LC_C2B.parse(fin); And from there the model provides different getters to access the message content. WHen the sub-message type is also a standard SWIFT MT message, there is also a generic way to parse it. For example, the MT798 mt798 = MT798.parse(fin); /* * Get the sub-message (content after field 77E) as another model object */ SwiftMessage subMessage = mt798.getSubMessage(); /* * Convert and cast to MT760 * (the type of the inner message is indicated in field 12 of the MT798) */ MT760 mt = (MT760) subMessage.toMT(); Where we use a generic parse of the envelop message, MT798, into the model. And then we use a special function to get the inner payload. The inner payload is a generic SwiftMessage object, which can be converted to a specific MT. Creating a new message There are different ways to create SCORE messages. The most simple way is just to create an MT798 envelop and then just append the specific fields of the inner sub-message type in order. // create the envelope message MT798 mt = new MT798(\"AAAAUSXXXXX\", \"BBBBUSXXXXX\"); // add mandatory fields from the envelope mt.append(new Field20(\"MNN9843\")); mt.append(new Field12(\"745\")); // add the separatory field mt.append(new Field77E()); // add the submessage type (745) fields mt.append(new Field27A(\"1/2\")); mt.append(new Field21P(\"34567AC1-1239\")); mt.append(new Field21S(\"34567AC1\")); mt.append(new Field20(\"PGFFA0815999\")); mt.append(new Field31C(\"200506\")); mt.append(new Field13E(\"202005061045\")); mt.append(new Field29B(\"Arthur Foo\")); Then if the sub-message type is also a sntandard MT type, and you already have its payload in a model message. Then you can create the envelop fields and append the whole inner content from the specific message model. // Source content of an MT760 to use as sub-message String fin = \"{1:F01AAAADEM0AXXX0000000000}{2:I760BBBBITRRXMCEN2020}{4:\\n\" + \":27A:2/2\\n\" + \":21A:2201091711320000\\n\" + \":15A:\\n\" + \":27:1/1\\n\" + \":22A:ISSU\\n\" + \":15B:\\n\" + \":20:Bla Blah\\n\" + \":30:250109\\n\" + \":22D:DGAR\\n\" + \":40C:ISPR\\n\" + \":23B:FIXD\\n\" + \":31E:250109\\n\" + \":35G:If things happen\\n\" + \":50:Mr. App\\n\" + \"This Way\\n\" + \"Our City\\n\" + \":51:Mr. Obligor\\n\" + \"His stay\\n\" + \":52D:Mr. Issue\\n\" + \":59:Mr. Bene\\n\" + \"In Road\\n\" + \":56A:ANLAITRRMFE\\n\" + \":32B:USD23456789,\\n\" + \":77U:Terms and conditions\\n\" + \"have been defined\\n\" + \":45L:Some details\\n\" + \"about the underlying tx\\n\" + \":24E:MAIL\\n\" + \":24G:OTHR\\n\" + \"Foobar\\n\" + \"-}\"; MT760 subMessage = MT760.parse(fin); // Create a new MT798 envelop message, copying the seder, receiver and message type from the MT760 MT798 mt798 = new MT798(subMessage.getSender(), subMessage.getReceiver()); mt798 .append(Field20.tag(\"1234\")) .append(Field12.tag(subMessage.getMessageType())) .append(Field77E.emptyTag()); // After field 77E copy all fields from the sub-message MT760 subMessage.getSwiftMessage().getBlock4().getTags().forEach(t -> mt798.append(t)); Validating a SCORE message In order to validate a SCORE message, if you just pass the plain message to the ValidationEngine , only the MT798 envelop fields will be validated. While the inner structure for the sub-message type will not be strictly checked. Thus to apply the specific constraints for the sub-message type, you need to use the specific validation scheme to use in the validation call. ValidationEngine engine = new ValidationEngine(); engine.initialize(); String fin = \"{1:F01AAAADEM0AXXX0000000000}{2:I798BBBBITRRXMCEN2020}{4: etc...}\"; List r = engine.validateMtMessage(fin, MtTypeScore.MT798_712_LC_C2B.scheme()); In the above validation call we are using the specific validation scheme for the MT798<712> LC C2B sub-message type. The MtTypeScore is a convenience enum containing all supported SCORE model structures, and can be used to access its scheme definition. For more information on MT schemes, check the Prowide Integrator Validation guide. Javadoc Online javadoc Prowide Integrator SCORE Javadoc SRU2023-9.4.x","title":"SCORE"},{"location":"integrator/score/#prowide-integrator-score","text":"","title":"Prowide Integrator SCORE"},{"location":"integrator/score/#overview","text":"The key feature provided by the SCORE extension is the specific model implementation for SWIFT for Corporate message structures. Which is a combination of sub-message types enclosed within an MT798 envelop.","title":"Overview"},{"location":"integrator/score/#parsing","text":"For message parsing, specific model classes are provided for each SWIFT for Corporates message type. For example, the 763 sub-message type, letter of credit, Customer to Bank, type can be parsed like this: MT798_763_LC_C2B mt = MT798_763_LC_C2B.parse(fin); And from there the model provides different getters to access the message content. WHen the sub-message type is also a standard SWIFT MT message, there is also a generic way to parse it. For example, the MT798 mt798 = MT798.parse(fin); /* * Get the sub-message (content after field 77E) as another model object */ SwiftMessage subMessage = mt798.getSubMessage(); /* * Convert and cast to MT760 * (the type of the inner message is indicated in field 12 of the MT798) */ MT760 mt = (MT760) subMessage.toMT(); Where we use a generic parse of the envelop message, MT798, into the model. And then we use a special function to get the inner payload. The inner payload is a generic SwiftMessage object, which can be converted to a specific MT.","title":"Parsing"},{"location":"integrator/score/#creating-a-new-message","text":"There are different ways to create SCORE messages. The most simple way is just to create an MT798 envelop and then just append the specific fields of the inner sub-message type in order. // create the envelope message MT798 mt = new MT798(\"AAAAUSXXXXX\", \"BBBBUSXXXXX\"); // add mandatory fields from the envelope mt.append(new Field20(\"MNN9843\")); mt.append(new Field12(\"745\")); // add the separatory field mt.append(new Field77E()); // add the submessage type (745) fields mt.append(new Field27A(\"1/2\")); mt.append(new Field21P(\"34567AC1-1239\")); mt.append(new Field21S(\"34567AC1\")); mt.append(new Field20(\"PGFFA0815999\")); mt.append(new Field31C(\"200506\")); mt.append(new Field13E(\"202005061045\")); mt.append(new Field29B(\"Arthur Foo\")); Then if the sub-message type is also a sntandard MT type, and you already have its payload in a model message. Then you can create the envelop fields and append the whole inner content from the specific message model. // Source content of an MT760 to use as sub-message String fin = \"{1:F01AAAADEM0AXXX0000000000}{2:I760BBBBITRRXMCEN2020}{4:\\n\" + \":27A:2/2\\n\" + \":21A:2201091711320000\\n\" + \":15A:\\n\" + \":27:1/1\\n\" + \":22A:ISSU\\n\" + \":15B:\\n\" + \":20:Bla Blah\\n\" + \":30:250109\\n\" + \":22D:DGAR\\n\" + \":40C:ISPR\\n\" + \":23B:FIXD\\n\" + \":31E:250109\\n\" + \":35G:If things happen\\n\" + \":50:Mr. App\\n\" + \"This Way\\n\" + \"Our City\\n\" + \":51:Mr. Obligor\\n\" + \"His stay\\n\" + \":52D:Mr. Issue\\n\" + \":59:Mr. Bene\\n\" + \"In Road\\n\" + \":56A:ANLAITRRMFE\\n\" + \":32B:USD23456789,\\n\" + \":77U:Terms and conditions\\n\" + \"have been defined\\n\" + \":45L:Some details\\n\" + \"about the underlying tx\\n\" + \":24E:MAIL\\n\" + \":24G:OTHR\\n\" + \"Foobar\\n\" + \"-}\"; MT760 subMessage = MT760.parse(fin); // Create a new MT798 envelop message, copying the seder, receiver and message type from the MT760 MT798 mt798 = new MT798(subMessage.getSender(), subMessage.getReceiver()); mt798 .append(Field20.tag(\"1234\")) .append(Field12.tag(subMessage.getMessageType())) .append(Field77E.emptyTag()); // After field 77E copy all fields from the sub-message MT760 subMessage.getSwiftMessage().getBlock4().getTags().forEach(t -> mt798.append(t));","title":"Creating a new message"},{"location":"integrator/score/#validating-a-score-message","text":"In order to validate a SCORE message, if you just pass the plain message to the ValidationEngine , only the MT798 envelop fields will be validated. While the inner structure for the sub-message type will not be strictly checked. Thus to apply the specific constraints for the sub-message type, you need to use the specific validation scheme to use in the validation call. ValidationEngine engine = new ValidationEngine(); engine.initialize(); String fin = \"{1:F01AAAADEM0AXXX0000000000}{2:I798BBBBITRRXMCEN2020}{4: etc...}\"; List r = engine.validateMtMessage(fin, MtTypeScore.MT798_712_LC_C2B.scheme()); In the above validation call we are using the specific validation scheme for the MT798<712> LC C2B sub-message type. The MtTypeScore is a convenience enum containing all supported SCORE model structures, and can be used to access its scheme definition. For more information on MT schemes, check the Prowide Integrator Validation guide.","title":"Validating a SCORE message"},{"location":"integrator/score/#javadoc","text":"Online javadoc Prowide Integrator SCORE Javadoc SRU2023-9.4.x","title":"Javadoc"},{"location":"integrator/sepa/","text":"Prowide Integrator SEPA Overview The key feature provided by the SEPA extension is the specific model implementation for the Single Euro Payments Area messages. This is a restricted ISO 20022 version with a subset of messages with specific constraints. The implementation is based on the publications by the European Payments Council (EPC). For more information for SEPA check https://www.europeanpaymentscouncil.eu The supported rulebook is the 2019 version 1.0 , in force from 17 November 2019 until November 2021. Supported message schemes The following table includes all the supported message types grouped into payment schemes. For each of them the first column indicates the message type identifier, the second column the usage description in SEPA and the third column the usage of the equivalent message type in ISO. SEPA Credit Transfer - Customer to Bank - SCT C2B (EPC132) pain.001.001.03 Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.001.001.03_ERI_Update Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.001.001.03_TransferBack Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.002.001.03 Customer Payment Status Report Customer Payment Status Report SEPA Instant Credit Transfer - Customer to Bank - SCT C2B INST (EPC121) pain.001.001.03 Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.001.001.03_TransferBack Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.002.001.03 Customer Payment Status Report Customer Payment Status Report SEPA Credit Transfer - Interbank - SCT INT (EPC115) camt.027.001.06 Interbank SCT Inquiry Claim Non-Receipt camt.029.001.03_NegAnRecall Interbank Negative Answer to a Recall of SEPA Credit Transfer Resolution of Investigation camt.029.001.03_NegReRFRO Interbank Negative Response to the Request for Recall by the Originator Resolution of Investigation camt.029.001.08_Conf_PosRecamt.087_Update Interbank Confirmed Positive Response to Claim for Value Date Correction Resolution of Investigation camt.029.001.08_NegRecamt.027_Update Interbank Negative Response to Claim Non-Receipt Resolution of Investigation camt.029.001.08_NegRecamt.087 Interbank Negative Response to Claim for Value Date Correction Resolution of Investigation camt.029.001.08_PosRecamt.027_Update Interbank Positive Response to Claim Non-Receipt Resolution of Investigation camt.029.001.08_PosRecamt.087_Update Interbank Positive Response to Claim for Value Date Correction With Request for Interest Compensation Resolution of Investigation camt.056.001.01_Recall Interbank Recall of SEPA Credit Transfer FI to FI Payment Cancellation Request camt.056.001.01_RFRO Request for Recall by the Originator FI to FI Payment Cancellation Request camt.087.001.05 Interbank SCT Inquiry Request to Modify Payment pacs.002.001.03 Interbank Reject SEPA Credit Transfer FI to FI Payment Status Report pacs.004.001.02_PosAnRecall Interbank Positive Answer to a Recall of SEPA Credit Transfer Interbank Return Credit Transfer pacs.004.001.02_PosReRFRO Interbank Positive Response to the Request for Recall by the Originator Interbank Return Credit Transfer pacs.004.001.02_Return Interbank Return SEPA Credit Transfer Interbank Return Credit Transfer pacs.008.001.02 Interbank Payment FI to FI Customer Credit Transfer pacs.008.001.02_ERI_Update Interbank Payment FI to FI Customer Credit Transfer pacs.028.001.01_INQ Request for a Status Update on a SEPA Credit Transfer Inquiry FI to FI Payment Status Request pacs.028.001.01_Recall Request for Status on a Recall of SEPA Credit Transfer FI to FI Payment Status Request pacs.028.001.01_RFRO_Update Request for a Status Update on a Request for Recall by the Originator FI to FI Payment Status Request SEPA Instant Credit Transfer - Interbank - SCT INT INST (EPC 122) camt.029.001.03_NegAnRecall Interbank Negative Answer to a Recall of SEPA Credit Transfer Resolution of Investigation camt.029.001.03_NegReRFRO Interbank Negative Response to the Request for Recall by the Originator Resolution of Investigation camt.056.001.01_Recall Interbank Recall of SEPA Credit Transfer FI to FI Payment Cancellation Request camt.056.001.01_RFRO Request for Recall by the Originator FI to FI Payment Cancellation Request pacs.002.001.03_Negative Interbank Reject SEPA Credit Transfer FI to FI Payment Status Report pacs.002.001.03_Positive_Update Interbank Accept SEPA Credit Transfer FI to FI Payment Status Report pacs.004.001.02_PosAnRecall Interbank Positive Answer to a Recall of SEPA Credit Transfer Interbank Return Credit Transfer pacs.004.001.02_PosReRFRO Interbank Positive Response to the Request for Recall by the Originator Interbank Return Credit Transfer pacs.008.001.02 Interbank Payment FI to FI Customer Credit Transfer pacs.028.001.01_Recall_Update Request for Status Update on a Recall of SEPA Credit Transfer FI to FI Payment Status Request pacs.028.001.01_RFRO_Update Request for a Status Update on a Request for Recall by the Originator FI to FI Payment Status Request pacs.028.001.01_Status Request for Status on a Recall of SEPA Credit Transfer FI to FI Payment Status Request SEPA DIrect Debit - Customer to Bank - SDD C2B (EPC130) pain.002.001.03 Bank to Customer Direct Debit Reject Payment Status Report pain.007.001.02 Customer to Bank Reversal Instruction for a Collection Customer to Bank Payment Reversal pain.008.001.02 Customer to Bank Direct Debit Collection Customer Direct Debit Initiation SEPA Direct Debit - E-Mandate Service - SDD EMS (EPC002) pain.009.001.01 Request Message \u2013 Issuing Initiation Request pain.010.001.01 Request Message \u2013 Amendment Amendment Request pain.011.001.01 Request Message \u2013 Cancellation Cancellation Request pain.012.001.01 Validation Message Acceptance Report SEPA Direct Debit - Interbank - SDD INT (EPC114) pacs.002.001.03 Interbank Direct Debit Reject FI to FI Payment Status Report pacs.003.001.02 Interbank Collection FI to FI Customer Direct Debit pacs.004.001.02 Interbank Direct Debit Return/Refund of a Collection Payment Return pacs.007.001.03 Interbank Reversal Instruction for a Collection Payment Reversal Message model For each of the described message types, a specific implementation message class is provided. The SEPA message subset shares the same ISO standard namespaces , however for each namespace, and thus for each message type, there can be more than one message model . In order to handle this situation, the SEPA message classes are organized into a package, where the package name maps part of the SEPA schema. For example, the pacs.002.001.03 from the SDD INT schema is located in a package: com . prowidesoftware . swift . model . mx . sepa . sdd . interbank . pacs002 For several message schemes, the same message types have different versions depending on the usage. In these cases, the model class includes the same suffix defined in the schemas from the EPC. For example, for SCT C2B pain.001you will find the default MxPain00100103 class but also the MxPain00100103TransferBack and MxPain00100103ERIUpdate variants. The three messages implement a SCT C2B pain.001, but depending on the usage they have different constraints. Therefore, in order to build a SEPA message, the specific use case, has to be identified in advance. Once the message class is identified, the creation of a new SEPA message is similar to the creation of any standard ISO message. You just populate the Java object and the model will already include the constraints from the SEPA schema. For example: MxPacs00400102Return mx = new MxPacs00400102Return (); mx . setPmtRtr ( new PaymentReturnV02SepaReturn ()); mx . getPmtRtr (). setGrpHdr ( new GroupHeader38Sepa ()); mx . getPmtRtr (). getGrpHdr (). setMsgId ( \"REFERENCE1234\" ); mx . getPmtRtr (). getGrpHdr (). setNbOfTxs ( \"1\" ); mx . getPmtRtr (). getGrpHdr (). setIntrBkSttlmDt ( DatatypeFactory . newInstance (). newXMLGregorianCalendar ( Instant . now (). toString ())); mx . getPmtRtr (). getGrpHdr (). setSttlmInf ( new SettlementInformation13Sepa ()); mx . getPmtRtr (). getGrpHdr (). getSttlmInf (). setSttlmMtd ( SettlementMethod1Code . INDA ); mx . getPmtRtr (). getGrpHdr (). setTtlRtrdIntrBkSttlmAmt ( new ActiveCurrencyAndAmountSepa ()); mx . getPmtRtr (). getGrpHdr (). getTtlRtrdIntrBkSttlmAmt (). setCcy ( ActiveCurrencyCodeSepa . EUR ); mx . getPmtRtr (). getGrpHdr (). getTtlRtrdIntrBkSttlmAmt (). setValue ( new BigDecimal ( \"1234.56\" )); The message object can then be serialized into XML using the message() method. Notice a SEPA message in XML format will be indistinguishable from a standard ISO message because SEPA is just a constraint of ISO messages, sharing the same namespace. Moreover, a SEPA message will always be a valid ISO message. To complement the message model, an enumeration SepaMessageType is provided with the list of supported SEPA message types. This enumeration implements the internal SchemaProvider interface, so it can be used with the Prowide Integrator Validator library to run the SEPA validation for an XML. SEPA validation Only available if you have a license of the Prowide Integrator Validation module. Along the standard ISO 20022 validation, the Validation module supports out-of-the-box validation for SEPA . There are two possible scenarios: * You are validating a message created by you in your application with the message model. * You are validating a message created externally and received in XML format. In the first case, you should have created a specific message object such as MxPain00100103 from the com.prowidesoftware.swift.model.mx.sepa.sct.c2b.pain001 package. Therefore, the model has already constrained the elements and elements values with the restrictions from the SEPA schemas. Moreover, the object implements the SchemaProvider interface. So when you call the validation engine passing the object as a parameter, the engine will already apply the corresponding SEPA schema. You can just use the validation call: validateMessage ( final AbstractMX msg ) In the second scenario, you just have the XML so the message itself cannot be distinguished from a regular ISO message. Notice, SEPA messages are a subset of ISO messages with special restrictions, but the XML namespace in a SEPA message is the same as the standard ISO namespace. So in order to validate these messages you need to provide additional information to the validation call to clearly identify the SEPA message type you intend to validate. For that, you should use the validation call: validateMxMessage ( final String xml , SchemaProvider schemaProvider ) Where for the SchemaProvider parameter you can use any value of the SepaMessageType enum. Restricted SEPA validation The model and validation we support out-of-the-box for SEPA is based on the schema publications by the European Payments Council (EPC) . Some institutions, such as the Deutsche Bundesbank have their own restriction for SEPA-Clearer . This restricted version of the SEPA messages require additional validation that is not available in the EPC schemas. So in order to do that, a recommended workaround is to use the Prowide Integrator SEPA model classes to build the messages, but then pass the specific SEPA restricted schema to the validation. Therefore, the overall message structure will be ensured by the model while the specific constraints will be detected by the validation. For Example: com . prowidesoftware . swift . model . mx . sepa . sct . interbank . pacs008 . MxPacs00800102 mx = new MxPacs00800102 (); mx . setFIToFICstmrCdtTrf ( new FIToFICustomerCreditTransferV02Sepa ()); mx . getFIToFICstmrCdtTrf (). setGrpHdr ( new GroupHeader33Sepa ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setMsgId ( \"1234\" ); [ More setters here \u2026 ] // load restricted SEPA schema from Bundesbank String xsd = Lib . readStream ( getClass (). getResourceAsStream ( \"sepa-bundesbank-pacs.008.001.02.xsd\" )); // assert the message is valid for the Bundesbank schema String xml = mx . message (); StreamSource streamSource = new StreamSource ( new StringReader ( xsd )); List < ValidationProblem > problems = engine . validateMxMessage ( xml , streamSource ); System . out . println ( ValidationProblem . printout ( problems )); Javadoc Online javadoc Prowide Integrator SEPA Javadoc SRU2023-9.4.x","title":"SEPA"},{"location":"integrator/sepa/#prowide-integrator-sepa","text":"","title":"Prowide Integrator SEPA"},{"location":"integrator/sepa/#overview","text":"The key feature provided by the SEPA extension is the specific model implementation for the Single Euro Payments Area messages. This is a restricted ISO 20022 version with a subset of messages with specific constraints. The implementation is based on the publications by the European Payments Council (EPC). For more information for SEPA check https://www.europeanpaymentscouncil.eu The supported rulebook is the 2019 version 1.0 , in force from 17 November 2019 until November 2021.","title":"Overview"},{"location":"integrator/sepa/#supported-message-schemes","text":"The following table includes all the supported message types grouped into payment schemes. For each of them the first column indicates the message type identifier, the second column the usage description in SEPA and the third column the usage of the equivalent message type in ISO.","title":"Supported message schemes"},{"location":"integrator/sepa/#sepa-credit-transfer-customer-to-bank-sct-c2b-epc132","text":"pain.001.001.03 Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.001.001.03_ERI_Update Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.001.001.03_TransferBack Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.002.001.03 Customer Payment Status Report Customer Payment Status Report SEPA Instant Credit Transfer - Customer to Bank - SCT C2B INST (EPC121) pain.001.001.03 Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.001.001.03_TransferBack Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.002.001.03 Customer Payment Status Report Customer Payment Status Report","title":"SEPA Credit Transfer - Customer to Bank - SCT C2B (EPC132)"},{"location":"integrator/sepa/#sepa-credit-transfer-interbank-sct-int-epc115","text":"camt.027.001.06 Interbank SCT Inquiry Claim Non-Receipt camt.029.001.03_NegAnRecall Interbank Negative Answer to a Recall of SEPA Credit Transfer Resolution of Investigation camt.029.001.03_NegReRFRO Interbank Negative Response to the Request for Recall by the Originator Resolution of Investigation camt.029.001.08_Conf_PosRecamt.087_Update Interbank Confirmed Positive Response to Claim for Value Date Correction Resolution of Investigation camt.029.001.08_NegRecamt.027_Update Interbank Negative Response to Claim Non-Receipt Resolution of Investigation camt.029.001.08_NegRecamt.087 Interbank Negative Response to Claim for Value Date Correction Resolution of Investigation camt.029.001.08_PosRecamt.027_Update Interbank Positive Response to Claim Non-Receipt Resolution of Investigation camt.029.001.08_PosRecamt.087_Update Interbank Positive Response to Claim for Value Date Correction With Request for Interest Compensation Resolution of Investigation camt.056.001.01_Recall Interbank Recall of SEPA Credit Transfer FI to FI Payment Cancellation Request camt.056.001.01_RFRO Request for Recall by the Originator FI to FI Payment Cancellation Request camt.087.001.05 Interbank SCT Inquiry Request to Modify Payment pacs.002.001.03 Interbank Reject SEPA Credit Transfer FI to FI Payment Status Report pacs.004.001.02_PosAnRecall Interbank Positive Answer to a Recall of SEPA Credit Transfer Interbank Return Credit Transfer pacs.004.001.02_PosReRFRO Interbank Positive Response to the Request for Recall by the Originator Interbank Return Credit Transfer pacs.004.001.02_Return Interbank Return SEPA Credit Transfer Interbank Return Credit Transfer pacs.008.001.02 Interbank Payment FI to FI Customer Credit Transfer pacs.008.001.02_ERI_Update Interbank Payment FI to FI Customer Credit Transfer pacs.028.001.01_INQ Request for a Status Update on a SEPA Credit Transfer Inquiry FI to FI Payment Status Request pacs.028.001.01_Recall Request for Status on a Recall of SEPA Credit Transfer FI to FI Payment Status Request pacs.028.001.01_RFRO_Update Request for a Status Update on a Request for Recall by the Originator FI to FI Payment Status Request","title":"SEPA Credit Transfer - Interbank - SCT INT (EPC115)"},{"location":"integrator/sepa/#sepa-instant-credit-transfer-interbank-sct-int-inst-epc-122","text":"camt.029.001.03_NegAnRecall Interbank Negative Answer to a Recall of SEPA Credit Transfer Resolution of Investigation camt.029.001.03_NegReRFRO Interbank Negative Response to the Request for Recall by the Originator Resolution of Investigation camt.056.001.01_Recall Interbank Recall of SEPA Credit Transfer FI to FI Payment Cancellation Request camt.056.001.01_RFRO Request for Recall by the Originator FI to FI Payment Cancellation Request pacs.002.001.03_Negative Interbank Reject SEPA Credit Transfer FI to FI Payment Status Report pacs.002.001.03_Positive_Update Interbank Accept SEPA Credit Transfer FI to FI Payment Status Report pacs.004.001.02_PosAnRecall Interbank Positive Answer to a Recall of SEPA Credit Transfer Interbank Return Credit Transfer pacs.004.001.02_PosReRFRO Interbank Positive Response to the Request for Recall by the Originator Interbank Return Credit Transfer pacs.008.001.02 Interbank Payment FI to FI Customer Credit Transfer pacs.028.001.01_Recall_Update Request for Status Update on a Recall of SEPA Credit Transfer FI to FI Payment Status Request pacs.028.001.01_RFRO_Update Request for a Status Update on a Request for Recall by the Originator FI to FI Payment Status Request pacs.028.001.01_Status Request for Status on a Recall of SEPA Credit Transfer FI to FI Payment Status Request","title":"SEPA Instant Credit Transfer - Interbank - SCT INT INST (EPC 122)"},{"location":"integrator/sepa/#sepa-direct-debit-customer-to-bank-sdd-c2b-epc130","text":"pain.002.001.03 Bank to Customer Direct Debit Reject Payment Status Report pain.007.001.02 Customer to Bank Reversal Instruction for a Collection Customer to Bank Payment Reversal pain.008.001.02 Customer to Bank Direct Debit Collection Customer Direct Debit Initiation","title":"SEPA DIrect Debit - Customer to Bank - SDD C2B (EPC130)"},{"location":"integrator/sepa/#sepa-direct-debit-e-mandate-service-sdd-ems-epc002","text":"pain.009.001.01 Request Message \u2013 Issuing Initiation Request pain.010.001.01 Request Message \u2013 Amendment Amendment Request pain.011.001.01 Request Message \u2013 Cancellation Cancellation Request pain.012.001.01 Validation Message Acceptance Report","title":"SEPA Direct Debit - E-Mandate Service - SDD EMS (EPC002)"},{"location":"integrator/sepa/#sepa-direct-debit-interbank-sdd-int-epc114","text":"pacs.002.001.03 Interbank Direct Debit Reject FI to FI Payment Status Report pacs.003.001.02 Interbank Collection FI to FI Customer Direct Debit pacs.004.001.02 Interbank Direct Debit Return/Refund of a Collection Payment Return pacs.007.001.03 Interbank Reversal Instruction for a Collection Payment Reversal","title":"SEPA Direct Debit - Interbank - SDD INT (EPC114)"},{"location":"integrator/sepa/#message-model","text":"For each of the described message types, a specific implementation message class is provided. The SEPA message subset shares the same ISO standard namespaces , however for each namespace, and thus for each message type, there can be more than one message model . In order to handle this situation, the SEPA message classes are organized into a package, where the package name maps part of the SEPA schema. For example, the pacs.002.001.03 from the SDD INT schema is located in a package: com . prowidesoftware . swift . model . mx . sepa . sdd . interbank . pacs002 For several message schemes, the same message types have different versions depending on the usage. In these cases, the model class includes the same suffix defined in the schemas from the EPC. For example, for SCT C2B pain.001you will find the default MxPain00100103 class but also the MxPain00100103TransferBack and MxPain00100103ERIUpdate variants. The three messages implement a SCT C2B pain.001, but depending on the usage they have different constraints. Therefore, in order to build a SEPA message, the specific use case, has to be identified in advance. Once the message class is identified, the creation of a new SEPA message is similar to the creation of any standard ISO message. You just populate the Java object and the model will already include the constraints from the SEPA schema. For example: MxPacs00400102Return mx = new MxPacs00400102Return (); mx . setPmtRtr ( new PaymentReturnV02SepaReturn ()); mx . getPmtRtr (). setGrpHdr ( new GroupHeader38Sepa ()); mx . getPmtRtr (). getGrpHdr (). setMsgId ( \"REFERENCE1234\" ); mx . getPmtRtr (). getGrpHdr (). setNbOfTxs ( \"1\" ); mx . getPmtRtr (). getGrpHdr (). setIntrBkSttlmDt ( DatatypeFactory . newInstance (). newXMLGregorianCalendar ( Instant . now (). toString ())); mx . getPmtRtr (). getGrpHdr (). setSttlmInf ( new SettlementInformation13Sepa ()); mx . getPmtRtr (). getGrpHdr (). getSttlmInf (). setSttlmMtd ( SettlementMethod1Code . INDA ); mx . getPmtRtr (). getGrpHdr (). setTtlRtrdIntrBkSttlmAmt ( new ActiveCurrencyAndAmountSepa ()); mx . getPmtRtr (). getGrpHdr (). getTtlRtrdIntrBkSttlmAmt (). setCcy ( ActiveCurrencyCodeSepa . EUR ); mx . getPmtRtr (). getGrpHdr (). getTtlRtrdIntrBkSttlmAmt (). setValue ( new BigDecimal ( \"1234.56\" )); The message object can then be serialized into XML using the message() method. Notice a SEPA message in XML format will be indistinguishable from a standard ISO message because SEPA is just a constraint of ISO messages, sharing the same namespace. Moreover, a SEPA message will always be a valid ISO message. To complement the message model, an enumeration SepaMessageType is provided with the list of supported SEPA message types. This enumeration implements the internal SchemaProvider interface, so it can be used with the Prowide Integrator Validator library to run the SEPA validation for an XML.","title":"Message model"},{"location":"integrator/sepa/#sepa-validation","text":"Only available if you have a license of the Prowide Integrator Validation module. Along the standard ISO 20022 validation, the Validation module supports out-of-the-box validation for SEPA . There are two possible scenarios: * You are validating a message created by you in your application with the message model. * You are validating a message created externally and received in XML format. In the first case, you should have created a specific message object such as MxPain00100103 from the com.prowidesoftware.swift.model.mx.sepa.sct.c2b.pain001 package. Therefore, the model has already constrained the elements and elements values with the restrictions from the SEPA schemas. Moreover, the object implements the SchemaProvider interface. So when you call the validation engine passing the object as a parameter, the engine will already apply the corresponding SEPA schema. You can just use the validation call: validateMessage ( final AbstractMX msg ) In the second scenario, you just have the XML so the message itself cannot be distinguished from a regular ISO message. Notice, SEPA messages are a subset of ISO messages with special restrictions, but the XML namespace in a SEPA message is the same as the standard ISO namespace. So in order to validate these messages you need to provide additional information to the validation call to clearly identify the SEPA message type you intend to validate. For that, you should use the validation call: validateMxMessage ( final String xml , SchemaProvider schemaProvider ) Where for the SchemaProvider parameter you can use any value of the SepaMessageType enum.","title":"SEPA validation"},{"location":"integrator/sepa/#restricted-sepa-validation","text":"The model and validation we support out-of-the-box for SEPA is based on the schema publications by the European Payments Council (EPC) . Some institutions, such as the Deutsche Bundesbank have their own restriction for SEPA-Clearer . This restricted version of the SEPA messages require additional validation that is not available in the EPC schemas. So in order to do that, a recommended workaround is to use the Prowide Integrator SEPA model classes to build the messages, but then pass the specific SEPA restricted schema to the validation. Therefore, the overall message structure will be ensured by the model while the specific constraints will be detected by the validation. For Example: com . prowidesoftware . swift . model . mx . sepa . sct . interbank . pacs008 . MxPacs00800102 mx = new MxPacs00800102 (); mx . setFIToFICstmrCdtTrf ( new FIToFICustomerCreditTransferV02Sepa ()); mx . getFIToFICstmrCdtTrf (). setGrpHdr ( new GroupHeader33Sepa ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setMsgId ( \"1234\" ); [ More setters here \u2026 ] // load restricted SEPA schema from Bundesbank String xsd = Lib . readStream ( getClass (). getResourceAsStream ( \"sepa-bundesbank-pacs.008.001.02.xsd\" )); // assert the message is valid for the Bundesbank schema String xml = mx . message (); StreamSource streamSource = new StreamSource ( new StringReader ( xsd )); List < ValidationProblem > problems = engine . validateMxMessage ( xml , streamSource ); System . out . println ( ValidationProblem . printout ( problems ));","title":"Restricted SEPA validation"},{"location":"integrator/sepa/#javadoc","text":"Online javadoc Prowide Integrator SEPA Javadoc SRU2023-9.4.x","title":"Javadoc"},{"location":"integrator/sic/","text":"Prowide Integrator SIC Overview The key feature provided by the SIC extension is the specific model implementation for the Swiss RGTS messages. This is a restricted ISO 20022 version with a subset of messages with specific constraints. For more information for SIC check https://www.six-group.com/interbank-clearing/en/home/standardization/iso-payments/iso20022/implementation-guidelines.html The supported schemas and guidelines version is 4.9 . Supported message schemes The following table includes all the supported message types: camt.003.001.07.ch.02 camt.004.001.08.ch.02 camt.005.001.08.ch.01 camt.006.001.08.ch.02 camt.007.001.08.ch.01 camt.008.001.08.ch.01 camt.019.001.07.ch.02 camt.025.001.05.ch.01 camt.027.001.06.chsepa.01 camt.029.001.08.chsepa.01 camt.029.001.09.ch.01 camt.048.001.05.ch.01 camt.050.001.05.ch.01 camt.052.001.08.ch.02 camt.054.001.08.ch.02 camt.056.001.08.ch.02 camt.087.001.05.chsepa.01 pacs.002.001.10.ch.02 pacs.004.001.09.ch.02 pacs.008.001.08.ch.02 pacs.009.001.08.ch.02 pacs.028.001.01.chsepa.02 Legacy from release 4.6: camt.003.001.05.ch.01 camt.004.001.06.ch.01 camt.005.001.06.ch.03 camt.006.001.06.ch.02 camt.007.001.06.ch.01 camt.008.001.06.ch.01 camt.019.001.05.ch.01 camt.025.001.03.ch.01 camt.027.001.06.chsepa.01 camt.029.001.03.ch.01 camt.029.001.08.chsepa.01 camt.048.001.03.ch.01 camt.050.001.03.ch.01 camt.052.001.02.ch.01 camt.054.001.02.ch.01 camt.056.001.01.ch.01 camt.087.001.05.chsepa.01 pacs.002.001.03.ch.01 pacs.004.001.02.ch.02 pacs.008.001.02.ch.02 pacs.009.001.02.ch.02 pacs.028.001.01.chsepa.02 Message model For each of the described message types, a specific implementation message class is provided, into a single common package: com . prowidesoftware . swift . model . mx . sic The package above always contains the latest release availalbe. For older releases, the package name includes the release version, for example: com . prowidesoftware . swift . model . mx . sic . v4_6 The SIC message subset uses custom namespaces , not aligned to the ISO standard namespaces. Once the message class is identified, the creation of a new SIC message is similar to the creation of any standard ISO message. You just populate the Java object and the model will already include the constraints from the SIC schema. For example: MxPacs00800102Ch02 mx = new MxPacs00800102Ch02 (); mx . setFIToFICstmrCdtTrf ( new FIToFICustomerCreditTransferV02 ()); mx . getFIToFICstmrCdtTrf (). setGrpHdr ( new GroupHeader33 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setMsgId ( \"1234\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setCreDtTm ( now ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setNbOfTxs ( \"1\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setIntrBkSttlmDt ( now ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setSttlmInf ( new SettlementInformation13Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getSttlmInf (). setSttlmMtd ( SettlementMethod1Code . CLRG ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setInstgAgt ( new BranchAndFinancialInstitutionIdentification4Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getInstgAgt (). setFinInstnId ( new FinancialInstitutionIdentification7 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getInstgAgt (). getFinInstnId (). setBIC ( \"ABCDUSXXXXX\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setInstdAgt ( new BranchAndFinancialInstitutionIdentification4Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getInstdAgt (). setFinInstnId ( new FinancialInstitutionIdentification7 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getInstdAgt (). getFinInstnId (). setBIC ( \"EFGHUSXXXXX\" ); mx . getFIToFICstmrCdtTrf (). addCdtTrfTxInf ( new CreditTransferTransactionInformation11 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setPmtId ( new PaymentIdentification3 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getPmtId (). setEndToEndId ( \"aaaa\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getPmtId (). setTxId ( \"bbbb\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setPmtTpInf ( new PaymentTypeInformation21 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getPmtTpInf (). setLclInstrm ( new LocalInstrument2Choice ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getPmtTpInf (). getLclInstrm (). setCd ( \"ESRPMT\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setIntrBkSttlmAmt ( new ActiveCurrencyAndAmount ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getIntrBkSttlmAmt (). setCcy ( \"USD\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getIntrBkSttlmAmt (). setValue ( new BigDecimal ( \"1234.56\" )); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setChrgBr ( ChargeBearerType1Code . CRED ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setDbtr ( new PartyIdentification32 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getDbtr (). setNm ( \"Foo1\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setDbtrAgt ( new BranchAndFinancialInstitutionIdentification4Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getDbtrAgt (). setFinInstnId ( new FinancialInstitutionIdentification7 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getDbtrAgt (). getFinInstnId (). setBIC ( \"AAAAUSXXXXX\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setCdtr ( new PartyIdentification32 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getCdtr (). setNm ( \"Foo2\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setCdtrAgt ( new BranchAndFinancialInstitutionIdentification4Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getCdtrAgt (). setFinInstnId ( new FinancialInstitutionIdentification7 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getCdtrAgt (). getFinInstnId (). setBIC ( \"AAAAUSXXXXX\" ); String xml = mx . message (); The serialized XML will have the proper custom SIC namespace. To complement the message model, an enumeration SicMessageType is provided with the list of supported SIC messages. This enumeration implements the internal SchemaProvider interface, so it can be used with the Prowide Integrator Validator library to run the SIC validation for an XML. SIC validation Only available if you have a license of the Prowide Integrator Validation module. Along the standard ISO 20022 validation, the Validation module supports out-of-the-box validation for SIC (Swiss RTGS). There are two possible scenarios: You are validating a message created by you in your application with the message model. You are validating a message created externally and received in XML format. In the first case, you should have created a specific message object such as MxPain00800102Ch02 from the com.prowidesoftware.swift.model.mx.sic package. Therefore, the model has already constrained the elements and elements values with the restrictions from the SIC schemas including binding to the custom SIC namespace . Moreover, the object implements the SchemaProvider interface. So when you call the validation engine passing the object as a parameter, the engine will already apply the corresponding SIC schema. You can just use the validation call: validateMessage ( final AbstractMX msg ) In the second scenario, you just have the XML, so the message structure cannot be distinguished from a regular ISO message. So in order to validate these messages, you need to provide additional information to the validation call to clearly identify the SIC message type you intend to validate. For that, you should use the validation call: validateMxMessage ( final String xml , SchemaProvider schemaProvider ) Where for the SchemaProvider parameter you can use any value of the SicMessageType enum. When your source content is already the XML it is always recommended to use the XML as parameter for the validation. If you parse the XML into an MX object first, and then call the validation using the parsed message as parameter, some errors may not be detected. The validation call with the model object is only intended for scenarios where you are building the message using the model API. SIC MT-MX Translations Only available if you have a license of the Prowide Integrator Translations module. Along the standard ISO 20022 translations, the MT-MX Translations module provides some specific out-of-the-box translations between MT messages and SIC ISO 20022 messages. The following translations are supported for the restricted ISO 20022 for SIC, the Swiss RTGS. The input and output MX model class is the specific class for the restricted ISO version. Such as MxPain00800102Ch02 instead of the standard ISO MxPain00800102 . MT to MX 103 Single Customer Credit Transfer pacs.008.001.02.ch.02 FIToFICustomerCreditTransferV02 SIC v2 202 General Financial Institution Transfer pacs.009.001.02.ch.02 FinancialInstitutionCreditTransferV02 SIC v2 202.COV General Financial Institution Transfer, Cover Payment pacs.009.001.02.ch.02 FinancialInstitutionCreditTransferV02 SIC v2 MX to MT pacs.008.001.02.ch.02 Single Customer Credit Transfer 2 SIC v2 103 Single Customer Credit Transfer pacs.009.001.02.ch.02 FinancialInstitutionCreditTransferV02 SIC v2 202 General Financial Institution Transfer pacs.009.001.02.ch.02 FinancialInstitutionCreditTransferV02 SIC v2 202.COV General Financial Institution Transfer, Cover Payment pacs.004.001.02.ch.02 PaymentReturnV02 103 RETURN Single Customer Credit Transfer Return pacs.002.001.03 FIToFIPaymentStatusReportV03 ACK / NACK Service message 21 Each of these translations is implemented in its own translation class. For information on the translation API, please check the Prowide Integrator Translations developer guide. Javadoc Online javadoc Prowide Integrator SDK Javadoc SRU2023-9.4.x","title":"SIC"},{"location":"integrator/sic/#prowide-integrator-sic","text":"","title":"Prowide Integrator SIC"},{"location":"integrator/sic/#overview","text":"The key feature provided by the SIC extension is the specific model implementation for the Swiss RGTS messages. This is a restricted ISO 20022 version with a subset of messages with specific constraints. For more information for SIC check https://www.six-group.com/interbank-clearing/en/home/standardization/iso-payments/iso20022/implementation-guidelines.html The supported schemas and guidelines version is 4.9 .","title":"Overview"},{"location":"integrator/sic/#supported-message-schemes","text":"The following table includes all the supported message types: camt.003.001.07.ch.02 camt.004.001.08.ch.02 camt.005.001.08.ch.01 camt.006.001.08.ch.02 camt.007.001.08.ch.01 camt.008.001.08.ch.01 camt.019.001.07.ch.02 camt.025.001.05.ch.01 camt.027.001.06.chsepa.01 camt.029.001.08.chsepa.01 camt.029.001.09.ch.01 camt.048.001.05.ch.01 camt.050.001.05.ch.01 camt.052.001.08.ch.02 camt.054.001.08.ch.02 camt.056.001.08.ch.02 camt.087.001.05.chsepa.01 pacs.002.001.10.ch.02 pacs.004.001.09.ch.02 pacs.008.001.08.ch.02 pacs.009.001.08.ch.02 pacs.028.001.01.chsepa.02 Legacy from release 4.6: camt.003.001.05.ch.01 camt.004.001.06.ch.01 camt.005.001.06.ch.03 camt.006.001.06.ch.02 camt.007.001.06.ch.01 camt.008.001.06.ch.01 camt.019.001.05.ch.01 camt.025.001.03.ch.01 camt.027.001.06.chsepa.01 camt.029.001.03.ch.01 camt.029.001.08.chsepa.01 camt.048.001.03.ch.01 camt.050.001.03.ch.01 camt.052.001.02.ch.01 camt.054.001.02.ch.01 camt.056.001.01.ch.01 camt.087.001.05.chsepa.01 pacs.002.001.03.ch.01 pacs.004.001.02.ch.02 pacs.008.001.02.ch.02 pacs.009.001.02.ch.02 pacs.028.001.01.chsepa.02","title":"Supported message schemes"},{"location":"integrator/sic/#message-model","text":"For each of the described message types, a specific implementation message class is provided, into a single common package: com . prowidesoftware . swift . model . mx . sic The package above always contains the latest release availalbe. For older releases, the package name includes the release version, for example: com . prowidesoftware . swift . model . mx . sic . v4_6 The SIC message subset uses custom namespaces , not aligned to the ISO standard namespaces. Once the message class is identified, the creation of a new SIC message is similar to the creation of any standard ISO message. You just populate the Java object and the model will already include the constraints from the SIC schema. For example: MxPacs00800102Ch02 mx = new MxPacs00800102Ch02 (); mx . setFIToFICstmrCdtTrf ( new FIToFICustomerCreditTransferV02 ()); mx . getFIToFICstmrCdtTrf (). setGrpHdr ( new GroupHeader33 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setMsgId ( \"1234\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setCreDtTm ( now ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setNbOfTxs ( \"1\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setIntrBkSttlmDt ( now ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setSttlmInf ( new SettlementInformation13Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getSttlmInf (). setSttlmMtd ( SettlementMethod1Code . CLRG ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setInstgAgt ( new BranchAndFinancialInstitutionIdentification4Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getInstgAgt (). setFinInstnId ( new FinancialInstitutionIdentification7 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getInstgAgt (). getFinInstnId (). setBIC ( \"ABCDUSXXXXX\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setInstdAgt ( new BranchAndFinancialInstitutionIdentification4Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getInstdAgt (). setFinInstnId ( new FinancialInstitutionIdentification7 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getInstdAgt (). getFinInstnId (). setBIC ( \"EFGHUSXXXXX\" ); mx . getFIToFICstmrCdtTrf (). addCdtTrfTxInf ( new CreditTransferTransactionInformation11 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setPmtId ( new PaymentIdentification3 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getPmtId (). setEndToEndId ( \"aaaa\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getPmtId (). setTxId ( \"bbbb\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setPmtTpInf ( new PaymentTypeInformation21 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getPmtTpInf (). setLclInstrm ( new LocalInstrument2Choice ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getPmtTpInf (). getLclInstrm (). setCd ( \"ESRPMT\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setIntrBkSttlmAmt ( new ActiveCurrencyAndAmount ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getIntrBkSttlmAmt (). setCcy ( \"USD\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getIntrBkSttlmAmt (). setValue ( new BigDecimal ( \"1234.56\" )); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setChrgBr ( ChargeBearerType1Code . CRED ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setDbtr ( new PartyIdentification32 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getDbtr (). setNm ( \"Foo1\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setDbtrAgt ( new BranchAndFinancialInstitutionIdentification4Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getDbtrAgt (). setFinInstnId ( new FinancialInstitutionIdentification7 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getDbtrAgt (). getFinInstnId (). setBIC ( \"AAAAUSXXXXX\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setCdtr ( new PartyIdentification32 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getCdtr (). setNm ( \"Foo2\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setCdtrAgt ( new BranchAndFinancialInstitutionIdentification4Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getCdtrAgt (). setFinInstnId ( new FinancialInstitutionIdentification7 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getCdtrAgt (). getFinInstnId (). setBIC ( \"AAAAUSXXXXX\" ); String xml = mx . message (); The serialized XML will have the proper custom SIC namespace. To complement the message model, an enumeration SicMessageType is provided with the list of supported SIC messages. This enumeration implements the internal SchemaProvider interface, so it can be used with the Prowide Integrator Validator library to run the SIC validation for an XML.","title":"Message model"},{"location":"integrator/sic/#sic-validation","text":"Only available if you have a license of the Prowide Integrator Validation module. Along the standard ISO 20022 validation, the Validation module supports out-of-the-box validation for SIC (Swiss RTGS). There are two possible scenarios: You are validating a message created by you in your application with the message model. You are validating a message created externally and received in XML format. In the first case, you should have created a specific message object such as MxPain00800102Ch02 from the com.prowidesoftware.swift.model.mx.sic package. Therefore, the model has already constrained the elements and elements values with the restrictions from the SIC schemas including binding to the custom SIC namespace . Moreover, the object implements the SchemaProvider interface. So when you call the validation engine passing the object as a parameter, the engine will already apply the corresponding SIC schema. You can just use the validation call: validateMessage ( final AbstractMX msg ) In the second scenario, you just have the XML, so the message structure cannot be distinguished from a regular ISO message. So in order to validate these messages, you need to provide additional information to the validation call to clearly identify the SIC message type you intend to validate. For that, you should use the validation call: validateMxMessage ( final String xml , SchemaProvider schemaProvider ) Where for the SchemaProvider parameter you can use any value of the SicMessageType enum. When your source content is already the XML it is always recommended to use the XML as parameter for the validation. If you parse the XML into an MX object first, and then call the validation using the parsed message as parameter, some errors may not be detected. The validation call with the model object is only intended for scenarios where you are building the message using the model API.","title":"SIC validation"},{"location":"integrator/sic/#sic-mt-mx-translations","text":"Only available if you have a license of the Prowide Integrator Translations module. Along the standard ISO 20022 translations, the MT-MX Translations module provides some specific out-of-the-box translations between MT messages and SIC ISO 20022 messages. The following translations are supported for the restricted ISO 20022 for SIC, the Swiss RTGS. The input and output MX model class is the specific class for the restricted ISO version. Such as MxPain00800102Ch02 instead of the standard ISO MxPain00800102 .","title":"SIC MT-MX Translations"},{"location":"integrator/sic/#mt-to-mx","text":"103 Single Customer Credit Transfer pacs.008.001.02.ch.02 FIToFICustomerCreditTransferV02 SIC v2 202 General Financial Institution Transfer pacs.009.001.02.ch.02 FinancialInstitutionCreditTransferV02 SIC v2 202.COV General Financial Institution Transfer, Cover Payment pacs.009.001.02.ch.02 FinancialInstitutionCreditTransferV02 SIC v2","title":"MT to MX"},{"location":"integrator/sic/#mx-to-mt","text":"pacs.008.001.02.ch.02 Single Customer Credit Transfer 2 SIC v2 103 Single Customer Credit Transfer pacs.009.001.02.ch.02 FinancialInstitutionCreditTransferV02 SIC v2 202 General Financial Institution Transfer pacs.009.001.02.ch.02 FinancialInstitutionCreditTransferV02 SIC v2 202.COV General Financial Institution Transfer, Cover Payment pacs.004.001.02.ch.02 PaymentReturnV02 103 RETURN Single Customer Credit Transfer Return pacs.002.001.03 FIToFIPaymentStatusReportV03 ACK / NACK Service message 21 Each of these translations is implemented in its own translation class. For information on the translation API, please check the Prowide Integrator Translations developer guide.","title":"MX to MT"},{"location":"integrator/sic/#javadoc","text":"Online javadoc Prowide Integrator SDK Javadoc SRU2023-9.4.x","title":"Javadoc"},{"location":"integrator/myformat/","text":"Prowide Integrator MyFormat - Overview The MyFormat module facilitates the conversion between SWIFT and proprietary data in any of these formats: Proprietary formats XML -> Custom XML structures JSON -> Custom Json structures CSV -> Custom CSV files with one or many messages Fixed-Length -> Custom fixed-length files with any record structure SWIFT standards FIN -> Any message type in the SWIFT MT standard (ISO 15022) MX -> Any message type in the SWIFT MX standard (ISO 20022) Any combination of formats is supported; as well as any message flow, inbound or outbound. Our library helps define detailed field to field mappings easily. The mappings are then embedded and deployed in your application to perform the translation on the fly . The translation process loads the source message and generates the target message dynamically, by applying your mapping rules. Since the module is packaged as a Java library, a simple API call to the library is enough to generate the output. Unlike other tools, in MyFormat there is no need to generate and compile code or to use any proprietary mapping UI. Javadoc Online javadoc Prowide Integrator MyFormat Javadoc SRU2023-9.4.x","title":"Prowide Integrator MyFormat - Overview"},{"location":"integrator/myformat/#prowide-integrator-myformat-overview","text":"The MyFormat module facilitates the conversion between SWIFT and proprietary data in any of these formats: Proprietary formats XML -> Custom XML structures JSON -> Custom Json structures CSV -> Custom CSV files with one or many messages Fixed-Length -> Custom fixed-length files with any record structure SWIFT standards FIN -> Any message type in the SWIFT MT standard (ISO 15022) MX -> Any message type in the SWIFT MX standard (ISO 20022) Any combination of formats is supported; as well as any message flow, inbound or outbound. Our library helps define detailed field to field mappings easily. The mappings are then embedded and deployed in your application to perform the translation on the fly . The translation process loads the source message and generates the target message dynamically, by applying your mapping rules. Since the module is packaged as a Java library, a simple API call to the library is enough to generate the output. Unlike other tools, in MyFormat there is no need to generate and compile code or to use any proprietary mapping UI.","title":"Prowide Integrator MyFormat - Overview"},{"location":"integrator/myformat/#javadoc","text":"Online javadoc Prowide Integrator MyFormat Javadoc SRU2023-9.4.x","title":"Javadoc"},{"location":"integrator/myformat/myformat-config/","text":"Mapping configuration The implementation for mapping configuration is the MappingTable class. When calling the translation, the engine expects as parameters this table along the source message to convert. This table contains basically the source and target formats definition, along a list of mapping rules The mapping rules can be added to the table programmatically, or they can be externalized and loaded from Excel files or from a Database. The following sections describe the different options. Programmatic Configuration When the mappings are a small set, or when doing a POC, it is possible to define the mapping configuration in your application code. The engine will use the mapping configuration defined in the code to perform the translation. This alternative to define the rules is more efficient and less error-prone, but any change to the mapping will require you to compile and deploy a new version of your solution. In this case, the conversion rules are programmatically coded. The MappingTable class defines the source and target formats and provides methods to set and modify the list of mapping rules. Example 1 : MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MT ); t . add ( new MappingRule ( \"1\" , \"32B/1\" )); t . add ( new MappingRule ( \"2\" , \"32B/2\" , WriteMode . APPEND , new Transformation ( Transformation . Key . replace , \".\" , \",\" ))); In this example, a mapping table is created to convert a CSV into an MT. Then two mapping rules are added to the table. The first rule will copy the content of the second column in the CSV (columns are zero-based) file into the first component of a field 32B of the MT. The second rule will append to the same field 32B, setting the content of the third column in the CSV file into the second component of the field. Notice the second rule also defines a transformation to replace the decimal separator in the CSV file (a dot) by a comma, which is the expected format in the MT. Example 2 : MappingTable t = new MappingTable ( FileFormat . XML , FileFormat . MT ); t . add ( new MappingRule ( \"/document/foo\" , \"20\" , new Transformation ( Transformation . Key . replace , \" \" , \"\" ), new Transformation ( Transformation . Key . upperCase ), new Transformation ( Transformation . Key . prepend , \"Hi \" ))); t . add ( new MappingRule ( \"\\\" 1234\\\"\" , \"20\" , WriteMode . APPEND )); t . add ( new MappingRule ( \"\\\"NOREF\\\"\" , \"21\" )); t . add ( new MappingRule ( \"/bad/path\" , \"16\" )); In this example, a mapping table is created to convert an XML into an MT. Then four mapping rules are added to the table. An method is also provided in the is provided in the MappingTable to validate the mapping rules. The validation will check that all selectors are well-formed according to the defined source and target file formats, and also that the transformation functions are defined with proper parameters. This validation is helpful for sanity check and to prevent exceptions during the actual translation in runtime. The validation is static, meaning it will not prevent creating wrong content because of invalid mapping rules logic or invalid input data. Since mapping tables are maintained as local variables in your program, you can instantiate as many mapping tables as a combination of source and target messages you need to process. If you\u2019ve implemented and want to use a custom transformation in a rule, you just create an instance of transformation passing your own implementing class, for example: t . add ( new MappingRule ( \"2\" , \"32B/2\" , WriteMode . APPEND , new Transformation ( new CustomTransformer ()))); External Configuration When the mapping configuration is a large set, or when its definition are closer to the business than to technical mappings, it is possible to define the mapping configuration in a separate file. The engine will load the mapping configuration from the file and use it to perform the translation. Thus, the maintenance of the mapping configuration is decoupled from the application code. Externalized mappings can be loaded from Excel sheets or database tables. In this case, the rules are defined and maintained decoupled from the translation code, loaded from an Excel spreadsheet or database . This usage is convenient when the conversion rules should be maintained by system analysts, and not developers, because it requires no coding during maintenance. Example : An Excel for this configuration way. The database option is similar, it uses a simple table schema with a similar syntax as in the sheet. The following sections describe the details of the mapping configuration in Excel and in Database. Mapping configuration in Excel files Mapping rules configurations can be loaded from files using Excel spreadsheets. Within an Excel file, each sheet (tab) can contain an independent mapping table. Each mapping table consists of the list of mapping rules to convert from a specific source message to a specific target message. The mapping table in an Excel sheet must contain three columns : Column 1 : The source selector with an expression according to the source message file format. The selector can optionally contain a read mode, such as \"foreach\". The source column is mandatory , cannot be left blank. It can contain literals (wrapped in double quotes or within a literal function) or selector expressions (example XPath or MtPath). Multiple source selectors may be defined in a single mapping rule according to the read mode; in such case, a comma separates the selectors. Examples in different file formats: E/E1/95Q \"FOO\" literal(FOO) /Document/PmtInf/PmtDtls/CshTxTp Document.CstmrCdtTrfInitn.GrpHdr.MsgId foreach(/Document/PmtInf[{N}]/PmtDtl[{M}]/CshTxCode) concat(/A/B/C, \"-\", /A/D/@attr) Column 2 : The optional transformation calls separated by a semicolon. The transformation column is optional, if it is left blank no transformations will be applied. Transformations are expressed as parameterized functions. Multiple transformations may be defined for a single mapping rule, in such case the functions are indicated in a single cell. Parameters are indicated between brackets next to the function name, and separated by commas. Integer parameters are indicated as plain digits, while string parameters wrapped in double quotes. The order of the transformations is important because they are applied from left to right, with the output of a transformation becoming the input for the next one. Examples: stripStart(\"/\"); formatMTDecimal(); append(\"$\") fromPIC(X(10)); stripToNull(); upperCase(); map(\"BENEFICIARY\", \"BEN\", \"SHARED\", \"SHA\", \"CUSTOMER\", \"OUR\"); Column 3 : The target selector with an expression according to the target message file format. The target column is mandatory , cannot be left blank, and must contain a single selector expression, proper to the target format. For example, an XPath expression if the message to create is an XML, or an MtPath if the created message is an MT. Column 4 : An optional write mode. The write mode column is optional . The accepted values for the columns are CREATE, UPDATE and APPEND. By default, the mapping rule will use the Create mode. Note this column also accept the SETUP value as valid. This is not a write mode but a transformation config expression. SETUP options will be described later in this doc. Each row in the sheet defines a specific mapping rule , with the first row intentionally skipped, so it can be used as a header reference. Notice that rules, order is important . The conversion flow will process the mapping table from top to bottom. This is particularly significant when creating MT messages because block 4 of a SWIFT MT message is a sorted list of fields. For other file formats, such as XML based messages, the rules order does not affect the structure of the created message. All cells in the spreadsheet must be in plain text format (numeric cells will be read as strings). Notice all selectors and transformation functions are expressed as strings. Loading the configuration To simplify loading the mapping configuration from Excel files, a specially suited MappingTableExcelLoader class is provided. The following example shows how to load a mapping configuration from a SpreadSheet on disk. MappingTableExcelLoader loader = new MappingTableExcelLoader ( getClass (). getResourceAsStream ( \"/sample.xls\" )); MappingTable mappingTable = loader . load ( \"A\" , FileFormat . XML , FileFormat . MT ); List < String > problems = loader . getProblems (); Notice that the source and target formats can be explicitly indicated when loading the table. This information is used for static validation and also in runtime to create proper reader and writer objects. You can also create the reader and writer object and pass those as parameter. For certain operations you will prefer to use this dependency-injection alternative. Depending on your particular needs you have several similar options for the table loading such as: MappingTable mappingTable = new MappingTable ( FileFormat . XML , FileFormat . MT ); MappingTableExcelLoader loader = new MappingTableExcelLoader ( getClass (). getResourceAsStream ( \"/sample.xls\" )); loader . load ( \"A\" , mappingTable ); Mapping tables can be handled individually or, if the same Spreadsheets contain several mapping tables, a full load can be called, reading each of the sheets (tabs). MappingTableExcelLoader loader = new MappingTableExcelLoader ( getClass (). getResourceAsStream ( \"/multi_tab.xls\" )); List < MappingTable > mappingTables = loader . load (); in the above example, all sheets in the file will be loaded and returned as a list of mapping tables. The problems list will contain all errors found in all sheets. The read MappingTable object will be passed as a parameter to the conversion engine along with the source message when a translation is performed. When translating multiple files, the mappings should be read only once in the lifecycle of the controlling program. Excel error handling The loading process will perform static syntax validations on each defined rule, and the provided file formats are used to validate the content selectors. If all rows are ok, the returned list from loader.getProblems() is empty. Otherwise, the list contains a comprehensive detail of found errors in plain English. List < String > problems = loader . getProblems (); Any excel inquiry error during the load will be caught and reported as plain Strings. When the MappingTableExcelLoader is used, the errors are stored in the loader object and can be retrieved with the getProblems() method. Since the loader is reentrant, the problems list is emptied before each load call. Although excel and syntax errors are reported by the loading, a call afterwards to the MappingTable#validate() is highly recommended. That manually triggered validation on the mapping table will ensure the rules are also semantically correct and will perform as expected. Since the mapping is normally loaded once during your application initialization, this syntax and semantic validation checks will be done only once and the report is static, in the sense that it is a validation on the mapping definition regardless of the actual runtime translations calls you do afterwards. So this is useful to detect mapping errors when the mapping rules are created or maintained. Mapping configuration in Database Mapping rules configurations can be loaded from a database table. The database structure is minimal to simplify setup and maintenance. It is conformed by a single database table, with fixed table and column names, and with the rules stored as text. Multiple mapping configurations can be stored in the same single database table; when the query is performed, a discriminator column with the configuration name is used to load specific subsets of rules. Each row in the database table defines a specific mapping rule, and contains seven columns as follows: Id : This is the internal unique identifier of the table record and is normally set to auto increment in the database. The mapping engine does not use this column. pw_conf_name column : This column is the discriminator and is used to group a set of mapping rules corresponding to a Mapping Table configuration. It would normally exist one configuration name for each source and target message combination. The value for the column has no restrictions but should be consistently set to all records belonging to the same configuration, and it cannot be null. Example: mt202_seev031 This discriminator is necessary to keep the single table design, instead of defining a more complex model with one-to-many relation between the mapping table and rules. pw_order column : When the rules are retrieved from the database, this column is used to order the results. It normally should contain a sequential number, local to the mapping configuration. Meaning, per each pw_conf_name an independent order counter. The order cannot be null. Notice that rules, order is important . The conversion flow will process the mapping table in ascending order of rules. This is particularly significant when creating MT messages because block 4 of a SWIFT MT message is a sorted list of fields. When creating XML based messages, the rules order does not affect the structure of the created XML. pw_source column : The source column is mandatory, cannot be null. It can contain literals (wrapped in double quotes) or selector expressions (example XPath or MtPath ). Please refer to the description of Column 1 in the configuration from Excel section above. pw_transformation column : The transformation column is optional, if it is left null no transformations will be applied. Transformations are expressed as parameterized functions. Multiple transformations may be defined for a single mapping rule, in such case the functions are indicated in the same database column, separated by a semicolon. Please refer to the description of Column 2 in the configuration from Excel section above. pw_target column : The target column is mandatory, cannot be null, and must contain a single selector expression, proper to the target format. For example, an XPath expression if the message to create is an XML, or an MtPath if the created message is an MT. Please refer to the description of Column 3 in the configuration from Excel section above. pw_mode column : The write mode column is optional. The accepted values for the columns are CREATE, UPDATE and APPEND. By default, the mapping rule will use the Create mode. Please refer to Setup commands for further details about SETUP mode. Loading the configuration The engine uses direct JDBC queries to access the database and load the rules, so the driver for your particular database must be available in the runtime classpath (for example: mysql-connector-java-version-bin.jar for MySQL). The MappingTable class provides a few methods called loadFromDatabase to load the rules. Such as: MappingTable table = new MappingTable ( FileFormat . XML , FileFormat . MT ); List < String > problems = MappingTable . loadFromDatabase ( \"jdbc:mysql://localhost/myformat\" , \"root\" , null , \"202_seev031\" , table ); Similar methods are available with connection, dataSource and datasource context name. Notice that the source and target formats must be explicitly indicated when creating the mapping table object parameter, there are no part of the loaded data. The read MappingTable object will be passed as a parameter to the conversion engine along with the source message when a translation is performed. When translating multiple files, the mappings should be read only once in the lifecycle of the controlling program. Custom table and scheme For additional flexibility when loading the mappings from the database, a specially suited MappingTableDatabaseLoader is also available. This utility class is intended for reuse. You can create a single loader instance with any of the construction options ( url, datasource, connection, etc...) and then call the load method multiple times to retrieve different mapping tables. For each load call you can provide the configuration name and optionally further customize the loader with the setters for the main table name, schema name, etc... Example 1: This code creates the loader with a Datasource as constructor parameter, and then two different mapping tables are loaded, each from a different database schema. MappingTableDatabaseLoader loader = new MappingTableDatabaseLoader ( datasource ); loader . setSchemaName ( \"CUSTOM_SCHEMA_1\" ); MappingTable table1 = loader . load ( \"test\" , FileFormat . XML , FileFormat . MT ); loader . setSchemaName ( \"CUSTOM_SCHEMA_2\" ); MappingTable table2 = loader . load ( \"test\" , FileFormat . XML , FileFormat . MX ); Example 2: This example creates a loader from a Connection as constructor parameter, and then loads the mapping table from a customized table, where the actual table name and columns have different names. MappingTableDatabaseLoader loader = new MappingTableDatabaseLoader ( conn ); loader . setMainTableName ( \"custom_table\" ); loader . getCustomColumnNames (). pw_conf_name = \"custom_pw_conf_name\" ; loader . getCustomColumnNames (). pw_order = \"custom_pw_order\" ; MappingTable table = loader . load ( \"test\" , FileFormat . XML , FileFormat . MT ); Notice that the source and target formats can be explicitly indicated when loading the mapping, since are not part of the loaded data. DB error handling Any database inquiry error during the load will be catched and reported as plain Strings. When the direct MappingTable#loadFromDatabase method is used, the method returns the errors as return value. And when the MappingTableDatabaseLoader is used, the errors are stored in the loader object and can be retrieved with the getProblems() method. Since the loader is reentrant, the problems list is emptied before each load call. Besides the database access errors, the imported rules are syntactically checked during parsing and a comprehensive detail of found errors will be catched and reported in the problems list. Although database and syntax errors are reported by the loading, a call afterwards to the MappingTable#validate() is highly recommended. That manually triggered validation on the mapping table will ensure the rules are also ** semantically** correct and will perform as expected. Since the mapping is normally loaded once during your application initialization, this syntax and semantic validation checks will be done only once and the report is static, in the sense that it is a validation on the mapping definition regardless of the actual runtime translations calls you do afterwards. So this is useful to detect mapping errors when the mapping rules are created or maintained. Setup commands In the externalized mapping configuration, spreadsheet or DB, several special rules can be added to probide global configuration for the mapping. These rules are called SETUP rules and are identified by the SETUP keyword in the write mode column. Then source in the rule is used to provide the command value, while the target is used to provide the actual command. For example: Source Transformations Target Write Mode \"CSV\" sourceFormat SETUP The following commands are supported: sourceFormat : To indicate the source format of the mapping table. Setting this in the mapping is the same as passing the Format parameter when creating a MappingTable instance. targetFormat : To indicate the target format of the mapping table. Setting this in the mapping is the same as passing the Format parameter when creating a MappingTable instance. mappingName : To indicate the name of the mapping table. mxType : To indicate the specific MX type in conversions from/into MX, for example \"pacs.008.001.08\". This parameter is used for two purposes: it will validate that all the MX expression paths in the source/target selectors are valid paths for the given message type. And, if the target message is MX, it initializes the message header and namespace declarations in the target message. appHdrType : To indicate the specific MX Application Header type in conversions into MX, for example \"BAH_V1\". This parameter is used mainly to set the message header type in the target message. Setting this in the mapping is the same as passing the AppHdrType parameter when creating a MxWriter instance. mtType : To indicate the specific MT type in conversions into MT, for example \"103\". This parameter is used mainly to initialize the message block 2 header in the target message. Setting this in the mapping is the same as passing the MtType parameter when creating a MtWriter instance. More setup commands are described in the specific file formats documentation. Validation The validate() method in the mapping table can be used to run a static syntax analysis of the mapping rules. You can then incorporate the validation as part of your development and testing procedures. The validation is especially useful when the mapping table is loaded from an external source (rules are not programmatically defined). The validation will parse all source and target selectors and will report any syntax error. The transformation expressions are also parsed to check the function calls are recognizable and with the expected number of arguments. MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MX ); ... t . add ( new MappingRule ( \"6\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/Dbtr/Nm\" )); t . add ( new MappingRule ( \"2\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/DbtrAcct/Nm\" )); ... if ( t . validate (). isEmpty ()) { ... } Many typical errors can be discovered with this static check. Notice, however, that a syntactically valid mapping table does not imply the mapping will produce a valid result at runtime. The compliance of the generated file depends on the source message content and on the business logic of the configured mapping rules.","title":"Mapping configuration"},{"location":"integrator/myformat/myformat-config/#mapping-configuration","text":"The implementation for mapping configuration is the MappingTable class. When calling the translation, the engine expects as parameters this table along the source message to convert. This table contains basically the source and target formats definition, along a list of mapping rules The mapping rules can be added to the table programmatically, or they can be externalized and loaded from Excel files or from a Database. The following sections describe the different options.","title":"Mapping configuration"},{"location":"integrator/myformat/myformat-config/#programmatic-configuration","text":"When the mappings are a small set, or when doing a POC, it is possible to define the mapping configuration in your application code. The engine will use the mapping configuration defined in the code to perform the translation. This alternative to define the rules is more efficient and less error-prone, but any change to the mapping will require you to compile and deploy a new version of your solution. In this case, the conversion rules are programmatically coded. The MappingTable class defines the source and target formats and provides methods to set and modify the list of mapping rules. Example 1 : MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MT ); t . add ( new MappingRule ( \"1\" , \"32B/1\" )); t . add ( new MappingRule ( \"2\" , \"32B/2\" , WriteMode . APPEND , new Transformation ( Transformation . Key . replace , \".\" , \",\" ))); In this example, a mapping table is created to convert a CSV into an MT. Then two mapping rules are added to the table. The first rule will copy the content of the second column in the CSV (columns are zero-based) file into the first component of a field 32B of the MT. The second rule will append to the same field 32B, setting the content of the third column in the CSV file into the second component of the field. Notice the second rule also defines a transformation to replace the decimal separator in the CSV file (a dot) by a comma, which is the expected format in the MT. Example 2 : MappingTable t = new MappingTable ( FileFormat . XML , FileFormat . MT ); t . add ( new MappingRule ( \"/document/foo\" , \"20\" , new Transformation ( Transformation . Key . replace , \" \" , \"\" ), new Transformation ( Transformation . Key . upperCase ), new Transformation ( Transformation . Key . prepend , \"Hi \" ))); t . add ( new MappingRule ( \"\\\" 1234\\\"\" , \"20\" , WriteMode . APPEND )); t . add ( new MappingRule ( \"\\\"NOREF\\\"\" , \"21\" )); t . add ( new MappingRule ( \"/bad/path\" , \"16\" )); In this example, a mapping table is created to convert an XML into an MT. Then four mapping rules are added to the table. An method is also provided in the is provided in the MappingTable to validate the mapping rules. The validation will check that all selectors are well-formed according to the defined source and target file formats, and also that the transformation functions are defined with proper parameters. This validation is helpful for sanity check and to prevent exceptions during the actual translation in runtime. The validation is static, meaning it will not prevent creating wrong content because of invalid mapping rules logic or invalid input data. Since mapping tables are maintained as local variables in your program, you can instantiate as many mapping tables as a combination of source and target messages you need to process. If you\u2019ve implemented and want to use a custom transformation in a rule, you just create an instance of transformation passing your own implementing class, for example: t . add ( new MappingRule ( \"2\" , \"32B/2\" , WriteMode . APPEND , new Transformation ( new CustomTransformer ())));","title":"Programmatic Configuration"},{"location":"integrator/myformat/myformat-config/#external-configuration","text":"When the mapping configuration is a large set, or when its definition are closer to the business than to technical mappings, it is possible to define the mapping configuration in a separate file. The engine will load the mapping configuration from the file and use it to perform the translation. Thus, the maintenance of the mapping configuration is decoupled from the application code. Externalized mappings can be loaded from Excel sheets or database tables. In this case, the rules are defined and maintained decoupled from the translation code, loaded from an Excel spreadsheet or database . This usage is convenient when the conversion rules should be maintained by system analysts, and not developers, because it requires no coding during maintenance. Example : An Excel for this configuration way. The database option is similar, it uses a simple table schema with a similar syntax as in the sheet. The following sections describe the details of the mapping configuration in Excel and in Database.","title":"External Configuration"},{"location":"integrator/myformat/myformat-config/#mapping-configuration-in-excel-files","text":"Mapping rules configurations can be loaded from files using Excel spreadsheets. Within an Excel file, each sheet (tab) can contain an independent mapping table. Each mapping table consists of the list of mapping rules to convert from a specific source message to a specific target message. The mapping table in an Excel sheet must contain three columns : Column 1 : The source selector with an expression according to the source message file format. The selector can optionally contain a read mode, such as \"foreach\". The source column is mandatory , cannot be left blank. It can contain literals (wrapped in double quotes or within a literal function) or selector expressions (example XPath or MtPath). Multiple source selectors may be defined in a single mapping rule according to the read mode; in such case, a comma separates the selectors. Examples in different file formats: E/E1/95Q \"FOO\" literal(FOO) /Document/PmtInf/PmtDtls/CshTxTp Document.CstmrCdtTrfInitn.GrpHdr.MsgId foreach(/Document/PmtInf[{N}]/PmtDtl[{M}]/CshTxCode) concat(/A/B/C, \"-\", /A/D/@attr) Column 2 : The optional transformation calls separated by a semicolon. The transformation column is optional, if it is left blank no transformations will be applied. Transformations are expressed as parameterized functions. Multiple transformations may be defined for a single mapping rule, in such case the functions are indicated in a single cell. Parameters are indicated between brackets next to the function name, and separated by commas. Integer parameters are indicated as plain digits, while string parameters wrapped in double quotes. The order of the transformations is important because they are applied from left to right, with the output of a transformation becoming the input for the next one. Examples: stripStart(\"/\"); formatMTDecimal(); append(\"$\") fromPIC(X(10)); stripToNull(); upperCase(); map(\"BENEFICIARY\", \"BEN\", \"SHARED\", \"SHA\", \"CUSTOMER\", \"OUR\"); Column 3 : The target selector with an expression according to the target message file format. The target column is mandatory , cannot be left blank, and must contain a single selector expression, proper to the target format. For example, an XPath expression if the message to create is an XML, or an MtPath if the created message is an MT. Column 4 : An optional write mode. The write mode column is optional . The accepted values for the columns are CREATE, UPDATE and APPEND. By default, the mapping rule will use the Create mode. Note this column also accept the SETUP value as valid. This is not a write mode but a transformation config expression. SETUP options will be described later in this doc. Each row in the sheet defines a specific mapping rule , with the first row intentionally skipped, so it can be used as a header reference. Notice that rules, order is important . The conversion flow will process the mapping table from top to bottom. This is particularly significant when creating MT messages because block 4 of a SWIFT MT message is a sorted list of fields. For other file formats, such as XML based messages, the rules order does not affect the structure of the created message. All cells in the spreadsheet must be in plain text format (numeric cells will be read as strings). Notice all selectors and transformation functions are expressed as strings.","title":"Mapping configuration in Excel files"},{"location":"integrator/myformat/myformat-config/#loading-the-configuration","text":"To simplify loading the mapping configuration from Excel files, a specially suited MappingTableExcelLoader class is provided. The following example shows how to load a mapping configuration from a SpreadSheet on disk. MappingTableExcelLoader loader = new MappingTableExcelLoader ( getClass (). getResourceAsStream ( \"/sample.xls\" )); MappingTable mappingTable = loader . load ( \"A\" , FileFormat . XML , FileFormat . MT ); List < String > problems = loader . getProblems (); Notice that the source and target formats can be explicitly indicated when loading the table. This information is used for static validation and also in runtime to create proper reader and writer objects. You can also create the reader and writer object and pass those as parameter. For certain operations you will prefer to use this dependency-injection alternative. Depending on your particular needs you have several similar options for the table loading such as: MappingTable mappingTable = new MappingTable ( FileFormat . XML , FileFormat . MT ); MappingTableExcelLoader loader = new MappingTableExcelLoader ( getClass (). getResourceAsStream ( \"/sample.xls\" )); loader . load ( \"A\" , mappingTable ); Mapping tables can be handled individually or, if the same Spreadsheets contain several mapping tables, a full load can be called, reading each of the sheets (tabs). MappingTableExcelLoader loader = new MappingTableExcelLoader ( getClass (). getResourceAsStream ( \"/multi_tab.xls\" )); List < MappingTable > mappingTables = loader . load (); in the above example, all sheets in the file will be loaded and returned as a list of mapping tables. The problems list will contain all errors found in all sheets. The read MappingTable object will be passed as a parameter to the conversion engine along with the source message when a translation is performed. When translating multiple files, the mappings should be read only once in the lifecycle of the controlling program.","title":"Loading the configuration"},{"location":"integrator/myformat/myformat-config/#excel-error-handling","text":"The loading process will perform static syntax validations on each defined rule, and the provided file formats are used to validate the content selectors. If all rows are ok, the returned list from loader.getProblems() is empty. Otherwise, the list contains a comprehensive detail of found errors in plain English. List < String > problems = loader . getProblems (); Any excel inquiry error during the load will be caught and reported as plain Strings. When the MappingTableExcelLoader is used, the errors are stored in the loader object and can be retrieved with the getProblems() method. Since the loader is reentrant, the problems list is emptied before each load call. Although excel and syntax errors are reported by the loading, a call afterwards to the MappingTable#validate() is highly recommended. That manually triggered validation on the mapping table will ensure the rules are also semantically correct and will perform as expected. Since the mapping is normally loaded once during your application initialization, this syntax and semantic validation checks will be done only once and the report is static, in the sense that it is a validation on the mapping definition regardless of the actual runtime translations calls you do afterwards. So this is useful to detect mapping errors when the mapping rules are created or maintained.","title":"Excel error handling"},{"location":"integrator/myformat/myformat-config/#mapping-configuration-in-database","text":"Mapping rules configurations can be loaded from a database table. The database structure is minimal to simplify setup and maintenance. It is conformed by a single database table, with fixed table and column names, and with the rules stored as text. Multiple mapping configurations can be stored in the same single database table; when the query is performed, a discriminator column with the configuration name is used to load specific subsets of rules. Each row in the database table defines a specific mapping rule, and contains seven columns as follows: Id : This is the internal unique identifier of the table record and is normally set to auto increment in the database. The mapping engine does not use this column. pw_conf_name column : This column is the discriminator and is used to group a set of mapping rules corresponding to a Mapping Table configuration. It would normally exist one configuration name for each source and target message combination. The value for the column has no restrictions but should be consistently set to all records belonging to the same configuration, and it cannot be null. Example: mt202_seev031 This discriminator is necessary to keep the single table design, instead of defining a more complex model with one-to-many relation between the mapping table and rules. pw_order column : When the rules are retrieved from the database, this column is used to order the results. It normally should contain a sequential number, local to the mapping configuration. Meaning, per each pw_conf_name an independent order counter. The order cannot be null. Notice that rules, order is important . The conversion flow will process the mapping table in ascending order of rules. This is particularly significant when creating MT messages because block 4 of a SWIFT MT message is a sorted list of fields. When creating XML based messages, the rules order does not affect the structure of the created XML. pw_source column : The source column is mandatory, cannot be null. It can contain literals (wrapped in double quotes) or selector expressions (example XPath or MtPath ). Please refer to the description of Column 1 in the configuration from Excel section above. pw_transformation column : The transformation column is optional, if it is left null no transformations will be applied. Transformations are expressed as parameterized functions. Multiple transformations may be defined for a single mapping rule, in such case the functions are indicated in the same database column, separated by a semicolon. Please refer to the description of Column 2 in the configuration from Excel section above. pw_target column : The target column is mandatory, cannot be null, and must contain a single selector expression, proper to the target format. For example, an XPath expression if the message to create is an XML, or an MtPath if the created message is an MT. Please refer to the description of Column 3 in the configuration from Excel section above. pw_mode column : The write mode column is optional. The accepted values for the columns are CREATE, UPDATE and APPEND. By default, the mapping rule will use the Create mode. Please refer to Setup commands for further details about SETUP mode.","title":"Mapping configuration in Database"},{"location":"integrator/myformat/myformat-config/#loading-the-configuration_1","text":"The engine uses direct JDBC queries to access the database and load the rules, so the driver for your particular database must be available in the runtime classpath (for example: mysql-connector-java-version-bin.jar for MySQL). The MappingTable class provides a few methods called loadFromDatabase to load the rules. Such as: MappingTable table = new MappingTable ( FileFormat . XML , FileFormat . MT ); List < String > problems = MappingTable . loadFromDatabase ( \"jdbc:mysql://localhost/myformat\" , \"root\" , null , \"202_seev031\" , table ); Similar methods are available with connection, dataSource and datasource context name. Notice that the source and target formats must be explicitly indicated when creating the mapping table object parameter, there are no part of the loaded data. The read MappingTable object will be passed as a parameter to the conversion engine along with the source message when a translation is performed. When translating multiple files, the mappings should be read only once in the lifecycle of the controlling program.","title":"Loading the configuration"},{"location":"integrator/myformat/myformat-config/#custom-table-and-scheme","text":"For additional flexibility when loading the mappings from the database, a specially suited MappingTableDatabaseLoader is also available. This utility class is intended for reuse. You can create a single loader instance with any of the construction options ( url, datasource, connection, etc...) and then call the load method multiple times to retrieve different mapping tables. For each load call you can provide the configuration name and optionally further customize the loader with the setters for the main table name, schema name, etc... Example 1: This code creates the loader with a Datasource as constructor parameter, and then two different mapping tables are loaded, each from a different database schema. MappingTableDatabaseLoader loader = new MappingTableDatabaseLoader ( datasource ); loader . setSchemaName ( \"CUSTOM_SCHEMA_1\" ); MappingTable table1 = loader . load ( \"test\" , FileFormat . XML , FileFormat . MT ); loader . setSchemaName ( \"CUSTOM_SCHEMA_2\" ); MappingTable table2 = loader . load ( \"test\" , FileFormat . XML , FileFormat . MX ); Example 2: This example creates a loader from a Connection as constructor parameter, and then loads the mapping table from a customized table, where the actual table name and columns have different names. MappingTableDatabaseLoader loader = new MappingTableDatabaseLoader ( conn ); loader . setMainTableName ( \"custom_table\" ); loader . getCustomColumnNames (). pw_conf_name = \"custom_pw_conf_name\" ; loader . getCustomColumnNames (). pw_order = \"custom_pw_order\" ; MappingTable table = loader . load ( \"test\" , FileFormat . XML , FileFormat . MT ); Notice that the source and target formats can be explicitly indicated when loading the mapping, since are not part of the loaded data.","title":"Custom table and scheme"},{"location":"integrator/myformat/myformat-config/#db-error-handling","text":"Any database inquiry error during the load will be catched and reported as plain Strings. When the direct MappingTable#loadFromDatabase method is used, the method returns the errors as return value. And when the MappingTableDatabaseLoader is used, the errors are stored in the loader object and can be retrieved with the getProblems() method. Since the loader is reentrant, the problems list is emptied before each load call. Besides the database access errors, the imported rules are syntactically checked during parsing and a comprehensive detail of found errors will be catched and reported in the problems list. Although database and syntax errors are reported by the loading, a call afterwards to the MappingTable#validate() is highly recommended. That manually triggered validation on the mapping table will ensure the rules are also ** semantically** correct and will perform as expected. Since the mapping is normally loaded once during your application initialization, this syntax and semantic validation checks will be done only once and the report is static, in the sense that it is a validation on the mapping definition regardless of the actual runtime translations calls you do afterwards. So this is useful to detect mapping errors when the mapping rules are created or maintained.","title":"DB error handling"},{"location":"integrator/myformat/myformat-config/#setup-commands","text":"In the externalized mapping configuration, spreadsheet or DB, several special rules can be added to probide global configuration for the mapping. These rules are called SETUP rules and are identified by the SETUP keyword in the write mode column. Then source in the rule is used to provide the command value, while the target is used to provide the actual command. For example: Source Transformations Target Write Mode \"CSV\" sourceFormat SETUP The following commands are supported: sourceFormat : To indicate the source format of the mapping table. Setting this in the mapping is the same as passing the Format parameter when creating a MappingTable instance. targetFormat : To indicate the target format of the mapping table. Setting this in the mapping is the same as passing the Format parameter when creating a MappingTable instance. mappingName : To indicate the name of the mapping table. mxType : To indicate the specific MX type in conversions from/into MX, for example \"pacs.008.001.08\". This parameter is used for two purposes: it will validate that all the MX expression paths in the source/target selectors are valid paths for the given message type. And, if the target message is MX, it initializes the message header and namespace declarations in the target message. appHdrType : To indicate the specific MX Application Header type in conversions into MX, for example \"BAH_V1\". This parameter is used mainly to set the message header type in the target message. Setting this in the mapping is the same as passing the AppHdrType parameter when creating a MxWriter instance. mtType : To indicate the specific MT type in conversions into MT, for example \"103\". This parameter is used mainly to initialize the message block 2 header in the target message. Setting this in the mapping is the same as passing the MtType parameter when creating a MtWriter instance. More setup commands are described in the specific file formats documentation.","title":"Setup commands"},{"location":"integrator/myformat/myformat-config/#validation","text":"The validate() method in the mapping table can be used to run a static syntax analysis of the mapping rules. You can then incorporate the validation as part of your development and testing procedures. The validation is especially useful when the mapping table is loaded from an external source (rules are not programmatically defined). The validation will parse all source and target selectors and will report any syntax error. The transformation expressions are also parsed to check the function calls are recognizable and with the expected number of arguments. MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MX ); ... t . add ( new MappingRule ( \"6\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/Dbtr/Nm\" )); t . add ( new MappingRule ( \"2\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/DbtrAcct/Nm\" )); ... if ( t . validate (). isEmpty ()) { ... } Many typical errors can be discovered with this static check. Notice, however, that a syntactically valid mapping table does not imply the mapping will produce a valid result at runtime. The compliance of the generated file depends on the source message content and on the business logic of the configured mapping rules.","title":"Validation"},{"location":"integrator/myformat/myformat-csv/","text":"Format > CSV CSV files can be used as source or target for a translation. Single or multiple line messages are supported. The selectors are flexible enough to read or write content with complex structures and record types. If the message is a CSV, the source selector will be just a number indicating the position of the element in the CSV row. This number is zero-based , meaning the first element in the row will be selected by a 0. CSV Selector The same CSV selector syntax is used for source and target. Meaning to express what content from a CSV input message is read, or to express where in the output CSV message the content is written. The basic selector format indicates the column of the field with a plain zero-based number. Since CSV messages can have elaborated structures, with different types of lines, identified by a record identifier (you could have the first column defining the structure of the following columns), then the selector supports also more complex variants. Those variants are defined by the csv-selector grammar. Structure The grammar enables defining basically three components, each serves a different purpose: Field (required): Provides a method to extract information from a line and can be expressed in two different ways: By Positions : This method requires just a number indicating the zero-based order of the column to select. By Name : This method uses a static map of field names. The field names must be defined as an initial setup, then in the selectors the field name can be used without the need to indicate column number every time. Variables (optional): The variables are optional and are used to reorder the input content read in a FOREACH. In CSV the FOREACH is used when the CSV contains multiple lines. The primary use case for variables in this context is for line numbers, but a variable can also be used to store content, and thus to reorder the input based on the content of an element (for example to group transactions per account or currency). Condition (optional): Provides a method to filter a subset of lines from the input, for example could be used to select the records based on a record type identified by the first column value in each line. Field Examples By Positions: By Name: // create the field definitions CsvFieldsDef defs = new CsvFieldsDef () . addField ( \"IBAN\" , \"1\" ) . addField ( \"ADDR1\" , \"2\" ) . addField ( \"ADDR2\" , \"3\" ) . addField ( \"ADDR3\" , \"4\" ) . addField ( \"BIC\" , \"5\" ); // create reader instance for source message String inputMsg = \"...\" ; CsvReader reader = CsvReader . builder ( inputMsg ). fieldsDef ( defs ). build (); Variables Examples Condition Examples Grammar The grammar structure for de CSV selector is as follows: The selector contains 2 subcomponents: Field : a column number (zero based) Selector-options : A list of variables ( opt-variables ) and/or conditions ( opt-condition-list ). Or Empty value (these subcomponents are optional) The opt-variables is an optional variable list that can contain any number of elements: variable : Valid values are \"{\" name \"}\" , \"{\" name \":\" field opt-field-condition \"}\" . The opt-condition-list is an optional condition (or opt-field-condition ) list that can contain any number of elements: condition : Valid values are \"\" , \"\" , \"<\" field \">\" , \"<\" field \"='\" value \"'>\" . Expressed in a formal way selector ::= field selector-options field ::= column number (zero based) selector-options ::= \"[\" opt-variables opt-condition-list \"]\" | EMPTY opt-variables ::= variables-list | EMPTY variables-list ::= variables-list variable | variable variable ::= \"{\" name \"}\" | \"{\" name \":\" field opt-field-condition \"}\" opt-condition-list ::= condition-list | EMPTY opt-field-condition ::= \"[\" condition-list \"]\" | EMPTY condition-list ::= condition-list condition | condition condition ::= \"\" | \"\" | \"<\" field \">\" | \"<\" field \"='\" value \"'>\" Grammar Behavior Examples Basic selectors 0 Selects the value in the first column. 3 Selects the value in the 4th column. Selectors with conditions 5[] Selects the value in the 5th column from the first row in the document. 0[<0='DTL'>] Selects the value in the 1st column from a line where the first column contains the record identifier \"DTL\". 3[<0='HDR'>] Selects the value in the 4th column from the first row starting with record identifier \"HDR\". 1[<0='DTL'>] Selects the value in the 2nd column from the lines 4 to 5 where the first column contains the record identifier \"DTL\". Selectors with variables 3[{N}] Selects the value in the 4th column, and stores the current line number in a variable \"N\". Variables are used in the context of a mapping rule with \"foreach\", when multiple message lines are being read or written. 2[{M:9}] Selects the value in the 3rd column, and stores the value in the 10th column in a variable \"M\". 6[{M:9}{N}] Selects the value in the 7th column, and stores the value in the 10th column in a variable \"M\" and the current line in a variable \"N\". Selectors with variables and conditions 1[{N}] Selects the value in the 2nd column from lines 1 to 4, and stores the line number in a variable \"N\". 3[{N}<0='DTL'>] Selects the value in the 4th column from all lines where the first column contains the record identifier \"DTL\", and stores the line number in a variable \"N\". 8[{M:9}<0='HDR'>] Selects the value in the 9th column from the first row having record identifier \"HRD\", and stores the value from the 10th column in a variable \"M\". 5[{M:9}{N}<0='DTL'>] Selects the value in the 6th column from all lines with record identifier \"DTL\", and stores the value from column 10 in a variable \"M\" and the line number in a variable \"N\". 3[{M:9[<0='HDR'>]}<0='DTL'>] Selects the value in the 4th column from all lines with record identifier \"DTL\", and stores the value in the 10th column from the first row in the header, in a variable \"M\". This complex variable definition can be handy to group content, in this case we are grouping by a value in the header. Notice the condition order is important. <0='DTL'> finds all DTL lines and then selects the first four lines <0='DTL'> finds the first four lines and from those, selects the ones with DTL Field name definition When the mapping is done programmatically, you can configure a dictionary of field names. You give a name to the field column in the CSV, and then you just use the naming in the mapping rules. This feature makes the mapping rules less error-prone. For example: CsvFieldsDef defs = new CsvLenFieldsDef () . addField ( \"RECORD\" , \"0\" ) . addField ( \"REFERENCE\" , \"4\" ) . addField ( \"SOURCE_ACCT\" , \"5\" ); MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MX ); // add the mx type to the message t . add ( new MappingRule ( \"pain.001.001.03\" , \"mxType\" , WriteMode . SETUP )); // file ref from HDR as message identifier t . add ( new MappingRule ( \"REFERENCE[]\" , \"/Document/CstmrCdtTrfInitn/GrpHdr/MsgId\" )); // source account t . add ( new MappingRule ( \"foreach(SOURCE_ACCT[{n}])\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/DbtrAcct/Id/Othr/Id\" )); In the example above, instead of \"5\" to select the 6th column in the CSV, we used a human-friendly term as \"SOURCE_ACCT\". The field definitions are provided to the translation process in the reader (the reader may allow more configuration options, such as the split separator). So you must call the translation passing your own instance of the reader and writer like this: // create reader instance for source message CsvReader reader = CsvReader . builder ( input ). separator ( '|' ). fieldsDef ( defs ). build (); // create writer and call translation MxWriter writer = new MxWriter ( MxType . pacs_008_001_02 ); // call the translation passing the reader, writer and the rules MyFormatEngine . translate ( reader , writer , t . getRules ()); Conversion FROM CSV When working with CSV as source message, you have two options. To generate a single target message with content from all source rows, or to generate on target message per source row. You can think of it as n to n, or n to 1. Generating one message per row (n to n) When the source message format contains multiple messages, you have to code the iteration in your process. For instance, if the source message is a CSV file where each row contains the data to produce a target MX message must create a CSV file reader first, then call the translation with a CsvReader per row like this: CsvFileReader fileReader = new CsvFileReader ( input ); while ( reader . hasNext ()) { // each element in the file reader is a message reader Csvreader reader = fileReader . next (); // a new writer instance must be provided on each iteration MxWriter writer = new MxWriter ( MxType . pain_001_001_03 ); // call the translation providing the reader, writer and rules MyFormatEngine . translate ( reader . next (), writer , rules ); // this is the created MX for the row MxPain00100103 mx = ( MxPain00100103 ) writer . mx (); } On each iteration, a new Mx is produced. A similar approach applies for an Excel source message. Generating one message per csv (n to 1) If your source message contains the data for a single target message distributed within different rows, you can use foreach selectors that will automatically iterate on your CSV rows and create repetitive elements in the target message. For example: t . add ( new MappingRule ( \"foreach(5)\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/CdtTrfTxInf/Cdtr/Nm\" )); The above rule will get the content on the 6th column in all rows of the source CSV and will generate one PmtInf element in the target MX per row. Notice the variable \"n\" in the target selector is implicit, it will be replaced by a number from 1 to the number of rows in the CSV. Special \"concat\" In case that you need to combine source values in order to create complex select rules, you can use the special expression \"concat\" . This expression concatenates the values of the fields indicated in the parameters. It also allows to add literal strings in order to add value separators. The expression should be double-quoted in order to be recognized as a string. For example the selector 0, \"|\", 1, \"|\", 2 will concatenate the values of the columns 0, 1 and 2 using a pipe symbol \"|\" as separator. Thus, if the source CSV contains the following line; foo,bar, baz, the result will be foo|bar|baz. When reading content from CSV, the concat can also be used within the value selector of a foreach expression, to produce more interesting and sometimes handy results. As explained in the Mapping Rule section, the foreach expression can be used to iterate over all rows in a CSV file. So for instance the selector foreach(0) will iterate over all rows in the CSV file, and the value read and propagated in each iteration will be the value of the first column in the CSV. Then a selector such as foreach(0, 1) will also iterate all column 0 in the CSV, but the value to propagate will be actually the content of column 1 in each line. Then when used together, the foreach and the concat, can produce the following results: For example: In this case, the engine will iterate over all CSV lines, and in each iteration it will propagate as value the content of the columns 0, 1 and 3 using # and : as separators. Given this input: The result will be: 11#AAA:12.34 55#XXX:55.55 99#ZZZ:67.89 This is useful when you need to write a value that depends on the content of multiple columns. That should be done by combining this expression with some transformations in order to obtain the desired result. Given the example above, if you need to write the value of the 2nd column only for rows where the 1st column value is larger than 55, you can use the following selector: The result will be: ZZZ Another example, if you need to format the value of the 3rd column to ##.#### format only for rows where the 2nd column value is \"XXX\", otherwise, remove decimals, you can use the following selector: The result will be: 12 55.5500 67 Conversion TO CSV The target CSV file could have a simple structure where all lines are the same. Or a more complex structure with record identifiers and different line types, each with a different number of columns. In the case where the structure is more complex, and you want to use target selectors with record identifiers (such as 3[<0='DTL'>] ) you might need to initialize your target message with default data . Setup: addRow The first part of your mapping table should consist of instructions to build the empty template of your target message. By doing this, you ensure the overall structure of the output file is valid, even though it will be empty until the actual mapping rules are processed. A special write mode called SETUP is used for this purpose, combined with a special \"command\" named addRow . In a setup mapping rule, the command replaces the target selector. For example, if your message structure contains a header record, followed by multiple detail records and with a footer record at the end; the following setup commands will initialize the file. MappingTable t = new MappingTable ( FileFormat . MX , FileFormat . CSV ); // create an empty header row identifier by HR t . add ( new MappingRule ( \"literal(HR,,,,)\" , \"addRow\" , WriteMode . SETUP )); // create multiple detail records identifier by TX t . add ( new MappingRule ( \"FOREACH(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf, \\\"TX,,,\\\")\" , \"addRow\" , WriteMode . SETUP )); // create a single footer record at the end, identified by FR t . add ( new MappingRule ( \"literal(FR,,)\" , \"addRow\" , WriteMode . SETUP )); Notice we used literal values to fill the rows with a record identifier in the first column, and just the split separator to generate empty columns for each row. Only one header and footer is generated, but the detailed record is generated as many times as actual transactions in the source file; meaning the initialization is not static but dynamic , it can use input data . After setup and regardless of the following mapping rules, the output will have a valid structure. The setup is also important for the filter selectors to work. Suppose you want to define a rule such as t . add ( new MappingRule ( \"foreach(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/CdtrAcct/Id/IBAN)\" , \"BEN_IBAN[]\" )); This rule will iterate the IBAN numbers in all transactions of the source message, and will write them in the \"BEN_IBAN\" field of all \"TX\" records in the target message. Without the setup, this filter would have written a single transaction row in the output. Setup: other commands Other optional SETUP commands are available when the target format is CSV. When the mapping is defined programmatically, these options are also available through plain Java API in the CsvWriter. However, in order to have the process configuration encapsulated along the mappings in the externalized (Excel or database) configuration, you can provide all these customizations in the mapping table. separator : The character to use as column's separator, it is comma by default. When used, this command should be placed before the addRow. smartQuotes : The string content \"true\" or \"false\" to enable or disable smart quoting. It is true by default, meaning column values will be quoted only if needed. When this is set to false, all column values will be quoted. smartEscapes : The string content \"true\" or \"false\" to enable or disable smart escaping. It is false by default, meaning column values will not be escaped. addFieldNames : The string content \"true\" or \"false\" to include or not the column names in an output CSV header line. columnNames : Comma separated list of column names.","title":"Format > CSV"},{"location":"integrator/myformat/myformat-csv/#format-csv","text":"CSV files can be used as source or target for a translation. Single or multiple line messages are supported. The selectors are flexible enough to read or write content with complex structures and record types. If the message is a CSV, the source selector will be just a number indicating the position of the element in the CSV row. This number is zero-based , meaning the first element in the row will be selected by a 0.","title":"Format > CSV"},{"location":"integrator/myformat/myformat-csv/#csv-selector","text":"The same CSV selector syntax is used for source and target. Meaning to express what content from a CSV input message is read, or to express where in the output CSV message the content is written. The basic selector format indicates the column of the field with a plain zero-based number. Since CSV messages can have elaborated structures, with different types of lines, identified by a record identifier (you could have the first column defining the structure of the following columns), then the selector supports also more complex variants. Those variants are defined by the csv-selector grammar.","title":"CSV Selector"},{"location":"integrator/myformat/myformat-csv/#structure","text":"The grammar enables defining basically three components, each serves a different purpose: Field (required): Provides a method to extract information from a line and can be expressed in two different ways: By Positions : This method requires just a number indicating the zero-based order of the column to select. By Name : This method uses a static map of field names. The field names must be defined as an initial setup, then in the selectors the field name can be used without the need to indicate column number every time. Variables (optional): The variables are optional and are used to reorder the input content read in a FOREACH. In CSV the FOREACH is used when the CSV contains multiple lines. The primary use case for variables in this context is for line numbers, but a variable can also be used to store content, and thus to reorder the input based on the content of an element (for example to group transactions per account or currency). Condition (optional): Provides a method to filter a subset of lines from the input, for example could be used to select the records based on a record type identified by the first column value in each line.","title":"Structure"},{"location":"integrator/myformat/myformat-csv/#field-examples","text":"By Positions: By Name: // create the field definitions CsvFieldsDef defs = new CsvFieldsDef () . addField ( \"IBAN\" , \"1\" ) . addField ( \"ADDR1\" , \"2\" ) . addField ( \"ADDR2\" , \"3\" ) . addField ( \"ADDR3\" , \"4\" ) . addField ( \"BIC\" , \"5\" ); // create reader instance for source message String inputMsg = \"...\" ; CsvReader reader = CsvReader . builder ( inputMsg ). fieldsDef ( defs ). build ();","title":"Field Examples"},{"location":"integrator/myformat/myformat-csv/#variables-examples","text":"","title":"Variables Examples"},{"location":"integrator/myformat/myformat-csv/#condition-examples","text":"","title":"Condition Examples"},{"location":"integrator/myformat/myformat-csv/#grammar","text":"The grammar structure for de CSV selector is as follows: The selector contains 2 subcomponents: Field : a column number (zero based) Selector-options : A list of variables ( opt-variables ) and/or conditions ( opt-condition-list ). Or Empty value (these subcomponents are optional) The opt-variables is an optional variable list that can contain any number of elements: variable : Valid values are \"{\" name \"}\" , \"{\" name \":\" field opt-field-condition \"}\" . The opt-condition-list is an optional condition (or opt-field-condition ) list that can contain any number of elements: condition : Valid values are \"\" , \"\" , \"<\" field \">\" , \"<\" field \"='\" value \"'>\" .","title":"Grammar"},{"location":"integrator/myformat/myformat-csv/#expressed-in-a-formal-way","text":"selector ::= field selector-options field ::= column number (zero based) selector-options ::= \"[\" opt-variables opt-condition-list \"]\" | EMPTY opt-variables ::= variables-list | EMPTY variables-list ::= variables-list variable | variable variable ::= \"{\" name \"}\" | \"{\" name \":\" field opt-field-condition \"}\" opt-condition-list ::= condition-list | EMPTY opt-field-condition ::= \"[\" condition-list \"]\" | EMPTY condition-list ::= condition-list condition | condition condition ::= \"\" | \"\" | \"<\" field \">\" | \"<\" field \"='\" value \"'>\"","title":"Expressed in a formal way"},{"location":"integrator/myformat/myformat-csv/#grammar-behavior-examples","text":"Basic selectors 0 Selects the value in the first column. 3 Selects the value in the 4th column. Selectors with conditions 5[] Selects the value in the 5th column from the first row in the document. 0[<0='DTL'>] Selects the value in the 1st column from a line where the first column contains the record identifier \"DTL\". 3[<0='HDR'>] Selects the value in the 4th column from the first row starting with record identifier \"HDR\". 1[<0='DTL'>] Selects the value in the 2nd column from the lines 4 to 5 where the first column contains the record identifier \"DTL\". Selectors with variables 3[{N}] Selects the value in the 4th column, and stores the current line number in a variable \"N\". Variables are used in the context of a mapping rule with \"foreach\", when multiple message lines are being read or written. 2[{M:9}] Selects the value in the 3rd column, and stores the value in the 10th column in a variable \"M\". 6[{M:9}{N}] Selects the value in the 7th column, and stores the value in the 10th column in a variable \"M\" and the current line in a variable \"N\". Selectors with variables and conditions 1[{N}] Selects the value in the 2nd column from lines 1 to 4, and stores the line number in a variable \"N\". 3[{N}<0='DTL'>] Selects the value in the 4th column from all lines where the first column contains the record identifier \"DTL\", and stores the line number in a variable \"N\". 8[{M:9}<0='HDR'>] Selects the value in the 9th column from the first row having record identifier \"HRD\", and stores the value from the 10th column in a variable \"M\". 5[{M:9}{N}<0='DTL'>] Selects the value in the 6th column from all lines with record identifier \"DTL\", and stores the value from column 10 in a variable \"M\" and the line number in a variable \"N\". 3[{M:9[<0='HDR'>]}<0='DTL'>] Selects the value in the 4th column from all lines with record identifier \"DTL\", and stores the value in the 10th column from the first row in the header, in a variable \"M\". This complex variable definition can be handy to group content, in this case we are grouping by a value in the header. Notice the condition order is important. <0='DTL'> finds all DTL lines and then selects the first four lines <0='DTL'> finds the first four lines and from those, selects the ones with DTL","title":"Grammar Behavior Examples"},{"location":"integrator/myformat/myformat-csv/#field-name-definition","text":"When the mapping is done programmatically, you can configure a dictionary of field names. You give a name to the field column in the CSV, and then you just use the naming in the mapping rules. This feature makes the mapping rules less error-prone. For example: CsvFieldsDef defs = new CsvLenFieldsDef () . addField ( \"RECORD\" , \"0\" ) . addField ( \"REFERENCE\" , \"4\" ) . addField ( \"SOURCE_ACCT\" , \"5\" ); MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MX ); // add the mx type to the message t . add ( new MappingRule ( \"pain.001.001.03\" , \"mxType\" , WriteMode . SETUP )); // file ref from HDR as message identifier t . add ( new MappingRule ( \"REFERENCE[]\" , \"/Document/CstmrCdtTrfInitn/GrpHdr/MsgId\" )); // source account t . add ( new MappingRule ( \"foreach(SOURCE_ACCT[{n}])\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/DbtrAcct/Id/Othr/Id\" )); In the example above, instead of \"5\" to select the 6th column in the CSV, we used a human-friendly term as \"SOURCE_ACCT\". The field definitions are provided to the translation process in the reader (the reader may allow more configuration options, such as the split separator). So you must call the translation passing your own instance of the reader and writer like this: // create reader instance for source message CsvReader reader = CsvReader . builder ( input ). separator ( '|' ). fieldsDef ( defs ). build (); // create writer and call translation MxWriter writer = new MxWriter ( MxType . pacs_008_001_02 ); // call the translation passing the reader, writer and the rules MyFormatEngine . translate ( reader , writer , t . getRules ());","title":"Field name definition"},{"location":"integrator/myformat/myformat-csv/#conversion-from-csv","text":"When working with CSV as source message, you have two options. To generate a single target message with content from all source rows, or to generate on target message per source row. You can think of it as n to n, or n to 1.","title":"Conversion FROM CSV"},{"location":"integrator/myformat/myformat-csv/#generating-one-message-per-row-n-to-n","text":"When the source message format contains multiple messages, you have to code the iteration in your process. For instance, if the source message is a CSV file where each row contains the data to produce a target MX message must create a CSV file reader first, then call the translation with a CsvReader per row like this: CsvFileReader fileReader = new CsvFileReader ( input ); while ( reader . hasNext ()) { // each element in the file reader is a message reader Csvreader reader = fileReader . next (); // a new writer instance must be provided on each iteration MxWriter writer = new MxWriter ( MxType . pain_001_001_03 ); // call the translation providing the reader, writer and rules MyFormatEngine . translate ( reader . next (), writer , rules ); // this is the created MX for the row MxPain00100103 mx = ( MxPain00100103 ) writer . mx (); } On each iteration, a new Mx is produced. A similar approach applies for an Excel source message.","title":"Generating one message per row (n to n)"},{"location":"integrator/myformat/myformat-csv/#generating-one-message-per-csv-n-to-1","text":"If your source message contains the data for a single target message distributed within different rows, you can use foreach selectors that will automatically iterate on your CSV rows and create repetitive elements in the target message. For example: t . add ( new MappingRule ( \"foreach(5)\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/CdtTrfTxInf/Cdtr/Nm\" )); The above rule will get the content on the 6th column in all rows of the source CSV and will generate one PmtInf element in the target MX per row. Notice the variable \"n\" in the target selector is implicit, it will be replaced by a number from 1 to the number of rows in the CSV.","title":"Generating one message per csv (n to 1)"},{"location":"integrator/myformat/myformat-csv/#special-concat","text":"In case that you need to combine source values in order to create complex select rules, you can use the special expression \"concat\" . This expression concatenates the values of the fields indicated in the parameters. It also allows to add literal strings in order to add value separators. The expression should be double-quoted in order to be recognized as a string. For example the selector 0, \"|\", 1, \"|\", 2 will concatenate the values of the columns 0, 1 and 2 using a pipe symbol \"|\" as separator. Thus, if the source CSV contains the following line; foo,bar, baz, the result will be foo|bar|baz. When reading content from CSV, the concat can also be used within the value selector of a foreach expression, to produce more interesting and sometimes handy results. As explained in the Mapping Rule section, the foreach expression can be used to iterate over all rows in a CSV file. So for instance the selector foreach(0) will iterate over all rows in the CSV file, and the value read and propagated in each iteration will be the value of the first column in the CSV. Then a selector such as foreach(0, 1) will also iterate all column 0 in the CSV, but the value to propagate will be actually the content of column 1 in each line. Then when used together, the foreach and the concat, can produce the following results: For example: In this case, the engine will iterate over all CSV lines, and in each iteration it will propagate as value the content of the columns 0, 1 and 3 using # and : as separators. Given this input: The result will be: 11#AAA:12.34 55#XXX:55.55 99#ZZZ:67.89 This is useful when you need to write a value that depends on the content of multiple columns. That should be done by combining this expression with some transformations in order to obtain the desired result. Given the example above, if you need to write the value of the 2nd column only for rows where the 1st column value is larger than 55, you can use the following selector: The result will be: ZZZ Another example, if you need to format the value of the 3rd column to ##.#### format only for rows where the 2nd column value is \"XXX\", otherwise, remove decimals, you can use the following selector: The result will be: 12 55.5500 67","title":"Special \"concat\""},{"location":"integrator/myformat/myformat-csv/#conversion-to-csv","text":"The target CSV file could have a simple structure where all lines are the same. Or a more complex structure with record identifiers and different line types, each with a different number of columns. In the case where the structure is more complex, and you want to use target selectors with record identifiers (such as 3[<0='DTL'>] ) you might need to initialize your target message with default data .","title":"Conversion TO CSV"},{"location":"integrator/myformat/myformat-csv/#setup-addrow","text":"The first part of your mapping table should consist of instructions to build the empty template of your target message. By doing this, you ensure the overall structure of the output file is valid, even though it will be empty until the actual mapping rules are processed. A special write mode called SETUP is used for this purpose, combined with a special \"command\" named addRow . In a setup mapping rule, the command replaces the target selector. For example, if your message structure contains a header record, followed by multiple detail records and with a footer record at the end; the following setup commands will initialize the file. MappingTable t = new MappingTable ( FileFormat . MX , FileFormat . CSV ); // create an empty header row identifier by HR t . add ( new MappingRule ( \"literal(HR,,,,)\" , \"addRow\" , WriteMode . SETUP )); // create multiple detail records identifier by TX t . add ( new MappingRule ( \"FOREACH(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf, \\\"TX,,,\\\")\" , \"addRow\" , WriteMode . SETUP )); // create a single footer record at the end, identified by FR t . add ( new MappingRule ( \"literal(FR,,)\" , \"addRow\" , WriteMode . SETUP )); Notice we used literal values to fill the rows with a record identifier in the first column, and just the split separator to generate empty columns for each row. Only one header and footer is generated, but the detailed record is generated as many times as actual transactions in the source file; meaning the initialization is not static but dynamic , it can use input data . After setup and regardless of the following mapping rules, the output will have a valid structure. The setup is also important for the filter selectors to work. Suppose you want to define a rule such as t . add ( new MappingRule ( \"foreach(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/CdtrAcct/Id/IBAN)\" , \"BEN_IBAN[]\" )); This rule will iterate the IBAN numbers in all transactions of the source message, and will write them in the \"BEN_IBAN\" field of all \"TX\" records in the target message. Without the setup, this filter would have written a single transaction row in the output.","title":"Setup: addRow"},{"location":"integrator/myformat/myformat-csv/#setup-other-commands","text":"Other optional SETUP commands are available when the target format is CSV. When the mapping is defined programmatically, these options are also available through plain Java API in the CsvWriter. However, in order to have the process configuration encapsulated along the mappings in the externalized (Excel or database) configuration, you can provide all these customizations in the mapping table. separator : The character to use as column's separator, it is comma by default. When used, this command should be placed before the addRow. smartQuotes : The string content \"true\" or \"false\" to enable or disable smart quoting. It is true by default, meaning column values will be quoted only if needed. When this is set to false, all column values will be quoted. smartEscapes : The string content \"true\" or \"false\" to enable or disable smart escaping. It is false by default, meaning column values will not be escaped. addFieldNames : The string content \"true\" or \"false\" to include or not the column names in an output CSV header line. columnNames : Comma separated list of column names.","title":"Setup: other commands"},{"location":"integrator/myformat/myformat-engine/","text":"Conversion Engine The conversion of messages is handled by the MyFormatEngine class. This class is stateless, meaning there is no need for initialization and disposal. The main entrypoint are the static translate methods. Different options for translation are available to ease conversion in common use cases. Generic translation The generic translation allows converting any source message to any target message with minimum restrictions. In this case, the translation method to use receives the source message as a String parameter along with the mapping table instance, and produces as a result the converted message also in String format. Once the mapping table and the source message is loaded, the translation call is straightforward: MappingTable mappings = ...; String source msg = ...; String target = MyFormatEngine . translate ( source , mappings ); Source message validation is out of scope in the translation. The provided content should be in the expected format as defined in the mapping table. If the selectors in the mapping rule cannot gather content due to a malformed source message, the translated result will be a null string. MT to MX translation To translate an MT message into an MX message, a specific translate method is provided. The difference between this translation and the generic translation is that model objects are used for source and target messages, instead of plain Strings. Therefore, the translate call receives the source MT as an AbstractMT and produces the result into an AbstractMX . Notice that the API defines the method with references to the generic abstract types, however specific MT and MX objects are actually used. Along with the source MT message object, the translate call receives the mapping rules as parameters. A complete mapping table is not necessary because the source and target file formats are implicit and constrained to MT and MX respectively. Finally, for the target message, the MxId object is used to properly identify the specific MX to create. For example: MT103 mt = MT103 . parse ( \"{1:F01\u2026\" ); List < MappingRule > rules = new ArrayList < MappingRule > (); rules . add ( new MappingRule ( \"sender\" , \"/AppHdr/Fr/FIId/FinInstnId/BICFI\" )); rules . add ( new MappingRule ( \"receiver\" , \"/AppHdr/To/FIId/FinInstnId/BICFI\" )); rules . add ( new MappingRule ( \"b3/121\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/PmtId/UETR\" )); rules . add ( new MappingRule ( \"32A/3\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt\" , new Transformation ( Transformation . Key . formatDecimal ))); rules . add ( new MappingRule ( \"32A/2\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt/@Ccy\" , WriteMode . APPEND )); rules . add ( new MappingRule ( \"32A/1\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmDt\" , new Transformation ( Transformation . Key . formatDateTime , \"yyMMdd\" , \"yyyy-MM-dd\" ))); MxId id = new MxId ( \"pacs.008.001.08\" ) MxPacs00800108 mx = ( MxPacs00800108 ) MyFormatEngine . translate ( mt , id , rules ); System . out . println ( mx . message ()); System . out . println ( mx . mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getIntrBkSttlmAmt (). getValue ()); Notice, a cast is required to use the getters of the specific created MX. In the rules, the target path should be either for the header (starting with /AppHdr ) or for the document body (starting with /Document ); and must be a valid path for the specific MX message being created. Rules with an unrecognized target path are ignored. MX to MT translation To translate an MX message into an MT message, a specific translate method is provided. The difference between this translation and the generic translation is that model objects are used for source and target messages, instead of plain Strings. Therefore, the translate call receives the source MX as an AbstractMX and produces the result into an AbstractMT . Notice that the API defines the method with references to the generic abstract types, however specific MT and MX objects are actually used. Along with the source MX message object, the translate call receives the mapping rules as parameter. A complete mapping table is not necessary because the source and target file formats are implicit and constrained to MX and MT respectively. Finally, for the target message, the message type must be provided to identify the specific MT message to create. For example: MxCamt00300105 mx = new MxCamt00300105 (); BusinessApplicationHeaderV01 header = new BusinessApplicationHeaderV01 (); header . setFr ( new Party9Choice ()); ... mx . setBusinessHeader ( new BusinessHeader ( header )); mx . setGetAcct ( new GetAccountV05 ()); mx . getGetAcct (). setAcctQryDef ( new AccountQuery1 ()); mx . getGetAcct (). getAcctQryDef (). setQryTp ( QueryType2Code . CHNG ); System . out . println ( mx . message ( \"message\" )); List < MappingRule > rules = new ArrayList < MappingRule > (); rules . add ( new MappingRule ( \"/AppHdr/Fr/FIId/BrnchId/Id\" , \"20\" )); rules . add ( new MappingRule ( \"/Document/GetAcct/AcctQryDef/QryTp\" , \"21\" )); MT202 mt = ( MT202 ) MyFormatEngine . translate ( mx , MtType . MT202 , rules ); System . out . println ( mt . message ()); System . out . println ( mt . getField20 (). getValue ()); System . out . println ( mt . getField21 (). getValue ()); Notice a cast is required to use the getters of the specific created MT. In the rules, the source path should be either for the header (starting with /AppHdr ) or for the document body (starting with /Document ); and must be a valid path for the specific MX message being read. Rules with an unrecognized source path are ignored. Rules order is particularly important when creating MT messages because in an MT message the text block (block 4) is not structured. Fields are appended to the message in the same order as they appear in the list of rules. Furthermore, a rule with write mode set to append or update will only take effect if the target field is exactly the same target field from the preceding rule.","title":"Conversion Engine"},{"location":"integrator/myformat/myformat-engine/#conversion-engine","text":"The conversion of messages is handled by the MyFormatEngine class. This class is stateless, meaning there is no need for initialization and disposal. The main entrypoint are the static translate methods. Different options for translation are available to ease conversion in common use cases.","title":"Conversion Engine"},{"location":"integrator/myformat/myformat-engine/#generic-translation","text":"The generic translation allows converting any source message to any target message with minimum restrictions. In this case, the translation method to use receives the source message as a String parameter along with the mapping table instance, and produces as a result the converted message also in String format. Once the mapping table and the source message is loaded, the translation call is straightforward: MappingTable mappings = ...; String source msg = ...; String target = MyFormatEngine . translate ( source , mappings ); Source message validation is out of scope in the translation. The provided content should be in the expected format as defined in the mapping table. If the selectors in the mapping rule cannot gather content due to a malformed source message, the translated result will be a null string.","title":"Generic translation"},{"location":"integrator/myformat/myformat-engine/#mt-to-mx-translation","text":"To translate an MT message into an MX message, a specific translate method is provided. The difference between this translation and the generic translation is that model objects are used for source and target messages, instead of plain Strings. Therefore, the translate call receives the source MT as an AbstractMT and produces the result into an AbstractMX . Notice that the API defines the method with references to the generic abstract types, however specific MT and MX objects are actually used. Along with the source MT message object, the translate call receives the mapping rules as parameters. A complete mapping table is not necessary because the source and target file formats are implicit and constrained to MT and MX respectively. Finally, for the target message, the MxId object is used to properly identify the specific MX to create. For example: MT103 mt = MT103 . parse ( \"{1:F01\u2026\" ); List < MappingRule > rules = new ArrayList < MappingRule > (); rules . add ( new MappingRule ( \"sender\" , \"/AppHdr/Fr/FIId/FinInstnId/BICFI\" )); rules . add ( new MappingRule ( \"receiver\" , \"/AppHdr/To/FIId/FinInstnId/BICFI\" )); rules . add ( new MappingRule ( \"b3/121\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/PmtId/UETR\" )); rules . add ( new MappingRule ( \"32A/3\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt\" , new Transformation ( Transformation . Key . formatDecimal ))); rules . add ( new MappingRule ( \"32A/2\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt/@Ccy\" , WriteMode . APPEND )); rules . add ( new MappingRule ( \"32A/1\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmDt\" , new Transformation ( Transformation . Key . formatDateTime , \"yyMMdd\" , \"yyyy-MM-dd\" ))); MxId id = new MxId ( \"pacs.008.001.08\" ) MxPacs00800108 mx = ( MxPacs00800108 ) MyFormatEngine . translate ( mt , id , rules ); System . out . println ( mx . message ()); System . out . println ( mx . mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getIntrBkSttlmAmt (). getValue ()); Notice, a cast is required to use the getters of the specific created MX. In the rules, the target path should be either for the header (starting with /AppHdr ) or for the document body (starting with /Document ); and must be a valid path for the specific MX message being created. Rules with an unrecognized target path are ignored.","title":"MT to MX translation"},{"location":"integrator/myformat/myformat-engine/#mx-to-mt-translation","text":"To translate an MX message into an MT message, a specific translate method is provided. The difference between this translation and the generic translation is that model objects are used for source and target messages, instead of plain Strings. Therefore, the translate call receives the source MX as an AbstractMX and produces the result into an AbstractMT . Notice that the API defines the method with references to the generic abstract types, however specific MT and MX objects are actually used. Along with the source MX message object, the translate call receives the mapping rules as parameter. A complete mapping table is not necessary because the source and target file formats are implicit and constrained to MX and MT respectively. Finally, for the target message, the message type must be provided to identify the specific MT message to create. For example: MxCamt00300105 mx = new MxCamt00300105 (); BusinessApplicationHeaderV01 header = new BusinessApplicationHeaderV01 (); header . setFr ( new Party9Choice ()); ... mx . setBusinessHeader ( new BusinessHeader ( header )); mx . setGetAcct ( new GetAccountV05 ()); mx . getGetAcct (). setAcctQryDef ( new AccountQuery1 ()); mx . getGetAcct (). getAcctQryDef (). setQryTp ( QueryType2Code . CHNG ); System . out . println ( mx . message ( \"message\" )); List < MappingRule > rules = new ArrayList < MappingRule > (); rules . add ( new MappingRule ( \"/AppHdr/Fr/FIId/BrnchId/Id\" , \"20\" )); rules . add ( new MappingRule ( \"/Document/GetAcct/AcctQryDef/QryTp\" , \"21\" )); MT202 mt = ( MT202 ) MyFormatEngine . translate ( mx , MtType . MT202 , rules ); System . out . println ( mt . message ()); System . out . println ( mt . getField20 (). getValue ()); System . out . println ( mt . getField21 (). getValue ()); Notice a cast is required to use the getters of the specific created MT. In the rules, the source path should be either for the header (starting with /AppHdr ) or for the document body (starting with /Document ); and must be a valid path for the specific MX message being read. Rules with an unrecognized source path are ignored. Rules order is particularly important when creating MT messages because in an MT message the text block (block 4) is not structured. Fields are appended to the message in the same order as they appear in the list of rules. Furthermore, a rule with write mode set to append or update will only take effect if the target field is exactly the same target field from the preceding rule.","title":"MX to MT translation"},{"location":"integrator/myformat/myformat-fin/","text":"Format > FIN (MT) This message format is the SWIFT MT (ISO 15022), used in the SWIFT FIN service. It can be used either as source or target for a translation. MT Selector For FIN messages, the selector in the mapping rules uses the MtPath , a proprietary and convenient way to localize any field or component in a FIN message. The same MTPath expressions can be used to select content from a source message when converting from FIN to something else, and also to indicate what field to write when converting from something else to FIN. For a detailed description of the MtPath please refer to the SDK developer guide. We just provide here a few examples to illustrate the selector capabilities: 21 selects the value of field 21 at block4 in the source message. A/20C/SEME selects value of generic field 20C, with qualifier SEME at sequence A B1/98A/2 selects component 2, of field 98A in sequence B1 92B/FirstCurrencyCode selects \"FirstCurrencyCode\" component, of field 92B 59/Line[2] selects the second line of component 59, with the name & address information. 70E/2/Line[1] selects the first line of the narrative in field 70E 70E/2/Line[*] selects all text of the narrative in field 70E. 93a selects value of the first field 93, for any letter option found b1/LogicalTerminal selects the logical terminal field of header block 1 b3/108 selects the value of field 108 at block header 3. E/E1/95Q selects the field 95Q in subsequence E1 within sequence E All features from MtPath expressions can be used for content selection. When the source message in the translation is an MT, the selector indicates which field or component within a field must be read. For example, a rule having A/20C/SEME in the source selector will get the value of the reference field, and pass that as content for the translation. Analogously, when the target message in the translation is an MT, the selector indicates what field or component must be written in the target message. For example, a target selector having E/E1/95Q will take the translation content and create in the target MT a field 95Q, within a sequence E1, nested in a sequence E. All sequence boundaries will be created automatically. Predicates The MtPath supports predicates to indicate repetition indexes. The predicates can be in the sequences or field segments of the path and are surrounded by brackets. For example: A/22F[1] selects the first repetition of field 22F in sequence A 22F[3] selects the third repetition of field 22F in sequence A E/E[2]/95Q selects the field 95Q in the second subsequence E1 within first sequence E A1[2]/13A[3] selects the third field 13A in the second instance of sequence A1 In the above examples, all predicates have numbers, meaning they reference a specific instance of the repetitive sequence of fields. When the selector is used in rule processing of multiple elements, the number can be replaced by a variable name. For example, the source selector foreach(A/22F[{n}]) will read all instances of field 22F in sequence A, and will propagate a variable named n with the repetition index. Repetition in a foreach is 1 based, meaning the first read 22F will have n=1 . These repetition variables can then be used in the target selector, to map each repetitive 22F to a specific repetitive element in the target message. When a path such as A/22F[{n}] is used in the target selector, to indicate what content to create, then the variable n will be replaced by the repetition index in the source selector. This can be used for instance to map a repetitive element in a source XML into a repetitive sequence or field in a target MX. Prefilled target message When translating into MT, the mandatory headers data will be initialized with default content. However, some header fields such as the message type , sender , and receiver are important. These fields can be set using mapping rules (The MtPath expression can target any field in any header block) but you can also apply the conversion to an existing MT object. This can be accomplished easily by passing your own instance of MT to the MtWriter . To use a prefilled writer, you need to call the Engine with your own instances of reader and writer for the specific file format involved in the translation. For example: // we create a message object with the sender and receiver MT101 init = new MT101 ( \"GULBKWKWXXX\" , \"ICBKARBAXXX\" ); // we initialize the writer with this message MtWriter writer = new MtWriter ( init ); // we define or load the mappings MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MT ); t . add ( new MappingRule ( \"0\" , \"21\" )); t . add ( new MappingRule ( \"1\" , \"32B/1\" )); t . add ( new MappingRule ( \"2\" , \"32B/2\" , WriteMode . APPEND )); t . add ( new MappingRule ( \"3\" , \"59/2\" )); // we create a reader as well CsvFileReader reader = new CsvFileReader ( input ); // we call the translation with the specific reader and writer instances MyFormatEngine . translate ( reader , writer , t . getRules ()); // we cast the created MT MT101 mt = ( MT101 ) writer . mt (); Note that the sample above can be also written like the one below, and will produce the pretty same result: // we create a message object with the sender and receiver MT101 init = new MT101 ( \"GULBKWKWXXX\" , \"ICBKARBAXXX\" ); // we initialize the writer with this message MtWriter writer = new MtWriter ( init ); // we define or load the mappings MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MT ); t . add ( new MappingRule ( \"0\" , \"21\" )); t . add ( new MappingRule ( \"1\" , \"32B/Currency\" )); t . add ( new MappingRule ( \"2\" , \"32B/Amount\" , WriteMode . APPEND )); t . add ( new MappingRule ( \"3\" , \"59/NameAndAddress\" )); // we create a reader as well CsvFileReader reader = new CsvFileReader ( input ); // we call the translation with the specific reader and writer instances MyFormatEngine . translate ( reader , writer , t . getRules ()); // we cast the created MT MT101 mt = ( MT101 ) writer . mt (); Note that all the component name's format is Camel Case. Please refer to SDK MtPath for further details about Mt path format. This procedure can be used to prefill any field in the target message. Since the rules are processed in order, if you prefill part of the target MT programmatically, beware that fields created from the mapping will always be appended after any field you had set. Using the MtWriter as a message builder The MtWriter can be used as a message builder. This means that you can create a new MT message from scratch, and then use the writer to add fields and components to it. This is useful when you need to create a message that is not a translation of another message, but a new message that you want to build programmatically. To use the MtWriter as a message builder, you need to create an instance of the writer with no arguments, and then use the write method to add fields and components to it. For example: // we create a writer for and MT509 message MtWriter writer = new MtWriter ( MtType . MT509 ); // we add the data for the mandatory headers (will be initialized with default values anyway) writer . write ( \"b1/LogicalTerminal\" , \"AAAAUS30AXXX\" ); writer . write ( \"b2/ReceiverAddress\" , \"BBBBTRRSXXXX\" ); writer . write ( \"b2/DeliveryMonitoring\" , \"2\" ); writer . write ( \"b2/ObsolescencePeriod\" , \"020\" ); // we add the message content leveraging the MtPath expressions writer . write ( \"A/20C/1\" , \"SEME\" ); writer . write ( \"A/20C/2\" , \"MAINREF1234\" , WriteMode . APPEND ); writer . write ( \"A/23G\" , \"INST\" ); writer . write ( \"A/98C/1\" , \"PREP\" ); writer . write ( \"A/98C/2\" , \"20240625101806\" , WriteMode . APPEND ); writer . write ( \"A/A1/13A/1\" , \"LINK\" ); writer . write ( \"A/A1/13A/2\" , \"509\" , WriteMode . APPEND ); writer . write ( \"A/A1/20C/1\" , \"RELA\" ); writer . write ( \"A/A1/20C/2\" , \"RELAREF1234\" , WriteMode . APPEND ); writer . write ( \"A/A1[2]/20C/1\" , \"PREV\" ); writer . write ( \"A/A1[2]/20C/2\" , \"1234\" , WriteMode . APPEND ); writer . write ( \"A/A2/25D/1\" , \"CPRC\" ); writer . write ( \"A/A2/25D/3\" , \"CAND\" , WriteMode . APPEND ); writer . write ( \"A/A2/A2a/24B/1\" , \"REJT\" ); writer . write ( \"A/A2/A2a/24B/3\" , \"ADEA\" , WriteMode . APPEND ); writer . write ( \"B/22H/1\" , \"BUSE\" ); writer . write ( \"B/22H/2\" , \"BUYI\" , WriteMode . APPEND ); writer . write ( \"B/22H/1\" , \"PAYM\" ); writer . write ( \"B/22H/2\" , \"APMT\" , WriteMode . APPEND ); writer . write ( \"B/36B/1\" , \"ORDR\" ); writer . write ( \"B/36B/3\" , \"123,45\" , WriteMode . APPEND ); writer . write ( \"B/35B\" , \"/US/FOO487AE9\" ); // we get the created MT MT509 mt = ( MT509 ) writer . mt (); The sample code above creates a new MT509 message with the following content: {1:F01AAAAUS30AXXX0000000000}{2:I509BBBBTRRSXXXXN2020}{4: :16R:GENL :20C::SEME//MAINREF1234 :23G:INST :98C::PREP//20240625101806 :16R:LINK :13A::LINK//509 :20C::RELA//RELAREF1234 :16S:LINK :16R:LINK :20C::PREV//1234 :16S:LINK :16R:STAT :25D::CPRC//CAND :16R:REAS :24B::REJT//ADEA :16S:REAS :16S:STAT :16S:GENL :16R:TRADE :22H::BUSE//BUYI :22H::PAYM//APMT :36B::ORDR///123,45 :35B:/US/FOO487AE9 :16S:TRADE -}; Notice how the boundary fields (16R and 16S) are automatically added by the writer based on the path expressions used.","title":"Format > FIN (MT)"},{"location":"integrator/myformat/myformat-fin/#format-fin-mt","text":"This message format is the SWIFT MT (ISO 15022), used in the SWIFT FIN service. It can be used either as source or target for a translation.","title":"Format > FIN (MT)"},{"location":"integrator/myformat/myformat-fin/#mt-selector","text":"For FIN messages, the selector in the mapping rules uses the MtPath , a proprietary and convenient way to localize any field or component in a FIN message. The same MTPath expressions can be used to select content from a source message when converting from FIN to something else, and also to indicate what field to write when converting from something else to FIN. For a detailed description of the MtPath please refer to the SDK developer guide. We just provide here a few examples to illustrate the selector capabilities: 21 selects the value of field 21 at block4 in the source message. A/20C/SEME selects value of generic field 20C, with qualifier SEME at sequence A B1/98A/2 selects component 2, of field 98A in sequence B1 92B/FirstCurrencyCode selects \"FirstCurrencyCode\" component, of field 92B 59/Line[2] selects the second line of component 59, with the name & address information. 70E/2/Line[1] selects the first line of the narrative in field 70E 70E/2/Line[*] selects all text of the narrative in field 70E. 93a selects value of the first field 93, for any letter option found b1/LogicalTerminal selects the logical terminal field of header block 1 b3/108 selects the value of field 108 at block header 3. E/E1/95Q selects the field 95Q in subsequence E1 within sequence E All features from MtPath expressions can be used for content selection. When the source message in the translation is an MT, the selector indicates which field or component within a field must be read. For example, a rule having A/20C/SEME in the source selector will get the value of the reference field, and pass that as content for the translation. Analogously, when the target message in the translation is an MT, the selector indicates what field or component must be written in the target message. For example, a target selector having E/E1/95Q will take the translation content and create in the target MT a field 95Q, within a sequence E1, nested in a sequence E. All sequence boundaries will be created automatically.","title":"MT Selector"},{"location":"integrator/myformat/myformat-fin/#predicates","text":"The MtPath supports predicates to indicate repetition indexes. The predicates can be in the sequences or field segments of the path and are surrounded by brackets. For example: A/22F[1] selects the first repetition of field 22F in sequence A 22F[3] selects the third repetition of field 22F in sequence A E/E[2]/95Q selects the field 95Q in the second subsequence E1 within first sequence E A1[2]/13A[3] selects the third field 13A in the second instance of sequence A1 In the above examples, all predicates have numbers, meaning they reference a specific instance of the repetitive sequence of fields. When the selector is used in rule processing of multiple elements, the number can be replaced by a variable name. For example, the source selector foreach(A/22F[{n}]) will read all instances of field 22F in sequence A, and will propagate a variable named n with the repetition index. Repetition in a foreach is 1 based, meaning the first read 22F will have n=1 . These repetition variables can then be used in the target selector, to map each repetitive 22F to a specific repetitive element in the target message. When a path such as A/22F[{n}] is used in the target selector, to indicate what content to create, then the variable n will be replaced by the repetition index in the source selector. This can be used for instance to map a repetitive element in a source XML into a repetitive sequence or field in a target MX.","title":"Predicates"},{"location":"integrator/myformat/myformat-fin/#prefilled-target-message","text":"When translating into MT, the mandatory headers data will be initialized with default content. However, some header fields such as the message type , sender , and receiver are important. These fields can be set using mapping rules (The MtPath expression can target any field in any header block) but you can also apply the conversion to an existing MT object. This can be accomplished easily by passing your own instance of MT to the MtWriter . To use a prefilled writer, you need to call the Engine with your own instances of reader and writer for the specific file format involved in the translation. For example: // we create a message object with the sender and receiver MT101 init = new MT101 ( \"GULBKWKWXXX\" , \"ICBKARBAXXX\" ); // we initialize the writer with this message MtWriter writer = new MtWriter ( init ); // we define or load the mappings MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MT ); t . add ( new MappingRule ( \"0\" , \"21\" )); t . add ( new MappingRule ( \"1\" , \"32B/1\" )); t . add ( new MappingRule ( \"2\" , \"32B/2\" , WriteMode . APPEND )); t . add ( new MappingRule ( \"3\" , \"59/2\" )); // we create a reader as well CsvFileReader reader = new CsvFileReader ( input ); // we call the translation with the specific reader and writer instances MyFormatEngine . translate ( reader , writer , t . getRules ()); // we cast the created MT MT101 mt = ( MT101 ) writer . mt (); Note that the sample above can be also written like the one below, and will produce the pretty same result: // we create a message object with the sender and receiver MT101 init = new MT101 ( \"GULBKWKWXXX\" , \"ICBKARBAXXX\" ); // we initialize the writer with this message MtWriter writer = new MtWriter ( init ); // we define or load the mappings MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MT ); t . add ( new MappingRule ( \"0\" , \"21\" )); t . add ( new MappingRule ( \"1\" , \"32B/Currency\" )); t . add ( new MappingRule ( \"2\" , \"32B/Amount\" , WriteMode . APPEND )); t . add ( new MappingRule ( \"3\" , \"59/NameAndAddress\" )); // we create a reader as well CsvFileReader reader = new CsvFileReader ( input ); // we call the translation with the specific reader and writer instances MyFormatEngine . translate ( reader , writer , t . getRules ()); // we cast the created MT MT101 mt = ( MT101 ) writer . mt (); Note that all the component name's format is Camel Case. Please refer to SDK MtPath for further details about Mt path format. This procedure can be used to prefill any field in the target message. Since the rules are processed in order, if you prefill part of the target MT programmatically, beware that fields created from the mapping will always be appended after any field you had set.","title":"Prefilled target message"},{"location":"integrator/myformat/myformat-fin/#using-the-mtwriter-as-a-message-builder","text":"The MtWriter can be used as a message builder. This means that you can create a new MT message from scratch, and then use the writer to add fields and components to it. This is useful when you need to create a message that is not a translation of another message, but a new message that you want to build programmatically. To use the MtWriter as a message builder, you need to create an instance of the writer with no arguments, and then use the write method to add fields and components to it. For example: // we create a writer for and MT509 message MtWriter writer = new MtWriter ( MtType . MT509 ); // we add the data for the mandatory headers (will be initialized with default values anyway) writer . write ( \"b1/LogicalTerminal\" , \"AAAAUS30AXXX\" ); writer . write ( \"b2/ReceiverAddress\" , \"BBBBTRRSXXXX\" ); writer . write ( \"b2/DeliveryMonitoring\" , \"2\" ); writer . write ( \"b2/ObsolescencePeriod\" , \"020\" ); // we add the message content leveraging the MtPath expressions writer . write ( \"A/20C/1\" , \"SEME\" ); writer . write ( \"A/20C/2\" , \"MAINREF1234\" , WriteMode . APPEND ); writer . write ( \"A/23G\" , \"INST\" ); writer . write ( \"A/98C/1\" , \"PREP\" ); writer . write ( \"A/98C/2\" , \"20240625101806\" , WriteMode . APPEND ); writer . write ( \"A/A1/13A/1\" , \"LINK\" ); writer . write ( \"A/A1/13A/2\" , \"509\" , WriteMode . APPEND ); writer . write ( \"A/A1/20C/1\" , \"RELA\" ); writer . write ( \"A/A1/20C/2\" , \"RELAREF1234\" , WriteMode . APPEND ); writer . write ( \"A/A1[2]/20C/1\" , \"PREV\" ); writer . write ( \"A/A1[2]/20C/2\" , \"1234\" , WriteMode . APPEND ); writer . write ( \"A/A2/25D/1\" , \"CPRC\" ); writer . write ( \"A/A2/25D/3\" , \"CAND\" , WriteMode . APPEND ); writer . write ( \"A/A2/A2a/24B/1\" , \"REJT\" ); writer . write ( \"A/A2/A2a/24B/3\" , \"ADEA\" , WriteMode . APPEND ); writer . write ( \"B/22H/1\" , \"BUSE\" ); writer . write ( \"B/22H/2\" , \"BUYI\" , WriteMode . APPEND ); writer . write ( \"B/22H/1\" , \"PAYM\" ); writer . write ( \"B/22H/2\" , \"APMT\" , WriteMode . APPEND ); writer . write ( \"B/36B/1\" , \"ORDR\" ); writer . write ( \"B/36B/3\" , \"123,45\" , WriteMode . APPEND ); writer . write ( \"B/35B\" , \"/US/FOO487AE9\" ); // we get the created MT MT509 mt = ( MT509 ) writer . mt (); The sample code above creates a new MT509 message with the following content: {1:F01AAAAUS30AXXX0000000000}{2:I509BBBBTRRSXXXXN2020}{4: :16R:GENL :20C::SEME//MAINREF1234 :23G:INST :98C::PREP//20240625101806 :16R:LINK :13A::LINK//509 :20C::RELA//RELAREF1234 :16S:LINK :16R:LINK :20C::PREV//1234 :16S:LINK :16R:STAT :25D::CPRC//CAND :16R:REAS :24B::REJT//ADEA :16S:REAS :16S:STAT :16S:GENL :16R:TRADE :22H::BUSE//BUYI :22H::PAYM//APMT :36B::ORDR///123,45 :35B:/US/FOO487AE9 :16S:TRADE -}; Notice how the boundary fields (16R and 16S) are automatically added by the writer based on the path expressions used.","title":"Using the MtWriter as a message builder"},{"location":"integrator/myformat/myformat-fixed/","text":"Format > Fixed-Length Fixed-length files can be used as source or target for a translation, and it is helpful to integrate legacy systems that cannot produce or consume XML, CSV or JSON files. Single or multiple line messages are supported. The selectors are flexible enough to read or write content with complex structures and record types. To ease manipulation of data in fixed-length files, specific transformation functions are provided, based on a subset of COBOL PIC Formats (PICTURE clause). Fixed-Length Selector The same fixlen selector syntax is used for source and target. Meaning to express what content from a fixed-length input message is read, or to express where in the output fixed-length message the content is written. The basic selector format indicates the position of the field, but since fixlen messages can have elaborate structures, then the selector supports also more complex variants, for instance to select records by record identifier. Structure The grammar enables defining basically three components, each serves a different purpose: Field (required): Provides a method to extract information from a line and can be expressed in three different ways, depending on how the file structure is specified one expression might be convenient over the others: By Positions : This method requires the start and end position (both included), in the line. This uses two dots as separator (\"..\") to indicate the range By Length : This method requires the start position and a length of characters (bytes) for the field. A slash (\"/\") is used to separate the start and length. By Name : This method uses a static map of field names. The field names must be defined as an initial setup, then in the selectors the field name can be used without the need to indicate position or length every time. Variables (optional): The variables are optional and are used to reorder the input content read in a FOREACH. The primary use case for variables in this context is for line numbers, but a variable can also be used to store content, and thus to reorder the input based on the content of an element (for example to group transactions per account or currency). Condition (optional): Provides a method to filter a subset of lines from the input, for example could be used to select the records based on a record type identified by the first character in each line. Field Examples By Positions: By Length: By Name: // create the field definitions FixedLenFieldsDef defs = new FixedLenFieldsDef () . addField ( \"IBAN\" , \"1/3\" ) . addField ( \"ADDR1\" , \"4/20\" ) . addField ( \"ADDR2\" , \"24/10\" ) . addField ( \"ADDR3\" , \"89/2\" ) . addField ( \"BIC\" , \"101/4\" ); // create reader instance for source message String inputMsg = \"...\" ; FixedLenReader reader = FixedLenReader . builder ( inputMsg ). fieldsDef ( defs ). build (); Variables Examples Condition Examples Grammar The grammar structure for de Fixed-length selector is as follows: The selector contains 2 subcomponents: Field : Valid values are from \"..\" to , from \"/\" len Selector-options : A list of variables ( opt-variables ) and/or conditions ( opt-condition-list ). Or Empty value (these subcomponents are optional) The opt-variables is an optional variable list that can contain any number of elements: variable : Valid values are \"{\" name \"}\" , \"{\" name \":\" field opt-field-condition \"}\" . The opt-condition-list is an optional condition (or opt-field-condition ) list that can contain any number of elements: condition : Valid values are \"\" , \"\" , \"<\" field \">\" , \"<\" field \"='\" value \"'>\" . Expressed in a formal way selector ::= field selector-options field ::= from \"..\" to |from \"/\" len selector-options ::= \"[\" opt-variables opt-condition-list \"]\" | EMPTY opt-variables ::= variables-list | EMPTY variables-list ::= variables-list variable | variable variable ::= \"{\" name \"}\" | \"{\" name \":\" field opt-field-condition \"}\" opt-condition-list ::= condition-list | EMPTY opt-field-condition ::= \"[\" condition-list \"]\" | EMPTY condition-list ::= condition-list condition | condition condition ::= \"\" | \"\" | \"<\" field \">\" | \"<\" field \"='\" value \"'>\" Grammar Behavior Examples Basic selectors 3..7 Selects the value in the positions 3 to 7. Both numbers, 3 and 7 indicate a position in the row and are always inclusive, meaning the character in position 3 and the character in position 7 are included in the result. Positions are one-based. 3/5 Selects the value in the position 3 to 7. Notice the 5 in this syntax, indicates the length, not the ending position. Selectors with conditions 3/5[] Selects the value in the position 3 to 7 from the first row in the document. 3/5[<1/3='DTL'>] Selects the value in the position 3 to 7 from a line where position 1 to 3 contain the record identifier \"DTL\". 3/5[<1/3='HDR'>] Selects the value in the positions 3 to 7 form the first row starting with record identifier \"HDR\". 3/5[<1/3='DTL'>] Selects the value in the position 3 to 7 from the lines 4 to 5 where position 1 to 3 contains the record identifier \"DTL\". Selectors with variables 3/5[{N}] Selects the value in the positions 3 to 7, and stores the current line number in a variable \"N\". Variables are used in the context of a mapping rule with \"foreach\", when multiple message lines are being read or written. 3/5[{M:9/3}] Selects the value in the positions 3 to 7, and stores the value in position 9 to 11 in a variable \"M\". 3/5[{M:9/3}{N}] Selects the value in the positions 3 to 7, and stores the value in position 9 to 11 in a variable \"M\" and the current line in a variable \"N\". Selectors with variables and conditions 3/5[{N}] Selects the value in the position 3 to 7 from lines 1 to 4, and stores the line number in a variable \"N\". 3/5[{N}<1/3='DTL'>] Selects the value in the position 3 to 7 from all lines where position 1 to 3 contains the record identifier \"DTL\", and stores the line number in a variable \"N\". 3/5[{M:9/3}<1/3='HDR'>] Selects the value in the positions 3 to 7 from the first row starting with record identifier \"HRD\", and stores the value in position 9 to 11 in a variable \"M\". 3/5[{M:9/3}{N}<1/3='DTL'>] Selects the value in the positions 3 to 7 from all lines with record identifier \"DTL\", and stores the value in position 9 to 11 in a variable \"M\" and the line number in variable \"N\". 3/5[{M:9/3[<1/3='HDR'>]}<1/3='DTL'>] Selects the value in the positions 3 to 7 from all lines with record identifier \"DTL\", and stores the value in position 9 to 11 from the first row in the header, in a variable \"M\". This complex variable definition can be handy to group content, in this case we are grouping by a value in the header. Notice the condition order is important. <1/3='DTL'> finds all DTL lines and then selects the first four lines <1/3='DTL'> finds the first four lines and from those, selects the ones with DTL Field name definition When the mapping is done programmatically, you can configure a dictionary of field names. You give a name to the field positions in your fixed-length structure, and then you just use the naming in the mapping rules. This feature makes the mapping rules less error-prone. For example: FixedLenFieldsDef defs = new FixedLenFieldsDef () . addField ( \"RECORD\" , \"1/3\" ) . addField ( \"REFERENCE\" , \"4/20\" ) . addField ( \"SOURCE_ACCT\" , \"24/30\" ); MappingTable t = new MappingTable ( FileFormat . FIXEDLEN , FileFormat . MX ); // add the mx type to the message t . add ( new MappingRule ( \"pain.001.001.03\" , \"mxType\" , WriteMode . SETUP )); // file ref from HDR as message identifier t . add ( new MappingRule ( \"REFERENCE[]\" , \"/Document/CstmrCdtTrfInitn/GrpHdr/MsgId\" , new Transformation ( Key . fromPIC , \"X(20)\" ))); // source account t . add ( new MappingRule ( \"foreach(SOURCE_ACCT[{n}])\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/DbtrAcct/Id/Othr/Id\" , new Transformation ( Key . fromPIC , \"X(30)\" ))); In the example above, instead of repeating the \"1/3\" in each record filter, we just use the term \"RECORD\". And the same applies for any field in any a mapping rule. The field definitions are provided to the translation process in the reader. So you must call the translation passing your own instance of the reader and writer like this: // create reader instance for source message FixedLenReader reader = FixedLenReader . builder ( input ). fieldsDef ( defs ). build (); // create writer and call translation MxWriter writer = new MxWriter ( MxType . pacs_008_001_02 ); // call the translation passing the reader, writer and the rules MyFormatEngine . translate ( reader , writer , t . getRules ()); Conversion FROM Fixed-Length A typical translation from fixed-length to other format will involve filtering by a record type (usually the first part of each row). For each record type, you will then need one rule per field in the record type. Then for repetitive records you would use a foreach while for non-repetitive record types you would use a simple rule. The only thing to remark when converting from fixed-length is that you should use a fromPIC transformation as the first transformation in all your mapping rules. The fromPIC will ensure the fixed-length content is cleaned and formatted before it is propagated to the target message. Conversion TO Fixed-Length Two remarks are important when converting to fixed-length. Setup The first part of your mapping table should consist of instructions to build the empty template of your target message. By doing this, you ensure the overall structure of the output file is valid, even though it will be empty until the actual mapping rules are processed. A special write mode called SETUP is used for this purpose, combined with a special \"command\" named addRow . In a setup mapping rule, the command replaces the target selector. For example, if your message structure contains a header record, followed by multiple detail records and with a footer record at the end; the following setup commands will initialize the file. MappingTable t = new MappingTable ( FileFormat . MX , FileFormat . FIXEDLEN ); // create an empty header row identifier by HR t . add ( new MappingRule ( null , \"addRow\" , WriteMode . SETUP , new Transformation ( Key . filler , \"HR\" , \"X(33)\" ))); // create multiple detail records identifier by TX t . add ( new MappingRule ( \"foreach(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/)\" , \"addRow\" , WriteMode . SETUP , new Transformation ( Key . filler , \"TX\" , \"X(110)\" , \"9(11).999\" , \"X(80)\" ))) // create a single footer record at the end, identified by FR t . add ( new MappingRule ( null , \"addRow\" , WriteMode . SETUP , new Transformation ( Key . filler , \"FR\" , \"9(15)\" , \"9(14).999\" , X ( 25 )))); Notice a special filler transformation is used to generate the empty rows. The filler transformation expects no value as input, and generates an empty line for the given combination of literal content and toPIC parameters. Only one header and footer is generated, but the detailed record is generated as many times as actual transactions in the source file; meaning the initialization is not static but dynamic , it can use input data . After setup and regardless of the following mapping rules, the output will have a valid structure. The setup is also important for the filter selectors to work. Suppose you want to define a rule such as t . add ( new MappingRule ( \"foreach(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/CdtrAcct/Id/IBAN)\" , \"BEN_IBAN[]\" , new Transformation ( Key . fromPIC , \"X(30)\" ) )); This rule will iterate the IBAN numbers in all transactions of the source message, and will write them in the \"BEN_IBAN\" field of all \"TX\" records in the target message. Without the setup, this filter would have written a single transaction row in the output. toPIC The second remark when creating fixed-length as output is that all rules should have a proper toPIC transformation as the last transformation in the pipeline. This is essential to make sure the processed value is finally converted to the expected format, with proper padding. Character Set Fixed-length files (and content, in general) uses 8-bit bytes and has usually been used with ASCII characters only. The module supports ISO-8859-1 characters (which corresponds to the subset of Unicode characters with values between 32 and 255, both inclusive). Given that Java strings use 16 bits characters while in memory, the module Reader and Write will replace characters that are out of valid range with a question mark. This should keep both input and output valid (high unicode characters should not be present in numbers anyway). The output can then be converted to UTF-8 if needed, but it should be noted that records having high ISO-8859-1 characters will not keep the length if converted to UTF-8.","title":"Format > Fixed-Length"},{"location":"integrator/myformat/myformat-fixed/#format-fixed-length","text":"Fixed-length files can be used as source or target for a translation, and it is helpful to integrate legacy systems that cannot produce or consume XML, CSV or JSON files. Single or multiple line messages are supported. The selectors are flexible enough to read or write content with complex structures and record types. To ease manipulation of data in fixed-length files, specific transformation functions are provided, based on a subset of COBOL PIC Formats (PICTURE clause).","title":"Format > Fixed-Length"},{"location":"integrator/myformat/myformat-fixed/#fixed-length-selector","text":"The same fixlen selector syntax is used for source and target. Meaning to express what content from a fixed-length input message is read, or to express where in the output fixed-length message the content is written. The basic selector format indicates the position of the field, but since fixlen messages can have elaborate structures, then the selector supports also more complex variants, for instance to select records by record identifier.","title":"Fixed-Length Selector"},{"location":"integrator/myformat/myformat-fixed/#structure","text":"The grammar enables defining basically three components, each serves a different purpose: Field (required): Provides a method to extract information from a line and can be expressed in three different ways, depending on how the file structure is specified one expression might be convenient over the others: By Positions : This method requires the start and end position (both included), in the line. This uses two dots as separator (\"..\") to indicate the range By Length : This method requires the start position and a length of characters (bytes) for the field. A slash (\"/\") is used to separate the start and length. By Name : This method uses a static map of field names. The field names must be defined as an initial setup, then in the selectors the field name can be used without the need to indicate position or length every time. Variables (optional): The variables are optional and are used to reorder the input content read in a FOREACH. The primary use case for variables in this context is for line numbers, but a variable can also be used to store content, and thus to reorder the input based on the content of an element (for example to group transactions per account or currency). Condition (optional): Provides a method to filter a subset of lines from the input, for example could be used to select the records based on a record type identified by the first character in each line.","title":"Structure"},{"location":"integrator/myformat/myformat-fixed/#field-examples","text":"By Positions: By Length: By Name: // create the field definitions FixedLenFieldsDef defs = new FixedLenFieldsDef () . addField ( \"IBAN\" , \"1/3\" ) . addField ( \"ADDR1\" , \"4/20\" ) . addField ( \"ADDR2\" , \"24/10\" ) . addField ( \"ADDR3\" , \"89/2\" ) . addField ( \"BIC\" , \"101/4\" ); // create reader instance for source message String inputMsg = \"...\" ; FixedLenReader reader = FixedLenReader . builder ( inputMsg ). fieldsDef ( defs ). build ();","title":"Field Examples"},{"location":"integrator/myformat/myformat-fixed/#variables-examples","text":"","title":"Variables Examples"},{"location":"integrator/myformat/myformat-fixed/#condition-examples","text":"","title":"Condition Examples"},{"location":"integrator/myformat/myformat-fixed/#grammar","text":"The grammar structure for de Fixed-length selector is as follows: The selector contains 2 subcomponents: Field : Valid values are from \"..\" to , from \"/\" len Selector-options : A list of variables ( opt-variables ) and/or conditions ( opt-condition-list ). Or Empty value (these subcomponents are optional) The opt-variables is an optional variable list that can contain any number of elements: variable : Valid values are \"{\" name \"}\" , \"{\" name \":\" field opt-field-condition \"}\" . The opt-condition-list is an optional condition (or opt-field-condition ) list that can contain any number of elements: condition : Valid values are \"\" , \"\" , \"<\" field \">\" , \"<\" field \"='\" value \"'>\" .","title":"Grammar"},{"location":"integrator/myformat/myformat-fixed/#expressed-in-a-formal-way","text":"selector ::= field selector-options field ::= from \"..\" to |from \"/\" len selector-options ::= \"[\" opt-variables opt-condition-list \"]\" | EMPTY opt-variables ::= variables-list | EMPTY variables-list ::= variables-list variable | variable variable ::= \"{\" name \"}\" | \"{\" name \":\" field opt-field-condition \"}\" opt-condition-list ::= condition-list | EMPTY opt-field-condition ::= \"[\" condition-list \"]\" | EMPTY condition-list ::= condition-list condition | condition condition ::= \"\" | \"\" | \"<\" field \">\" | \"<\" field \"='\" value \"'>\"","title":"Expressed in a formal way"},{"location":"integrator/myformat/myformat-fixed/#grammar-behavior-examples","text":"Basic selectors 3..7 Selects the value in the positions 3 to 7. Both numbers, 3 and 7 indicate a position in the row and are always inclusive, meaning the character in position 3 and the character in position 7 are included in the result. Positions are one-based. 3/5 Selects the value in the position 3 to 7. Notice the 5 in this syntax, indicates the length, not the ending position. Selectors with conditions 3/5[] Selects the value in the position 3 to 7 from the first row in the document. 3/5[<1/3='DTL'>] Selects the value in the position 3 to 7 from a line where position 1 to 3 contain the record identifier \"DTL\". 3/5[<1/3='HDR'>] Selects the value in the positions 3 to 7 form the first row starting with record identifier \"HDR\". 3/5[<1/3='DTL'>] Selects the value in the position 3 to 7 from the lines 4 to 5 where position 1 to 3 contains the record identifier \"DTL\". Selectors with variables 3/5[{N}] Selects the value in the positions 3 to 7, and stores the current line number in a variable \"N\". Variables are used in the context of a mapping rule with \"foreach\", when multiple message lines are being read or written. 3/5[{M:9/3}] Selects the value in the positions 3 to 7, and stores the value in position 9 to 11 in a variable \"M\". 3/5[{M:9/3}{N}] Selects the value in the positions 3 to 7, and stores the value in position 9 to 11 in a variable \"M\" and the current line in a variable \"N\". Selectors with variables and conditions 3/5[{N}] Selects the value in the position 3 to 7 from lines 1 to 4, and stores the line number in a variable \"N\". 3/5[{N}<1/3='DTL'>] Selects the value in the position 3 to 7 from all lines where position 1 to 3 contains the record identifier \"DTL\", and stores the line number in a variable \"N\". 3/5[{M:9/3}<1/3='HDR'>] Selects the value in the positions 3 to 7 from the first row starting with record identifier \"HRD\", and stores the value in position 9 to 11 in a variable \"M\". 3/5[{M:9/3}{N}<1/3='DTL'>] Selects the value in the positions 3 to 7 from all lines with record identifier \"DTL\", and stores the value in position 9 to 11 in a variable \"M\" and the line number in variable \"N\". 3/5[{M:9/3[<1/3='HDR'>]}<1/3='DTL'>] Selects the value in the positions 3 to 7 from all lines with record identifier \"DTL\", and stores the value in position 9 to 11 from the first row in the header, in a variable \"M\". This complex variable definition can be handy to group content, in this case we are grouping by a value in the header. Notice the condition order is important. <1/3='DTL'> finds all DTL lines and then selects the first four lines <1/3='DTL'> finds the first four lines and from those, selects the ones with DTL","title":"Grammar Behavior Examples"},{"location":"integrator/myformat/myformat-fixed/#field-name-definition","text":"When the mapping is done programmatically, you can configure a dictionary of field names. You give a name to the field positions in your fixed-length structure, and then you just use the naming in the mapping rules. This feature makes the mapping rules less error-prone. For example: FixedLenFieldsDef defs = new FixedLenFieldsDef () . addField ( \"RECORD\" , \"1/3\" ) . addField ( \"REFERENCE\" , \"4/20\" ) . addField ( \"SOURCE_ACCT\" , \"24/30\" ); MappingTable t = new MappingTable ( FileFormat . FIXEDLEN , FileFormat . MX ); // add the mx type to the message t . add ( new MappingRule ( \"pain.001.001.03\" , \"mxType\" , WriteMode . SETUP )); // file ref from HDR as message identifier t . add ( new MappingRule ( \"REFERENCE[]\" , \"/Document/CstmrCdtTrfInitn/GrpHdr/MsgId\" , new Transformation ( Key . fromPIC , \"X(20)\" ))); // source account t . add ( new MappingRule ( \"foreach(SOURCE_ACCT[{n}])\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/DbtrAcct/Id/Othr/Id\" , new Transformation ( Key . fromPIC , \"X(30)\" ))); In the example above, instead of repeating the \"1/3\" in each record filter, we just use the term \"RECORD\". And the same applies for any field in any a mapping rule. The field definitions are provided to the translation process in the reader. So you must call the translation passing your own instance of the reader and writer like this: // create reader instance for source message FixedLenReader reader = FixedLenReader . builder ( input ). fieldsDef ( defs ). build (); // create writer and call translation MxWriter writer = new MxWriter ( MxType . pacs_008_001_02 ); // call the translation passing the reader, writer and the rules MyFormatEngine . translate ( reader , writer , t . getRules ());","title":"Field name definition"},{"location":"integrator/myformat/myformat-fixed/#conversion-from-fixed-length","text":"A typical translation from fixed-length to other format will involve filtering by a record type (usually the first part of each row). For each record type, you will then need one rule per field in the record type. Then for repetitive records you would use a foreach while for non-repetitive record types you would use a simple rule. The only thing to remark when converting from fixed-length is that you should use a fromPIC transformation as the first transformation in all your mapping rules. The fromPIC will ensure the fixed-length content is cleaned and formatted before it is propagated to the target message.","title":"Conversion FROM Fixed-Length"},{"location":"integrator/myformat/myformat-fixed/#conversion-to-fixed-length","text":"Two remarks are important when converting to fixed-length.","title":"Conversion TO Fixed-Length"},{"location":"integrator/myformat/myformat-fixed/#setup","text":"The first part of your mapping table should consist of instructions to build the empty template of your target message. By doing this, you ensure the overall structure of the output file is valid, even though it will be empty until the actual mapping rules are processed. A special write mode called SETUP is used for this purpose, combined with a special \"command\" named addRow . In a setup mapping rule, the command replaces the target selector. For example, if your message structure contains a header record, followed by multiple detail records and with a footer record at the end; the following setup commands will initialize the file. MappingTable t = new MappingTable ( FileFormat . MX , FileFormat . FIXEDLEN ); // create an empty header row identifier by HR t . add ( new MappingRule ( null , \"addRow\" , WriteMode . SETUP , new Transformation ( Key . filler , \"HR\" , \"X(33)\" ))); // create multiple detail records identifier by TX t . add ( new MappingRule ( \"foreach(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/)\" , \"addRow\" , WriteMode . SETUP , new Transformation ( Key . filler , \"TX\" , \"X(110)\" , \"9(11).999\" , \"X(80)\" ))) // create a single footer record at the end, identified by FR t . add ( new MappingRule ( null , \"addRow\" , WriteMode . SETUP , new Transformation ( Key . filler , \"FR\" , \"9(15)\" , \"9(14).999\" , X ( 25 )))); Notice a special filler transformation is used to generate the empty rows. The filler transformation expects no value as input, and generates an empty line for the given combination of literal content and toPIC parameters. Only one header and footer is generated, but the detailed record is generated as many times as actual transactions in the source file; meaning the initialization is not static but dynamic , it can use input data . After setup and regardless of the following mapping rules, the output will have a valid structure. The setup is also important for the filter selectors to work. Suppose you want to define a rule such as t . add ( new MappingRule ( \"foreach(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/CdtrAcct/Id/IBAN)\" , \"BEN_IBAN[]\" , new Transformation ( Key . fromPIC , \"X(30)\" ) )); This rule will iterate the IBAN numbers in all transactions of the source message, and will write them in the \"BEN_IBAN\" field of all \"TX\" records in the target message. Without the setup, this filter would have written a single transaction row in the output.","title":"Setup"},{"location":"integrator/myformat/myformat-fixed/#topic","text":"The second remark when creating fixed-length as output is that all rules should have a proper toPIC transformation as the last transformation in the pipeline. This is essential to make sure the processed value is finally converted to the expected format, with proper padding.","title":"toPIC"},{"location":"integrator/myformat/myformat-fixed/#character-set","text":"Fixed-length files (and content, in general) uses 8-bit bytes and has usually been used with ASCII characters only. The module supports ISO-8859-1 characters (which corresponds to the subset of Unicode characters with values between 32 and 255, both inclusive). Given that Java strings use 16 bits characters while in memory, the module Reader and Write will replace characters that are out of valid range with a question mark. This should keep both input and output valid (high unicode characters should not be present in numbers anyway). The output can then be converted to UTF-8 if needed, but it should be noted that records having high ISO-8859-1 characters will not keep the length if converted to UTF-8.","title":"Character Set"},{"location":"integrator/myformat/myformat-json/","text":"JSON JSON payloads can be used as source or target for a translation. JSON selector is pretty much similar to XML one. JSON Selector If the message is an JSON, the selector uses JsonPath expressions. All the common syntax for JsonPath expressions can be used, including simple predicates and attributes in the elements. The paths must always be absolute, though. For example: document.sttlmInstrDtls.sttlmDtTm.dtTm selects the value of the element dtTm document.pmtDtls.Debtor.pstlAddr.addrLine[1] selects the value of the first occurrence of element AddrLine within pstlAddr document.pmtDtls.debtor.pstlAddr.addrLine[3] selects the value of the third occurrence of element AddrLine within pstlAddr When the source message in the translation is an JSON message, the selector indicates which element text or attribute must be read. For example, a rule having .document.pmtDtls.sttlmAmt in the source selector will get the value of the element sttlmAmt , and pass that as content for the translation. Analogously, when the target message in the translation is an JSON, the selector indicates what element must be written in the target message. For example, a target selector having document.sttlmInstrDtls.sttlmDtTm.dtTm will take the translation content and create in the target JSON an element dtTm. All elements in the path parent structure will be created automatically. Predicates The JsonPath supports predicates to indicate repetition indexes within array structures. The predicates can be in any segment of the path, where the element is of type array. For example, document.cstmrCdtTrfInitn.pmtInf[2].cdtTrfTxInf[3].cdtrAgt selects the cdtrAgt element in the third repetition of cdtTrfTxInf within the second repetition of pmtInf . In the above examples, all predicates have numbers, meaning they reference a nested structure of arrays in the JSON. When the selector is used in rule processing multiple elements, the number can be replaced by a variable name. For example the source selector document.cstmrCdtTrfInitn.pmtInf[{m}].cdtTrfTxInf[{n}].cdtrAgt will read all instances of the element cdtrAgt , and will propagate a variable named m with the repetition index of pmtInf and a variable n with the repetition of cdtTrfTxInf . Repetition in a foreach is 1 based, meaning the first read pmtInf will have n=1 . These repetition variables can then be used in the target selector, to map repetitive elements read from the source message into elements of an array in the target JSON message. Prefilled target message When translating into JSON, sometimes it is necessary to apply a translation into existing content. This can be accomplished easily, passing your own instances of the reader and writer to the engine. // Mapping definition MappingTable t = new MappingTable ( FileFormat . MT , FileFormat . JSON ); t . add ( new MappingRule ( \"20\" , \"document.header.foo\" , WriteMode . CREATE )); t . add ( new MappingRule ( \"32A/3\" , \"document.transaction.amount\" , new Transformation ( Transformation . Key . formatDecimal ))); assertTrue ( t . validate (). isEmpty ()); // existing JSON message JsonWriter existingJsonWriter = new JsonWriter ( \"{'document': { 'header': { 'uniqueID': 'URGP3225' }}}\" ); // sample source message MT103 mt = new MT103 (); mt . append ( new Field20 ( \"XXX\" )); mt . append ( new Field32A ( \"151019USD1234,5\" )); MtReader mtReader = new MtReader ( mt ); // translation call passing a pre-filled JSON writer instance MyFormatEngine . translate ( mtReader , existingJsonWriter , t . rules );","title":"Format > JSON"},{"location":"integrator/myformat/myformat-json/#json","text":"JSON payloads can be used as source or target for a translation. JSON selector is pretty much similar to XML one.","title":"JSON"},{"location":"integrator/myformat/myformat-json/#json-selector","text":"If the message is an JSON, the selector uses JsonPath expressions. All the common syntax for JsonPath expressions can be used, including simple predicates and attributes in the elements. The paths must always be absolute, though. For example: document.sttlmInstrDtls.sttlmDtTm.dtTm selects the value of the element dtTm document.pmtDtls.Debtor.pstlAddr.addrLine[1] selects the value of the first occurrence of element AddrLine within pstlAddr document.pmtDtls.debtor.pstlAddr.addrLine[3] selects the value of the third occurrence of element AddrLine within pstlAddr When the source message in the translation is an JSON message, the selector indicates which element text or attribute must be read. For example, a rule having .document.pmtDtls.sttlmAmt in the source selector will get the value of the element sttlmAmt , and pass that as content for the translation. Analogously, when the target message in the translation is an JSON, the selector indicates what element must be written in the target message. For example, a target selector having document.sttlmInstrDtls.sttlmDtTm.dtTm will take the translation content and create in the target JSON an element dtTm. All elements in the path parent structure will be created automatically.","title":"JSON Selector"},{"location":"integrator/myformat/myformat-json/#predicates","text":"The JsonPath supports predicates to indicate repetition indexes within array structures. The predicates can be in any segment of the path, where the element is of type array. For example, document.cstmrCdtTrfInitn.pmtInf[2].cdtTrfTxInf[3].cdtrAgt selects the cdtrAgt element in the third repetition of cdtTrfTxInf within the second repetition of pmtInf . In the above examples, all predicates have numbers, meaning they reference a nested structure of arrays in the JSON. When the selector is used in rule processing multiple elements, the number can be replaced by a variable name. For example the source selector document.cstmrCdtTrfInitn.pmtInf[{m}].cdtTrfTxInf[{n}].cdtrAgt will read all instances of the element cdtrAgt , and will propagate a variable named m with the repetition index of pmtInf and a variable n with the repetition of cdtTrfTxInf . Repetition in a foreach is 1 based, meaning the first read pmtInf will have n=1 . These repetition variables can then be used in the target selector, to map repetitive elements read from the source message into elements of an array in the target JSON message.","title":"Predicates"},{"location":"integrator/myformat/myformat-json/#prefilled-target-message","text":"When translating into JSON, sometimes it is necessary to apply a translation into existing content. This can be accomplished easily, passing your own instances of the reader and writer to the engine. // Mapping definition MappingTable t = new MappingTable ( FileFormat . MT , FileFormat . JSON ); t . add ( new MappingRule ( \"20\" , \"document.header.foo\" , WriteMode . CREATE )); t . add ( new MappingRule ( \"32A/3\" , \"document.transaction.amount\" , new Transformation ( Transformation . Key . formatDecimal ))); assertTrue ( t . validate (). isEmpty ()); // existing JSON message JsonWriter existingJsonWriter = new JsonWriter ( \"{'document': { 'header': { 'uniqueID': 'URGP3225' }}}\" ); // sample source message MT103 mt = new MT103 (); mt . append ( new Field20 ( \"XXX\" )); mt . append ( new Field32A ( \"151019USD1234,5\" )); MtReader mtReader = new MtReader ( mt ); // translation call passing a pre-filled JSON writer instance MyFormatEngine . translate ( mtReader , existingJsonWriter , t . rules );","title":"Prefilled target message"},{"location":"integrator/myformat/myformat-rule/","text":"Mapping Rule A mapping rule defines how a portion of content from the source message is transformed and appended into the target message. Therefore, a conversion from a source message into a target message is composed of a list of mapping rules . The mapping rules can be defined programmatically or by providing a configuration file. The configuration file could be a simple Excel spreadsheet with the mappings. The general structure of a mapping rule contains the following elements: Source : The source is used to identify which field in the source message must be read. It is indicated as a selector expression with a syntax corresponding to the source message format. For an MT it could be a field within a sequence, for an XML it is an XPath, and for a Fixed-length it can be a field within a specific record type. Transformation : Transformations are optional and allows changing the read value before appending it into the target message. An out-of-the-box dictionary of transformation is provided. The transformations can be combined, enabling a wide range of data manipulation options. Target : The target selector is used to identify where in the target message to read and optionally transformed content will be set. Read Mode : The read mode is optional, and it is used to define how to read and process content from the source message. The supported modes are: Single : This is the default mode, it reads a single value from the source message, regardless of the content being repetitive or not. Foreach : Reads multiple repetitive values from the source content and process them in a loop. The same mapping rule is applied for each read value. The foreach can receive one or two selectors. When two selectors are received, the first one is used to compute the repetitions, while the second one is used to get the actual value for the translation. This is particularly useful when you need to get a general content from the source message and copy the same value to multiple repetitive instances in the target message. Literal : Instead of providing a content selector, this mode is used to have a fixed value directly in the rule. Literal are defined as literal(foo) and also as quoted text with just \"foo\". Concat : Receives multiple selectors, and concatenates all read content into a single value. This selector will concatenate the values of the fields indicated in the parameters. It also allows quoted literals as parameters. A typical use case is to combine values from the source message along a fixed separator. For example when reading content from an MT you can have as selector something like CONCAT(20, \"|\", 21, \"|\", 59/1) which will generate as value the concatenation of the field 20, a pipe, the field 21, another pipe and the account number from field 59. Write Mode : Finally, the write mode is optional, and it is used to define what to do when the content already exists in the target message, for example, create, overwrite or append. Create : This is the default mode. A new element or field will always be created in the target message, regardless if the element already exists. Update : Checks if the target element or field exists before creating a new one. If the element is found, its value is overwritten with the new value from the rule. If the target element does not exist, this mode is similar to Create. Append : Checks if the target element exists before creating a new one. If the element is found, its value will be kept and the new value from the rule will be appended. If the target element does not exist, this mode is similar to Create. Setup : Used in some file formats, such as fixed-length, to initialize the output like an empty template, or define configuration options for the output message (encoding, namespace, etc\u2026). There are some setup command to define also general attributes of the mapping table, such as the specific source and target format and type. This simple but flexible scheme allows almost all message conversion scenarios. Generic Examples The following tables illustrate different combinations of parameters for a mapping rule, regardless of the message format. A complete translation between a source and a target message is done with a table containing a list of mapping rules. Example 1 - Simple Mapping Source Transformations Target Write Mode Selector 1 Selector 2 Reads the content located at Selector 1 in the source message, and writes the read value, at the position indicated by Selector 2 in the target message. A single value is read. The read value is propagated as is, without transformations. The write mode is not specified, so a new element is created in the target message. Example 2 - Transformation Source Transformations Target Write Mode Selector 1 Transformation 1 Selector 2 Reads content indicated by Selector 1 , applies a transformation Transformation 1 , and writes the manipulated content in Selector 2 in the target message. Example 3 - Multiple Transformations Source Transformations Target Write Mode Selector 1 Transformation 1, Transformation 2, Transformation 3 Selector 2 Reads content indicated by Selector 1 , applies the three transformations 1, 2, and 3, and writes the manipulated content in Selector 2 in the target message. The transformations are processed in a pipeline , where the output of one transformation becomes the input for the next transformation. Example 4 - Write Mode Source Transformations Target Write Mode Selector 1 Transformation 1 Selector 2 Append Reads content indicated by Selector 1 , applies the transformations Transformation 1, and writes the manipulated content in Selector 2 in the target message. If the element indicated by Selector 2 does not exist in the target message, it will be created. If the element exists, the processed value is appended to the existing content of the existing element. Example 5 - Literal Source Transformations Target Write Mode Literal(foo) Selector 2 In this example, instead of providing a selector for the source message, we provide a literal content \"foo\". The value \"foo\" is then written in Selector 2 in the target message. Example 6 - Multiple Sources Source Transformations Target Write Mode Concat(Selector 1, Selector 1') Selector 2 In this example, we provide two selectors for the source message. Combined with a Concat read mode. The concatenation of both read values is then passed through the translation and written in Selector 2 in the target message. Example 7 - Foreach with single selector Source Transformations Target Write Mode Foreach(Selector 1) Transformation 1 Selector 2 Reads multiple values from the source message at the location indicated by Selector 1 . Each read value is passed through Transformation 1 and written in the target message at the location indicated by Selector 2 . Example 8 - Foreach with double selector Source Transformations Target Write Mode Foreach(Selector 1, Selector 1') Transformation 1 Selector 2 Reads multiple values from the source message at the location indicated by the combination of Selector 1 (used to iterate the loop) and Selector 1' (used to get the actual value). Each read value is passed through Transformation 1 and written in the target message at the location indicated by Selector 2 . Note that when reading from Mt (ie. using MtReader) there are some scenarios where the Selector 1' is set to get values from optional fields. In this case it is possible to obtain null values as results if the Field is absent. This will result in a list of values with some null values in it. To avoid this behavior and get a list of not null values there is a special property that can be set in the MtReader that will avoid adding null values to the result list. This property is true by default. MtReader reader = new MtReader ( mt ); reader . setAllowReadManyWithValueSelectorNullItems ( false ); Selectors The selectors are a key feature in a mapping rule. A selector is a plain String defining a precise element or field in a message. The selector expressions are used in a mapping rule to indicate what content from the source message is read, or where in the target message the content is going to be written. The syntax of the selector depends on the file format. Please refer to the specific section for a file format to see the grammar of the selector. We provide here a few simple examples to illustrate the versatility of the selectors and how they are used to getting content from different types of file. Format Selector Description MT E/E1/95Q selects the field 95Q in subsequence E1 within sequence E MT 59/Line[2] selects the second line of component 59, with the name & address information MX /Document/SttlmInstrDtls/DtTm selects the value of the element DtTm MX /Document/PmtDtls/SttlmAmt/@Ccy selects the value of the attribute Ccy in the element SttlmAmt XML /A/B[3]/C Selects the value of element C in the third child B in the root node A JSON X.Y[2].Z Selects the value of element Z in the second sub-element of the array Y in the element X CSV 3 Select the third column in a CSV row CSV 5[ <1='DTL'> ] Selects the fifth column from a CSV line, where column 1 contains \"DTL\" FIXED-LENGTH 3..7[ ] Selects the value in the positions 3 to 7 in the first row FIXED-LENGTH 3/5[ <1/3='DTL'> ] Selects the value in the position 3 to 7 from a line where position 1 to 3 contain the record identified by \"DTL\" Transformation The transformation in a mapping rule is optional. If no transformation is defined, the found source content is copied into the target message unchanged. Transformations are defined as functions, and a mapping rule can define several functions that will be applied one after the other. All parameters are String unless indicated otherwise. All functions include an implicit input parameter. This parameter will be the result of the selector in the mapping rule or the result of a previous transformation if the rule defines more than one transformation. Function names are not case-sensitive when defined in configuration files. If a transformation cannot be applied because of a wrong parameter or an unexpected input, the input content is returned unaltered. This includes content being null. A transformation or a combination of transformation which result is null will not set any content into the target message. Therefore, there is a substantial difference, for example, between striping a content to null or empty. ** Empty strings from the source selector and or as a result of transformations are propagated to the target message. Meaning null and empty have different semantics**. For example, the function upperCase takes no additional argument and will transform the Source content into upper case. But the function substring(start, end) requires two additional parameters for the start and end positions of the truncation to apply. A comprehensive list of available functions is provided in the Transformations section. Pipeline Transformation functions can be combined into a pipeline . Meaning, for a single rule several transformations may be defined and all of them will be called in the defined order. The input for the first transformation function will be the result of the Source selector, and thereafter the output of a transformation becomes the input for the next one. This allows complex transformation of content using a limited set of atomic operations. Conditionals The mapping rules do not support conditional logic and conditional operators. However, a special semantic implemented for null values can overcome this limitation in most situations. There are two ways to produce a null value: With a selector that finds no result: if a Source selector does not produce any result applied to the source message, for example if the element is optional in the source message, then the mapping rule will be skipped. Meaning, it will not create empty content in the target message. This is useful to deal with optional content in the source message, you can just add the mapping for the optional content and if it is not present, the rule will be silently ignored. With a transformation: When the content in the source message is present, you can apply one or many transformations that in some scenarios will produce a null. In particular, you can use the stripToNull transformation. Besides the above simple approaches, there are two power functions especially suited to achieve more complex conditional logic: IfMatches and IfNotMatches . Both functions accept a regex as input and will let the content pass through if they match or not match the regex. Example 1: For example, if you want to achieve this type of simple conditional logic: IF ( Selector A = \"C\" ) THEN \"UNIT\" -> Selector B ELSE \"FAMT\" -> Selector B Where basically if the source selector has a \"C\" you will write the literal \"UNIT\" in the target, otherwise you will write \"FAMT\". The above can be resolved with the ifElse transformation like this: Source Transformations Target Selector A ifElse(\"C\", \"UNIT\", \"FAMT\") Selector B You can achieve the same with the ifMatches and ifNotMatches transformation, using two mapping rules, one to catch the IF and another to catch the ELSE: Source Transformations Target Selector A ifMatches(\"C\"); fixed(\"UNIT\") Selector B Selector A ifNotMatches(\"C\"); fixed(\"FAMT\") Selector B In the first rule when the source content is a \"C\" the IfMatches will match and thus propagate that \"C\" literal as value. Then instead of using the literal, we use a fixed transformation to write something else in the target. IN this same rule when the source content is not the \"C\" literal, the IfMatches will not match, thus it will return null and no further transformation is evaluated, and no content is written to the output. The second rule will do the opposite, it will propagate content and write the fixed value only when the input did not match. Example 2: For example, if you want to achieve this more complex type of conditional logic: IF ( Selector 1 = CANC or Selector 1 = AMD ) THEN Selector 2 -> Selector A ELSE Selector 3 -> Selector B You have three different source selectors. The \"Selector 1\" is used for the conditional logic check, then depending on that you will propagate to the output the content from two other different selectors \"Selector 2\" and \"Selector 3\" conditionally. The above is mapped like this: Source Transformations Target Concat(Selector 1, \";\", Selector 2, \";\", Selector 3) ifMatches(\u2018^(CANC|AMND);.+;\u2019), removeFirst(\u2018^(CANC|AMND);\u2019), removeFirst(\u2018;.*$\u2019) Selector A Concat(Selector 1, \";\", Selector 2, \";\", Selector 3) ifNotMatches(\u2018^(CANC|AMND);.+\u2019), removeFirst(\u2018^.+;') Selector B The source selector is a concatenation of the actual selectors, separated by a semicolon. So the source content selection will produce a semicolon separated string. Then the transformation will pass through the content of Selectors 2 or Selector 3 depending on the content of Selector 1. Then, the second rule will do the same, passing through the content of selector 3. Note that the transformation ifMatches , ifNotMatches can be replaced by ifElse when the Target selector is the same. If a different Target is going to be selected based on the input, then you need to use the ifMatches and ifNotMatches transformation. Let's check an actual example based on transformation above: Selector 1 = CANC Selector 2 = XXX Selector 3 = YYY Given those values and the Concat function, the Source value that the Transfomations receive will be CANC;XXX;YYY . Then the transformations will result like this: For the first row, and the first transformation ifMatches(\u2018^(CANC|AMND);.+;\u2019) , it will be evaluated as true since the input starts with \u00b4CANC;XXX;\u00b4. The output from transformation 1 to transformation 2 , will be the same as the input one (it will be null if the input is evaluated as false). For the first row, and the second transformation removeFirst(\u2018^(CANC|AMND);\u2019) , this will remove the substring CANC; . The output from Transformation 2 to Transformation 3 will be XXX;YYY . For the first row, and the third transformation removeFirst(\u2018;.*$\u2019) , this will remove the substring that is the suffix to the first ; char, that'll be ;YYY . The output from Transformation 3 to Target (in this case Selector A) will be XXX . Note that this is the value from Selector 2 . In this case since the second row transformation doesn't match the input value, so it will produce a null value as a result, and the rest of the transformation will not be applied. Let's check another example, that matches the second row from transformation above: This case will produce null as a result for first row and will perform the transformation for the second one. Selector 1 = AAA Selector 2 = XXX Selector 3 = YYY Given those values and the Concat function, the Source value that the Transfomations receive will be AAA;XXX;YYY . Then the transformations will result like this: For the second row, and the first transformation ifNotMatches(\u2018^(CANC|AMND);.+\u2019) , it will be evaluated to true since the input starts with AAA; that doesn't match the regex expression ^(CANC|AMND);.+ . The output from Transformation 1 to Transformation 2 , will be the same as the input one. For the second row, and the second transformation removeFirst(\u2018^.+;\u2019) , this will remove the substring that is the prefix to the last ; char. The output from Transformation 2 to Target (in this case Selector A) will be YYY . Note that this is the value from Selector 3 . Please this two code examples that are equivalent to what's described above. Example 1 // IF (Selector 1 = CANC or Selector 1 = AMD) // THEN Selector 2 -> Selector A (Target) // ELSE Selector 3-> Selector B String selector1 = \"CANC\" ; String selector2 = \"CLREL\" ; String selector3 = \"ORIGREL\" ; String selectorInput = selector1 + \";\" + selector2 + \";\" + selector3 ; Transformation tNotMatching = new Transformation ( Key . ifNotMatches , \"^(CANC|AMND);.+\" ); assertNull ( tNotMatching . transform ( selectorInput )); Transformation t1 = new Transformation ( Key . ifMatches , \"^(CANC|AMND);.+;\" ); String t1Result = t1 . transform ( selectorInput ); assertEquals ( selectorInput , t1Result ); Transformation t2 = new Transformation ( Key . removeFirst , \"^(CANC|AMND);\" ); String t2Result = t2 . transform ( t1Result ); assertEquals ( \"CLREL;ORIGREL\" , t2Result ); Transformation t3 = new Transformation ( Key . removeFirst , \";.*$\" ); String t3Result = t3 . transform ( t2Result ); assertEquals ( selector2 , t3Result ); // selector2 to Selector A (Target) Example 2 // IF (Selector 1 = CANC or Selector 1 = AMD) // THEN Selector 2 -> Selector A // ELSE Selector 3-> Selector B (Target) String selector1 = \"AAA\" ; String selector2 = \"CLREL\" ; String selector3 = \"ORIGREL\" ; String selectorInput = selector1 + \";\" + selector2 + \";\" + selector3 ; Transformation tNotMatching = new Transformation ( Key . ifMatches , \"^(CANC|AMND);.+;\" ); assertNull ( tNotMatching . transform ( selectorInput )); Transformation t1 = new Transformation ( Key . ifNotMatches , \"^(CANC|AMND);.+\" ); String t1Result = t1 . transform ( selectorInput ); assertEquals ( selectorInput , t1Result ); Transformation t2 = new Transformation ( Key . removeFirst , \"^.+;\" ); String t2Result = t2 . transform ( t1Result ); assertEquals ( selector3 , t2Result ); // selector3 to Selector B (Target) Custom Transformations When the out-of-the-box transformations are not enough, custom functions can be added by implementing the Transformer interface in your own class. class CustomTransformer implements Transformer { @Override public String transform ( String src , Object [] args ) { return StringUtils . upperCase ( src ); } @Override public String getTransformerName () { return \"myTransformer\" ; } @Override public boolean isValid ( Object [] args ) { return true ; } } The example above implements a simple uppercase transformation. The transform method is where the custom manipulation is implemented, the method receives the input to transform and optionally some parameters, and returns the altered content. The getTransformerName is used to provide a unique name to the function so that it can be referenced in the mapping configuration. The isValid method is optional, to validate for example if the provided arguments are valid. If the mapping configuration is done programmatically, then the custom transformer class can be used directly in the code when the MappingRule objects are created. If the mapping configuration is externalized, for example, loaded from an Excel sheet, then the custom transformer must be registered so that the name is recognized when parsing the configuration. In order to register your custom transformer, you just need to call this anywhere in your initialization. TransformationRegistry . register ( \"myTransformer\" , new CustomTransformer ()); Then, in your mapping configuration, you can use \"myTransformer\" along any of the out-of-the-box transformations functions.","title":"Mapping Rule"},{"location":"integrator/myformat/myformat-rule/#mapping-rule","text":"A mapping rule defines how a portion of content from the source message is transformed and appended into the target message. Therefore, a conversion from a source message into a target message is composed of a list of mapping rules . The mapping rules can be defined programmatically or by providing a configuration file. The configuration file could be a simple Excel spreadsheet with the mappings. The general structure of a mapping rule contains the following elements: Source : The source is used to identify which field in the source message must be read. It is indicated as a selector expression with a syntax corresponding to the source message format. For an MT it could be a field within a sequence, for an XML it is an XPath, and for a Fixed-length it can be a field within a specific record type. Transformation : Transformations are optional and allows changing the read value before appending it into the target message. An out-of-the-box dictionary of transformation is provided. The transformations can be combined, enabling a wide range of data manipulation options. Target : The target selector is used to identify where in the target message to read and optionally transformed content will be set. Read Mode : The read mode is optional, and it is used to define how to read and process content from the source message. The supported modes are: Single : This is the default mode, it reads a single value from the source message, regardless of the content being repetitive or not. Foreach : Reads multiple repetitive values from the source content and process them in a loop. The same mapping rule is applied for each read value. The foreach can receive one or two selectors. When two selectors are received, the first one is used to compute the repetitions, while the second one is used to get the actual value for the translation. This is particularly useful when you need to get a general content from the source message and copy the same value to multiple repetitive instances in the target message. Literal : Instead of providing a content selector, this mode is used to have a fixed value directly in the rule. Literal are defined as literal(foo) and also as quoted text with just \"foo\". Concat : Receives multiple selectors, and concatenates all read content into a single value. This selector will concatenate the values of the fields indicated in the parameters. It also allows quoted literals as parameters. A typical use case is to combine values from the source message along a fixed separator. For example when reading content from an MT you can have as selector something like CONCAT(20, \"|\", 21, \"|\", 59/1) which will generate as value the concatenation of the field 20, a pipe, the field 21, another pipe and the account number from field 59. Write Mode : Finally, the write mode is optional, and it is used to define what to do when the content already exists in the target message, for example, create, overwrite or append. Create : This is the default mode. A new element or field will always be created in the target message, regardless if the element already exists. Update : Checks if the target element or field exists before creating a new one. If the element is found, its value is overwritten with the new value from the rule. If the target element does not exist, this mode is similar to Create. Append : Checks if the target element exists before creating a new one. If the element is found, its value will be kept and the new value from the rule will be appended. If the target element does not exist, this mode is similar to Create. Setup : Used in some file formats, such as fixed-length, to initialize the output like an empty template, or define configuration options for the output message (encoding, namespace, etc\u2026). There are some setup command to define also general attributes of the mapping table, such as the specific source and target format and type. This simple but flexible scheme allows almost all message conversion scenarios.","title":"Mapping Rule"},{"location":"integrator/myformat/myformat-rule/#generic-examples","text":"The following tables illustrate different combinations of parameters for a mapping rule, regardless of the message format. A complete translation between a source and a target message is done with a table containing a list of mapping rules. Example 1 - Simple Mapping Source Transformations Target Write Mode Selector 1 Selector 2 Reads the content located at Selector 1 in the source message, and writes the read value, at the position indicated by Selector 2 in the target message. A single value is read. The read value is propagated as is, without transformations. The write mode is not specified, so a new element is created in the target message. Example 2 - Transformation Source Transformations Target Write Mode Selector 1 Transformation 1 Selector 2 Reads content indicated by Selector 1 , applies a transformation Transformation 1 , and writes the manipulated content in Selector 2 in the target message. Example 3 - Multiple Transformations Source Transformations Target Write Mode Selector 1 Transformation 1, Transformation 2, Transformation 3 Selector 2 Reads content indicated by Selector 1 , applies the three transformations 1, 2, and 3, and writes the manipulated content in Selector 2 in the target message. The transformations are processed in a pipeline , where the output of one transformation becomes the input for the next transformation. Example 4 - Write Mode Source Transformations Target Write Mode Selector 1 Transformation 1 Selector 2 Append Reads content indicated by Selector 1 , applies the transformations Transformation 1, and writes the manipulated content in Selector 2 in the target message. If the element indicated by Selector 2 does not exist in the target message, it will be created. If the element exists, the processed value is appended to the existing content of the existing element. Example 5 - Literal Source Transformations Target Write Mode Literal(foo) Selector 2 In this example, instead of providing a selector for the source message, we provide a literal content \"foo\". The value \"foo\" is then written in Selector 2 in the target message. Example 6 - Multiple Sources Source Transformations Target Write Mode Concat(Selector 1, Selector 1') Selector 2 In this example, we provide two selectors for the source message. Combined with a Concat read mode. The concatenation of both read values is then passed through the translation and written in Selector 2 in the target message. Example 7 - Foreach with single selector Source Transformations Target Write Mode Foreach(Selector 1) Transformation 1 Selector 2 Reads multiple values from the source message at the location indicated by Selector 1 . Each read value is passed through Transformation 1 and written in the target message at the location indicated by Selector 2 . Example 8 - Foreach with double selector Source Transformations Target Write Mode Foreach(Selector 1, Selector 1') Transformation 1 Selector 2 Reads multiple values from the source message at the location indicated by the combination of Selector 1 (used to iterate the loop) and Selector 1' (used to get the actual value). Each read value is passed through Transformation 1 and written in the target message at the location indicated by Selector 2 . Note that when reading from Mt (ie. using MtReader) there are some scenarios where the Selector 1' is set to get values from optional fields. In this case it is possible to obtain null values as results if the Field is absent. This will result in a list of values with some null values in it. To avoid this behavior and get a list of not null values there is a special property that can be set in the MtReader that will avoid adding null values to the result list. This property is true by default. MtReader reader = new MtReader ( mt ); reader . setAllowReadManyWithValueSelectorNullItems ( false );","title":"Generic Examples"},{"location":"integrator/myformat/myformat-rule/#selectors","text":"The selectors are a key feature in a mapping rule. A selector is a plain String defining a precise element or field in a message. The selector expressions are used in a mapping rule to indicate what content from the source message is read, or where in the target message the content is going to be written. The syntax of the selector depends on the file format. Please refer to the specific section for a file format to see the grammar of the selector. We provide here a few simple examples to illustrate the versatility of the selectors and how they are used to getting content from different types of file. Format Selector Description MT E/E1/95Q selects the field 95Q in subsequence E1 within sequence E MT 59/Line[2] selects the second line of component 59, with the name & address information MX /Document/SttlmInstrDtls/DtTm selects the value of the element DtTm MX /Document/PmtDtls/SttlmAmt/@Ccy selects the value of the attribute Ccy in the element SttlmAmt XML /A/B[3]/C Selects the value of element C in the third child B in the root node A JSON X.Y[2].Z Selects the value of element Z in the second sub-element of the array Y in the element X CSV 3 Select the third column in a CSV row CSV 5[ <1='DTL'> ] Selects the fifth column from a CSV line, where column 1 contains \"DTL\" FIXED-LENGTH 3..7[ ] Selects the value in the positions 3 to 7 in the first row FIXED-LENGTH 3/5[ <1/3='DTL'> ] Selects the value in the position 3 to 7 from a line where position 1 to 3 contain the record identified by \"DTL\"","title":"Selectors"},{"location":"integrator/myformat/myformat-rule/#transformation","text":"The transformation in a mapping rule is optional. If no transformation is defined, the found source content is copied into the target message unchanged. Transformations are defined as functions, and a mapping rule can define several functions that will be applied one after the other. All parameters are String unless indicated otherwise. All functions include an implicit input parameter. This parameter will be the result of the selector in the mapping rule or the result of a previous transformation if the rule defines more than one transformation. Function names are not case-sensitive when defined in configuration files. If a transformation cannot be applied because of a wrong parameter or an unexpected input, the input content is returned unaltered. This includes content being null. A transformation or a combination of transformation which result is null will not set any content into the target message. Therefore, there is a substantial difference, for example, between striping a content to null or empty. ** Empty strings from the source selector and or as a result of transformations are propagated to the target message. Meaning null and empty have different semantics**. For example, the function upperCase takes no additional argument and will transform the Source content into upper case. But the function substring(start, end) requires two additional parameters for the start and end positions of the truncation to apply. A comprehensive list of available functions is provided in the Transformations section.","title":"Transformation"},{"location":"integrator/myformat/myformat-rule/#pipeline","text":"Transformation functions can be combined into a pipeline . Meaning, for a single rule several transformations may be defined and all of them will be called in the defined order. The input for the first transformation function will be the result of the Source selector, and thereafter the output of a transformation becomes the input for the next one. This allows complex transformation of content using a limited set of atomic operations.","title":"Pipeline"},{"location":"integrator/myformat/myformat-rule/#conditionals","text":"The mapping rules do not support conditional logic and conditional operators. However, a special semantic implemented for null values can overcome this limitation in most situations. There are two ways to produce a null value: With a selector that finds no result: if a Source selector does not produce any result applied to the source message, for example if the element is optional in the source message, then the mapping rule will be skipped. Meaning, it will not create empty content in the target message. This is useful to deal with optional content in the source message, you can just add the mapping for the optional content and if it is not present, the rule will be silently ignored. With a transformation: When the content in the source message is present, you can apply one or many transformations that in some scenarios will produce a null. In particular, you can use the stripToNull transformation. Besides the above simple approaches, there are two power functions especially suited to achieve more complex conditional logic: IfMatches and IfNotMatches . Both functions accept a regex as input and will let the content pass through if they match or not match the regex. Example 1: For example, if you want to achieve this type of simple conditional logic: IF ( Selector A = \"C\" ) THEN \"UNIT\" -> Selector B ELSE \"FAMT\" -> Selector B Where basically if the source selector has a \"C\" you will write the literal \"UNIT\" in the target, otherwise you will write \"FAMT\". The above can be resolved with the ifElse transformation like this: Source Transformations Target Selector A ifElse(\"C\", \"UNIT\", \"FAMT\") Selector B You can achieve the same with the ifMatches and ifNotMatches transformation, using two mapping rules, one to catch the IF and another to catch the ELSE: Source Transformations Target Selector A ifMatches(\"C\"); fixed(\"UNIT\") Selector B Selector A ifNotMatches(\"C\"); fixed(\"FAMT\") Selector B In the first rule when the source content is a \"C\" the IfMatches will match and thus propagate that \"C\" literal as value. Then instead of using the literal, we use a fixed transformation to write something else in the target. IN this same rule when the source content is not the \"C\" literal, the IfMatches will not match, thus it will return null and no further transformation is evaluated, and no content is written to the output. The second rule will do the opposite, it will propagate content and write the fixed value only when the input did not match. Example 2: For example, if you want to achieve this more complex type of conditional logic: IF ( Selector 1 = CANC or Selector 1 = AMD ) THEN Selector 2 -> Selector A ELSE Selector 3 -> Selector B You have three different source selectors. The \"Selector 1\" is used for the conditional logic check, then depending on that you will propagate to the output the content from two other different selectors \"Selector 2\" and \"Selector 3\" conditionally. The above is mapped like this: Source Transformations Target Concat(Selector 1, \";\", Selector 2, \";\", Selector 3) ifMatches(\u2018^(CANC|AMND);.+;\u2019), removeFirst(\u2018^(CANC|AMND);\u2019), removeFirst(\u2018;.*$\u2019) Selector A Concat(Selector 1, \";\", Selector 2, \";\", Selector 3) ifNotMatches(\u2018^(CANC|AMND);.+\u2019), removeFirst(\u2018^.+;') Selector B The source selector is a concatenation of the actual selectors, separated by a semicolon. So the source content selection will produce a semicolon separated string. Then the transformation will pass through the content of Selectors 2 or Selector 3 depending on the content of Selector 1. Then, the second rule will do the same, passing through the content of selector 3. Note that the transformation ifMatches , ifNotMatches can be replaced by ifElse when the Target selector is the same. If a different Target is going to be selected based on the input, then you need to use the ifMatches and ifNotMatches transformation. Let's check an actual example based on transformation above: Selector 1 = CANC Selector 2 = XXX Selector 3 = YYY Given those values and the Concat function, the Source value that the Transfomations receive will be CANC;XXX;YYY . Then the transformations will result like this: For the first row, and the first transformation ifMatches(\u2018^(CANC|AMND);.+;\u2019) , it will be evaluated as true since the input starts with \u00b4CANC;XXX;\u00b4. The output from transformation 1 to transformation 2 , will be the same as the input one (it will be null if the input is evaluated as false). For the first row, and the second transformation removeFirst(\u2018^(CANC|AMND);\u2019) , this will remove the substring CANC; . The output from Transformation 2 to Transformation 3 will be XXX;YYY . For the first row, and the third transformation removeFirst(\u2018;.*$\u2019) , this will remove the substring that is the suffix to the first ; char, that'll be ;YYY . The output from Transformation 3 to Target (in this case Selector A) will be XXX . Note that this is the value from Selector 2 . In this case since the second row transformation doesn't match the input value, so it will produce a null value as a result, and the rest of the transformation will not be applied. Let's check another example, that matches the second row from transformation above: This case will produce null as a result for first row and will perform the transformation for the second one. Selector 1 = AAA Selector 2 = XXX Selector 3 = YYY Given those values and the Concat function, the Source value that the Transfomations receive will be AAA;XXX;YYY . Then the transformations will result like this: For the second row, and the first transformation ifNotMatches(\u2018^(CANC|AMND);.+\u2019) , it will be evaluated to true since the input starts with AAA; that doesn't match the regex expression ^(CANC|AMND);.+ . The output from Transformation 1 to Transformation 2 , will be the same as the input one. For the second row, and the second transformation removeFirst(\u2018^.+;\u2019) , this will remove the substring that is the prefix to the last ; char. The output from Transformation 2 to Target (in this case Selector A) will be YYY . Note that this is the value from Selector 3 . Please this two code examples that are equivalent to what's described above. Example 1 // IF (Selector 1 = CANC or Selector 1 = AMD) // THEN Selector 2 -> Selector A (Target) // ELSE Selector 3-> Selector B String selector1 = \"CANC\" ; String selector2 = \"CLREL\" ; String selector3 = \"ORIGREL\" ; String selectorInput = selector1 + \";\" + selector2 + \";\" + selector3 ; Transformation tNotMatching = new Transformation ( Key . ifNotMatches , \"^(CANC|AMND);.+\" ); assertNull ( tNotMatching . transform ( selectorInput )); Transformation t1 = new Transformation ( Key . ifMatches , \"^(CANC|AMND);.+;\" ); String t1Result = t1 . transform ( selectorInput ); assertEquals ( selectorInput , t1Result ); Transformation t2 = new Transformation ( Key . removeFirst , \"^(CANC|AMND);\" ); String t2Result = t2 . transform ( t1Result ); assertEquals ( \"CLREL;ORIGREL\" , t2Result ); Transformation t3 = new Transformation ( Key . removeFirst , \";.*$\" ); String t3Result = t3 . transform ( t2Result ); assertEquals ( selector2 , t3Result ); // selector2 to Selector A (Target) Example 2 // IF (Selector 1 = CANC or Selector 1 = AMD) // THEN Selector 2 -> Selector A // ELSE Selector 3-> Selector B (Target) String selector1 = \"AAA\" ; String selector2 = \"CLREL\" ; String selector3 = \"ORIGREL\" ; String selectorInput = selector1 + \";\" + selector2 + \";\" + selector3 ; Transformation tNotMatching = new Transformation ( Key . ifMatches , \"^(CANC|AMND);.+;\" ); assertNull ( tNotMatching . transform ( selectorInput )); Transformation t1 = new Transformation ( Key . ifNotMatches , \"^(CANC|AMND);.+\" ); String t1Result = t1 . transform ( selectorInput ); assertEquals ( selectorInput , t1Result ); Transformation t2 = new Transformation ( Key . removeFirst , \"^.+;\" ); String t2Result = t2 . transform ( t1Result ); assertEquals ( selector3 , t2Result ); // selector3 to Selector B (Target)","title":"Conditionals"},{"location":"integrator/myformat/myformat-rule/#custom-transformations","text":"When the out-of-the-box transformations are not enough, custom functions can be added by implementing the Transformer interface in your own class. class CustomTransformer implements Transformer { @Override public String transform ( String src , Object [] args ) { return StringUtils . upperCase ( src ); } @Override public String getTransformerName () { return \"myTransformer\" ; } @Override public boolean isValid ( Object [] args ) { return true ; } } The example above implements a simple uppercase transformation. The transform method is where the custom manipulation is implemented, the method receives the input to transform and optionally some parameters, and returns the altered content. The getTransformerName is used to provide a unique name to the function so that it can be referenced in the mapping configuration. The isValid method is optional, to validate for example if the provided arguments are valid. If the mapping configuration is done programmatically, then the custom transformer class can be used directly in the code when the MappingRule objects are created. If the mapping configuration is externalized, for example, loaded from an Excel sheet, then the custom transformer must be registered so that the name is recognized when parsing the configuration. In order to register your custom transformer, you just need to call this anywhere in your initialization. TransformationRegistry . register ( \"myTransformer\" , new CustomTransformer ()); Then, in your mapping configuration, you can use \"myTransformer\" along any of the out-of-the-box transformations functions.","title":"Custom Transformations"},{"location":"integrator/myformat/myformat-setup-commands/","text":"Setup commands The SETUP commands are a special form of mapping rule used to provide general parameters for the translation. They use the same structure of a normal rule. But instead of defining how to map a value from the source message to the target message, they are used to provide overall configuration options to the mapping process. There are multiple SETUP commands, some are global (for any file format) and others are specific for a given file format. The most clear and simple example is the separator when creating CSV files. By default, a comma is used, but it can be changed to any other character by using a SETUP command. Below there is an example about how to use this command type: Source Transformations Target Write Mode \"\\t\" separator SETUP The Source column is used to indicate the configuration value The Target column is used to indicate the command name (configuration key) The Write Mode is used to indicate this rule is actually a SETUP instruction Other example would be to define in the externalized mapping table the file format of the source and taget message: Source Transformations Target Write Mode \"MT\" sourceFormat SETUP \"CSV\" targetFormat SETUP Most SETUP commands have an equivalent way to be defined directly in the source code, with setters for the MappingTable object, or setters in the different format Writer objects. However, the SETUP commands are the way to achieve the same in the actual mapping configuration, along the transformation rules. This is specially useful when the mapping is externalized in a spreadsheet or database, and the source code is not available. All the available setup command names, its accepted values and behavior are listed below. Some commands are global for any type of translation, while others are specific for a given file format. General setup commands sourceFormat Sets the mapping table input to the indicated format. Accepted values: [\"MX\", \"MT\", \"CSV, \"XML\", \"JSON\", \"FIXEDLEN\"] targetFormat Sets the mapping table output to the indicated format. Accepted values: [\"MX\", \"MT\", \"CSV, \"XML\", \"JSON\", \"FIXEDLEN\"] mappingName Sets the mapping table name. CSV target format specific commands addRow Allow to create a valid the empty template of your target CSV, by adding empty slots that will be set at rule processing time. This is useful when the CSV structure contains multiple lines, such as a first row for a header, multiple rows converted from repetitive elements in the source message, and a trailer row. separator The character to use as column's separator, it is comma by default . When used, this command should be placed before the addRow . smartQuotes Enable/disable smart quoting. True by default , meaning column values will be quoted only if needed, else, if false, all column values will be quoted. When disabled a row might look like '\"2023/04/05\", \"EUR\", \"102.39\"' while, if enabled, it could look like '2023/04/05, EUR, 102.39' Accepted values: [\"true\", \"false\"] smartEscapes Enable/disable smart escaping. False by default , meaning column values will not be escaped. Accepted values: [\"true\", \"false\"] fieldNames This command allows you to define aliases for the CSV columns. The accepted value is a list of labels separated by any character. You can use any separator character, such as a comma, a tab or a semicolon. For example, if you have a CSV with three columns and you want to assign the labels \"Date\" , \"Currency\" , and \"Amount\" to them, you can provide a comma-separated list like '\"Date\", \"Currency\", \"Amount\"' . Another example, let's say you have a CSV file with four columns and you want to assign the labels Name , ID , City , and Country to them. In this case, you can provide a list of these labels separated by a semicolon, such as \"Name;ID;City;Country\" . In the mapping, instead of using column numbers as selectors, these labels can be used instead. You can enable or disable this behavior by using the SETUP command addFieldNames , as described below. addFieldNames Enable/disable to include or not the column names in an output CSV header line. The utilization of this command requires the presence of the SETUP command fieldNames . If the fieldNames command is not present, then this command is bypassed. It is false by default , meaning no header row is generated in the output CSV. Accepted values: [\"true\", \"false\"] MX target format specific commands mxType Allow to indicate the specific MX type in conversions from/into MX Accepted values: [\"pacs.008.001.08\", \"camt.003.001.04\", \"sese.001.001.02\", ..., any ISO20022 valid mx type] appHdrType Allow to indicate the specific MX type in conversions into MX Accepted values: [\"LEGACY\", \"BAH_V1\", \"BAH_V2\", \"BAH_V3\"] MT target format specific commands mtType Allow to indicate the specific MT type in conversions into MT Accepted values: [\"103\", \"MT103\", \"202\", \"MT530\", ..., any valid MT type] FIXLEN target format specific commands addRow Allow to create a valid the empty template of your target fixed-length message, by adding empty slots that will be set at rule processing time. This is useful when the CSV structure contains multiple lines, such as a first row for a header, multiple rows converted from repetitive elements in the source message, and a trailer row.","title":"Setup Commands"},{"location":"integrator/myformat/myformat-setup-commands/#setup-commands","text":"The SETUP commands are a special form of mapping rule used to provide general parameters for the translation. They use the same structure of a normal rule. But instead of defining how to map a value from the source message to the target message, they are used to provide overall configuration options to the mapping process. There are multiple SETUP commands, some are global (for any file format) and others are specific for a given file format. The most clear and simple example is the separator when creating CSV files. By default, a comma is used, but it can be changed to any other character by using a SETUP command. Below there is an example about how to use this command type: Source Transformations Target Write Mode \"\\t\" separator SETUP The Source column is used to indicate the configuration value The Target column is used to indicate the command name (configuration key) The Write Mode is used to indicate this rule is actually a SETUP instruction Other example would be to define in the externalized mapping table the file format of the source and taget message: Source Transformations Target Write Mode \"MT\" sourceFormat SETUP \"CSV\" targetFormat SETUP Most SETUP commands have an equivalent way to be defined directly in the source code, with setters for the MappingTable object, or setters in the different format Writer objects. However, the SETUP commands are the way to achieve the same in the actual mapping configuration, along the transformation rules. This is specially useful when the mapping is externalized in a spreadsheet or database, and the source code is not available. All the available setup command names, its accepted values and behavior are listed below. Some commands are global for any type of translation, while others are specific for a given file format. General setup commands sourceFormat Sets the mapping table input to the indicated format. Accepted values: [\"MX\", \"MT\", \"CSV, \"XML\", \"JSON\", \"FIXEDLEN\"] targetFormat Sets the mapping table output to the indicated format. Accepted values: [\"MX\", \"MT\", \"CSV, \"XML\", \"JSON\", \"FIXEDLEN\"] mappingName Sets the mapping table name. CSV target format specific commands addRow Allow to create a valid the empty template of your target CSV, by adding empty slots that will be set at rule processing time. This is useful when the CSV structure contains multiple lines, such as a first row for a header, multiple rows converted from repetitive elements in the source message, and a trailer row. separator The character to use as column's separator, it is comma by default . When used, this command should be placed before the addRow . smartQuotes Enable/disable smart quoting. True by default , meaning column values will be quoted only if needed, else, if false, all column values will be quoted. When disabled a row might look like '\"2023/04/05\", \"EUR\", \"102.39\"' while, if enabled, it could look like '2023/04/05, EUR, 102.39' Accepted values: [\"true\", \"false\"] smartEscapes Enable/disable smart escaping. False by default , meaning column values will not be escaped. Accepted values: [\"true\", \"false\"] fieldNames This command allows you to define aliases for the CSV columns. The accepted value is a list of labels separated by any character. You can use any separator character, such as a comma, a tab or a semicolon. For example, if you have a CSV with three columns and you want to assign the labels \"Date\" , \"Currency\" , and \"Amount\" to them, you can provide a comma-separated list like '\"Date\", \"Currency\", \"Amount\"' . Another example, let's say you have a CSV file with four columns and you want to assign the labels Name , ID , City , and Country to them. In this case, you can provide a list of these labels separated by a semicolon, such as \"Name;ID;City;Country\" . In the mapping, instead of using column numbers as selectors, these labels can be used instead. You can enable or disable this behavior by using the SETUP command addFieldNames , as described below. addFieldNames Enable/disable to include or not the column names in an output CSV header line. The utilization of this command requires the presence of the SETUP command fieldNames . If the fieldNames command is not present, then this command is bypassed. It is false by default , meaning no header row is generated in the output CSV. Accepted values: [\"true\", \"false\"] MX target format specific commands mxType Allow to indicate the specific MX type in conversions from/into MX Accepted values: [\"pacs.008.001.08\", \"camt.003.001.04\", \"sese.001.001.02\", ..., any ISO20022 valid mx type] appHdrType Allow to indicate the specific MX type in conversions into MX Accepted values: [\"LEGACY\", \"BAH_V1\", \"BAH_V2\", \"BAH_V3\"] MT target format specific commands mtType Allow to indicate the specific MT type in conversions into MT Accepted values: [\"103\", \"MT103\", \"202\", \"MT530\", ..., any valid MT type] FIXLEN target format specific commands addRow Allow to create a valid the empty template of your target fixed-length message, by adding empty slots that will be set at rule processing time. This is useful when the CSV structure contains multiple lines, such as a first row for a header, multiple rows converted from repetitive elements in the source message, and a trailer row.","title":"Setup commands"},{"location":"integrator/myformat/myformat-sql-table/","text":"SQL table structure This section describe the table structure to be used when the mapping configuration is loaded dynamically from a SQL database, as an alternative to the mapping from Excel spreadsheets or the programmatic mapping. Notice this is not to load data to translate, but the mapping configuration itself. It is static information with the definitions for the translation process. The below SQL snippets can be used to create the table in different database engines. MySQL create table pw_mapping_rule ( id bigint not null auto_increment , pw_conf_name varchar ( 50 ) not null , pw_order integer not null , pw_source varchar ( 255 ) not null , pw_transformation varchar ( 255 ), pw_target varchar ( 100 ) not null , pw_mode varchar ( 20 ), primary key ( id ) ); SQLServer create table pw_mapping_rule ( id numeric ( 19 , 0 ) identity not null , pw_conf_name varchar ( 50 ) not null , pw_order int not null , pw_source varchar ( 255 ) not null , pw_transformation varchar ( 255 ), pw_target varchar ( 100 ) not null , pw_mode varchar ( 20 ), primary key ( id ) ); Oracle create table pw_mapping_rule ( id number ( 19 , 0 ) not null , pw_conf_name varchar ( 50 ) not null , pw_order number ( 10 , 0 ) not null , pw_source varchar ( 255 ) not null , pw_transformation varchar ( 255 ), pw_target varchar ( 100 ) not null , pw_mode varchar ( 20 ), primary key ( id ) ); Derby create table pw_mapping_rule ( id bigint generated by default as identity , pw_conf_name varchar ( 50 ) not null , pw_order integer not null , pw_source varchar ( 255 ) not null , pw_transformation varchar ( 255 ), pw_target varchar ( 100 ) not null , pw_mode varchar ( 20 ), primary key ( id ) ); When using Prowide Integrator to develop an external component that interacts with Prowide Enterprise, it might be a good idea to store the actual mappings in Prowide Enterprise, and access them programmatically from the external component. Since the Prowide Enterprise tables are different from the expected table for the Integrator database loader, the following VIEW can be used. By creating this VIEW in the Prowide Enterprise database, the Integrator database loader will be able to load any mapping with the default options. The two configuration tables in the Enterprise are flattened to the single table expected by the Integrator. CREATE VIEW pw_mapping_rule AS SELECT FM . id AS 'id' , FC . name AS 'pw_conf_name' , FM . order_key AS 'pw_order' , CASE WHEN FM . read_mode = 'LITERAL' THEN concat ( 'literal(' , FM . source_selector , ')' ) WHEN FM . read_mode = 'FOREACH' THEN concat ( 'foreach(' , FM . source_selector , ')' ) WHEN FM . read_mode = 'CONCAT' THEN concat ( 'concat(' , FM . source_selector , ')' ) ELSE FM . source_selector END AS 'pw_source' , FM . transformations AS 'pw_transformation' , FM . target_selector AS 'pw_target' , FM . write_mode AS 'pw_mode' FROM my_format_configuration FC INNER JOIN my_format_mapping FM ON FC . id = FM . conf_id","title":"SQL table structure"},{"location":"integrator/myformat/myformat-sql-table/#sql-table-structure","text":"This section describe the table structure to be used when the mapping configuration is loaded dynamically from a SQL database, as an alternative to the mapping from Excel spreadsheets or the programmatic mapping. Notice this is not to load data to translate, but the mapping configuration itself. It is static information with the definitions for the translation process. The below SQL snippets can be used to create the table in different database engines.","title":"SQL table structure"},{"location":"integrator/myformat/myformat-sql-table/#mysql","text":"create table pw_mapping_rule ( id bigint not null auto_increment , pw_conf_name varchar ( 50 ) not null , pw_order integer not null , pw_source varchar ( 255 ) not null , pw_transformation varchar ( 255 ), pw_target varchar ( 100 ) not null , pw_mode varchar ( 20 ), primary key ( id ) );","title":"MySQL"},{"location":"integrator/myformat/myformat-sql-table/#sqlserver","text":"create table pw_mapping_rule ( id numeric ( 19 , 0 ) identity not null , pw_conf_name varchar ( 50 ) not null , pw_order int not null , pw_source varchar ( 255 ) not null , pw_transformation varchar ( 255 ), pw_target varchar ( 100 ) not null , pw_mode varchar ( 20 ), primary key ( id ) );","title":"SQLServer"},{"location":"integrator/myformat/myformat-sql-table/#oracle","text":"create table pw_mapping_rule ( id number ( 19 , 0 ) not null , pw_conf_name varchar ( 50 ) not null , pw_order number ( 10 , 0 ) not null , pw_source varchar ( 255 ) not null , pw_transformation varchar ( 255 ), pw_target varchar ( 100 ) not null , pw_mode varchar ( 20 ), primary key ( id ) );","title":"Oracle"},{"location":"integrator/myformat/myformat-sql-table/#derby","text":"create table pw_mapping_rule ( id bigint generated by default as identity , pw_conf_name varchar ( 50 ) not null , pw_order integer not null , pw_source varchar ( 255 ) not null , pw_transformation varchar ( 255 ), pw_target varchar ( 100 ) not null , pw_mode varchar ( 20 ), primary key ( id ) ); When using Prowide Integrator to develop an external component that interacts with Prowide Enterprise, it might be a good idea to store the actual mappings in Prowide Enterprise, and access them programmatically from the external component. Since the Prowide Enterprise tables are different from the expected table for the Integrator database loader, the following VIEW can be used. By creating this VIEW in the Prowide Enterprise database, the Integrator database loader will be able to load any mapping with the default options. The two configuration tables in the Enterprise are flattened to the single table expected by the Integrator. CREATE VIEW pw_mapping_rule AS SELECT FM . id AS 'id' , FC . name AS 'pw_conf_name' , FM . order_key AS 'pw_order' , CASE WHEN FM . read_mode = 'LITERAL' THEN concat ( 'literal(' , FM . source_selector , ')' ) WHEN FM . read_mode = 'FOREACH' THEN concat ( 'foreach(' , FM . source_selector , ')' ) WHEN FM . read_mode = 'CONCAT' THEN concat ( 'concat(' , FM . source_selector , ')' ) ELSE FM . source_selector END AS 'pw_source' , FM . transformations AS 'pw_transformation' , FM . target_selector AS 'pw_target' , FM . write_mode AS 'pw_mode' FROM my_format_configuration FC INNER JOIN my_format_mapping FM ON FC . id = FM . conf_id","title":"Derby"},{"location":"integrator/myformat/myformat-transformations/","text":"Transformation functions The following table lists all available functions for the transformation in mapping rules. Text generation These are transformations that generate values rather than transform input ones. For these special cases, you'd want to use a dummy source selector (i.e. \"-\"). Text generation now() Returns the current date-time from the system clock in the local time-zone, formatted as yyyy-MM-dd'T'HH:mm:ss.SSSZ (ISO 8601) . now(utcOffset) Returns the current date-time from the system clock at the specified UTC Offset or ZoneId, formatted as yyyy-MM-dd'T'HH:mm:ss.SSSZ (ISO 8601) . uetr() Generates a new random UETR Text manipulation Text manipulation abbreviate(maxWidth) Abbreviates a String using ellipses. This will turn \"A long sentence that must be abbreviated\"\" into \"A long sentence...\". append(suffix) Appends the suffix to the end of the input. appendIfMissing(suffix) Appends the suffix to the end of the input if the input does not already end with the suffix. appendIfMissingIgnoreCase(suffix) Appends the suffix to the end of the input if the input does not already end, case-insensitive, with the suffix. capitalize() Capitalizes the input, changing the first letter to title case. No other letters are changed. chop() Remove the last character from the input. defaultString(default) If the input is null, empty or blank, returns the value indicated as default, otherwise returns the input unaltered. fixed(default) Returns the fixed value provided by the parameter, regardless of the input content. This transformation is useful to generate fixed content based on source elements being present or not. If a source selector finds content, even if the content is empty or blank, then the rule is executed, and this fixed content is added to the output message. However, if the source selector returns null, because the source content is not present, then fixed content will not be added to the output message. Notice that to force creation of fixed content regardless of an input selector, transformations are not required because plain literal values can be provided directly as source selectors. formatDateTime(sourceFormat, targetFormat) Formats a date or datetime input given its source and target formats. The format definition must be compliant to Java SimpleDateFormat. Returns the formatted date or the input unaltered if it cannot be formatted. formatMTDecimal() Formats a number in decimal notation (with dot as decimal separator) into a SWIFT MT amount. SWIFT amounts in MT messages are expressed with no thousand's separator, with mandatory comma as decimal separator and with the decimal part optional. Returns the formatted amount or input unaltered if it cannot format as decimal. formatDecimal() Formats a number into decimal notation (with dot as decimal separator and without thousands separator). Returns the formatted amount or input unaltered if it cannot format as decimal. The decimal part is always present in the result, initialized with .0 if the source number does not have decimals. This is aimed to convert MT numbers with commas as decimal separators into big decimal compatible values. So if the input has a comma, the comma is interpreted as a decimal separator and the dot (if present) will be dropped. Meaning 1.234,56 is converted into 1234.56. The transformation also handles MT numbers with missing decimal digits, such as 123, that is converted into 123.0. formatDecimal(format) Formats a number into decimal notation given the expected output format. The format definition must be compliant to Java DecimalFormat. This is similar to the formatDecimal without a parameter, in the sense that a comma in the input is parsed as a decimal separator. This transformation is useful when converting from MT amounts into big decimal compatible values. For example, if you want to have all converted numbers with at least 3 decimal digits, you would pass as parameter the format \"0.000####\". Returns the formatted amount or input unaltered if it cannot format as decimal. ifElse(regex, resultIfTrue, resultIfFalse) Checks if the input string matches the regex. If matches, the resultIfTrue is returned, else resultIfFalse. ifMatches(regex) If the input matches the regex, the input is forwarded as the transformation result. If it does not match, the transformation returns null (meaning content in the target selector will not be written). ifNotMatches(regex) If the input does not match the regex, the input is forwarded as the transformation result. If it does match, the transformation returns null (meaning content in the target selector will not be written). indexOf(searchString) Finds the first index within a String. If not found, returns null. indexOfIgnoreCase(searchString) Finds the first index within a String ignoring the case. If not found, returns null. lastIndexOf(searchString) Finds the last index within a String. If not found, returns null. lastIndexOfIgnoreCase(searchString) Finds the last index within a String ignoring the case. If not found, returns null. left(len:int) Returns the leftmost len characters of the input. leftPad(size:int) Left pad of the input with spaces (' '). leftPad(size:int, padString) Left pad of the input with a specified String. lowerCase() Converts the input to lowercase. map(key, value, key, value, ...) Replaces the input with a mapped value. The mapping tuples are passed as a simple list of parameters that will be interpreted in pairs. The number of parameters must be even. For example, the list of parameters P, PROC, F, FULL will transform an input string \"F\" into the string \"FULL\". To map simple values, check replace and replaceIfEquals . If the value is not found in the map, it is returned as is. normalizeSpace() Returns the input with whitespace normalized by using trim(String) to remove leading and trailing whitespace, and then replacing sequences of whitespace characters by a single space. prepend(prefix) Prepends the prefix to the start of the input. prependIfMissing(prefix) Prepends the prefix to the start of the input if the input does not already start with the prefix. prependIfMissingIgnoreCase(prefix) Prepends the prefix to the start of the input if the input does not already start, case-insensitive, with the prefix. remove(remove) Removes all occurrences of a substring from within the input. removeAll(regex) Removes each substring of the text String that matches the given regular expression. removeFirst(regex) Removes the first substring of the text string that matches the given regular expression. removeStart(remove) Removes a substring only if it is at the beginning of the input, otherwise returns the input unaltered. removeStartIgnoreCase(remove) Case insensitive removal of a substring if it is at the beginning of the input, otherwise returns the input unaltered. removeEnd(remove) Removes a substring only if it is at the end of the input, otherwise returns the input unaltered. removeEndIgnoreCase(remove) Case insensitive removal of a substring if it is at the end of the input, otherwise returns the input unaltered. removeWhitespace() Deletes all whitespaces from the input. replace(searchString, replacement) Replaces all occurrences of searchString within the input with the replacement. replace(searchString) Replaces all occurrences of searchString within the input with empty, therefore deleting the searchString from the input. replaceAll(regex, replacement) Replaces each substring of the text String that matches the given regular expression with the given replacement. This is similar to the replacePattern(regex, replacement) but without the DOTALL in the regex. replaceFirst(regex, replacement) Replaces the first substring of the text string that matches the given regular expression with the given replacement. replaceIfEquals(searchString, replacementIfEquals, replacementIfNotEquals) Compares the input with searchString; if equals, replacementIfEquals is returned, otherwise replacementIfNotEquals is returned. replaceOnce(searchString, replacement) Replaces the first occurrence of searchString within the input with the replacement. replaceOnce(searchString) Replaces the first occurrence of searchString within the input with an empty, therefore deleting the first occurrence of searchString from the input. replacePattern(regex, replacement) Replaces each substring of the source String that matches the given regular expression with the given replacement. This is similar to the replaceAll(regex, replacement) but using the DOTALL in the regex. right(len:int) Returns the rightmost len characters of the input. rightPad(size:int) Right pad of the input with spaces (' '). rightPad(size:int, padString) Right pad of the input with a specified String. stripToNull() Strips whitespace from the start and end of the input, returning null if the String is empty (\"\") after the strip. stripToEmpty() Strips whitespace from the start and end of the input, returning an empty String if null input. strip(stripChars) Strips any of a set of characters from the start and end of the input. Notice this removes any of the indicated characters, to strip all occurrences of a String use remove(searchString). stripStart() Strips whitespaces from the start of the input. stripStart(stripChars) Strips any of a set of characters from the start of the input. Notice this removes any of the indicated characters, to strip a complete String use removeStart(searchString). stripEnd() Strips whitespaces from the end of the input. stripEnd(stripChars) Strips any of a set of characters from the end of the input. Notice this removes any of the indicated characters, to strip a complete String use removeEnd(searchString). substring(start:int) Gets a substring of the input starting at the position indicated as start. substring(start:int, end:int) Gets a substring of the input between the indicated start and end position. substringAfter(separator) Gets the substring after the first occurrence of a separator. The separator is not returned. substringAfterLast(separator) Gets the substring after the last occurrence of a separator. The separator is not returned. substringBefore(separator) Gets the substring before the first occurrence of a separator. The separator is not returned. substringBeforeLast(separator) Gets the substring before the last occurrence of a separator. The separator is not returned. substringBetween(tag) Gets the String that is nested in between two instances of the indicated String. substringBetween(open, close) Gets the String that is nested in between two Strings. Only the first match is returned. swapCase() Swaps the case of the input, changing upper and title case to lowercase, and lowercase to uppercase. toTimeZone(dateTimeFormat, targetUtcOffset) Gets the formatted input date-time and converts it to the target UTC timezone or ZoneId toTimeZone(dateTimeFormat, sourceUtcOffset, targetUtcOffset) Gets the formatted input date-time at source UTC timezone or ZoneId, and converts it to the target UTC timezone or ZoneId unwrap(wrapToken) Unwraps a given string from the input, meaning it removes the given wrapToken from the beginning and/or ending of the input. This is the opposite operation of the wrap(wrapWith). Notice, if the input is not quoted with the wrapping token at both the beginning and end of the string, the input is returned unaltered. Meaning, wrap is removed only when present at both beginning and end of the input string. upperCase() Converts the input to uppercase. wrap(wrapWith) Wraps the input with a character or string, adding the character before and after the input. wrapLines(lineLength) Wraps a single line of text, identifying words by ' '. Long words (such as URLs) will be wrapped. wrapLinesPrepend(lineLength, prefix) Similar to wrapLines, but it will also add the given prefix at the beginning of each resulting line. The lineLength parameter should be the maximum line length including the prefix. This function is particularly useful when generating MT narrative fields where lines must be preceded by a double slash. wrapLinesPreserve(lineLength) Similar to wrapLines(lineLength) but if the input is already split into lines, the original LF are preserved while doing the wrap. If an original line contains less than the length limit, that line is copied as is to the output. Only lines exceeding the length are wrapped. wrapLinesPreservePrepend(lineLength, prefix) Similar to wrapLinesPrepend(lineLength, prefix) but if the input is already split into lines, the original LF are preserved while doing the wrap. If an original line contains less than the length limit, that line is copied as is to the output. Only lines exceeding the length are wrapped. Math Operations Math Operations add(added:int) Converts the input to an integer value and adds the parameter integer. Returns the result of the mathematical add operation, or null if the input is not an integer value. addDecimal(added:decimal) Converts the input to a decimal value and adds the parameter decimal. Returns the result of the mathematical add operation or null if the input is not a decimal value (with dot as decimal separator and no thousands separators, ex: 123.4). subtract(subtracted:int) Converts the input to an integer value and subtracts the parameter integer. Returns the result of the mathematical subtract operation, or null if the input is not an integer value. subtractDecimal(subtracted:decimal) Converts the input to a decimal value and subtracts the parameter decimal. Returns the result of the mathematical subtract operation or null if the input is not a decimal value (with dot as decimal separator and no thousands separators, ex: 123.4). divide(divisor:int) Converts the input to a decimal value and divides it to the parameter integer. Returns the result of the mathematical division operation, or null if the input is not a valid number. The result is rounded to two decimal parts. divide(divisor:int, decimals:int) Converts the input to a decimal value and divides it to the parameter decimal. Returns the result of the mathematical division operation, or null if the input is not a valid number. The result is rounded to specified decimal parts. divideDecimal(divisor:decimal) Converts the input to a decimal value and divides it to the parameter decimal. Returns the result of the mathematical division operation, or null if the input is not a valid number. The result is rounded to two decimal parts. divideDecimal(divisor:decimal, decimals:int) Converts the input to a decimal value and divides it to the parameter decimal. Returns the result of the mathematical division operation, or null if the input is not a valid number. The result is rounded to the indicated decimal parts. round(decimals:int) Converts the input to a decimal value and rounds it to the indicated decimal parts. Returns the rounded value or null if the input is not a valid number. BIC operations BIC operations bic8(address) Takes a BIC or logical terminal address and returns the BIC8 part. bic11(address) Takes a BIC or logical terminal address and returns the BIC11 part. bicBranch(address) Takes a BIC or logical terminal address and returns the branch (or XXX if branch is not defined). bicCountry(address) Takes a BIC or logical terminal address and returns the country code. bicInstitution(address) Takes a BIC or logical terminal address and returns the institution part (first 4 characters). Custom Additional functions are added to the module on a regular basis and distributed with the product within maintenance updates. You can also add your own transformation functions in a regular Java class by implementing the Transformer interface. Fixed-Length For translation from or to fixed-length files, some special transformation functions are provided: filler, fromPIC, toPIC. Fixed-Length operations filler(format \u2026 ) This transformation takes multiple PIC formats as input and generates a single output value that complies with the PIC formats. For example: filler(\"HDR\", \"X(4)\", \"9(8)\") will generate the string \"HDR 00000000\" where the input will be ignored. It is especially suited to initialize records in a target fixed-length file. fromPIC(format) This transformation reads the input string according to the received PIC format. It is especially suited to read content from a fixed-length file. For example, fromPIC(\"9(6)V99\") applied to the value \"00123456\" will return \"1234.56\". toPIC(format) This transformation takes the input string and processes it to generate a string compliant with the parameter PIC format. It is especially suited to write content in a fixed-length file. For example: toPIC(\"9(6)V99\") applied to the value \"1234.56\" will return \"00123456\". These functions are a subset of the legacy COBOL PIC Formats (PICTURE clause). This transformation is especially suited to convert to/from fixed length strings to normal strings, but could be helpful for other message formats. A few letters are reserved values for PIC formats (described in the following table). Any other character will be considered to appear as is in the input/output string. Letter Description X Indicates any character can be present (see the section on Character Set, below). A Same as A. While in COBOL these codes have different usage, in our implementation they are the same. 9 Indicates a decimal digit can be present. V Indicates an implied virtual decimal separator. It is common in Fixed Len formats to store digits without the decimal separator (ex: 123.45 can be stored as 012345 using a PIC of 9999V99, note how an extra leading zero is added). . (decimal dot) Indicates a dot as decimal separator. It is rarely used in Fixed Len formats (usually, the V is used). , (comma) Indicates a comma as decimal separator. It is rarely used in Fixed Len formats (usually, the V is used) S Indicates a sign for a numeric value. It can be in the front or in the back of the value (ex: S9999 or 9999S). When used, a \"+\" or \" \" implies positive, a \"-\" implies negative Z Indicates left padding blanks * Indicates the asterisk character is used for left padding Only the characters \"9\", \"X\" and \"A\" can be repeated. Whenever repetitions are needed, they can be replaced with a reduced version, by putting the number of repetitions between parentheses. Example \"99\" can be indicated as \"9(2)\", \" 999999V99\" can be indicated as \"9(6)V99\" and \"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\" can be indicated as \"X(40)\". When these reserved characters (A, X, Z, etc\u2026) are used in the PIC definition, they must be escaped with a backward slash. Some examples of different PICs are: Source PIC Format Description Result \"12345.67\" 9(6)V99 Number with implied decimal point \"01234567\" \"2125553344\" 999.999.9999 Telephone number with dots between components \"212.555.3344\" \"20180415\" 9999-99-99 A date \"2018-04-15\" \"C1234AAB\" \"X 9999 XXX\" An Argentinian Postal Code \"C 1234 AAB\" \"0876543210-\" \"9(7)V999S\" A negative number with 3 decimals (note the leading and trailing zeros are removed) \"-876543.21\" \"1234567\" \"S9(9)\" A signed 9 digits integer \"+001234567\" \"-12.34\" \"9(6)V99S\" A signed 8 digits number, with sign as suffix and decimal separator \"00001234-\" \"12345.6\" \"ZZ9(5).9\" A number with decimal separator a left padded with blank \" 12345.6\" \"20190506170339\" \"9999-99-99T99:99:99\" A formatted date and time \"2019-05-06T17:03:39\" fromPIC This transformation takes the input string and processes it according to the received PIC format (see below), returning a new string. Examples: Transformation Input Output fromPIC(\"9(6)V99\") \"00123456\" \"1234.56\" fromPIC(\"9(3).99S\") \"000.01-\" \"-0.01\" fromPIC(\"S9(3).99\") \"+765.43\" \"765.43\" fromPIC(\"S9(3).99\") \" 765.43\" \"765.43\" fromPIC(\"X(10)\") \"Test! \" \"Test!\" toPIC This transformation takes the input string and processes it to generate a string compliant with the received PIC format (see below), returning a new string. Examples: Transformation Input Output toPIC(\"9(6)V99\") \"1234.56\" \"00123456\" toPIC(\"9(3).99S\") \"-0.01\" \"000.01-\" toPIC(\"S9(3).99\") \"+765.43\" \"+765.43\" toPIC(\"S9(3).99\") \"765.43\" \"+765.43\" toPIC(\"X(10)\") \"Test!\" \"Test! \"","title":"Transformations"},{"location":"integrator/myformat/myformat-transformations/#transformation-functions","text":"The following table lists all available functions for the transformation in mapping rules.","title":"Transformation functions"},{"location":"integrator/myformat/myformat-transformations/#text-generation","text":"These are transformations that generate values rather than transform input ones. For these special cases, you'd want to use a dummy source selector (i.e. \"-\"). Text generation now() Returns the current date-time from the system clock in the local time-zone, formatted as yyyy-MM-dd'T'HH:mm:ss.SSSZ (ISO 8601) . now(utcOffset) Returns the current date-time from the system clock at the specified UTC Offset or ZoneId, formatted as yyyy-MM-dd'T'HH:mm:ss.SSSZ (ISO 8601) . uetr() Generates a new random UETR","title":"Text generation"},{"location":"integrator/myformat/myformat-transformations/#text-manipulation","text":"Text manipulation abbreviate(maxWidth) Abbreviates a String using ellipses. This will turn \"A long sentence that must be abbreviated\"\" into \"A long sentence...\". append(suffix) Appends the suffix to the end of the input. appendIfMissing(suffix) Appends the suffix to the end of the input if the input does not already end with the suffix. appendIfMissingIgnoreCase(suffix) Appends the suffix to the end of the input if the input does not already end, case-insensitive, with the suffix. capitalize() Capitalizes the input, changing the first letter to title case. No other letters are changed. chop() Remove the last character from the input. defaultString(default) If the input is null, empty or blank, returns the value indicated as default, otherwise returns the input unaltered. fixed(default) Returns the fixed value provided by the parameter, regardless of the input content. This transformation is useful to generate fixed content based on source elements being present or not. If a source selector finds content, even if the content is empty or blank, then the rule is executed, and this fixed content is added to the output message. However, if the source selector returns null, because the source content is not present, then fixed content will not be added to the output message. Notice that to force creation of fixed content regardless of an input selector, transformations are not required because plain literal values can be provided directly as source selectors. formatDateTime(sourceFormat, targetFormat) Formats a date or datetime input given its source and target formats. The format definition must be compliant to Java SimpleDateFormat. Returns the formatted date or the input unaltered if it cannot be formatted. formatMTDecimal() Formats a number in decimal notation (with dot as decimal separator) into a SWIFT MT amount. SWIFT amounts in MT messages are expressed with no thousand's separator, with mandatory comma as decimal separator and with the decimal part optional. Returns the formatted amount or input unaltered if it cannot format as decimal. formatDecimal() Formats a number into decimal notation (with dot as decimal separator and without thousands separator). Returns the formatted amount or input unaltered if it cannot format as decimal. The decimal part is always present in the result, initialized with .0 if the source number does not have decimals. This is aimed to convert MT numbers with commas as decimal separators into big decimal compatible values. So if the input has a comma, the comma is interpreted as a decimal separator and the dot (if present) will be dropped. Meaning 1.234,56 is converted into 1234.56. The transformation also handles MT numbers with missing decimal digits, such as 123, that is converted into 123.0. formatDecimal(format) Formats a number into decimal notation given the expected output format. The format definition must be compliant to Java DecimalFormat. This is similar to the formatDecimal without a parameter, in the sense that a comma in the input is parsed as a decimal separator. This transformation is useful when converting from MT amounts into big decimal compatible values. For example, if you want to have all converted numbers with at least 3 decimal digits, you would pass as parameter the format \"0.000####\". Returns the formatted amount or input unaltered if it cannot format as decimal. ifElse(regex, resultIfTrue, resultIfFalse) Checks if the input string matches the regex. If matches, the resultIfTrue is returned, else resultIfFalse. ifMatches(regex) If the input matches the regex, the input is forwarded as the transformation result. If it does not match, the transformation returns null (meaning content in the target selector will not be written). ifNotMatches(regex) If the input does not match the regex, the input is forwarded as the transformation result. If it does match, the transformation returns null (meaning content in the target selector will not be written). indexOf(searchString) Finds the first index within a String. If not found, returns null. indexOfIgnoreCase(searchString) Finds the first index within a String ignoring the case. If not found, returns null. lastIndexOf(searchString) Finds the last index within a String. If not found, returns null. lastIndexOfIgnoreCase(searchString) Finds the last index within a String ignoring the case. If not found, returns null. left(len:int) Returns the leftmost len characters of the input. leftPad(size:int) Left pad of the input with spaces (' '). leftPad(size:int, padString) Left pad of the input with a specified String. lowerCase() Converts the input to lowercase. map(key, value, key, value, ...) Replaces the input with a mapped value. The mapping tuples are passed as a simple list of parameters that will be interpreted in pairs. The number of parameters must be even. For example, the list of parameters P, PROC, F, FULL will transform an input string \"F\" into the string \"FULL\". To map simple values, check replace and replaceIfEquals . If the value is not found in the map, it is returned as is. normalizeSpace() Returns the input with whitespace normalized by using trim(String) to remove leading and trailing whitespace, and then replacing sequences of whitespace characters by a single space. prepend(prefix) Prepends the prefix to the start of the input. prependIfMissing(prefix) Prepends the prefix to the start of the input if the input does not already start with the prefix. prependIfMissingIgnoreCase(prefix) Prepends the prefix to the start of the input if the input does not already start, case-insensitive, with the prefix. remove(remove) Removes all occurrences of a substring from within the input. removeAll(regex) Removes each substring of the text String that matches the given regular expression. removeFirst(regex) Removes the first substring of the text string that matches the given regular expression. removeStart(remove) Removes a substring only if it is at the beginning of the input, otherwise returns the input unaltered. removeStartIgnoreCase(remove) Case insensitive removal of a substring if it is at the beginning of the input, otherwise returns the input unaltered. removeEnd(remove) Removes a substring only if it is at the end of the input, otherwise returns the input unaltered. removeEndIgnoreCase(remove) Case insensitive removal of a substring if it is at the end of the input, otherwise returns the input unaltered. removeWhitespace() Deletes all whitespaces from the input. replace(searchString, replacement) Replaces all occurrences of searchString within the input with the replacement. replace(searchString) Replaces all occurrences of searchString within the input with empty, therefore deleting the searchString from the input. replaceAll(regex, replacement) Replaces each substring of the text String that matches the given regular expression with the given replacement. This is similar to the replacePattern(regex, replacement) but without the DOTALL in the regex. replaceFirst(regex, replacement) Replaces the first substring of the text string that matches the given regular expression with the given replacement. replaceIfEquals(searchString, replacementIfEquals, replacementIfNotEquals) Compares the input with searchString; if equals, replacementIfEquals is returned, otherwise replacementIfNotEquals is returned. replaceOnce(searchString, replacement) Replaces the first occurrence of searchString within the input with the replacement. replaceOnce(searchString) Replaces the first occurrence of searchString within the input with an empty, therefore deleting the first occurrence of searchString from the input. replacePattern(regex, replacement) Replaces each substring of the source String that matches the given regular expression with the given replacement. This is similar to the replaceAll(regex, replacement) but using the DOTALL in the regex. right(len:int) Returns the rightmost len characters of the input. rightPad(size:int) Right pad of the input with spaces (' '). rightPad(size:int, padString) Right pad of the input with a specified String. stripToNull() Strips whitespace from the start and end of the input, returning null if the String is empty (\"\") after the strip. stripToEmpty() Strips whitespace from the start and end of the input, returning an empty String if null input. strip(stripChars) Strips any of a set of characters from the start and end of the input. Notice this removes any of the indicated characters, to strip all occurrences of a String use remove(searchString). stripStart() Strips whitespaces from the start of the input. stripStart(stripChars) Strips any of a set of characters from the start of the input. Notice this removes any of the indicated characters, to strip a complete String use removeStart(searchString). stripEnd() Strips whitespaces from the end of the input. stripEnd(stripChars) Strips any of a set of characters from the end of the input. Notice this removes any of the indicated characters, to strip a complete String use removeEnd(searchString). substring(start:int) Gets a substring of the input starting at the position indicated as start. substring(start:int, end:int) Gets a substring of the input between the indicated start and end position. substringAfter(separator) Gets the substring after the first occurrence of a separator. The separator is not returned. substringAfterLast(separator) Gets the substring after the last occurrence of a separator. The separator is not returned. substringBefore(separator) Gets the substring before the first occurrence of a separator. The separator is not returned. substringBeforeLast(separator) Gets the substring before the last occurrence of a separator. The separator is not returned. substringBetween(tag) Gets the String that is nested in between two instances of the indicated String. substringBetween(open, close) Gets the String that is nested in between two Strings. Only the first match is returned. swapCase() Swaps the case of the input, changing upper and title case to lowercase, and lowercase to uppercase. toTimeZone(dateTimeFormat, targetUtcOffset) Gets the formatted input date-time and converts it to the target UTC timezone or ZoneId toTimeZone(dateTimeFormat, sourceUtcOffset, targetUtcOffset) Gets the formatted input date-time at source UTC timezone or ZoneId, and converts it to the target UTC timezone or ZoneId unwrap(wrapToken) Unwraps a given string from the input, meaning it removes the given wrapToken from the beginning and/or ending of the input. This is the opposite operation of the wrap(wrapWith). Notice, if the input is not quoted with the wrapping token at both the beginning and end of the string, the input is returned unaltered. Meaning, wrap is removed only when present at both beginning and end of the input string. upperCase() Converts the input to uppercase. wrap(wrapWith) Wraps the input with a character or string, adding the character before and after the input. wrapLines(lineLength) Wraps a single line of text, identifying words by ' '. Long words (such as URLs) will be wrapped. wrapLinesPrepend(lineLength, prefix) Similar to wrapLines, but it will also add the given prefix at the beginning of each resulting line. The lineLength parameter should be the maximum line length including the prefix. This function is particularly useful when generating MT narrative fields where lines must be preceded by a double slash. wrapLinesPreserve(lineLength) Similar to wrapLines(lineLength) but if the input is already split into lines, the original LF are preserved while doing the wrap. If an original line contains less than the length limit, that line is copied as is to the output. Only lines exceeding the length are wrapped. wrapLinesPreservePrepend(lineLength, prefix) Similar to wrapLinesPrepend(lineLength, prefix) but if the input is already split into lines, the original LF are preserved while doing the wrap. If an original line contains less than the length limit, that line is copied as is to the output. Only lines exceeding the length are wrapped.","title":"Text manipulation"},{"location":"integrator/myformat/myformat-transformations/#math-operations","text":"Math Operations add(added:int) Converts the input to an integer value and adds the parameter integer. Returns the result of the mathematical add operation, or null if the input is not an integer value. addDecimal(added:decimal) Converts the input to a decimal value and adds the parameter decimal. Returns the result of the mathematical add operation or null if the input is not a decimal value (with dot as decimal separator and no thousands separators, ex: 123.4). subtract(subtracted:int) Converts the input to an integer value and subtracts the parameter integer. Returns the result of the mathematical subtract operation, or null if the input is not an integer value. subtractDecimal(subtracted:decimal) Converts the input to a decimal value and subtracts the parameter decimal. Returns the result of the mathematical subtract operation or null if the input is not a decimal value (with dot as decimal separator and no thousands separators, ex: 123.4). divide(divisor:int) Converts the input to a decimal value and divides it to the parameter integer. Returns the result of the mathematical division operation, or null if the input is not a valid number. The result is rounded to two decimal parts. divide(divisor:int, decimals:int) Converts the input to a decimal value and divides it to the parameter decimal. Returns the result of the mathematical division operation, or null if the input is not a valid number. The result is rounded to specified decimal parts. divideDecimal(divisor:decimal) Converts the input to a decimal value and divides it to the parameter decimal. Returns the result of the mathematical division operation, or null if the input is not a valid number. The result is rounded to two decimal parts. divideDecimal(divisor:decimal, decimals:int) Converts the input to a decimal value and divides it to the parameter decimal. Returns the result of the mathematical division operation, or null if the input is not a valid number. The result is rounded to the indicated decimal parts. round(decimals:int) Converts the input to a decimal value and rounds it to the indicated decimal parts. Returns the rounded value or null if the input is not a valid number.","title":"Math Operations"},{"location":"integrator/myformat/myformat-transformations/#bic-operations","text":"BIC operations bic8(address) Takes a BIC or logical terminal address and returns the BIC8 part. bic11(address) Takes a BIC or logical terminal address and returns the BIC11 part. bicBranch(address) Takes a BIC or logical terminal address and returns the branch (or XXX if branch is not defined). bicCountry(address) Takes a BIC or logical terminal address and returns the country code. bicInstitution(address) Takes a BIC or logical terminal address and returns the institution part (first 4 characters).","title":"BIC operations"},{"location":"integrator/myformat/myformat-transformations/#custom","text":"Additional functions are added to the module on a regular basis and distributed with the product within maintenance updates. You can also add your own transformation functions in a regular Java class by implementing the Transformer interface.","title":"Custom"},{"location":"integrator/myformat/myformat-transformations/#fixed-length","text":"For translation from or to fixed-length files, some special transformation functions are provided: filler, fromPIC, toPIC. Fixed-Length operations filler(format \u2026 ) This transformation takes multiple PIC formats as input and generates a single output value that complies with the PIC formats. For example: filler(\"HDR\", \"X(4)\", \"9(8)\") will generate the string \"HDR 00000000\" where the input will be ignored. It is especially suited to initialize records in a target fixed-length file. fromPIC(format) This transformation reads the input string according to the received PIC format. It is especially suited to read content from a fixed-length file. For example, fromPIC(\"9(6)V99\") applied to the value \"00123456\" will return \"1234.56\". toPIC(format) This transformation takes the input string and processes it to generate a string compliant with the parameter PIC format. It is especially suited to write content in a fixed-length file. For example: toPIC(\"9(6)V99\") applied to the value \"1234.56\" will return \"00123456\". These functions are a subset of the legacy COBOL PIC Formats (PICTURE clause). This transformation is especially suited to convert to/from fixed length strings to normal strings, but could be helpful for other message formats. A few letters are reserved values for PIC formats (described in the following table). Any other character will be considered to appear as is in the input/output string. Letter Description X Indicates any character can be present (see the section on Character Set, below). A Same as A. While in COBOL these codes have different usage, in our implementation they are the same. 9 Indicates a decimal digit can be present. V Indicates an implied virtual decimal separator. It is common in Fixed Len formats to store digits without the decimal separator (ex: 123.45 can be stored as 012345 using a PIC of 9999V99, note how an extra leading zero is added). . (decimal dot) Indicates a dot as decimal separator. It is rarely used in Fixed Len formats (usually, the V is used). , (comma) Indicates a comma as decimal separator. It is rarely used in Fixed Len formats (usually, the V is used) S Indicates a sign for a numeric value. It can be in the front or in the back of the value (ex: S9999 or 9999S). When used, a \"+\" or \" \" implies positive, a \"-\" implies negative Z Indicates left padding blanks * Indicates the asterisk character is used for left padding Only the characters \"9\", \"X\" and \"A\" can be repeated. Whenever repetitions are needed, they can be replaced with a reduced version, by putting the number of repetitions between parentheses. Example \"99\" can be indicated as \"9(2)\", \" 999999V99\" can be indicated as \"9(6)V99\" and \"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\" can be indicated as \"X(40)\". When these reserved characters (A, X, Z, etc\u2026) are used in the PIC definition, they must be escaped with a backward slash. Some examples of different PICs are: Source PIC Format Description Result \"12345.67\" 9(6)V99 Number with implied decimal point \"01234567\" \"2125553344\" 999.999.9999 Telephone number with dots between components \"212.555.3344\" \"20180415\" 9999-99-99 A date \"2018-04-15\" \"C1234AAB\" \"X 9999 XXX\" An Argentinian Postal Code \"C 1234 AAB\" \"0876543210-\" \"9(7)V999S\" A negative number with 3 decimals (note the leading and trailing zeros are removed) \"-876543.21\" \"1234567\" \"S9(9)\" A signed 9 digits integer \"+001234567\" \"-12.34\" \"9(6)V99S\" A signed 8 digits number, with sign as suffix and decimal separator \"00001234-\" \"12345.6\" \"ZZ9(5).9\" A number with decimal separator a left padded with blank \" 12345.6\" \"20190506170339\" \"9999-99-99T99:99:99\" A formatted date and time \"2019-05-06T17:03:39\"","title":"Fixed-Length"},{"location":"integrator/myformat/myformat-transformations/#frompic","text":"This transformation takes the input string and processes it according to the received PIC format (see below), returning a new string. Examples: Transformation Input Output fromPIC(\"9(6)V99\") \"00123456\" \"1234.56\" fromPIC(\"9(3).99S\") \"000.01-\" \"-0.01\" fromPIC(\"S9(3).99\") \"+765.43\" \"765.43\" fromPIC(\"S9(3).99\") \" 765.43\" \"765.43\" fromPIC(\"X(10)\") \"Test! \" \"Test!\"","title":"fromPIC"},{"location":"integrator/myformat/myformat-transformations/#topic","text":"This transformation takes the input string and processes it to generate a string compliant with the received PIC format (see below), returning a new string. Examples: Transformation Input Output toPIC(\"9(6)V99\") \"1234.56\" \"00123456\" toPIC(\"9(3).99S\") \"-0.01\" \"000.01-\" toPIC(\"S9(3).99\") \"+765.43\" \"+765.43\" toPIC(\"S9(3).99\") \"765.43\" \"+765.43\" toPIC(\"X(10)\") \"Test!\" \"Test! \"","title":"toPIC"},{"location":"integrator/myformat/myformat-xml/","text":"Format > XML and MX XML files can be used as source or target for a translation. Translations for XML and MX (ISO 20022) share a similar implementation and thus offer similar features. The main difference is that for XML the structure can be anything, while for MX the XML structure must be compliant with the specific MX message type. XML Selector If the message is an XML (including MX messages), the selector uses XPath expressions. All the common syntax for XPath expressions can be used, including simple predicates and attributes in the elements. The paths must always be absolute, though. For example: /Document/SttlmInstrDtls/SttlmDtTm/DtTm selects the value of the element DtTm /Document/PmtDtls/SttlmAmt/@Ccy selects the value of the attribute Ccy in the element SttlmAmt /Document/PmtDtls/Debtor/PstlAddr/AddrLine[1] selects the value of the first occurrence of element AddrLine within PstlAddr /Document/PmtDtls/Debtor/PstlAddr/AddrLine[3] selects the value of the third occurrence of element AddrLine within PstlAddr When the source message in the translation is an XML or MX message, the selector indicates which element text or attribute must be read. For example, a rule having /Document/PmtDtls/SttlmAmt/@Ccy in the source selector will get the value of the currency attribute, and pass that as content for the translation. Analogously, when the target message in the translation is an XML o MX, the selector indicates what element or attribute must be written in the target message. For exampl,e a target selector having /Document/SttlmInstrDtls/SttlmDtTm/DtTm will take the translation content and create in the target XML an element DtTm. All elements in the path parent structure will be created automatically. Predicates The XPath supports predicates to indicate repetition indexes. The predicates can be in any segment of the path. For example, /Document/CstmrCdtTrfInitn/PmtInf[2]/CdtTrfTxInf[3]/CdtrAgt selects the CdtrAgt element in the third repetition of CdtTrfTxInf within the second repetition of PmtInf . In the above examples, all predicates have numbers, meaning they reference a specific instance of the repetitive elements. When the selector is used in rule processing multiple elements, the number can be replaced by a variable name. For example the source selector /Document/CstmrCdtTrfInitn/PmtInf[{m}]/CdtTrfTxInf[{n}]/CdtrAgt will read all instances of the element CdtrAgt , and will propagate a variable named m with the repetition index of PmtInf and a variable n with the repetition of CdtTrfTxInf . Repetition in a foreach is 1 based, meaning the first read PmtInf will have n=1 . These repetition variables can then be used in the target selector, to map each repetitive 22F to a specific repetitive element in the target message. Prefilled target message When translating into XML or MX, sometimes it is necessary to apply a translation into existing content. This can be accomplished easily, passing your own instances of the reader and writer to the engine. // Mapping definition MappingTable t = new MappingTable ( FileFormat . MT , FileFormat . MX ); rules . add ( new MappingRule ( \"/Document/Foo/Amount\" , \"/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/Amt/EqvtAmt/Amt\" , WriteMode . CREATE )); // existing MX message MxPain00100103 mx = new MxPain00100103 (); mx . setBusinessHeader ( new BusinessHeader ()); mx . getBusinessHeader (). setBusinessApplicationHeader ( new BusinessApplicationHeaderV01 ()); mx . getBusinessHeader (). getBusinessApplicationHeader (). setBizMsgIdr ( \"1234\" ); mx . setCstmrCdtTrfInitn ( new CustomerCreditTransferInitiationV03 ()); mx . getCstmrCdtTrfInitn (). setGrpHdr ( new GroupHeader32 ()); mx . getCstmrCdtTrfInitn (). getGrpHdr (). setMsgId ( \"5678\" ); // writer initialized with the MX message MxWriter preFilledWriter = new MxWriter ( mx ); // sample source message MT103 mt = new MT103 (); mt . append ( new Field20 ( \"XXX\" )); mt . append ( new Field32A ( \"151019USD1234,5\" )); MtReader mtReader = new MtReader ( mt ); // translation call passing a pre-filled MX writer instance MyFormatEngine . translate ( mtReader , preFilledWriter , t . rules ); MX to MX case When translating from MX to MX, the source and target messages must be of the same message type. Then the mxType for output message and path validation should be setup like below: MappingTable t = new MappingTable ( FileFormat . MX , FileFormat . MX ); t . add ( new MappingRule ( MxTypePacs . pacs_008_001_08 . mxId (). id (), SetupCommand . mxType . name (), WriteMode . SETUP )); t . add ( new MappingRule ( \"/Document/CstmrCdtTrfInitn/GrpHdr/MsgId\" , \"/Document/FIToFICstmrCdtTrf/GrpHdr/MsgId\" )); t . add ( new MappingRule ( \"FOREACH(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf, ../DbtrAcct/Id/IBAN)\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf[1]/PmtId/TxId\" , WriteMode . APPEND )); RulePathValidator rulePathValidator = new RulePathValidator () . withSourceSchemaProvider ( MxTypePain . pain_001_001_03 ) . withTargetSchemaProvider ( MxTypePacs . pacs_008_001_08 ); List < String > validate = MappingValidator . validate ( t . getRules (), t , rulePathValidator );","title":"Format > XML and MX"},{"location":"integrator/myformat/myformat-xml/#format-xml-and-mx","text":"XML files can be used as source or target for a translation. Translations for XML and MX (ISO 20022) share a similar implementation and thus offer similar features. The main difference is that for XML the structure can be anything, while for MX the XML structure must be compliant with the specific MX message type.","title":"Format > XML and MX"},{"location":"integrator/myformat/myformat-xml/#xml-selector","text":"If the message is an XML (including MX messages), the selector uses XPath expressions. All the common syntax for XPath expressions can be used, including simple predicates and attributes in the elements. The paths must always be absolute, though. For example: /Document/SttlmInstrDtls/SttlmDtTm/DtTm selects the value of the element DtTm /Document/PmtDtls/SttlmAmt/@Ccy selects the value of the attribute Ccy in the element SttlmAmt /Document/PmtDtls/Debtor/PstlAddr/AddrLine[1] selects the value of the first occurrence of element AddrLine within PstlAddr /Document/PmtDtls/Debtor/PstlAddr/AddrLine[3] selects the value of the third occurrence of element AddrLine within PstlAddr When the source message in the translation is an XML or MX message, the selector indicates which element text or attribute must be read. For example, a rule having /Document/PmtDtls/SttlmAmt/@Ccy in the source selector will get the value of the currency attribute, and pass that as content for the translation. Analogously, when the target message in the translation is an XML o MX, the selector indicates what element or attribute must be written in the target message. For exampl,e a target selector having /Document/SttlmInstrDtls/SttlmDtTm/DtTm will take the translation content and create in the target XML an element DtTm. All elements in the path parent structure will be created automatically.","title":"XML Selector"},{"location":"integrator/myformat/myformat-xml/#predicates","text":"The XPath supports predicates to indicate repetition indexes. The predicates can be in any segment of the path. For example, /Document/CstmrCdtTrfInitn/PmtInf[2]/CdtTrfTxInf[3]/CdtrAgt selects the CdtrAgt element in the third repetition of CdtTrfTxInf within the second repetition of PmtInf . In the above examples, all predicates have numbers, meaning they reference a specific instance of the repetitive elements. When the selector is used in rule processing multiple elements, the number can be replaced by a variable name. For example the source selector /Document/CstmrCdtTrfInitn/PmtInf[{m}]/CdtTrfTxInf[{n}]/CdtrAgt will read all instances of the element CdtrAgt , and will propagate a variable named m with the repetition index of PmtInf and a variable n with the repetition of CdtTrfTxInf . Repetition in a foreach is 1 based, meaning the first read PmtInf will have n=1 . These repetition variables can then be used in the target selector, to map each repetitive 22F to a specific repetitive element in the target message.","title":"Predicates"},{"location":"integrator/myformat/myformat-xml/#prefilled-target-message","text":"When translating into XML or MX, sometimes it is necessary to apply a translation into existing content. This can be accomplished easily, passing your own instances of the reader and writer to the engine. // Mapping definition MappingTable t = new MappingTable ( FileFormat . MT , FileFormat . MX ); rules . add ( new MappingRule ( \"/Document/Foo/Amount\" , \"/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/Amt/EqvtAmt/Amt\" , WriteMode . CREATE )); // existing MX message MxPain00100103 mx = new MxPain00100103 (); mx . setBusinessHeader ( new BusinessHeader ()); mx . getBusinessHeader (). setBusinessApplicationHeader ( new BusinessApplicationHeaderV01 ()); mx . getBusinessHeader (). getBusinessApplicationHeader (). setBizMsgIdr ( \"1234\" ); mx . setCstmrCdtTrfInitn ( new CustomerCreditTransferInitiationV03 ()); mx . getCstmrCdtTrfInitn (). setGrpHdr ( new GroupHeader32 ()); mx . getCstmrCdtTrfInitn (). getGrpHdr (). setMsgId ( \"5678\" ); // writer initialized with the MX message MxWriter preFilledWriter = new MxWriter ( mx ); // sample source message MT103 mt = new MT103 (); mt . append ( new Field20 ( \"XXX\" )); mt . append ( new Field32A ( \"151019USD1234,5\" )); MtReader mtReader = new MtReader ( mt ); // translation call passing a pre-filled MX writer instance MyFormatEngine . translate ( mtReader , preFilledWriter , t . rules );","title":"Prefilled target message"},{"location":"integrator/myformat/myformat-xml/#mx-to-mx-case","text":"When translating from MX to MX, the source and target messages must be of the same message type. Then the mxType for output message and path validation should be setup like below: MappingTable t = new MappingTable ( FileFormat . MX , FileFormat . MX ); t . add ( new MappingRule ( MxTypePacs . pacs_008_001_08 . mxId (). id (), SetupCommand . mxType . name (), WriteMode . SETUP )); t . add ( new MappingRule ( \"/Document/CstmrCdtTrfInitn/GrpHdr/MsgId\" , \"/Document/FIToFICstmrCdtTrf/GrpHdr/MsgId\" )); t . add ( new MappingRule ( \"FOREACH(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf, ../DbtrAcct/Id/IBAN)\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf[1]/PmtId/TxId\" , WriteMode . APPEND )); RulePathValidator rulePathValidator = new RulePathValidator () . withSourceSchemaProvider ( MxTypePain . pain_001_001_03 ) . withTargetSchemaProvider ( MxTypePacs . pacs_008_001_08 ); List < String > validate = MappingValidator . validate ( t . getRules (), t , rulePathValidator );","title":"MX to MX case"},{"location":"integrator/sdk/","text":"Prowide Integrator SDK - Overview The Prowide Integrator SDK is the cornerstone library for the Prowide Integrator suite. It provides a set of handy APIs to handle MT messages and interact with SWIFT networks and services, such as SWIFT Alliance Access (SAA). The key features provided by the SDK are: API to create and parse the DataPDU (SAA XML v2 message envelope) LAU signing and verification for SAA integration Multipurpose BIC Dictionary Customizable TXT and HTML expanded printout for MT messages MtPath to simplify content selection in MT (FIN) messages Javadoc Online javadoc Prowide Integrator SDK Javadoc SRU2023-9.4.x","title":"Prowide Integrator SDK - Overview"},{"location":"integrator/sdk/#prowide-integrator-sdk-overview","text":"The Prowide Integrator SDK is the cornerstone library for the Prowide Integrator suite. It provides a set of handy APIs to handle MT messages and interact with SWIFT networks and services, such as SWIFT Alliance Access (SAA). The key features provided by the SDK are: API to create and parse the DataPDU (SAA XML v2 message envelope) LAU signing and verification for SAA integration Multipurpose BIC Dictionary Customizable TXT and HTML expanded printout for MT messages MtPath to simplify content selection in MT (FIN) messages","title":"Prowide Integrator SDK - Overview"},{"location":"integrator/sdk/#javadoc","text":"Online javadoc Prowide Integrator SDK Javadoc SRU2023-9.4.x","title":"Javadoc"},{"location":"integrator/sdk/sdk-bicdirectory/","text":"BIC Directory (import and query) In order to perform multiple processes, it is required to access some BIC directory that contains a complete BIC codes database. This information is mainly used by the validation module to perform BIC code validation, but it is also available for any suitable use to the applications by means of Java API. The data is distributed as an independent jar file named pw-integrator-data-1.X.X.jar . The jar contains the BIC directory in binary form, packaged into an embedded Derby database. The main entry point to access and query the directory is the class: http://api.prowidesoftware.com/javadoc/SRU2023-9/module-sdk/com/prowidesoftware/swift/BICDirectory.html/ IMPORTANT : The data jar provided with the package is just an example to get started. Since the BIC codes are monthly updated by SWIFT, the information in the pw-integrator-data-1.X.X.jar file should be updated often, by replacing the file with a fresher one. It is under the customer responsibility of keeping the directory updated to the latest version of BIC reference information distributed by swift. Updating the BIC Directory The tool to update the BIC directory is the BICImporter process. This process will create a new BIC directory jar file by reading the BIC data from an input file. This item is enclosed in the SDK jar file, and should be executed, by command line, as follows: java -cp CLASSPATH com.prowidesoftware.swift.app.BICImporter TXT_FILE Where CLASSPATH is the SDK jar and dependencies. In this case: * pw-swift-integrator-sdk * commons-lang3 * derby Note that if you downloaded Integrator from a download link, just use \"*;lib/*\" as CLASSPATH. Any other case just include the 3 jar's paths (i.e. \"pw-swift-integrator-sdk-SRU2022-9.3.13.jar;lib/commons-lang3-3.12.0.jar;lib/derby-10.12.1.1.jar\" ) And TXT_FILE is the path to the BIC directory file to import (i.e. FI_201806.txt ). Please see the Supported data files for further details. After the import run, a new pw-swift-integrator-data-1.X.X.jar will be created at ./ and should be used to replace the old one from your project setup. Run example and expected output: $ java -cp \"*;lib/*\" com.prowidesoftware.swift.app.BICImporter FI_201806.txt BICImporter: starting FI_201806.txt file import... BICImporter: detected file format BIC DIRECTORY 2018 BICImporter: initializing a new database BICImporter: starting import process BICImporter: processed 100 so far BICImporter: processed 200 so far ... ... BICImporter: processed 5005 so far Shutdown result: Derby system shutdown. BICImporter: 4999 records imported, 6 records ignored, in 16122ms Where the 4999 count is for the records marked with add (A), modification (M) or update (U) in the imported file, and the 6 count is for the records marked with delete (D) in the imported file. Since we create a fresh new directory each time, there is no need to delete pre-existing data and the deletion indication is just ignored. For the BIC Plus the non-operational records in the file will also be counted as ignored. Please notice that these BIC upgrades are available online at swiftrefdata.com to the BIC directory online subscribers. The data file is included with your Integrator download just for convenience, but you need to keep the information up to date, downloading and importing the new BIC information monthly published by SWIFT to subscribers. Supported data files The BIC Directory and in particular the BICImporter tool seamlessly support data files from any of these sources: Legacy BIC Directory: FI_YYYYMM.txt BIC Directory 2018: BICDIR2018_V1_FULL_YYYYMMDD.txt BIC Plus: BICPLUS_V1_FULL_YYYYMMDD.txt The catalog database is generated from scratch on each import run, so the full (no delta) files are required. Regarding the new BIC Plus support, since the Prowide Integrator BIC directory is used for BICs lookup and validation, when importing BIC codes from the extended BIC Plus files, only the operationally active records are loaded. The data files can be downloaded from https://www.swiftrefdata.com/ upon subscription to the SWIFT Ref services from SWIFT. Using a custom database The IBICDirectory interface can be implemented to provide a custom BIC directory. The default implementation is the BICDirectory class , which uses the embedded Derby database included in the pw-swift-integrator-data-1.X.X.jar file. To use your own BIC database, you can implement the IBICDirectory interface and provide your own implementation to the BICDirectory class. For example, to use a MySQL database. The custom implementation then can be injected as needed in the relevant features. For example, to use the custom implementation in the expanded printout, you can pass the custom implementation to the PrintoutWriter constructor. Then to use a custom BIC directory in the validation module, you can set your own instance to the ValidationConfiguration in the ValidationEngine . Validating the generated pw-integrator-data-1.X.X.jar Once the update process is complete, is it possible to verify the result. For that purpose a tool called BICQuery is provided. It can be used as indicated below: $ java -cp \"*;lib/*\" com.prowidesoftware.swift.app.BICQuery 'AFABAFKA' row,code,branch,branchInformation,cityHeading,countryName,extraInformation,institutionName,location,physicalAddressPart1,physicalAddressPart2,physicalAddressPart3,physicalAddressPart4,POBCountryName,POBLocation,POBNumber,subtypeIndication,tagIdentifier,valueAddedServices 1, AFABAFKA, XXX, , KABUL, AFGHANISTAN, CK, ARIAN BANK, 5810 KABUL, HOUSE NO.2, HANZALA MOSQUE ROAD, QALAI FATH, , , , , , SUPE, FIN Alternatively, there are some options for running this command. Use -short arg for an abbreviated result: $ java -cp \"*;lib/*\" com.prowidesoftware.swift.app.BICQuery '-short' 'AFABAFKA' 1> AFABAFKAXXX Use % arg for a SQL like type query: $ java -cp \"*;lib/*\" com.prowidesoftware.swift.app.BICQuery 'AAA%' row,code,branch,branchInformation,cityHeading,countryName,extraInformation,institutionName,location,physicalAddressPart1,physicalAddressPart2,physicalAddressPart3,physicalAddressPart4,POBCountryName,POBLocation,POBNumber,subtypeIndication,tagIdentifier,valueAddedServices 1, AAAARSBG, XXX, , BEOGRAD, SERBIA, CB, TELENOR BANKA AD, 11070 BEOGRAD, OMLADINSKIH BRIGADA 90V, , , , , , , SUPE, EB+FINTG+ 2, AAACKWKW, XXX, , KUWAIT, KUWAIT, CK, ALMUZAINI EXCHANGE COMPANY KSC (CLOSED), 13022 KUWAIT, OPPOSITE PUBLIC LIBRARY, ALI AL SALEM STREET, MUBARAKIA, SAFAT, , KUWAIT, 13022 KUWAIT, POB 2156, SUPE, FIN 3, AAADFRP1, XXX, , PARIS, FRANCE, NP, ASSET ALLOCATION ADVISORS SA, 75008 PARIS, 3, AVENUE HOCHE, CHEZ NSM, CHEZ NSM, , , , , NSWB, 4, AAAJBG21, XXX, , PLOVDIV, BULGARIA, N2, ARCUS ASSET MANAGEMENT JSC, 4000 PLOVDIV, BUSINESS CENTER LEGIS, 152, 6TH OF SEPTEMBER BLVD., , , , , , NSWB, 5, AAALSARI, ALK, (EASTERN AREA ALKHOBAR), ALKHOBAR, SAUDI ARABIA, BRA CR, SAUDI HOLLANDI BANK, ALKHOBAR, , , , , , , , SUPE, FINTG+ 6, AAASTHB1, XXX, , BANGKOK, THAILAND, NB, ASIA PLUS SECURITIES PUBLIC COMPANY LIMITED, BANGKOK 10120, SATHORN CITY TOWER, 3RD/1 FLOOR, 175 SOUTH SATHORN ROAD, , , , , NSWB, Note: depending on your SQL engine, you would need to use ? for the same purpose.","title":"BIC directory"},{"location":"integrator/sdk/sdk-bicdirectory/#bic-directory-import-and-query","text":"In order to perform multiple processes, it is required to access some BIC directory that contains a complete BIC codes database. This information is mainly used by the validation module to perform BIC code validation, but it is also available for any suitable use to the applications by means of Java API. The data is distributed as an independent jar file named pw-integrator-data-1.X.X.jar . The jar contains the BIC directory in binary form, packaged into an embedded Derby database. The main entry point to access and query the directory is the class: http://api.prowidesoftware.com/javadoc/SRU2023-9/module-sdk/com/prowidesoftware/swift/BICDirectory.html/ IMPORTANT : The data jar provided with the package is just an example to get started. Since the BIC codes are monthly updated by SWIFT, the information in the pw-integrator-data-1.X.X.jar file should be updated often, by replacing the file with a fresher one. It is under the customer responsibility of keeping the directory updated to the latest version of BIC reference information distributed by swift.","title":"BIC Directory (import and query)"},{"location":"integrator/sdk/sdk-bicdirectory/#updating-the-bic-directory","text":"The tool to update the BIC directory is the BICImporter process. This process will create a new BIC directory jar file by reading the BIC data from an input file. This item is enclosed in the SDK jar file, and should be executed, by command line, as follows: java -cp CLASSPATH com.prowidesoftware.swift.app.BICImporter TXT_FILE Where CLASSPATH is the SDK jar and dependencies. In this case: * pw-swift-integrator-sdk * commons-lang3 * derby Note that if you downloaded Integrator from a download link, just use \"*;lib/*\" as CLASSPATH. Any other case just include the 3 jar's paths (i.e. \"pw-swift-integrator-sdk-SRU2022-9.3.13.jar;lib/commons-lang3-3.12.0.jar;lib/derby-10.12.1.1.jar\" ) And TXT_FILE is the path to the BIC directory file to import (i.e. FI_201806.txt ). Please see the Supported data files for further details. After the import run, a new pw-swift-integrator-data-1.X.X.jar will be created at ./ and should be used to replace the old one from your project setup. Run example and expected output: $ java -cp \"*;lib/*\" com.prowidesoftware.swift.app.BICImporter FI_201806.txt BICImporter: starting FI_201806.txt file import... BICImporter: detected file format BIC DIRECTORY 2018 BICImporter: initializing a new database BICImporter: starting import process BICImporter: processed 100 so far BICImporter: processed 200 so far ... ... BICImporter: processed 5005 so far Shutdown result: Derby system shutdown. BICImporter: 4999 records imported, 6 records ignored, in 16122ms Where the 4999 count is for the records marked with add (A), modification (M) or update (U) in the imported file, and the 6 count is for the records marked with delete (D) in the imported file. Since we create a fresh new directory each time, there is no need to delete pre-existing data and the deletion indication is just ignored. For the BIC Plus the non-operational records in the file will also be counted as ignored. Please notice that these BIC upgrades are available online at swiftrefdata.com to the BIC directory online subscribers. The data file is included with your Integrator download just for convenience, but you need to keep the information up to date, downloading and importing the new BIC information monthly published by SWIFT to subscribers.","title":"Updating the BIC Directory"},{"location":"integrator/sdk/sdk-bicdirectory/#supported-data-files","text":"The BIC Directory and in particular the BICImporter tool seamlessly support data files from any of these sources: Legacy BIC Directory: FI_YYYYMM.txt BIC Directory 2018: BICDIR2018_V1_FULL_YYYYMMDD.txt BIC Plus: BICPLUS_V1_FULL_YYYYMMDD.txt The catalog database is generated from scratch on each import run, so the full (no delta) files are required. Regarding the new BIC Plus support, since the Prowide Integrator BIC directory is used for BICs lookup and validation, when importing BIC codes from the extended BIC Plus files, only the operationally active records are loaded. The data files can be downloaded from https://www.swiftrefdata.com/ upon subscription to the SWIFT Ref services from SWIFT.","title":"Supported data files"},{"location":"integrator/sdk/sdk-bicdirectory/#using-a-custom-database","text":"The IBICDirectory interface can be implemented to provide a custom BIC directory. The default implementation is the BICDirectory class , which uses the embedded Derby database included in the pw-swift-integrator-data-1.X.X.jar file. To use your own BIC database, you can implement the IBICDirectory interface and provide your own implementation to the BICDirectory class. For example, to use a MySQL database. The custom implementation then can be injected as needed in the relevant features. For example, to use the custom implementation in the expanded printout, you can pass the custom implementation to the PrintoutWriter constructor. Then to use a custom BIC directory in the validation module, you can set your own instance to the ValidationConfiguration in the ValidationEngine .","title":"Using a custom database"},{"location":"integrator/sdk/sdk-bicdirectory/#validating-the-generated-pw-integrator-data-1xxjar","text":"Once the update process is complete, is it possible to verify the result. For that purpose a tool called BICQuery is provided. It can be used as indicated below: $ java -cp \"*;lib/*\" com.prowidesoftware.swift.app.BICQuery 'AFABAFKA' row,code,branch,branchInformation,cityHeading,countryName,extraInformation,institutionName,location,physicalAddressPart1,physicalAddressPart2,physicalAddressPart3,physicalAddressPart4,POBCountryName,POBLocation,POBNumber,subtypeIndication,tagIdentifier,valueAddedServices 1, AFABAFKA, XXX, , KABUL, AFGHANISTAN, CK, ARIAN BANK, 5810 KABUL, HOUSE NO.2, HANZALA MOSQUE ROAD, QALAI FATH, , , , , , SUPE, FIN Alternatively, there are some options for running this command. Use -short arg for an abbreviated result: $ java -cp \"*;lib/*\" com.prowidesoftware.swift.app.BICQuery '-short' 'AFABAFKA' 1> AFABAFKAXXX Use % arg for a SQL like type query: $ java -cp \"*;lib/*\" com.prowidesoftware.swift.app.BICQuery 'AAA%' row,code,branch,branchInformation,cityHeading,countryName,extraInformation,institutionName,location,physicalAddressPart1,physicalAddressPart2,physicalAddressPart3,physicalAddressPart4,POBCountryName,POBLocation,POBNumber,subtypeIndication,tagIdentifier,valueAddedServices 1, AAAARSBG, XXX, , BEOGRAD, SERBIA, CB, TELENOR BANKA AD, 11070 BEOGRAD, OMLADINSKIH BRIGADA 90V, , , , , , , SUPE, EB+FINTG+ 2, AAACKWKW, XXX, , KUWAIT, KUWAIT, CK, ALMUZAINI EXCHANGE COMPANY KSC (CLOSED), 13022 KUWAIT, OPPOSITE PUBLIC LIBRARY, ALI AL SALEM STREET, MUBARAKIA, SAFAT, , KUWAIT, 13022 KUWAIT, POB 2156, SUPE, FIN 3, AAADFRP1, XXX, , PARIS, FRANCE, NP, ASSET ALLOCATION ADVISORS SA, 75008 PARIS, 3, AVENUE HOCHE, CHEZ NSM, CHEZ NSM, , , , , NSWB, 4, AAAJBG21, XXX, , PLOVDIV, BULGARIA, N2, ARCUS ASSET MANAGEMENT JSC, 4000 PLOVDIV, BUSINESS CENTER LEGIS, 152, 6TH OF SEPTEMBER BLVD., , , , , , NSWB, 5, AAALSARI, ALK, (EASTERN AREA ALKHOBAR), ALKHOBAR, SAUDI ARABIA, BRA CR, SAUDI HOLLANDI BANK, ALKHOBAR, , , , , , , , SUPE, FINTG+ 6, AAASTHB1, XXX, , BANGKOK, THAILAND, NB, ASIA PLUS SECURITIES PUBLIC COMPANY LIMITED, BANGKOK 10120, SATHORN CITY TOWER, 3RD/1 FLOOR, 175 SOUTH SATHORN ROAD, , , , , NSWB, Note: depending on your SQL engine, you would need to use ? for the same purpose.","title":"Validating the generated pw-integrator-data-1.X.X.jar"},{"location":"integrator/sdk/sdk-datapdu/","text":"DataPDU (XML v2) The Protocol Data Units (DataPDU) is an XML wrapper used in transmission between message partners and SWIFT Alliance Access (SAA). It can seamlessly wrap both MT and MX messages. The structure is also known as XML V2. The root element of the XML v2 structure is a DataPDU element, where the children elements are the Revision , the Header and the Body . When the wrapper is built for an MX message, the Body element contains the complete ISO 20022 message with the optional AppHdr and Document . While for MT messages, since MT format is not XML-based, the FIN content is put into the Body element as a plain string base64 encoded. From the XML v2 perspective, the Body is always a SwAny element, not defined in the SAA schema. The same DataPDU is also used for transmission reports (ACK/NAK). There are multiple revisions of the SAA schemas for the DataPDU structure. The library supports several versions, and more can be added on demand. The provided API gives an option to use a default version or a specific one, by using classes in the specific version package. The following sections describe different use cases and the relevant API. Inbound DataPDU To process inbound DataPDU files received from SAA the easiest way is to parse the content with the AbstractDataPDU class: DataPDUContentParser parser = AbstractDataPDU . parse ( xml ); if ( parser . type () == DataPDUType . Message_MX ) { AbstractMX mx = parser . extractMx (); } Since SAA supports multiple revisions of the schemas, the parser above will automatically detect the schema version and the returned object will be a specific instance for the detected revision. The DataPDUContentParser is an interface implemented by all revision models. Thus, you can parse the main elements of the DataPDU and extract the payload message without bothering about the specific revision that is received from SAA. With the parser, you can check the DataPDU type, and extract the MX or MT message. In the above example the mx object will be a specific message type instance, such as MxPacs00800108 with the header and document parsed from the DataPDU. If you don\u2019t care if it is an MT o MX, you can also run a generic extraction like this: DataPDUContentParser parser = AbstractDataPDU . parse ( xml ); AbstractSwiftMessage msg = parser . extractMessage (); Where the extracted message will be either an MX, an MT or even a Service21 message (ACK) id the DataPDU is a Transmission Report. Finally, if more specific elements of the DataPDU structure have to be read, you can cast the generic DataPDUContentParser to a specific implementation instance. In order to do this, you have to know in advance the specific version, or you can use the getRevision to get it. if ( \"2.0.13\" . equals ( parser . getRevision ) { DataPDUParser parserV13 = ( DataPDUParser ) parser ; Priority p = parserV13 . getHeader (). getMessage (). getNetworkInfo (). getPriority (); } Where the DataPDUParser is a class in the specific implementation in the com.prowidesoftware.swift.wrappers.saa.v_2_0_14 package. Similar classes are available for the supported revisions. The AbstractDataPDU parser just checks the enclosed revision in the XML and delegates to the specific implementation. Using a fixed version of the DataPDU If you need to access the DataPDU content, besides extracting the MT/MX payload and you receive many different versions from your interfaces, you could also use the latest revision to parse all of them. So that you avoid casting the model to the different versions. For example, if you are using the latest revision, you can use the following code to parse: DataPDUParser dataPdu = com . prowidesoftware . swift . wrappers . saa . v2_0_14 . DataPDUParser . parse ( xml ); Setting a specific DN to the message There's the possibility that you need to use the DN Id instead of BIC one, in those cases, you can use the following code: MxSwiftMessage mx = new MxSwiftMessage ( xml ); DataPDUWriter dataPDUWriter = new DataPDUWriter ( mx ); dataPDUWriter . getHeader (). getMessage (). getSender (). setDN ( new BIC ( mx . getSender ()). distinguishedName ()); dataPDUWriter . getHeader (). getMessage (). getReceiver (). setDN ( new BIC ( mx . getReceiver ()). distinguishedName ()); final String dataPDU = dataPDUWriter . xml (); Stripping the binary prefix When calling any of the DataPDU parsing options make sure your XML string does not contain the binary prefix. If it does you can remove this prefix from the XML string before calling the parsing methods. For example: DataPDUParser . parse ( XmlV2Utils . stripBinaryPrefix ( xml )); Find more information for the binary prefix below. Outbound DataPDU To create an outbound DataPDU file to be sent to SAA the easiest way is to use the DataPDUWriter class. Since multiple versions of the DataPDU structure exist for SAA, there is a DataPDUWriter for each in the specific version packages, such as com.prowidesoftware.swift.wrappers.saa.v_2_0_14 . Then, multiple constructor options are available, each for a different purpose. For example, to build a DataPDU completely from scratch you can use: DataPDUWriter writer = new DataPDUWriter (); writer . setHeader ( new Header ()); writer . getHeader (). setMessage ( new Message ()); writer . getHeader (). getMessage (). setSenderReference ( \"senderRef123\" ); writer . getHeader (). getMessage (). setFormat ( \"File\" ); As you can see in the above example, you have a comprehensive setters API to build any element of the DataPDU. Then the xml() method can be used on the writer to generate the actual XML content of the DataPDU. When sending MT or MX messages as the payload of a DataPDU envelope, specific constructors are provided, such as: MtSwiftMessage mt = new MtSwiftMessage ( fin ); DataPDUWriter w = new DataPDUWriter ( mt )); final String xml = w . xml (); And the same for Mx. The above will automatically marshall the MT or MX payload into the generated XML. For MY messages, it will encode the message body in base 64. Where for MX, the AppHdr and Document elements will be enclosed into the Body of the DataPDU. Meaning, this constructor will automatically generate the Body element of the DataPDU from the parameter message. If the use case requires creating a new DataPDU by modifying an existing XML, the writer has also constructor options from an XML string and from a DataPDUParser . Thus, you can use the parser to read an existing XML structure, and then create a writer out of it for modifications. DataPDUWriter factory When the writer has to be created from and existing XML in order to do modifications or content enrichment, a factory can be used to create the specific version of the writer automatically for a given XML input: AbstractDataPDU dataPDUWriter = DataPDUWriterFactory . getDataPDUWriter ( xml ); writer . getHeader (). getMessage (). setSenderReference ( \"senderRef123\" ); ... final String dataPDU = dataPDUWriter . xml (); The factory extracts the revision number from the given XML string and returns a specific DataPDUWriter instance (subclass of the AbstractDataPDU ) corresponding to that extracted revision. If the revision number does not match any of the supported versions or the XML is null, it defaults to the latest. MT encoded content When MT messages are wrapped into the XML, the MT content is put in the Body as a single base64 encoded string. This encoded string could have: The complete MT message including headers, text block and trailers. Just the text block (block 4) By default, the writer will write the whole message content in the encoded string when creating the Body element. The API accepts an optional configuration class where you can change this default behavior and indicate whether in your environment the XML for MT should be created with only the block 4 encoded in the Body element. As for the parser, the encoded Body will be autodetected. When the complete MT content is present, that will be parsed into the returned MT instance. And if only the block 4 is encoded in the Body element, the headers and trailer will be recreated by the parser using information from other elements in the XML. MX custom namespaces When constructing an MX message, the DataPDUWriter automatically incorporates the default namespaces for the MX message, specifically h for Header and Doc for Document . However, to override this default behavior, one can specify a desired namespace. Alternatively, setting the namespace to null can exclude it from being included. Check the code below: MxCamt00300105 mxCamt00300105 = MxCamt00300105 . parse ( your_mx ); DataPDUWriter w = new DataPDUWriter ( mxCamt00300105 , \"REF VAL\" , \"FOOZLULL\" , \"FOOZLULL\" ); final XmlV2Configuration conf = new XmlV2Configuration (); MxWriteParams mxHeaderWriteParams = new MxWriteParams (); mxHeaderWriteParams . prefix = \"header\" ; conf . setMxHeaderWriteParams ( mxHeaderWriteParams ); MxWriteParams mxDocumentWriteParams = new MxWriteParams (); mxDocumentWriteParams . prefix = mxCamt00300105 . getBusinessProcess (); conf . setMxDocumentWriteParams ( mxDocumentWriteParams ); final String xml = w . xml ( conf ); This will produce the following XML: 2.0.13 REF VAL camt.003.001.05 MX Input FOOZLULLAXXX FOOZLULLXXXX ... ... 2015-08-27T08:59:00Z ... TransmissionReport The DataPDU is also used by SAA to return transmission reports. For this purpose, the DataPDU/Header structure is a choice that can hold a simple Message but also a Transmission Report and other structures. When the parser is called and the DataPDU/Header/TransmissionReport is found with an embedded MT , the parsed message result will be a FIN ACK/NAK as the following. Meaning a call like this: DataPDUContentParser parser = AbstractDataPDU . parse ( xml ); AbstractSwiftMessage msg = parser . extractMessage (); Will extract into the AbstractSwiftMessage a message payload like this: {1:F21AAAAGHA0AXXX241764}{4:{177:19101921138}{451:0}}{1:F01AAAAGHA0AXXX241764}{2:I103BBBBGHA0XXXXN}{3:{121:8a0c1649-efa9-42a6-8dcf-8df8c9b2c99f}}{4: :20:REFERENCE123 :23B:CRED :26T:123 :32A:191019EUR1, :50A:/1234456 AAAAGHA0 :59:/234455 Foo :71A:OUR -} Where you have the service message (21) with the date time and ACK fields, followed by the original message. You can then use the original message to do the internal matching in your application to reconcile the ACK and the original sent message. A similar Transmission Report is generated by SAA to acknowledge MX messages. In this case, the result of the parser is still a FIN service 21 message like this: {1:F21SPXAINJJAA05151}{4:{177:1102111528}{451:0}{108:PPTEI00000001013}} Which is just a service message (21) without any attached original message. Since the original message was an MX. In this scenario, if the MUR is present in the XML v2, you will find it in the field 108, and you can use it to match the original MX sent. The original MX message is not present in the result because there is no equivalence in ISO 20022 for the FIN service messages service type 21. For MT acknowledges, we can, because FIN defines such a structure where you have a service message plus an original message attached. But there is no message model to hold an ACK along an original MX, that structure is the actual DataPDU. Therefore, if you have to process ACK/NAK for MX, and you need the original message parsed because the MUR is not enough for the reconciliation, you can still accomplish that with the API like this: DataPDUParser parser = AbstractDataPDU . parse ( xml ); parser . getHeader (). getTransmissionReport (). getMessage (). getBody (); More info on ACK https://dev.prowidesoftware.com/latest/open-source/core/mt-ack/ DataPDU binary prefix (XmlV2Utils) The DataPDU is a regular UTF-8 encoded XML, but it can be preceded by a binary prefix with a digital signature. The Xmlv2Utils class is the main entry point to handle this binary prefix for the DataPDU XMLs. This prefix is actually obsolete in SAA, but only supported for backward compatibility. When reading an XML the XmlV2Utils class will strip the prefix if present. And when writing an XML a parameter is available to indicate whether the prefix must be generated or not. For inbound messages, to convert an XML into a message, you just need to call: AbstractSwiftMessage message = XmlV2Utils . readMessage ( xml ); The message variable will contain as result the embedded MT or MX message. The implementation will just strip the prefix if present, and will call the DataPDU parsing API to extract the enclosed message. For outbound messages, the XmlV2Utils class provides additional methods to select the usage of the binary prefix. Notice however when the flag to generate the binary prefix is true, this prefix will be generated with just the message size, but the signature will be filled with nulls. If you need to send outbound messages to SAA with a valid computed signature in the binary prefix, check the section describing LAU.","title":"DataPDU"},{"location":"integrator/sdk/sdk-datapdu/#datapdu-xml-v2","text":"The Protocol Data Units (DataPDU) is an XML wrapper used in transmission between message partners and SWIFT Alliance Access (SAA). It can seamlessly wrap both MT and MX messages. The structure is also known as XML V2. The root element of the XML v2 structure is a DataPDU element, where the children elements are the Revision , the Header and the Body . When the wrapper is built for an MX message, the Body element contains the complete ISO 20022 message with the optional AppHdr and Document . While for MT messages, since MT format is not XML-based, the FIN content is put into the Body element as a plain string base64 encoded. From the XML v2 perspective, the Body is always a SwAny element, not defined in the SAA schema. The same DataPDU is also used for transmission reports (ACK/NAK). There are multiple revisions of the SAA schemas for the DataPDU structure. The library supports several versions, and more can be added on demand. The provided API gives an option to use a default version or a specific one, by using classes in the specific version package. The following sections describe different use cases and the relevant API.","title":"DataPDU (XML v2)"},{"location":"integrator/sdk/sdk-datapdu/#inbound-datapdu","text":"To process inbound DataPDU files received from SAA the easiest way is to parse the content with the AbstractDataPDU class: DataPDUContentParser parser = AbstractDataPDU . parse ( xml ); if ( parser . type () == DataPDUType . Message_MX ) { AbstractMX mx = parser . extractMx (); } Since SAA supports multiple revisions of the schemas, the parser above will automatically detect the schema version and the returned object will be a specific instance for the detected revision. The DataPDUContentParser is an interface implemented by all revision models. Thus, you can parse the main elements of the DataPDU and extract the payload message without bothering about the specific revision that is received from SAA. With the parser, you can check the DataPDU type, and extract the MX or MT message. In the above example the mx object will be a specific message type instance, such as MxPacs00800108 with the header and document parsed from the DataPDU. If you don\u2019t care if it is an MT o MX, you can also run a generic extraction like this: DataPDUContentParser parser = AbstractDataPDU . parse ( xml ); AbstractSwiftMessage msg = parser . extractMessage (); Where the extracted message will be either an MX, an MT or even a Service21 message (ACK) id the DataPDU is a Transmission Report. Finally, if more specific elements of the DataPDU structure have to be read, you can cast the generic DataPDUContentParser to a specific implementation instance. In order to do this, you have to know in advance the specific version, or you can use the getRevision to get it. if ( \"2.0.13\" . equals ( parser . getRevision ) { DataPDUParser parserV13 = ( DataPDUParser ) parser ; Priority p = parserV13 . getHeader (). getMessage (). getNetworkInfo (). getPriority (); } Where the DataPDUParser is a class in the specific implementation in the com.prowidesoftware.swift.wrappers.saa.v_2_0_14 package. Similar classes are available for the supported revisions. The AbstractDataPDU parser just checks the enclosed revision in the XML and delegates to the specific implementation.","title":"Inbound DataPDU"},{"location":"integrator/sdk/sdk-datapdu/#using-a-fixed-version-of-the-datapdu","text":"If you need to access the DataPDU content, besides extracting the MT/MX payload and you receive many different versions from your interfaces, you could also use the latest revision to parse all of them. So that you avoid casting the model to the different versions. For example, if you are using the latest revision, you can use the following code to parse: DataPDUParser dataPdu = com . prowidesoftware . swift . wrappers . saa . v2_0_14 . DataPDUParser . parse ( xml );","title":"Using a fixed version of the DataPDU"},{"location":"integrator/sdk/sdk-datapdu/#setting-a-specific-dn-to-the-message","text":"There's the possibility that you need to use the DN Id instead of BIC one, in those cases, you can use the following code: MxSwiftMessage mx = new MxSwiftMessage ( xml ); DataPDUWriter dataPDUWriter = new DataPDUWriter ( mx ); dataPDUWriter . getHeader (). getMessage (). getSender (). setDN ( new BIC ( mx . getSender ()). distinguishedName ()); dataPDUWriter . getHeader (). getMessage (). getReceiver (). setDN ( new BIC ( mx . getReceiver ()). distinguishedName ()); final String dataPDU = dataPDUWriter . xml ();","title":"Setting a specific DN to the message"},{"location":"integrator/sdk/sdk-datapdu/#stripping-the-binary-prefix","text":"When calling any of the DataPDU parsing options make sure your XML string does not contain the binary prefix. If it does you can remove this prefix from the XML string before calling the parsing methods. For example: DataPDUParser . parse ( XmlV2Utils . stripBinaryPrefix ( xml )); Find more information for the binary prefix below.","title":"Stripping the binary prefix"},{"location":"integrator/sdk/sdk-datapdu/#outbound-datapdu","text":"To create an outbound DataPDU file to be sent to SAA the easiest way is to use the DataPDUWriter class. Since multiple versions of the DataPDU structure exist for SAA, there is a DataPDUWriter for each in the specific version packages, such as com.prowidesoftware.swift.wrappers.saa.v_2_0_14 . Then, multiple constructor options are available, each for a different purpose. For example, to build a DataPDU completely from scratch you can use: DataPDUWriter writer = new DataPDUWriter (); writer . setHeader ( new Header ()); writer . getHeader (). setMessage ( new Message ()); writer . getHeader (). getMessage (). setSenderReference ( \"senderRef123\" ); writer . getHeader (). getMessage (). setFormat ( \"File\" ); As you can see in the above example, you have a comprehensive setters API to build any element of the DataPDU. Then the xml() method can be used on the writer to generate the actual XML content of the DataPDU. When sending MT or MX messages as the payload of a DataPDU envelope, specific constructors are provided, such as: MtSwiftMessage mt = new MtSwiftMessage ( fin ); DataPDUWriter w = new DataPDUWriter ( mt )); final String xml = w . xml (); And the same for Mx. The above will automatically marshall the MT or MX payload into the generated XML. For MY messages, it will encode the message body in base 64. Where for MX, the AppHdr and Document elements will be enclosed into the Body of the DataPDU. Meaning, this constructor will automatically generate the Body element of the DataPDU from the parameter message. If the use case requires creating a new DataPDU by modifying an existing XML, the writer has also constructor options from an XML string and from a DataPDUParser . Thus, you can use the parser to read an existing XML structure, and then create a writer out of it for modifications.","title":"Outbound DataPDU"},{"location":"integrator/sdk/sdk-datapdu/#datapduwriter-factory","text":"When the writer has to be created from and existing XML in order to do modifications or content enrichment, a factory can be used to create the specific version of the writer automatically for a given XML input: AbstractDataPDU dataPDUWriter = DataPDUWriterFactory . getDataPDUWriter ( xml ); writer . getHeader (). getMessage (). setSenderReference ( \"senderRef123\" ); ... final String dataPDU = dataPDUWriter . xml (); The factory extracts the revision number from the given XML string and returns a specific DataPDUWriter instance (subclass of the AbstractDataPDU ) corresponding to that extracted revision. If the revision number does not match any of the supported versions or the XML is null, it defaults to the latest.","title":"DataPDUWriter factory"},{"location":"integrator/sdk/sdk-datapdu/#mt-encoded-content","text":"When MT messages are wrapped into the XML, the MT content is put in the Body as a single base64 encoded string. This encoded string could have: The complete MT message including headers, text block and trailers. Just the text block (block 4) By default, the writer will write the whole message content in the encoded string when creating the Body element. The API accepts an optional configuration class where you can change this default behavior and indicate whether in your environment the XML for MT should be created with only the block 4 encoded in the Body element. As for the parser, the encoded Body will be autodetected. When the complete MT content is present, that will be parsed into the returned MT instance. And if only the block 4 is encoded in the Body element, the headers and trailer will be recreated by the parser using information from other elements in the XML.","title":"MT encoded content"},{"location":"integrator/sdk/sdk-datapdu/#mx-custom-namespaces","text":"When constructing an MX message, the DataPDUWriter automatically incorporates the default namespaces for the MX message, specifically h for Header and Doc for Document . However, to override this default behavior, one can specify a desired namespace. Alternatively, setting the namespace to null can exclude it from being included. Check the code below: MxCamt00300105 mxCamt00300105 = MxCamt00300105 . parse ( your_mx ); DataPDUWriter w = new DataPDUWriter ( mxCamt00300105 , \"REF VAL\" , \"FOOZLULL\" , \"FOOZLULL\" ); final XmlV2Configuration conf = new XmlV2Configuration (); MxWriteParams mxHeaderWriteParams = new MxWriteParams (); mxHeaderWriteParams . prefix = \"header\" ; conf . setMxHeaderWriteParams ( mxHeaderWriteParams ); MxWriteParams mxDocumentWriteParams = new MxWriteParams (); mxDocumentWriteParams . prefix = mxCamt00300105 . getBusinessProcess (); conf . setMxDocumentWriteParams ( mxDocumentWriteParams ); final String xml = w . xml ( conf ); This will produce the following XML: 2.0.13 REF VAL camt.003.001.05 MX Input FOOZLULLAXXX FOOZLULLXXXX ... ... 2015-08-27T08:59:00Z ... ","title":"MX custom namespaces"},{"location":"integrator/sdk/sdk-datapdu/#transmissionreport","text":"The DataPDU is also used by SAA to return transmission reports. For this purpose, the DataPDU/Header structure is a choice that can hold a simple Message but also a Transmission Report and other structures. When the parser is called and the DataPDU/Header/TransmissionReport is found with an embedded MT , the parsed message result will be a FIN ACK/NAK as the following. Meaning a call like this: DataPDUContentParser parser = AbstractDataPDU . parse ( xml ); AbstractSwiftMessage msg = parser . extractMessage (); Will extract into the AbstractSwiftMessage a message payload like this: {1:F21AAAAGHA0AXXX241764}{4:{177:19101921138}{451:0}}{1:F01AAAAGHA0AXXX241764}{2:I103BBBBGHA0XXXXN}{3:{121:8a0c1649-efa9-42a6-8dcf-8df8c9b2c99f}}{4: :20:REFERENCE123 :23B:CRED :26T:123 :32A:191019EUR1, :50A:/1234456 AAAAGHA0 :59:/234455 Foo :71A:OUR -} Where you have the service message (21) with the date time and ACK fields, followed by the original message. You can then use the original message to do the internal matching in your application to reconcile the ACK and the original sent message. A similar Transmission Report is generated by SAA to acknowledge MX messages. In this case, the result of the parser is still a FIN service 21 message like this: {1:F21SPXAINJJAA05151}{4:{177:1102111528}{451:0}{108:PPTEI00000001013}} Which is just a service message (21) without any attached original message. Since the original message was an MX. In this scenario, if the MUR is present in the XML v2, you will find it in the field 108, and you can use it to match the original MX sent. The original MX message is not present in the result because there is no equivalence in ISO 20022 for the FIN service messages service type 21. For MT acknowledges, we can, because FIN defines such a structure where you have a service message plus an original message attached. But there is no message model to hold an ACK along an original MX, that structure is the actual DataPDU. Therefore, if you have to process ACK/NAK for MX, and you need the original message parsed because the MUR is not enough for the reconciliation, you can still accomplish that with the API like this: DataPDUParser parser = AbstractDataPDU . parse ( xml ); parser . getHeader (). getTransmissionReport (). getMessage (). getBody (); More info on ACK https://dev.prowidesoftware.com/latest/open-source/core/mt-ack/","title":"TransmissionReport"},{"location":"integrator/sdk/sdk-datapdu/#datapdu-binary-prefix-xmlv2utils","text":"The DataPDU is a regular UTF-8 encoded XML, but it can be preceded by a binary prefix with a digital signature. The Xmlv2Utils class is the main entry point to handle this binary prefix for the DataPDU XMLs. This prefix is actually obsolete in SAA, but only supported for backward compatibility. When reading an XML the XmlV2Utils class will strip the prefix if present. And when writing an XML a parameter is available to indicate whether the prefix must be generated or not. For inbound messages, to convert an XML into a message, you just need to call: AbstractSwiftMessage message = XmlV2Utils . readMessage ( xml ); The message variable will contain as result the embedded MT or MX message. The implementation will just strip the prefix if present, and will call the DataPDU parsing API to extract the enclosed message. For outbound messages, the XmlV2Utils class provides additional methods to select the usage of the binary prefix. Notice however when the flag to generate the binary prefix is true, this prefix will be generated with just the message size, but the signature will be filled with nulls. If you need to send outbound messages to SAA with a valid computed signature in the binary prefix, check the section describing LAU.","title":"DataPDU binary prefix (XmlV2Utils)"},{"location":"integrator/sdk/sdk-lau/","text":"LAU The SDK provide API for Local Authentication (LAU) to ensure incoming and outgoing messages are not tempered between the back-office applications and the SWIFT Alliance Access , increasing overall infrastructure security. LAU is based on the industry standard algorithm HMAC-SHA256, and is the only authentication method supported by SAA for transmission of message files to SWIFT. The LAU authentication consists of adding a digital signature calculated using the message body and a pair of shared keys that are uniquely defined for each back-office. In the SAA the keys and the LAU are enabled per Message Partner configuration. The LAU key consists of 32 printable characters entered as two 16 character strings. This allows users to have dual control over the maintenance of these keys. SWIFT has also defined complexity rules which must be followed while creating the key. The entry point for the LAU API is the LAU class. This class provides methods to sing an outgoing message, adding the signature in the security trailer block, and also methods to verify the signature of an incoming message. The LAU signature can be located in two places: As the MDG field in an MT trailer block In the XML v2 (DataPDU) envelop While the trailer block is exclusive for MT messages, the XML v2 (DataPDU) envelop can be used as a wrapper for both MT and MX payloads, and also as a companion file to sign or verify a FileAct exchange. http://api.prowidesoftware.com/integrator/com/prowidesoftware/swift/lau/LAU.html/ Outbound flow When a message is created in the back-office application, the signature should be added. Signing an AbstractMT (computing the MDG trailer) The API receives the message instance and the pair of keys to use, and will compute and add to the message a trailer block \"S\" with the MDG tag containing the calculated signature. String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); LAU lau = new LAU (); lau . sign ( mt , authParams ); After the above call, the mt parameter will contain a trailer like this: {S:{MDG:FA926417A34D0D9235080413FC03B9052B68FD7F3AC41B0C8EADD68FF89064CC}} This is the simplest LAU usage scenario, only available for MT interfaces, with no XML involved. Signing an XML v2 (DataPDU) This section explains how to create the LAU structure, when signing an outbound payload. The API receives the plain XML structure as a String , computes the digest and the signature, and returns a new XML containing the LAU section. The XML v2 in this use case is a wrapper with an MT or MX payload. String signedXml = lau . signXmlV2 ( unsignedXml , new AuthParameters ( leftKey , rightKey )); You can create the parameter unsignedXml with ease from the MtSwiftMessage or MxSwiftMessage using the XmlV2Utils class like this: String unsignedXml = XmlV2Utils . write ( message ); This XmlV2Utils class is used to add or strip this binary prefix from the XML v2 envelop. Notice the XML v2 envelop contains inside a DataPDU XML structure. For details on this structure see the DataPDU documentation. Signing an XML v2 companion file for FileAct LAU signing is also provided for the companion file of FileAct exchanges. In FileAct the actual payload is a file with any format. The payload could be an MX message or any other things. The signing API takes a DataPDU xml for the companion file (you must create and provide this XML) and the content in bytes of the payload file. The API will first compute the payload digest and add it to the companion XML. Then the whole XML digest is calculated and signed. Path path = Paths . get ( \"payload.txt\" ); byte [] data = Files . readAllBytes ( path ); String signedCompanionXml = lau . signFileActXmlV2 ( unsignedCompanionXml , data , new AuthParameters ( leftKey , rightKey )); You then send both the payload.txt file and the created signedCompanionXml files to SAA. If the companion file must also contain the binary prefix, you can further apply the binary prefix computation to that companion file ( Computing the binary prefix for XML v2 ) As for the structure of the companion file, the required content will depend on the type of payload you have to exchange and the configuration in SAA. You can use the DataPDUWriter API to create that file easily. As a reference, the code below will create a companion file when the payload file is an MX: MxPain00100103 mx = MxPain00100103 . parse ( Lib . readResource ( \"Pain001_Message.xml\" )); DataPDUWriter pdu = new DataPDUWriter (); Message pduMessage = new Message (); pdu . getDataPDU (). getHeader (). setMessage ( pduMessage ); pduMessage . setSenderReference ( mx . getCstmrCdtTrfInitn (). getGrpHdr (). getMsgId ()); pduMessage . setMessageIdentifier ( mx . getMxId (). id ()); pduMessage . setFormat ( \"File\" ); pduMessage . setSubFormat ( SubFormat . INPUT ); String senderBIC = mx . getCstmrCdtTrfInitn (). getGrpHdr (). getInitgPty (). getId (). getOrgId (). getBICOrBEI (); LogicalTerminalAddress senderLT = new LogicalTerminalAddress ( senderBIC ); pduMessage . setSender ( new AddressInfo ()); pduMessage . getSender (). setBIC12 ( senderLT . getSenderLogicalTerminalAddress ()); String receiverBIC = mx . getCstmrCdtTrfInitn (). getPmtInf (). get ( 0 ). getDbtrAgt (). getFinInstnId (). getBIC (); LogicalTerminalAddress receiverLT = new LogicalTerminalAddress ( receiverBIC ); pduMessage . setReceiver ( new AddressInfo ()); pduMessage . getReceiver (). setBIC12 ( receiverLT . getReceiverLogicalTerminalAddress ()); pduMessage . setInterfaceInfo ( new InterfaceInfo ()); pduMessage . getInterfaceInfo (). setUserReference ( mx . getCstmrCdtTrfInitn (). getPmtInf (). get ( 0 ). getPmtInfId ()); pduMessage . setNetworkInfo ( new NetworkInfo ()); pduMessage . getNetworkInfo (). setService ( \"swift.corp.fa!p\" ); pduMessage . setFileLogicalName ( \"Pain001_Message.xml\" ); String unsignedCompanionXML = pdu . xml (); Computing the binary prefix for XML v2 Depending on how the SAA is configured, it might be also expecting the binary prefix signature for XML v2. This prefix adds another layer of security to the XML v2 exchanges by computing an HMAC on the transmitted file. This additional signature is added as a binary prefix, before the XML declaration. In this usage scenario you have to do the signing in two steps: First you create the internal LAU structure. String signedXml = lau . signXmlV2 ( xml , authParams ); Then you add the binary prefix signature on top String binPrefixed = lau . signBinaryPrefix ( xml , authParams2 ); The binPrefixed string result will contain both the LAU signature segment inside the DataPDU, and the whole XML prefixed with the binary signature (it contains the 0x1f, etc). Inbound Flow When a message is received from SAA it will already contain the MDG tag in the FIN message or the LAU signature elements in the XML v2 if you receive content from SAA as XML v2 wrappers. In order to ensure the message has not been tampered, the back-office application must verify the signature. Verifying an AbstractMT (MDG trailer) When you receive an MT message containing the MDG trailer, you can verify that the message has not been tampered with: String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); LAU lau = new LAU (); boolean result = lau . verify ( mt , authParams ); If the result of the verification is false, the back-office application should reject the message and follow proper actions to deal with the situation. Verifying an XML v2 (DataPDU) This verification will check the LAU structure in the XML content. The verification involves computing the digest on a canonicalized XML, and computing the signature for the digest. Both the digest and the computed signature should match with the content in the LAU structure to consider the message authenticated. String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); LAU lau = new LAU (); boolean result = lau . verifyXmlV2 ( signedXml , authParams ); If the result of the verification is false, the back-office application should reject the message and follow proper actions to deal with the situation. Once the XML is verified, you can parse its content into an MtSwiftMessage or MxSwiftMessage with ease using the XmlV2Utils class like this: AbstractSwiftMessage message = XmlV2Utils . readMessage ( signedXml ); For more details regarding the above API v2 check the XML v2 section in this guide. Verifying an XML v2 companion file for FileAct This verification is used when you receive from SAA two messages, the actual payload file, and an XML v2 companion file with the signature. In FileAct the actual payload is a file with any format. The payload could be an MX message or any other things. The verification API takes the DataPDU xml for the companion file containing the signature and the content in bytes of the payload file. String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); LAU lau = new LAU (); Path path = Paths . get ( \"payload.txt\" ); byte [] data = Files . readAllBytes ( path ); boolean result = lau . verifyFileActXmlV2 ( signedCompanionXml , data , authParams ); If the result of the verification is false, the back-office application should reject the message and follow proper actions to deal with the situation. Verifying a binary prefix Depending on how the SAA is configured, you might receive the XML v2 messages with a binary prefix. This prefix adds another layer of security to the XML v2 exchanges by computing an HMAC on the transmitted file, and it is independent of the internal LAU structure in the XML. LAU lau = new LAU (); // verify the binary prefix String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); if ( ! lau . verifyBinaryPrefix ( binPrefix , authParams )) { // message not valid } String xml = XmlV2Utils . stripBinaryPrefix ( binPrefix ); // verify the xml signature String rightKey2 = \"Abcd1234abcd1234B\" ; String leftKey2 = \"Abcd1234abcd1234B\" ; AuthParameters authParams2 = new AuthParameters ( rightKey , leftKey ); if ( ! lau . verifyXmlV2 ( xml , authParams2 )) { // message not valid } The snipped above will first check the binary prefix. If that is valid, the prefix is removed from the file content and the LAU structure is verified. When both steps pass the verification, you can rest assured the message has not been tampered. Processing Options for DataPDU The LAU verification (and also the signing) involves first computing a digest, then applying the specific signing algorithm to the computed digest. While the algorithm part is normally explicit and clear, the digest computation is very sensitive to any small change in the payload or in the way to do the canonicalization of the payload. To cape with this, some processing parameters can be adjusted in the LAU object. Like this: // configure LAU for Alliance Lite LAU lau = new LAU(); lau.getProcessingParameters().setIncludeLAUInDigest(true).setSignatureNamespacePrefix(\"dsig\"); // the keys AuthParameters authParams = new AuthParameters(\"Abcd1234abcd1234A\", \"Abcd1234abcd1234A\"); // try to verify message and payload boolean verify = lau.verifyXmlV2(payload, authParams); In the above example the processing parameters is instructed to use an empty element in the digest computation and also to use the \"dssig\" prefix instead of the \"ds\" default. The default processing parameters are kept in sync with what is normally required for SWIFT Alliance Access, while the configuration in the example above is needed when exchanging messages with recent versions of SWIFT Alliance Lite. LAUSigner The LAUSigner is a helper class containing the LAU utility instance along with the pair of keys. It can be thought of as a cache for the keys. To follow the four-eyes principle, the back-office application is expected to distribute each pair of the keys to a different supervisor user so that in order to release a message, both keys are entered in the system. The application can then control whether to ask for the keys for each message or per batch of messages. This class can be used then to hold the provided keys entered by the users in a detached flow than the actual signing and verification. A scenario for this could be to create a LAUSigner instance object and store it in the Spring Context, letting the application just look for the signer and sign messages, while a background thread could deal with key setup and renewal if necessary. The LAUSigner API is straightforward to use. It is created with the AuthParameters and then provides simple methods to sign and verify the messages. http://api.prowidesoftware.com/integrator/com/prowidesoftware/swift/lau/LAUSigner.html/ Non-compliant messages The signature computation is sensitive to the message character encoding. The default API requires the message to be compliant with LAU specification. This means that there are no user defined blocks (except perhaps a Block S), that the FIN representation of the message is composed exclusively of ASCII characters and that the end of lines uses CRLF. When transmitting a message to or from SAA you must ensure the encoding is not altered. In the scenario where a message with non ASCII characters must be signed or verified, for example when working on an alternative (non-SWIFT) network, additional parameters can be passed to the API. The additional parameter ProcessingParameters can be passed to indicate the specific Charset to use in the signature computation, or to indicate the original Charset used to calculate the signature when verifying a received message.","title":"LAU"},{"location":"integrator/sdk/sdk-lau/#lau","text":"The SDK provide API for Local Authentication (LAU) to ensure incoming and outgoing messages are not tempered between the back-office applications and the SWIFT Alliance Access , increasing overall infrastructure security. LAU is based on the industry standard algorithm HMAC-SHA256, and is the only authentication method supported by SAA for transmission of message files to SWIFT. The LAU authentication consists of adding a digital signature calculated using the message body and a pair of shared keys that are uniquely defined for each back-office. In the SAA the keys and the LAU are enabled per Message Partner configuration. The LAU key consists of 32 printable characters entered as two 16 character strings. This allows users to have dual control over the maintenance of these keys. SWIFT has also defined complexity rules which must be followed while creating the key. The entry point for the LAU API is the LAU class. This class provides methods to sing an outgoing message, adding the signature in the security trailer block, and also methods to verify the signature of an incoming message. The LAU signature can be located in two places: As the MDG field in an MT trailer block In the XML v2 (DataPDU) envelop While the trailer block is exclusive for MT messages, the XML v2 (DataPDU) envelop can be used as a wrapper for both MT and MX payloads, and also as a companion file to sign or verify a FileAct exchange. http://api.prowidesoftware.com/integrator/com/prowidesoftware/swift/lau/LAU.html/","title":"LAU"},{"location":"integrator/sdk/sdk-lau/#outbound-flow","text":"When a message is created in the back-office application, the signature should be added.","title":"Outbound flow"},{"location":"integrator/sdk/sdk-lau/#signing-an-abstractmt-computing-the-mdg-trailer","text":"The API receives the message instance and the pair of keys to use, and will compute and add to the message a trailer block \"S\" with the MDG tag containing the calculated signature. String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); LAU lau = new LAU (); lau . sign ( mt , authParams ); After the above call, the mt parameter will contain a trailer like this: {S:{MDG:FA926417A34D0D9235080413FC03B9052B68FD7F3AC41B0C8EADD68FF89064CC}} This is the simplest LAU usage scenario, only available for MT interfaces, with no XML involved.","title":"Signing an AbstractMT (computing the MDG trailer)"},{"location":"integrator/sdk/sdk-lau/#signing-an-xml-v2-datapdu","text":"This section explains how to create the LAU structure, when signing an outbound payload. The API receives the plain XML structure as a String , computes the digest and the signature, and returns a new XML containing the LAU section. The XML v2 in this use case is a wrapper with an MT or MX payload. String signedXml = lau . signXmlV2 ( unsignedXml , new AuthParameters ( leftKey , rightKey )); You can create the parameter unsignedXml with ease from the MtSwiftMessage or MxSwiftMessage using the XmlV2Utils class like this: String unsignedXml = XmlV2Utils . write ( message ); This XmlV2Utils class is used to add or strip this binary prefix from the XML v2 envelop. Notice the XML v2 envelop contains inside a DataPDU XML structure. For details on this structure see the DataPDU documentation.","title":"Signing an XML v2 (DataPDU)"},{"location":"integrator/sdk/sdk-lau/#signing-an-xml-v2-companion-file-for-fileact","text":"LAU signing is also provided for the companion file of FileAct exchanges. In FileAct the actual payload is a file with any format. The payload could be an MX message or any other things. The signing API takes a DataPDU xml for the companion file (you must create and provide this XML) and the content in bytes of the payload file. The API will first compute the payload digest and add it to the companion XML. Then the whole XML digest is calculated and signed. Path path = Paths . get ( \"payload.txt\" ); byte [] data = Files . readAllBytes ( path ); String signedCompanionXml = lau . signFileActXmlV2 ( unsignedCompanionXml , data , new AuthParameters ( leftKey , rightKey )); You then send both the payload.txt file and the created signedCompanionXml files to SAA. If the companion file must also contain the binary prefix, you can further apply the binary prefix computation to that companion file ( Computing the binary prefix for XML v2 ) As for the structure of the companion file, the required content will depend on the type of payload you have to exchange and the configuration in SAA. You can use the DataPDUWriter API to create that file easily. As a reference, the code below will create a companion file when the payload file is an MX: MxPain00100103 mx = MxPain00100103 . parse ( Lib . readResource ( \"Pain001_Message.xml\" )); DataPDUWriter pdu = new DataPDUWriter (); Message pduMessage = new Message (); pdu . getDataPDU (). getHeader (). setMessage ( pduMessage ); pduMessage . setSenderReference ( mx . getCstmrCdtTrfInitn (). getGrpHdr (). getMsgId ()); pduMessage . setMessageIdentifier ( mx . getMxId (). id ()); pduMessage . setFormat ( \"File\" ); pduMessage . setSubFormat ( SubFormat . INPUT ); String senderBIC = mx . getCstmrCdtTrfInitn (). getGrpHdr (). getInitgPty (). getId (). getOrgId (). getBICOrBEI (); LogicalTerminalAddress senderLT = new LogicalTerminalAddress ( senderBIC ); pduMessage . setSender ( new AddressInfo ()); pduMessage . getSender (). setBIC12 ( senderLT . getSenderLogicalTerminalAddress ()); String receiverBIC = mx . getCstmrCdtTrfInitn (). getPmtInf (). get ( 0 ). getDbtrAgt (). getFinInstnId (). getBIC (); LogicalTerminalAddress receiverLT = new LogicalTerminalAddress ( receiverBIC ); pduMessage . setReceiver ( new AddressInfo ()); pduMessage . getReceiver (). setBIC12 ( receiverLT . getReceiverLogicalTerminalAddress ()); pduMessage . setInterfaceInfo ( new InterfaceInfo ()); pduMessage . getInterfaceInfo (). setUserReference ( mx . getCstmrCdtTrfInitn (). getPmtInf (). get ( 0 ). getPmtInfId ()); pduMessage . setNetworkInfo ( new NetworkInfo ()); pduMessage . getNetworkInfo (). setService ( \"swift.corp.fa!p\" ); pduMessage . setFileLogicalName ( \"Pain001_Message.xml\" ); String unsignedCompanionXML = pdu . xml ();","title":"Signing an XML v2 companion file for FileAct"},{"location":"integrator/sdk/sdk-lau/#computing-the-binary-prefix-for-xml-v2","text":"Depending on how the SAA is configured, it might be also expecting the binary prefix signature for XML v2. This prefix adds another layer of security to the XML v2 exchanges by computing an HMAC on the transmitted file. This additional signature is added as a binary prefix, before the XML declaration. In this usage scenario you have to do the signing in two steps: First you create the internal LAU structure. String signedXml = lau . signXmlV2 ( xml , authParams ); Then you add the binary prefix signature on top String binPrefixed = lau . signBinaryPrefix ( xml , authParams2 ); The binPrefixed string result will contain both the LAU signature segment inside the DataPDU, and the whole XML prefixed with the binary signature (it contains the 0x1f, etc).","title":"Computing the binary prefix for XML v2"},{"location":"integrator/sdk/sdk-lau/#inbound-flow","text":"When a message is received from SAA it will already contain the MDG tag in the FIN message or the LAU signature elements in the XML v2 if you receive content from SAA as XML v2 wrappers. In order to ensure the message has not been tampered, the back-office application must verify the signature.","title":"Inbound Flow"},{"location":"integrator/sdk/sdk-lau/#verifying-an-abstractmt-mdg-trailer","text":"When you receive an MT message containing the MDG trailer, you can verify that the message has not been tampered with: String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); LAU lau = new LAU (); boolean result = lau . verify ( mt , authParams ); If the result of the verification is false, the back-office application should reject the message and follow proper actions to deal with the situation.","title":"Verifying an AbstractMT (MDG trailer)"},{"location":"integrator/sdk/sdk-lau/#verifying-an-xml-v2-datapdu","text":"This verification will check the LAU structure in the XML content. The verification involves computing the digest on a canonicalized XML, and computing the signature for the digest. Both the digest and the computed signature should match with the content in the LAU structure to consider the message authenticated. String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); LAU lau = new LAU (); boolean result = lau . verifyXmlV2 ( signedXml , authParams ); If the result of the verification is false, the back-office application should reject the message and follow proper actions to deal with the situation. Once the XML is verified, you can parse its content into an MtSwiftMessage or MxSwiftMessage with ease using the XmlV2Utils class like this: AbstractSwiftMessage message = XmlV2Utils . readMessage ( signedXml ); For more details regarding the above API v2 check the XML v2 section in this guide.","title":"Verifying an XML v2 (DataPDU)"},{"location":"integrator/sdk/sdk-lau/#verifying-an-xml-v2-companion-file-for-fileact","text":"This verification is used when you receive from SAA two messages, the actual payload file, and an XML v2 companion file with the signature. In FileAct the actual payload is a file with any format. The payload could be an MX message or any other things. The verification API takes the DataPDU xml for the companion file containing the signature and the content in bytes of the payload file. String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); LAU lau = new LAU (); Path path = Paths . get ( \"payload.txt\" ); byte [] data = Files . readAllBytes ( path ); boolean result = lau . verifyFileActXmlV2 ( signedCompanionXml , data , authParams ); If the result of the verification is false, the back-office application should reject the message and follow proper actions to deal with the situation.","title":"Verifying an XML v2 companion file for FileAct"},{"location":"integrator/sdk/sdk-lau/#verifying-a-binary-prefix","text":"Depending on how the SAA is configured, you might receive the XML v2 messages with a binary prefix. This prefix adds another layer of security to the XML v2 exchanges by computing an HMAC on the transmitted file, and it is independent of the internal LAU structure in the XML. LAU lau = new LAU (); // verify the binary prefix String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); if ( ! lau . verifyBinaryPrefix ( binPrefix , authParams )) { // message not valid } String xml = XmlV2Utils . stripBinaryPrefix ( binPrefix ); // verify the xml signature String rightKey2 = \"Abcd1234abcd1234B\" ; String leftKey2 = \"Abcd1234abcd1234B\" ; AuthParameters authParams2 = new AuthParameters ( rightKey , leftKey ); if ( ! lau . verifyXmlV2 ( xml , authParams2 )) { // message not valid } The snipped above will first check the binary prefix. If that is valid, the prefix is removed from the file content and the LAU structure is verified. When both steps pass the verification, you can rest assured the message has not been tampered.","title":"Verifying a binary prefix"},{"location":"integrator/sdk/sdk-lau/#processing-options-for-datapdu","text":"The LAU verification (and also the signing) involves first computing a digest, then applying the specific signing algorithm to the computed digest. While the algorithm part is normally explicit and clear, the digest computation is very sensitive to any small change in the payload or in the way to do the canonicalization of the payload. To cape with this, some processing parameters can be adjusted in the LAU object. Like this: // configure LAU for Alliance Lite LAU lau = new LAU(); lau.getProcessingParameters().setIncludeLAUInDigest(true).setSignatureNamespacePrefix(\"dsig\"); // the keys AuthParameters authParams = new AuthParameters(\"Abcd1234abcd1234A\", \"Abcd1234abcd1234A\"); // try to verify message and payload boolean verify = lau.verifyXmlV2(payload, authParams); In the above example the processing parameters is instructed to use an empty element in the digest computation and also to use the \"dssig\" prefix instead of the \"ds\" default. The default processing parameters are kept in sync with what is normally required for SWIFT Alliance Access, while the configuration in the example above is needed when exchanging messages with recent versions of SWIFT Alliance Lite.","title":"Processing Options for DataPDU"},{"location":"integrator/sdk/sdk-lau/#lausigner","text":"The LAUSigner is a helper class containing the LAU utility instance along with the pair of keys. It can be thought of as a cache for the keys. To follow the four-eyes principle, the back-office application is expected to distribute each pair of the keys to a different supervisor user so that in order to release a message, both keys are entered in the system. The application can then control whether to ask for the keys for each message or per batch of messages. This class can be used then to hold the provided keys entered by the users in a detached flow than the actual signing and verification. A scenario for this could be to create a LAUSigner instance object and store it in the Spring Context, letting the application just look for the signer and sign messages, while a background thread could deal with key setup and renewal if necessary. The LAUSigner API is straightforward to use. It is created with the AuthParameters and then provides simple methods to sign and verify the messages. http://api.prowidesoftware.com/integrator/com/prowidesoftware/swift/lau/LAUSigner.html/","title":"LAUSigner"},{"location":"integrator/sdk/sdk-lau/#non-compliant-messages","text":"The signature computation is sensitive to the message character encoding. The default API requires the message to be compliant with LAU specification. This means that there are no user defined blocks (except perhaps a Block S), that the FIN representation of the message is composed exclusively of ASCII characters and that the end of lines uses CRLF. When transmitting a message to or from SAA you must ensure the encoding is not altered. In the scenario where a message with non ASCII characters must be signed or verified, for example when working on an alternative (non-SWIFT) network, additional parameters can be passed to the API. The additional parameter ProcessingParameters can be passed to indicate the specific Charset to use in the signature computation, or to indicate the original Charset used to calculate the signature when verifying a received message.","title":"Non-compliant messages"},{"location":"integrator/sdk/sdk-mtpath/","text":"MT Path This unique feature of the SDK gives the possibility to query MT messages content by means of path expressions ( analogous to XML XPath). The syntax and semantics of this path expression is proprietary and particularly designed for MT messages, based on the understanding that besides being a plain list of fields, the underlying structure of MT messages can be processed like a tree conformed by blocks, sequences, subsequences, and fields. A path is then composed by the following steps: BLOCK / SEQUENCE[*] / FIELD / QUALIFIER / (COMPONENT | COMPONENT_NAME) / LINE Where at least a field or a sequence must be present, while all other items are optional. Depending on the path expression, the target element to find may be a set of fields or a set of sequences. Query for fields Example of path expressions referencing fields , and fields components: b3/108 gets the value of field 108 at block header 3. A/20C/SEME gets value of generic field 20C, with qualifier SEME at sequence A B1[2]/98A/2 gets component 2, of field 98A in the second instance of sequence B1 50K/NameAndAddress selects the \"NameAndAddress\" component, of field 50K 93a gets value of fields 93, for any letter option found b1/LogicalTerminal gets the logical terminal field of header block 1 Notice from the above examples that path may refer to fields in the text block (block 4) but also in the header blocks. The field is mandatory when the expected target is a field, but the rest of elements (sequence, qualifier, component, line) are optional. Also notice that the component name must comply the Camel Case format. Examples of compliant component names are: FINCopyServiceCode TypeOfAgreement NumberOfAmendment The Line indication can be used within field path expressions to retrieve a specific line within the field's value. 59/Line[2] gets the second line of component 59, with the name & address information. Notice that this will perform a semantic line retrieval based on the field components definition, so this is not the same as just splitting the value in lines and getting one of the lines with an index. If the field defines the first line components as optional and those components are not present in the particular field instance, then Line[1] will return null because according to the field definition the first line is not present. The Line step can be particularly useful combined with a component indication. For example, for field 70E the narrative content starts from the second component. So the following examples show how to get specific lines of the field\u2019s narrative text. 70E/2/Line[1] gets the first line of the narrative, notice the component 2 is the narrative and is used as an offset for the line selector 70E/2/Line[*] gets all text of the narrative, notice the * is used to select all lines, and the component indication offset, so the lines are gathered starting from the narrative component. The examples above can be also expressed using the component name instead of the component number. The result will be exactly the same: 70E/Narrative/Line[1] 70E/Narrative/Line[*] Query for sequences When the target element is a sequence, the path has a similar syntax but the field, component, qualifier, and line elements are not present. Example of path expressions referencing sequences , and fields components: A1 gets all sequences A1. A1a[2] gets the second instance of sequence A1 for the indicated second instance of A1a Sequence steps include additional capacities. First, the path can contain more than one sequence step, giving the capacity to chain several sequences and subsequences indications to define a very specific portion of the message tree structure. Second, it supports axes. Sequence axis Unlike axis in strict XML XPath, where the axis defines a node-set relative to the current node; in MtPath the implementation of axis support is limited to parent and child , and only admitted in sequence steps. Parent The parent axis is used to get the parent sequence in any sequence step. A[1]/A1[2]/A1a gets all sequences A1a within the second instance of A1, within the first instance of A. parent::A1a[2] gets the container sequence A1 for the indicated second instance of A1a All this can be combined to define more complex paths, for example: A/parent::A1b[3]/95P/ACOW/3 gets component 3, of all fields 95P in the parent sequence of each third instance of a subsequence A1b The parent axis is particularly useful in situations where you would use the unsupported double dot (\"..\") to traverse up in the sequence tree. For example, if you have an MtPathResult with a sequence, and you want to query a field in the parent sequence of that current position. You would then create a path using the parent axis, running the evaluation with the current MtPathResult as starting point (current node). Child The child axis is used to indicate that the field, component or line to retrieve must be a direct child of the contained sequence. E/98A gets all fields 98A in either E or further subsequences such as E1 or E2. While this: child::E/98A gets all fields 98A that are direct children of sequence E, meaning it will not return 98A occurrences in subsequences such as E1 or E2. Notice by default all MtPath expressions result in any sequence descendant. So, in situations where the queried field can be present on the target sequence but also on subsequences, this axis is useful to clearly determine if the query will be on direct elements or on any descendant. In strict XML XPath the double slash (\"//\") is used when the search must be in any descendant of a step. Also, worth mentioning the child axis only makes sense in the last sequence step. A query with child:E/E1 will return no results because sequences E1 will be removed from the result set then the child:E step is processed. Sample code The following example shows how to perform a simple path query on an MT message. It gets second component of field 20C with qualifier SEME: MT535 mt = MT535 . parse (...); List < MtPathResult > found = MtPath . evaluate ( \"20C/SEME/2\" , mt ); System . out . println ( found . get ( 0 ). getComponent ()); The result of the query is always a List and these result objects are hybrid containers for sequences, fields, or components. The following sample is equivalent to the one above, but using the component name instead of the component number: MT535 mt = MT535 . parse (...); List < MtPathResult > found = MtPath . evaluate ( \"20C/SEME/Reference\" , mt ); System . out . println ( found . get ( 0 ). getComponent ()); This other example shows how to search for all instances of field 93, any letter option, in any instance of sequence B; printing out the value of each found field. Notice in this example we gather the actual fields from the result, while in the previous one we\u2019ve printed the component. found = MtPath . evaluate ( \"B[*]/93a\" , mt ); for ( MtPathResult f : found ) { System . out . println ( f . getField (). getValue ()); } The result will be properly populated with the found content according to the processed path expression. For example, if the expression references a sequence with no field information, the MtPathResult object will contain the found sequences while the field and component attributes will be left null. If the path references a field, then the MtPathResult will contain each found field along with its containing sequence. And finally if the path references a component, the result will contain the found component value, but also the field where the component was found, and the container sequence of such a field. In other terms, when searching for components we are also searching for fields, and when searching for fields we are also searching for sequences. Check the javadoc for more API options. Queries can also be nested, providing an MtPathResult as \"current node\" for the expression evaluation. This is particularly useful if you have a query to retrieve sequences, and then you iterate the sequences running more queries to get fields within the current sequence in the loop. ACK content selection The service 21 messages (ACK and NAK) have a different structure for block 4. Instead of fields in multiple lines, all fields are contained in inner blocks. From the MtPath expression, this difference in the structure is the same, and you can retrieve the content with the same expressions as for any other message type. For example: String fin = \"{1:F21BBBBARB1A0B20509002124}{4:{177:2011140437}{451:0}}\" ; AbstractMT mt = AbstractMT . parse ( fin ); List < MtPathResult > found = MtPath . evaluate ( \"451\" , mt ); System . out . println ( found . get ( 0 ). value ()); The result of the query will be the value \"0\" from the ACK block 4. Then, if the ACK/NAK contains the original sent message attached as a suffix after the service 21 message, a special keyword @attach can be used to select content from the original message. For example: String fin = \"{1:F21BBBBARB1A0B20509002124}{4:{177:2011140437}{451:0}}\" + \"{1:F01AAAAARB1A0B20509002124}{2:I999ADRBNL21XXXXN}{4:\\n\" + \":20:REFERENCE123\\n\" + \":21:REPORT ABC NAN\\n\" + \":79:TEST FOO BAR\\n\" + \"-}\" ; AbstractMT mt = AbstractMT . parse ( fin ); List < MtPathResult > found = MtPath . evaluate ( \"@attach/20\" , mt ); System . out . println ( found . get ( 0 ). value ()); The result of the query will be the value \"REFERENCE123\" from the block 4 of the original sent message, present after the ACK content. The @attach can be combined with any type of path expressions, such as: @attach/b1/LogicalTerminal @attach/b2 @attach/59/Line[2] @attach/32A/2 @attach/90B/AmountTypeCode Alternatively, the @main keyword can be used to retrieve content from the original message attached to an ACK/NAK The @main can be used as follows: * @main/b1/LogicalTerminal * @main/b4 More path expression examples can be found at https://github.com/prowide/ MtPath to build messages The MtPath expressions can also be used to build messages, leveraging the MtWriter component from the MyFormat library. The MtWriter exposes a method write that takes an MtPath expression and a value to write in the target message, and internally creates the necessary sequences and fields to write the content. Check the MyFormat documentation for more details on how to use the MtWriter to build messages.","title":"MT Path"},{"location":"integrator/sdk/sdk-mtpath/#mt-path","text":"This unique feature of the SDK gives the possibility to query MT messages content by means of path expressions ( analogous to XML XPath). The syntax and semantics of this path expression is proprietary and particularly designed for MT messages, based on the understanding that besides being a plain list of fields, the underlying structure of MT messages can be processed like a tree conformed by blocks, sequences, subsequences, and fields. A path is then composed by the following steps: BLOCK / SEQUENCE[*] / FIELD / QUALIFIER / (COMPONENT | COMPONENT_NAME) / LINE Where at least a field or a sequence must be present, while all other items are optional. Depending on the path expression, the target element to find may be a set of fields or a set of sequences.","title":"MT Path"},{"location":"integrator/sdk/sdk-mtpath/#query-for-fields","text":"Example of path expressions referencing fields , and fields components: b3/108 gets the value of field 108 at block header 3. A/20C/SEME gets value of generic field 20C, with qualifier SEME at sequence A B1[2]/98A/2 gets component 2, of field 98A in the second instance of sequence B1 50K/NameAndAddress selects the \"NameAndAddress\" component, of field 50K 93a gets value of fields 93, for any letter option found b1/LogicalTerminal gets the logical terminal field of header block 1 Notice from the above examples that path may refer to fields in the text block (block 4) but also in the header blocks. The field is mandatory when the expected target is a field, but the rest of elements (sequence, qualifier, component, line) are optional. Also notice that the component name must comply the Camel Case format. Examples of compliant component names are: FINCopyServiceCode TypeOfAgreement NumberOfAmendment The Line indication can be used within field path expressions to retrieve a specific line within the field's value. 59/Line[2] gets the second line of component 59, with the name & address information. Notice that this will perform a semantic line retrieval based on the field components definition, so this is not the same as just splitting the value in lines and getting one of the lines with an index. If the field defines the first line components as optional and those components are not present in the particular field instance, then Line[1] will return null because according to the field definition the first line is not present. The Line step can be particularly useful combined with a component indication. For example, for field 70E the narrative content starts from the second component. So the following examples show how to get specific lines of the field\u2019s narrative text. 70E/2/Line[1] gets the first line of the narrative, notice the component 2 is the narrative and is used as an offset for the line selector 70E/2/Line[*] gets all text of the narrative, notice the * is used to select all lines, and the component indication offset, so the lines are gathered starting from the narrative component. The examples above can be also expressed using the component name instead of the component number. The result will be exactly the same: 70E/Narrative/Line[1] 70E/Narrative/Line[*]","title":"Query for fields"},{"location":"integrator/sdk/sdk-mtpath/#query-for-sequences","text":"When the target element is a sequence, the path has a similar syntax but the field, component, qualifier, and line elements are not present. Example of path expressions referencing sequences , and fields components: A1 gets all sequences A1. A1a[2] gets the second instance of sequence A1 for the indicated second instance of A1a Sequence steps include additional capacities. First, the path can contain more than one sequence step, giving the capacity to chain several sequences and subsequences indications to define a very specific portion of the message tree structure. Second, it supports axes.","title":"Query for sequences"},{"location":"integrator/sdk/sdk-mtpath/#sequence-axis","text":"Unlike axis in strict XML XPath, where the axis defines a node-set relative to the current node; in MtPath the implementation of axis support is limited to parent and child , and only admitted in sequence steps. Parent The parent axis is used to get the parent sequence in any sequence step. A[1]/A1[2]/A1a gets all sequences A1a within the second instance of A1, within the first instance of A. parent::A1a[2] gets the container sequence A1 for the indicated second instance of A1a All this can be combined to define more complex paths, for example: A/parent::A1b[3]/95P/ACOW/3 gets component 3, of all fields 95P in the parent sequence of each third instance of a subsequence A1b The parent axis is particularly useful in situations where you would use the unsupported double dot (\"..\") to traverse up in the sequence tree. For example, if you have an MtPathResult with a sequence, and you want to query a field in the parent sequence of that current position. You would then create a path using the parent axis, running the evaluation with the current MtPathResult as starting point (current node). Child The child axis is used to indicate that the field, component or line to retrieve must be a direct child of the contained sequence. E/98A gets all fields 98A in either E or further subsequences such as E1 or E2. While this: child::E/98A gets all fields 98A that are direct children of sequence E, meaning it will not return 98A occurrences in subsequences such as E1 or E2. Notice by default all MtPath expressions result in any sequence descendant. So, in situations where the queried field can be present on the target sequence but also on subsequences, this axis is useful to clearly determine if the query will be on direct elements or on any descendant. In strict XML XPath the double slash (\"//\") is used when the search must be in any descendant of a step. Also, worth mentioning the child axis only makes sense in the last sequence step. A query with child:E/E1 will return no results because sequences E1 will be removed from the result set then the child:E step is processed.","title":"Sequence axis"},{"location":"integrator/sdk/sdk-mtpath/#sample-code","text":"The following example shows how to perform a simple path query on an MT message. It gets second component of field 20C with qualifier SEME: MT535 mt = MT535 . parse (...); List < MtPathResult > found = MtPath . evaluate ( \"20C/SEME/2\" , mt ); System . out . println ( found . get ( 0 ). getComponent ()); The result of the query is always a List and these result objects are hybrid containers for sequences, fields, or components. The following sample is equivalent to the one above, but using the component name instead of the component number: MT535 mt = MT535 . parse (...); List < MtPathResult > found = MtPath . evaluate ( \"20C/SEME/Reference\" , mt ); System . out . println ( found . get ( 0 ). getComponent ()); This other example shows how to search for all instances of field 93, any letter option, in any instance of sequence B; printing out the value of each found field. Notice in this example we gather the actual fields from the result, while in the previous one we\u2019ve printed the component. found = MtPath . evaluate ( \"B[*]/93a\" , mt ); for ( MtPathResult f : found ) { System . out . println ( f . getField (). getValue ()); } The result will be properly populated with the found content according to the processed path expression. For example, if the expression references a sequence with no field information, the MtPathResult object will contain the found sequences while the field and component attributes will be left null. If the path references a field, then the MtPathResult will contain each found field along with its containing sequence. And finally if the path references a component, the result will contain the found component value, but also the field where the component was found, and the container sequence of such a field. In other terms, when searching for components we are also searching for fields, and when searching for fields we are also searching for sequences. Check the javadoc for more API options. Queries can also be nested, providing an MtPathResult as \"current node\" for the expression evaluation. This is particularly useful if you have a query to retrieve sequences, and then you iterate the sequences running more queries to get fields within the current sequence in the loop.","title":"Sample code"},{"location":"integrator/sdk/sdk-mtpath/#ack-content-selection","text":"The service 21 messages (ACK and NAK) have a different structure for block 4. Instead of fields in multiple lines, all fields are contained in inner blocks. From the MtPath expression, this difference in the structure is the same, and you can retrieve the content with the same expressions as for any other message type. For example: String fin = \"{1:F21BBBBARB1A0B20509002124}{4:{177:2011140437}{451:0}}\" ; AbstractMT mt = AbstractMT . parse ( fin ); List < MtPathResult > found = MtPath . evaluate ( \"451\" , mt ); System . out . println ( found . get ( 0 ). value ()); The result of the query will be the value \"0\" from the ACK block 4. Then, if the ACK/NAK contains the original sent message attached as a suffix after the service 21 message, a special keyword @attach can be used to select content from the original message. For example: String fin = \"{1:F21BBBBARB1A0B20509002124}{4:{177:2011140437}{451:0}}\" + \"{1:F01AAAAARB1A0B20509002124}{2:I999ADRBNL21XXXXN}{4:\\n\" + \":20:REFERENCE123\\n\" + \":21:REPORT ABC NAN\\n\" + \":79:TEST FOO BAR\\n\" + \"-}\" ; AbstractMT mt = AbstractMT . parse ( fin ); List < MtPathResult > found = MtPath . evaluate ( \"@attach/20\" , mt ); System . out . println ( found . get ( 0 ). value ()); The result of the query will be the value \"REFERENCE123\" from the block 4 of the original sent message, present after the ACK content. The @attach can be combined with any type of path expressions, such as: @attach/b1/LogicalTerminal @attach/b2 @attach/59/Line[2] @attach/32A/2 @attach/90B/AmountTypeCode Alternatively, the @main keyword can be used to retrieve content from the original message attached to an ACK/NAK The @main can be used as follows: * @main/b1/LogicalTerminal * @main/b4 More path expression examples can be found at https://github.com/prowide/","title":"ACK content selection"},{"location":"integrator/sdk/sdk-mtpath/#mtpath-to-build-messages","text":"The MtPath expressions can also be used to build messages, leveraging the MtWriter component from the MyFormat library. The MtWriter exposes a method write that takes an MtPath expression and a value to write in the target message, and internally creates the necessary sequences and fields to write the content. Check the MyFormat documentation for more details on how to use the MtWriter to build messages.","title":"MtPath to build messages"},{"location":"integrator/sdk/sdk-printout/","text":"Expanded printout The expanded printout generates a human-friendly representation of a message content, including: Comprehensive labels for sequences, fields, and components Expanded BIC information with the institution name and location Formatted dates and amounts The implementation is generic and can be applied to any MT or MX (ISO 20022) message. MT Printout The main entry point for the feature is the PrintoutWriter class and the print methods. The printout can be done directly into a String object, or an OutputStream can be passed as argument. The following example illustrates the default printout in TXT format for an MT103: ------------------------- Instance Type and Transmission ------------------------- Copy sent to SWIFT Priority/Delivery : Urgent/Delivery Notification ------------------------- Message Header ----------------------------------------- Swift : FIN 103 Single Customer Credit Transfer Sender : XBDSJPJTBXXX - FOO CAPITAL MARKETS (JAPAN) LTD., TOKYO (JAPAN) Receiver : XOJPJPJTXMF1 - BANK OF FOOBAR - (FOR FOOOBAR'S RESERVES USE ONLY) (JAPAN) MUR : FOOB3926BE868XXX ------------------------- Message Text ------------------------------------------- 20: Sender's Reference Reference: 11111111 23B: Bank Operation Code Type: CRED 32A: Value Date/Currency/Interbank Settled Amount Date: Feb 4, 2013 Currency: EUR Amount: 1,234,567.89 33B: Currency/Instructed Amount Currency: USD Amount: 89,431.4 50A: Ordering Customer Account: 12345678901234567890 BIC: AAAAUS33XXX - FOOBAR AND CO. INC. () 59: Beneficiary Customer Account: 12345678901234567890 Name And Address: JOE DOE Name And Address 2: MyStreet 1234 71A: Details of Charges Code: OUR ------------------------- Message Trailer ----------------------------------------- CHK: 3916EF336FF7 Sequences, fields and components are printed with label. BICs are expanded with the institution name and location. Dates and amounts are formatted. Please check the sample below about how to create a printout similar to the one listed above. SwiftMessage m = SwiftMessage . parse ( \"{1:F01XBDSJPJTBXXX0000000000}{2:I103XOJPJPJTXMF1U2}{3:{108:FOOB3926BE868XXX}}{4:\\n\" + \":20:11111111\\n\" + \":23B:CRED\\n\" + \":32A:130204EUR1234567,89\\n\" + \":33B:USD89431,40\\n\" + \":50A:/12345678901234567890\\n\" + \"AAAAUS33XXX\\n\" + \":59:/12345678901234567890\\n\" + \"JOE DOE\\n\" + \"MyStreet 1234\\n\" + \":71A:OUR\\n\" + \"-}\" ); final String text = new PrintoutWriter (). print ( m ); System . out . println ( text ); Localization The default output prints labels using the default locale, however a specific locale can be passed in the constructor. Current supported languages are English, Spanish, Russian, French, German, and Italian . If a different locale is configured or passed as an argument, or if a particular label is not found in the specific locale, the printing falls back to English as default. MT Info The MTInfo is a helper class to retrieve message information (label, descriptions) from resource bundles and to print formatted field values. It is used by the printout feature, but can be used independently as well. The resource bundles include translations for English, Spanish, Russian, French, German, and Italian . These labels are provided in the pw_mt_info.properties files. The object is instantiated provided a Locale and a specific MT message object. Then API is provided to retrieve fields and sequence labels for the particular MT. MX Printout A similar printout can be generated for MX messages using the MxPrintoutWriter . The output is slightly different. The following example illustrates the default printout in TXT format for an pacs.009: ------------------------- Instance Type and Transmission ------------------------- Copy sent to SWIFT Priority : Normal ------------------------- Message Header ----------------------------------------- Message Type : pacs.009.001.08 - Financial Institution Credit Transfer V08 Sender : AAAAFRPBTGT - FOO BANK OF CANADA, PARIS BRANCH - (TARGET) (FRANCE) Receiver : BBBBDEFFXXX - FOOBAR BANK AG (GERMANY) Reference : FOOJUNE01234 Service Name : swift.cbprplus.02 Creation : 2022-11-11T11:11:11Z ----------------------------- Document ------------------------------------------- Group Header Message Identification : NONREF Creation Date Time : 2022-06-02T20:04:35-04:00 Number Of Transactions : 1 Settlement Information Settlement Method : CLRG Clearing System Code : TGT Credit Transfer Transaction Information Payment Identification Instruction Identification : FOO TEST 5 End To End Identification : FOOJUNE0222T5 UETR : 145c2054-dc14-4b95-93a3-f8e99a712345 Interbank Settlement Amount : EUR 567 Interbank Settlement Date : 2022-11-11 Instructing Agent Financial Institution Identification BICFI : AAAAFRPBTGT - FOO BANK OF CANADA, PARIS BRANCH - (TARGET) (FRANCE) Instructed Agent Financial Institution Identification BICFI : BBBBDEFFXXX - FOOBAR BANK AG (GERMANY) Debtor Financial Institution Identification BICFI : CCCCFRPBTGT - FOO BANK OF CANADA, PARIS BRANCH - (TARGET) (FRANCE) Creditor Financial Institution Identification BICFI : DDDDDEFFXXX - FOOBAR BANK AG (GERMANY) The nested structure of the actual XML is printed with nested indentation. Then BIC information is expanded with the institution name and location, and dates and amounts are formatted. Please check the sample below about how to obtain a printout similar to the one listed above. String xmlInput = \"\\n\" + \"\\n\" + \"\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" AAAAFRPBTGT\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" BBBBDEFFXXX\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" FOOJUNE01234\\n\" + \" pacs.009.001.08\\n\" + \" swift.cbprplus.02\\n\" + \" Normal\\n\" + \" 2022-11-11T11:11:11Z\\n\" + \"\\n\" + \"\\n\" + \" \\n\" + \" \\n\" + \" NONREF\\n\" + \" 2022-06-02T20:04:35-04:00\\n\" + \" 1\\n\" + \" \\n\" + \" CLRG\\n\" + \" \\n\" + \" TGT\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" FOO TEST 5\\n\" + \" FOOJUNE0222T5\\n\" + \" 145c2054-dc14-4b95-93a3-f8e99a712345\\n\" + \" \\n\" + \" 567\\n\" + \" 2022-11-11\\n\" + \" \\n\" + \" \\n\" + \" AAAAFRPBTGT\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" BBBBDEFFXXX\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" CCCCFRPBTGT\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" DDDDDEFFXXX\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \"\\n\" + \"\" ; MxSwiftMessage m = MxSwiftMessage . parse ( xmlInput ); m . setDirection ( MessageIOType . outgoing ); MxPrintoutWriter mxPrintoutWriter = new MxPrintoutWriter ( Locale . ENGLISH , new MxTxtPrintoutVisitor ()); System . out . println ( mxPrintoutWriter . print ( m )); MX Info The MXInfo is a helper class to retrieve ISO 20022 labels for message elements. This classe is created after an ISO 20022 enriched schema, containing documentation annotations. On creation, the XSD is traversed and the labels are stored in a map. MxLabelInfo labelInfo = new MxLabelInfo(MxType.pacs_008_001_10.schema()); Then given a path to a specific element in the specific MX, a similar complete path is returned with the segments as human-friendly labels. For example given the path; /Document/FIToFICstmrCdtTrf/CdtTrfTxInf/InstgAgt/FinInstnId/PstlAdr/DstrctNm the method returns: /Document/FIToFICustomerCreditTransferV10/CreditTransferTransactionInformation/InstructingAgent/FinancialInstitutionIdentification/PostalAddress/DistrictName This is what the MxPrintoutWriter uses to print the MX messages. Customization All aspects of the printout can be customized by providing an implementation of the PrintoutVisitor interface. The methods in this interface are called in a specific order, passing a portion of data retrieved from the message and expecting the output in return. Default implementations for the interface are provided for TXT and HTML formats. As an alternative to implementing the interface from scratch, the default implementations for TXT and HTML can be extended in order to provide an alternative implementation just for specific methods. The interface could be use even to generate a JSON version of the message content, with labels. BIC data A BIC directory is used to print the institution name along with the BIC. By default, the printout uses the default implementation of IBICDirectory from the BICDirectory class. This class uses an Apache Derby DB contained in the pw-swift-integrator-data-1.X.X.jar file. This DB contains the BIC data from the SWIFT BIC directory, and can be updated by you. If you already have a BIC data source and want to use it, you can implement the IBICDirectory interface and pass it to the printout writer constructor. If you do not need the BIC data and want to avoid adding the data jar as dependency, you can pass null to the printout writer constructor like this: PrintoutWriter printoutWriter = new PrintoutWriter ( Locale . ENGLISH , new TxtPrintoutVisitor (), null ); final String text = printoutWriter . print ( m ); Then whenever a BIC is found in the message, it will be printed as is, without the institution name.","title":"Expanded printout"},{"location":"integrator/sdk/sdk-printout/#expanded-printout","text":"The expanded printout generates a human-friendly representation of a message content, including: Comprehensive labels for sequences, fields, and components Expanded BIC information with the institution name and location Formatted dates and amounts The implementation is generic and can be applied to any MT or MX (ISO 20022) message.","title":"Expanded printout"},{"location":"integrator/sdk/sdk-printout/#mt-printout","text":"The main entry point for the feature is the PrintoutWriter class and the print methods. The printout can be done directly into a String object, or an OutputStream can be passed as argument. The following example illustrates the default printout in TXT format for an MT103: ------------------------- Instance Type and Transmission ------------------------- Copy sent to SWIFT Priority/Delivery : Urgent/Delivery Notification ------------------------- Message Header ----------------------------------------- Swift : FIN 103 Single Customer Credit Transfer Sender : XBDSJPJTBXXX - FOO CAPITAL MARKETS (JAPAN) LTD., TOKYO (JAPAN) Receiver : XOJPJPJTXMF1 - BANK OF FOOBAR - (FOR FOOOBAR'S RESERVES USE ONLY) (JAPAN) MUR : FOOB3926BE868XXX ------------------------- Message Text ------------------------------------------- 20: Sender's Reference Reference: 11111111 23B: Bank Operation Code Type: CRED 32A: Value Date/Currency/Interbank Settled Amount Date: Feb 4, 2013 Currency: EUR Amount: 1,234,567.89 33B: Currency/Instructed Amount Currency: USD Amount: 89,431.4 50A: Ordering Customer Account: 12345678901234567890 BIC: AAAAUS33XXX - FOOBAR AND CO. INC. () 59: Beneficiary Customer Account: 12345678901234567890 Name And Address: JOE DOE Name And Address 2: MyStreet 1234 71A: Details of Charges Code: OUR ------------------------- Message Trailer ----------------------------------------- CHK: 3916EF336FF7 Sequences, fields and components are printed with label. BICs are expanded with the institution name and location. Dates and amounts are formatted. Please check the sample below about how to create a printout similar to the one listed above. SwiftMessage m = SwiftMessage . parse ( \"{1:F01XBDSJPJTBXXX0000000000}{2:I103XOJPJPJTXMF1U2}{3:{108:FOOB3926BE868XXX}}{4:\\n\" + \":20:11111111\\n\" + \":23B:CRED\\n\" + \":32A:130204EUR1234567,89\\n\" + \":33B:USD89431,40\\n\" + \":50A:/12345678901234567890\\n\" + \"AAAAUS33XXX\\n\" + \":59:/12345678901234567890\\n\" + \"JOE DOE\\n\" + \"MyStreet 1234\\n\" + \":71A:OUR\\n\" + \"-}\" ); final String text = new PrintoutWriter (). print ( m ); System . out . println ( text );","title":"MT Printout"},{"location":"integrator/sdk/sdk-printout/#localization","text":"The default output prints labels using the default locale, however a specific locale can be passed in the constructor. Current supported languages are English, Spanish, Russian, French, German, and Italian . If a different locale is configured or passed as an argument, or if a particular label is not found in the specific locale, the printing falls back to English as default.","title":"Localization"},{"location":"integrator/sdk/sdk-printout/#mt-info","text":"The MTInfo is a helper class to retrieve message information (label, descriptions) from resource bundles and to print formatted field values. It is used by the printout feature, but can be used independently as well. The resource bundles include translations for English, Spanish, Russian, French, German, and Italian . These labels are provided in the pw_mt_info.properties files. The object is instantiated provided a Locale and a specific MT message object. Then API is provided to retrieve fields and sequence labels for the particular MT.","title":"MT Info"},{"location":"integrator/sdk/sdk-printout/#mx-printout","text":"A similar printout can be generated for MX messages using the MxPrintoutWriter . The output is slightly different. The following example illustrates the default printout in TXT format for an pacs.009: ------------------------- Instance Type and Transmission ------------------------- Copy sent to SWIFT Priority : Normal ------------------------- Message Header ----------------------------------------- Message Type : pacs.009.001.08 - Financial Institution Credit Transfer V08 Sender : AAAAFRPBTGT - FOO BANK OF CANADA, PARIS BRANCH - (TARGET) (FRANCE) Receiver : BBBBDEFFXXX - FOOBAR BANK AG (GERMANY) Reference : FOOJUNE01234 Service Name : swift.cbprplus.02 Creation : 2022-11-11T11:11:11Z ----------------------------- Document ------------------------------------------- Group Header Message Identification : NONREF Creation Date Time : 2022-06-02T20:04:35-04:00 Number Of Transactions : 1 Settlement Information Settlement Method : CLRG Clearing System Code : TGT Credit Transfer Transaction Information Payment Identification Instruction Identification : FOO TEST 5 End To End Identification : FOOJUNE0222T5 UETR : 145c2054-dc14-4b95-93a3-f8e99a712345 Interbank Settlement Amount : EUR 567 Interbank Settlement Date : 2022-11-11 Instructing Agent Financial Institution Identification BICFI : AAAAFRPBTGT - FOO BANK OF CANADA, PARIS BRANCH - (TARGET) (FRANCE) Instructed Agent Financial Institution Identification BICFI : BBBBDEFFXXX - FOOBAR BANK AG (GERMANY) Debtor Financial Institution Identification BICFI : CCCCFRPBTGT - FOO BANK OF CANADA, PARIS BRANCH - (TARGET) (FRANCE) Creditor Financial Institution Identification BICFI : DDDDDEFFXXX - FOOBAR BANK AG (GERMANY) The nested structure of the actual XML is printed with nested indentation. Then BIC information is expanded with the institution name and location, and dates and amounts are formatted. Please check the sample below about how to obtain a printout similar to the one listed above. String xmlInput = \"\\n\" + \"\\n\" + \"\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" AAAAFRPBTGT\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" BBBBDEFFXXX\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" FOOJUNE01234\\n\" + \" pacs.009.001.08\\n\" + \" swift.cbprplus.02\\n\" + \" Normal\\n\" + \" 2022-11-11T11:11:11Z\\n\" + \"\\n\" + \"\\n\" + \" \\n\" + \" \\n\" + \" NONREF\\n\" + \" 2022-06-02T20:04:35-04:00\\n\" + \" 1\\n\" + \" \\n\" + \" CLRG\\n\" + \" \\n\" + \" TGT\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" FOO TEST 5\\n\" + \" FOOJUNE0222T5\\n\" + \" 145c2054-dc14-4b95-93a3-f8e99a712345\\n\" + \" \\n\" + \" 567\\n\" + \" 2022-11-11\\n\" + \" \\n\" + \" \\n\" + \" AAAAFRPBTGT\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" BBBBDEFFXXX\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" CCCCFRPBTGT\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" DDDDDEFFXXX\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \"\\n\" + \"\" ; MxSwiftMessage m = MxSwiftMessage . parse ( xmlInput ); m . setDirection ( MessageIOType . outgoing ); MxPrintoutWriter mxPrintoutWriter = new MxPrintoutWriter ( Locale . ENGLISH , new MxTxtPrintoutVisitor ()); System . out . println ( mxPrintoutWriter . print ( m ));","title":"MX Printout"},{"location":"integrator/sdk/sdk-printout/#mx-info","text":"The MXInfo is a helper class to retrieve ISO 20022 labels for message elements. This classe is created after an ISO 20022 enriched schema, containing documentation annotations. On creation, the XSD is traversed and the labels are stored in a map. MxLabelInfo labelInfo = new MxLabelInfo(MxType.pacs_008_001_10.schema()); Then given a path to a specific element in the specific MX, a similar complete path is returned with the segments as human-friendly labels. For example given the path; /Document/FIToFICstmrCdtTrf/CdtTrfTxInf/InstgAgt/FinInstnId/PstlAdr/DstrctNm the method returns: /Document/FIToFICustomerCreditTransferV10/CreditTransferTransactionInformation/InstructingAgent/FinancialInstitutionIdentification/PostalAddress/DistrictName This is what the MxPrintoutWriter uses to print the MX messages.","title":"MX Info"},{"location":"integrator/sdk/sdk-printout/#customization","text":"All aspects of the printout can be customized by providing an implementation of the PrintoutVisitor interface. The methods in this interface are called in a specific order, passing a portion of data retrieved from the message and expecting the output in return. Default implementations for the interface are provided for TXT and HTML formats. As an alternative to implementing the interface from scratch, the default implementations for TXT and HTML can be extended in order to provide an alternative implementation just for specific methods. The interface could be use even to generate a JSON version of the message content, with labels.","title":"Customization"},{"location":"integrator/sdk/sdk-printout/#bic-data","text":"A BIC directory is used to print the institution name along with the BIC. By default, the printout uses the default implementation of IBICDirectory from the BICDirectory class. This class uses an Apache Derby DB contained in the pw-swift-integrator-data-1.X.X.jar file. This DB contains the BIC data from the SWIFT BIC directory, and can be updated by you. If you already have a BIC data source and want to use it, you can implement the IBICDirectory interface and pass it to the printout writer constructor. If you do not need the BIC data and want to avoid adding the data jar as dependency, you can pass null to the printout writer constructor like this: PrintoutWriter printoutWriter = new PrintoutWriter ( Locale . ENGLISH , new TxtPrintoutVisitor (), null ); final String text = printoutWriter . print ( m ); Then whenever a BIC is found in the message, it will be printed as is, without the institution name.","title":"BIC data"},{"location":"integrator/sdk/sdk-schemes/","text":"MT messages structure schemes in XML Message schemes are a central and powerful part of the component. Message structure schemes are mainly used by the message validator module, but they may be suitable for multiple purposes in a SWIFT message management application. For example, they can be the base information source of a message creation user interface. The schemes are defined by means of an XML, and provided as a Java model in the library. The structure is statically defined in a SchemeNNN class. The following examples serve to quickly understand the content and general structure of these XML schemas: Example 1: Simple message with two inner sequences. Example 2: with two level sequences. (...) Loading schemes To access the out-of-the-box schemes, the MtType enumeration can be used. This enumeration is updated yearly and contains all types available for the current SRU. For example, MtType.MT103.scheme() will return a Scheme object with the specific message schema for MT103. Semantics of XML elements and attributes scheme : Mandatory container tag and root element of every scheme. It identifies the MT being structured. Attributes: name : mandatory identifier of the scheme, usually related to an MT name, as mentioned in the SWIFT Handbook . description : Optional description of message scheme. sequence : All message fields must be part of a specific sequence. At least one main sequence is required, even if the standard does not mention it. Sequences can be nested, conforming to the blocks and subblocks of the message as needed. Attributes: name : Optional name for the sequence, can be a letter based name as used through the SWIFT handbook or any functional name related to the contents of the sequence. minRepetitions : Mandatory attribute accepting an integer number to indicate the minimum repetitions expected of the sequence. A value of \"0\" means that the sequence will be optional, a value of \"1\" means that the sequence is mandatory, and a value of \"n\" (being n an integer number greater than 1) means that the sequence is mandatory and at least n sequences must be filled for a message to be valid according to this scheme definition. maxRepetitions : Mandatory attribute accepting a positive integer number greater or equal to 1 to indicate the maximum allowed repetitions of the sequence. A value of \"1\" means that the sequence can have up to one repetition and a value of \"n\" (being n an integer number greater than 1) means that the sequence is mandatory and at most n sequences can be filled for a message to be valid according to this scheme definition. To allow an unlimited number of repetitions, the literal \"UNLIMITED\" can be used. field : This element defines a SWIFT field. Represents a set of zero or more fields of the sequence. Repetition attributes must be present, as well as \"id\". The letterOption attribute is optional, and the literal \"NONE\" is supported. A letter option indicating \"A, B, NONE\" on a field with id \"50\" for example, means that the field can be 50A, 50B or 50 with no letter option. It accepts the same tag attributes as the sequence element, plus: id : Mandatory attribute to indicate the field numeric identifier without the letter options. letterOptions : Optional attribute to indicate the letter options admitted for the field. The letter option must be ppercase, and it admits a single letter or a comma separated list of letters. The literal \"NONE\" can also be used to indicate that the field admits an empty letter option (Notice that a \"NONE\" value is the default for the element, meaning that if the letterOption attribute is not present, the field will not accept letter options. The literal is useful for particular fields where it is valid to a letter option \"A\" for example as well as no letter option at all). qualifiers : Optional attribute to specify fixed values for the field. The attribute value supports complex combination from a simple fixed literal to a combination of qualifiers per letter option and field\u2019s components. For example, a simple value of \"GENL\" means that the field is expected to have the literal GENL as value. Multiple values can be indicated with a comma/whitespace separated list, for example: \"SECU, SEGU, OTHR\" meaning that the field can have any of the mentioned literals. If the field supports several letter options, the literal qualifiers can be indicated for particular letter options for example: \"SECU, A.SEGU, B.OTHR\" means that literal SEGU is expected for any letter option, SEGU is expected for letter option A, and OTHR for letter option B. By default the qualifier is validated against the first component of the field. If a specific field\u2019s component is expected to have the qualifier, a letter, and component number combination can be expressed. For example, the qualifier J.5.ACCU means that for letter option J, field\u2019s component 5 is expected to have the literal ACCU as value. Fieldsets This section describes some advanced features of the XML schemes that may be useful to tune up validations on specific scenarios. All messages for category 5, as well as some messages for category 3 have an extensive structure definition. These definitions are performed with the same XML described above, but including two special features: fieldsets and evaluations. A fieldset is a definition of a message field that has several consecutive and unordered instances. All fields in the fieldset share the field number, but may accept different letter options and different qualifiers. For example, the following definition will accept up to three instances of field 20C with the qualifiers CORP, SEME and COAF, with two of them mandatory and one optional:
            The validation of this structure is well covered by the SWIFT Handbook . Please notice that a fieldset is different from a field with repetitions because it can have different qualifiers, letter options, and expected repetitions of each item. It also is different from a sequence because the items can appear in the message in any order. Semantic of the fieldset XML definition and attributes: fieldset : Mandatory container tag and root element of every fieldset. Attributes: id : Mandatory identifier field's number defined by the fieldset. All inner items will share this field number. letterOption : Optional identification of the letter option. If this attribute is defined on the fieldset tag, all inner items will share the same expected letter options. minRepetitions : Optional attribute accepting an integer number to indicate the minimum repetitions expected of all inner items of this fieldset. If this attribute is defined on the fieldset tag, all inner items will share the same expected minimum repetition. maxRepetitions : Optional attribute accepting a positive integer number greater or equal to 1 to indicate the maximum allowed repetitions of all inner items of this fieldset. If this attribute is defined on the fieldset tag, all inner items will share the same expected maximum repetition. item : Definition of each possible field instance into the container fieldset. Attributes: letterOption : Optional identification of the letter option. This value can be overwritten if the letter option is defined at the container fieldset. minRepetitions : Definition of the minimum repetitions expected for the field instance. This value can be overwritten if the letter option is defined at the container fieldset. If the attribute is not defined for the fieldset, it is mandatory to define it in the item. maxRepetitions : Definition of the maximum repetitions expected for the field instance. This value can be overwritten if the letter option is defined at the container fieldset. If the attribute is not defined for the fieldset, it is mandatory to define it in the item. qualifiers : Optional attribute to specify fixed values for the field. Qualifier validation evaluations Qualifier validation elements are used to indicate the allowed field qualifiers and conditional qualifiers within field, fieldset and item elements. Notice for simple cases where the field or item expects certain qualifiers, the direct qualifiers attribute described above suffices. However, for some message types the logic to determine the expected qualifier is more complex and has to be defined conditionally. The qualifierValidation element might contain several attributes. Some attributes are used as a conditional , to determine if the actual validation applies. Plus the attributes to define the actual constraint . For example, the following definition will match fields 94B, with qualifiers PRIC or RATS, and if the DSS (data source definition) of the field is not set, then the conditional qualifier (component 3) must be LMAR, FIND, THEO or VEND.
            In the above example, the notDssCondition is the conditional and the conditionalQualifiers is the actual constraint. The available attributes for the conditional part are: notDssCondition : boolean value, when true, means the field\u2019s DSS (data source definition) should not be present for the qualifier validation to apply. letterCondition : string value with the field instance letter option (admits a csv list), the qualifier validation will be applied only if the field matches the letter. qualifierCondition : a specific qualifier that the field must match in order for the conditional qualifier validation to apply. The available attributes for the constraint are: qualifiers(list) : function that evaluates to true if the field main qualifier has any of the given values. The list parameter is a string value with one or many qualifiers, separated with a comma. Each qualifier may be prefixed with an integer to specify the component that will be checked (by default, the component checked is the component 1). conditionalQualifiers(list) : function that evaluates to true if the field conditional qualifier has any of the given values. The component used as a \"conditional qualifier\" is the third component. For example, when the field defines a data source scheme as the second component (for example 22F), or the second component if the field does not define a data source scheme (for example 12C). The conditional qualifier function is intended only for generic fields (Field that implements the interface GenericField ). For all other fields, the verifyQualifier function should be used. Then when defining the actual qualifiers or conditional qualifiers list in the constraint, a couple of fixed literal expressions are supported. These are needed just for two particular cases. These expressions are interpreted as literals, thus these specific strings are the only ones supported: [3!n_NOT_ZERO] : string value that can be used in a qualifier list parameter and will evaluate to true if the component value is composed of three numbers and not 000. [4!n_NOT_ZERO] : string value that can be used in a qualifier list parameter and will evaluate to true if the component value is composed of four numbers and not 000. Several examples of qualifierValidation can be found in the included XML schemes of the package. For example: During the validation, the attributes in the qualifierValidation element are evaluated in order to determine if the input is valid or not. The validation engine will match the field/item only if all the attributes are evaluated as true. If an evaluation is false, the field may be reported as an unexpected field.","title":"MT schemes"},{"location":"integrator/sdk/sdk-schemes/#mt-messages-structure-schemes-in-xml","text":"Message schemes are a central and powerful part of the component. Message structure schemes are mainly used by the message validator module, but they may be suitable for multiple purposes in a SWIFT message management application. For example, they can be the base information source of a message creation user interface. The schemes are defined by means of an XML, and provided as a Java model in the library. The structure is statically defined in a SchemeNNN class. The following examples serve to quickly understand the content and general structure of these XML schemas: Example 1: Simple message with two inner sequences. Example 2: with two level sequences. (...) ","title":"MT messages structure schemes in XML"},{"location":"integrator/sdk/sdk-schemes/#loading-schemes","text":"To access the out-of-the-box schemes, the MtType enumeration can be used. This enumeration is updated yearly and contains all types available for the current SRU. For example, MtType.MT103.scheme() will return a Scheme object with the specific message schema for MT103.","title":"Loading schemes"},{"location":"integrator/sdk/sdk-schemes/#semantics-of-xml-elements-and-attributes","text":"scheme : Mandatory container tag and root element of every scheme. It identifies the MT being structured. Attributes: name : mandatory identifier of the scheme, usually related to an MT name, as mentioned in the SWIFT Handbook . description : Optional description of message scheme. sequence : All message fields must be part of a specific sequence. At least one main sequence is required, even if the standard does not mention it. Sequences can be nested, conforming to the blocks and subblocks of the message as needed. Attributes: name : Optional name for the sequence, can be a letter based name as used through the SWIFT handbook or any functional name related to the contents of the sequence. minRepetitions : Mandatory attribute accepting an integer number to indicate the minimum repetitions expected of the sequence. A value of \"0\" means that the sequence will be optional, a value of \"1\" means that the sequence is mandatory, and a value of \"n\" (being n an integer number greater than 1) means that the sequence is mandatory and at least n sequences must be filled for a message to be valid according to this scheme definition. maxRepetitions : Mandatory attribute accepting a positive integer number greater or equal to 1 to indicate the maximum allowed repetitions of the sequence. A value of \"1\" means that the sequence can have up to one repetition and a value of \"n\" (being n an integer number greater than 1) means that the sequence is mandatory and at most n sequences can be filled for a message to be valid according to this scheme definition. To allow an unlimited number of repetitions, the literal \"UNLIMITED\" can be used. field : This element defines a SWIFT field. Represents a set of zero or more fields of the sequence. Repetition attributes must be present, as well as \"id\". The letterOption attribute is optional, and the literal \"NONE\" is supported. A letter option indicating \"A, B, NONE\" on a field with id \"50\" for example, means that the field can be 50A, 50B or 50 with no letter option. It accepts the same tag attributes as the sequence element, plus: id : Mandatory attribute to indicate the field numeric identifier without the letter options. letterOptions : Optional attribute to indicate the letter options admitted for the field. The letter option must be ppercase, and it admits a single letter or a comma separated list of letters. The literal \"NONE\" can also be used to indicate that the field admits an empty letter option (Notice that a \"NONE\" value is the default for the element, meaning that if the letterOption attribute is not present, the field will not accept letter options. The literal is useful for particular fields where it is valid to a letter option \"A\" for example as well as no letter option at all). qualifiers : Optional attribute to specify fixed values for the field. The attribute value supports complex combination from a simple fixed literal to a combination of qualifiers per letter option and field\u2019s components. For example, a simple value of \"GENL\" means that the field is expected to have the literal GENL as value. Multiple values can be indicated with a comma/whitespace separated list, for example: \"SECU, SEGU, OTHR\" meaning that the field can have any of the mentioned literals. If the field supports several letter options, the literal qualifiers can be indicated for particular letter options for example: \"SECU, A.SEGU, B.OTHR\" means that literal SEGU is expected for any letter option, SEGU is expected for letter option A, and OTHR for letter option B. By default the qualifier is validated against the first component of the field. If a specific field\u2019s component is expected to have the qualifier, a letter, and component number combination can be expressed. For example, the qualifier J.5.ACCU means that for letter option J, field\u2019s component 5 is expected to have the literal ACCU as value.","title":"Semantics of XML elements and attributes"},{"location":"integrator/sdk/sdk-schemes/#fieldsets","text":"This section describes some advanced features of the XML schemes that may be useful to tune up validations on specific scenarios. All messages for category 5, as well as some messages for category 3 have an extensive structure definition. These definitions are performed with the same XML described above, but including two special features: fieldsets and evaluations. A fieldset is a definition of a message field that has several consecutive and unordered instances. All fields in the fieldset share the field number, but may accept different letter options and different qualifiers. For example, the following definition will accept up to three instances of field 20C with the qualifiers CORP, SEME and COAF, with two of them mandatory and one optional:
            The validation of this structure is well covered by the SWIFT Handbook . Please notice that a fieldset is different from a field with repetitions because it can have different qualifiers, letter options, and expected repetitions of each item. It also is different from a sequence because the items can appear in the message in any order. Semantic of the fieldset XML definition and attributes: fieldset : Mandatory container tag and root element of every fieldset. Attributes: id : Mandatory identifier field's number defined by the fieldset. All inner items will share this field number. letterOption : Optional identification of the letter option. If this attribute is defined on the fieldset tag, all inner items will share the same expected letter options. minRepetitions : Optional attribute accepting an integer number to indicate the minimum repetitions expected of all inner items of this fieldset. If this attribute is defined on the fieldset tag, all inner items will share the same expected minimum repetition. maxRepetitions : Optional attribute accepting a positive integer number greater or equal to 1 to indicate the maximum allowed repetitions of all inner items of this fieldset. If this attribute is defined on the fieldset tag, all inner items will share the same expected maximum repetition. item : Definition of each possible field instance into the container fieldset. Attributes: letterOption : Optional identification of the letter option. This value can be overwritten if the letter option is defined at the container fieldset. minRepetitions : Definition of the minimum repetitions expected for the field instance. This value can be overwritten if the letter option is defined at the container fieldset. If the attribute is not defined for the fieldset, it is mandatory to define it in the item. maxRepetitions : Definition of the maximum repetitions expected for the field instance. This value can be overwritten if the letter option is defined at the container fieldset. If the attribute is not defined for the fieldset, it is mandatory to define it in the item. qualifiers : Optional attribute to specify fixed values for the field.","title":"Fieldsets"},{"location":"integrator/sdk/sdk-schemes/#qualifier-validation-evaluations","text":"Qualifier validation elements are used to indicate the allowed field qualifiers and conditional qualifiers within field, fieldset and item elements. Notice for simple cases where the field or item expects certain qualifiers, the direct qualifiers attribute described above suffices. However, for some message types the logic to determine the expected qualifier is more complex and has to be defined conditionally. The qualifierValidation element might contain several attributes. Some attributes are used as a conditional , to determine if the actual validation applies. Plus the attributes to define the actual constraint . For example, the following definition will match fields 94B, with qualifiers PRIC or RATS, and if the DSS (data source definition) of the field is not set, then the conditional qualifier (component 3) must be LMAR, FIND, THEO or VEND.
            In the above example, the notDssCondition is the conditional and the conditionalQualifiers is the actual constraint. The available attributes for the conditional part are: notDssCondition : boolean value, when true, means the field\u2019s DSS (data source definition) should not be present for the qualifier validation to apply. letterCondition : string value with the field instance letter option (admits a csv list), the qualifier validation will be applied only if the field matches the letter. qualifierCondition : a specific qualifier that the field must match in order for the conditional qualifier validation to apply. The available attributes for the constraint are: qualifiers(list) : function that evaluates to true if the field main qualifier has any of the given values. The list parameter is a string value with one or many qualifiers, separated with a comma. Each qualifier may be prefixed with an integer to specify the component that will be checked (by default, the component checked is the component 1). conditionalQualifiers(list) : function that evaluates to true if the field conditional qualifier has any of the given values. The component used as a \"conditional qualifier\" is the third component. For example, when the field defines a data source scheme as the second component (for example 22F), or the second component if the field does not define a data source scheme (for example 12C). The conditional qualifier function is intended only for generic fields (Field that implements the interface GenericField ). For all other fields, the verifyQualifier function should be used. Then when defining the actual qualifiers or conditional qualifiers list in the constraint, a couple of fixed literal expressions are supported. These are needed just for two particular cases. These expressions are interpreted as literals, thus these specific strings are the only ones supported: [3!n_NOT_ZERO] : string value that can be used in a qualifier list parameter and will evaluate to true if the component value is composed of three numbers and not 000. [4!n_NOT_ZERO] : string value that can be used in a qualifier list parameter and will evaluate to true if the component value is composed of four numbers and not 000. Several examples of qualifierValidation can be found in the included XML schemes of the package. For example: During the validation, the attributes in the qualifierValidation element are evaluated in order to determine if the input is valid or not. The validation engine will match the field/item only if all the attributes are evaluated as true. If an evaluation is false, the field may be reported as an unexpected field.","title":"Qualifier validation evaluations"},{"location":"integrator/translations/","text":"Prowide Integrator Translations - Overview The Translations library provides out-of-the-box conversions between MT and ISO 20022 messages. The library is used in runtime, as a regular dependency, to convert messages on the fly. The conversion process is based on a set of rules that are embedded in the implementation and are maintained by Prowide as the standards change. The translation is built on top of the Prowide Core and Prowide ISO 20022 message model. Therefore, the same API and classes used for parsing or building the messages are used as parameters and return values of the translation. Automatic message conversion is also possible by means of a Factory that given a source message in either MT or MX format can autodetect the message type and find a suitable translator implementation for its equivalent in the other standard. Javadoc Online javadoc Prowide Integrator Translations Javadoc SRU2023-9.4.x","title":"Prowide Integrator Translations - Overview"},{"location":"integrator/translations/#prowide-integrator-translations-overview","text":"The Translations library provides out-of-the-box conversions between MT and ISO 20022 messages. The library is used in runtime, as a regular dependency, to convert messages on the fly. The conversion process is based on a set of rules that are embedded in the implementation and are maintained by Prowide as the standards change. The translation is built on top of the Prowide Core and Prowide ISO 20022 message model. Therefore, the same API and classes used for parsing or building the messages are used as parameters and return values of the translation. Automatic message conversion is also possible by means of a Factory that given a source message in either MT or MX format can autodetect the message type and find a suitable translator implementation for its equivalent in the other standard.","title":"Prowide Integrator Translations - Overview"},{"location":"integrator/translations/#javadoc","text":"Online javadoc Prowide Integrator Translations Javadoc SRU2023-9.4.x","title":"Javadoc"},{"location":"integrator/translations/translations-avail/","text":"Available Translations The following table contains all out-of-the-box translations. The provided implementations within its internal mapping logic are based on the equivalence tables defined by SWIFT. Notice there is no linear correlation between the source and target of the available translation, meaning that if A can be translated to B, the reverse is not always true. The tables below are only a general reference. New translations are added on a regular basis. For a most accurate and up-to-date list, please check the actual classes available in the com.prowidesoftware.swift.translations package of your distribution, and in the restricted ISO 20022 version subpackages such as com.prowidesoftware.swift.translations.cbpr and com.prowidesoftware.swift.translations.sic . MT to MX ISO Source Target 101 pain.001.001.03 101 pain.001.001.08 101 pain.001.001.09 102 pacs.008.001.08 102 pacs.008.001.09 102 pacs.008.001.10 103 pacs.002.001.10 103 pacs.004.001.09 103 pacs.004.001.10 103 pacs.008.001.02 103 pacs.008.001.06 103 pacs.008.001.07 103 pacs.008.001.08 103 pacs.008.001.09 103 pacs.008.001.10 103.REMIT pacs.008.001.02 103.REMIT pacs.008.001.06 103.REMIT pacs.008.001.07 103.REMIT pacs.008.001.08 103.REMIT pacs.008.001.09 103.REMIT pacs.008.001.10 103.STP pacs.008.001.02 103.STP pacs.008.001.06 103.STP pacs.008.001.07 103.STP pacs.008.001.08 103.STP pacs.008.001.09 104 pacs.003.001.08 104 pacs.003.001.09 104 pacs.003.001.10 104 pain.008.001.08 107 pacs.003.001.08 107 pacs.003.001.09 107 pacs.003.001.10 110 camt.107.001.01 111 camt.108.001.01 112 camt.109.001.01 192 camt.056.001.08 192 camt.056.001.10 192 camt.058.001.08 196 camt.029.001.09 196 camt.029.001.11 199 pacs.002.001.10 200 camt.050.001.05 200 pacs.009.001.08 200 pacs.009.001.09 200 pacs.009.001.10 202 pacs.002.001.10 202 pacs.004.001.09 202 pacs.004.001.10 202 pacs.009.001.02 202 pacs.009.001.06 202 pacs.009.001.07 202 pacs.009.001.08 202 pacs.009.001.09 202 pacs.009.001.10 202.COV pacs.002.001.10 202.COV pacs.009.001.02 202.COV pacs.009.001.06 202.COV pacs.009.001.07 202.COV pacs.009.001.08 202.COV pacs.009.001.09 202.COV pacs.009.001.10 204 pacs.010.001.03 205 pacs.002.001.10 205 pacs.004.001.09 205 pacs.004.001.10 205 pacs.009.001.08 205 pacs.009.001.09 205.COV pacs.002.001.10 205.COV pacs.009.001.08 205.COV pacs.009.001.09 210 camt.057.001.06 292 camt.056.001.08 292 camt.056.001.10 292 camt.058.001.08 296 camt.029.001.09 296 camt.029.001.11 299 pacs.002.001.10 300 fxtr.014.001.03 502 setr.004.002.01 502 setr.010.002.01 508 semt.015.002.01 508 semt.020.002.01 509 setr.016.001.04 509 setr.016.002.01 509 setr.017.001.04 515 setr.006.001.04 515 setr.006.002.01 515 setr.012.001.04 515 setr.012.002.01 524 semt.013.002.01 524 sese.020.002.01 530 sese.030.001.08 530 sese.030.002.01 535 semt.002.001.11 535 semt.002.002.03 535 semt.003.002.03 535 semt.020.002.01 536 semt.017.001.12 536 semt.020.002.01 537 semt.018.001.13 537 semt.018.002.01 537 semt.020.002.01 538 semt.016.002.01 538 semt.020.002.01 540 sese.020.001.06 540 sese.020.001.07 540 sese.020.002.01 540 sese.023.001.09 540 sese.023.001.11 540 sese.023.002.01 540 sese.033.002.01 540 sese.036.002.01 541 sese.020.001.06 541 sese.020.001.07 541 sese.020.002.01 541 sese.023.001.09 541 sese.023.001.11 541 sese.023.002.01 541 sese.033.002.01 541 sese.036.002.01 542 sese.020.001.06 542 sese.020.001.07 542 sese.020.002.01 542 sese.023.001.09 542 sese.023.001.11 542 sese.023.002.01 542 sese.033.002.01 542 sese.036.002.01 543 sese.020.001.06 543 sese.020.001.07 543 sese.020.002.01 543 sese.023.001.09 543 sese.023.001.11 543 sese.023.002.01 543 sese.033.002.01 543 sese.036.002.01 544 semt.020.002.01 544 sese.025.001.09 544 sese.025.001.11 544 sese.025.002.01 544 sese.026.001.10 544 sese.026.002.01 544 sese.035.002.01 545 semt.020.002.01 545 sese.025.001.09 545 sese.025.001.11 545 sese.025.002.01 545 sese.026.001.10 545 sese.026.002.01 545 sese.035.002.01 546 semt.020.002.01 546 sese.025.001.09 546 sese.025.001.11 546 sese.025.002.01 546 sese.026.001.10 546 sese.026.002.01 546 sese.035.002.01 547 semt.020.002.01 547 sese.025.001.09 547 sese.025.001.11 547 sese.025.002.01 547 sese.026.001.10 547 sese.026.002.01 547 sese.035.002.01 548 semt.014.002.01 548 sese.022.002.01 548 sese.024.001.10 548 sese.024.001.11 548 sese.024.001.12 548 sese.024.002.01 548 sese.027.001.05 548 sese.027.002.01 548 sese.031.001.08 548 sese.031.002.01 548 sese.032.002.01 548 sese.034.002.01 549 semt.021.002.01 549 sese.021.002.01 564 seev.031.001.10 564 seev.031.001.11 564 seev.031.002.02 564 seev.031.002.06 564 seev.031.002.12 564 seev.031.002.13 564 seev.035.001.12 564 seev.035.002.02 564 seev.035.002.12 564 seev.039.002.02 564 seev.039.002.06 564 seev.039.002.11 564 seev.044.001.10 564 seev.044.002.02 564 seev.044.002.10 565 seev.033.002.02 565 seev.033.002.12 565 seev.040.002.02 565 seev.040.002.11 566 seev.036.001.12 566 seev.036.002.02 566 seev.036.002.06 566 seev.036.002.07 566 seev.036.002.08 566 seev.036.002.09 566 seev.036.002.12 566 seev.037.001.12 566 seev.037.002.02 566 seev.037.002.06 566 seev.037.002.07 566 seev.037.002.08 566 seev.037.002.09 566 seev.037.002.12 567 seev.032.002.02 567 seev.032.002.08 567 seev.034.002.02 567 seev.034.002.13 567 seev.041.001.10 567 seev.041.002.12 568 seev.031.001.10 568 seev.031.001.11 568 seev.031.002.02 568 seev.031.002.06 568 seev.031.002.12 568 seev.031.002.13 568 seev.038.002.02 568 seev.038.002.07 578 semt.020.001.07 578 semt.020.002.01 578 sese.028.001.08 578 sese.028.002.01 578 sese.029.002.01 586 semt.019.002.01 586 semt.020.002.01 586 sese.037.002.01 900 camt.054.001.02 900 camt.054.001.06 900 camt.054.001.07 900 camt.054.001.08 900 camt.054.001.09 910 camt.054.001.02 910 camt.054.001.06 910 camt.054.001.07 910 camt.054.001.08 910 camt.054.001.09 920 camt.060.001.05 920 camt.060.001.06 940 camt.053.001.02 940 camt.053.001.06 940 camt.053.001.07 940 camt.053.001.08 940 camt.053.001.09 940 camt.053.001.10 940 camt.053.001.11 941 camt.052.001.02 941 camt.052.001.06 941 camt.052.001.07 941 camt.052.001.08 941 camt.052.001.09 942 camt.052.001.02 942 camt.052.001.06 942 camt.052.001.07 942 camt.052.001.08 942 camt.052.001.09 950 camt.053.001.02 950 camt.053.001.06 950 camt.053.001.07 950 camt.053.001.08 950 camt.053.001.09 950 camt.053.001.10 950 camt.053.001.11 CBPR Source Target 101 pain.001.001.09 102 pacs.008.001.08 102.STP pacs.008.001.08.STP 103 pacs.002.001.10 103 pacs.004.001.09 103 pacs.008.001.08 103.STP pacs.008.001.08.STP 104 pacs.003.001.08 104 pain.008.001.08 107 pacs.003.001.08 110 camt.107.001.01 111 camt.108.001.01 112 camt.109.001.01 192 camt.055.001.08 192 camt.056.001.08 196 camt.029.001.09 199 pacs.002.001.10 200 pacs.009.001.08 201 pacs.009.001.08 202 pacs.002.001.10 202 pacs.004.001.09 202 pacs.009.001.08 202 pacs.009.001.08.ADV 202.COV pacs.002.001.10 202.COV pacs.009.001.08.COV 203 pacs.009.001.08 204 pacs.010.001.03 205 pacs.002.001.10 205 pacs.004.001.09 205 pacs.009.001.08 205.COV pacs.002.001.10 205.COV pacs.009.001.08.COV 210 camt.057.001.06 292 camt.056.001.08 292 camt.058.001.08 296 camt.029.001.09 299 pacs.002.001.10 900 camt.054.001.08 910 camt.054.001.08 920 camt.060.001.05 940 camt.053.001.08 941 camt.052.001.08 942 camt.052.001.08 950 camt.053.001.08 CHATS Source Target 103 pacs.008.001.08 192 camt.056.001.08 202 pacs.009.001.08 202.COV pacs.009.001.08 292 camt.056.001.08 LYNX Source Target 103 pacs.004.001.09 103 pacs.008.001.08 202 pacs.004.001.09 202 pacs.009.001.08 202.COV pacs.009.001.08 205 pacs.004.001.09 205 pacs.009.001.08 RITS Source Target 103 pacs.008.001.09 202 pacs.009.001.09 202.COV pacs.009.001.09 SCRIPS Source Target 103 pacs.008.001.08 202 pacs.009.001.08 202.COV pacs.009.001.08 SIC_v4_10 Source Target 103 pacs.008.001.08.Ch02 202 pacs.009.001.08.Ch03 202.COV pacs.009.001.08.Ch03 SWIFTGO Source Target 103 pacs.008.001.08 199 trck.001.001.02 199 trck.002.001.01 T2 Source Target 103 pacs.004.001.09 103 pacs.008.001.08 202 pacs.004.001.09 202 pacs.009.001.08 205 pacs.004.001.09 205 pacs.009.001.08 MX to MT ISO Source Target camt.029.001.09 196 camt.029.001.09 296 camt.029.001.11 196 camt.029.001.11 296 camt.050.001.05 200 camt.052.001.06 941 camt.052.001.06 942 camt.052.001.07 941 camt.052.001.07 942 camt.052.001.08 941 camt.052.001.08 942 camt.052.001.09 941 camt.052.001.09 942 camt.053.001.02 940 camt.053.001.06 940 camt.053.001.06 950 camt.053.001.07 940 camt.053.001.07 950 camt.053.001.08 940 camt.053.001.08 950 camt.053.001.09 940 camt.053.001.09 950 camt.053.001.10 940 camt.053.001.10 950 camt.053.001.11 940 camt.053.001.11 950 camt.054.001.06 900 camt.054.001.06 910 camt.054.001.07 900 camt.054.001.07 910 camt.054.001.08 900 camt.054.001.08 910 camt.054.001.09 900 camt.054.001.09 910 camt.056.001.08 192 camt.056.001.08 292 camt.056.001.10 192 camt.056.001.10 292 camt.057.001.06 210 camt.060.001.05 920 camt.060.001.06 920 camt.107.001.01 110 camt.108.001.01 111 camt.109.001.01 112 pacs.002.001.10 199 pacs.002.001.10 299 pacs.003.001.08 104 pacs.003.001.08 107 pacs.003.001.09 104 pacs.003.001.09 107 pacs.003.001.10 104 pacs.003.001.10 107 pacs.004.001.02 103 pacs.004.001.09 103 pacs.004.001.09 202 pacs.004.001.09 205 pacs.004.001.10 103 pacs.004.001.10 202 pacs.004.001.10 205 pacs.008.001.02 103 pacs.008.001.06 103 pacs.008.001.07 103 pacs.008.001.08 102 pacs.008.001.08 103 pacs.008.001.08 103.REMIT pacs.008.001.09 102 pacs.008.001.09 103 pacs.008.001.10 102 pacs.008.001.10 103 pacs.009.001.02 202 pacs.009.001.02 202.COV pacs.009.001.06 202 pacs.009.001.06 202.COV pacs.009.001.07 202 pacs.009.001.07 202.COV pacs.009.001.08 200 pacs.009.001.08 202 pacs.009.001.08 202.COV pacs.009.001.08 205 pacs.009.001.08 205.COV pacs.009.001.09 200 pacs.009.001.09 202 pacs.009.001.09 202.COV pacs.009.001.09 205 pacs.009.001.10 200 pacs.009.001.10 202 pacs.009.001.10 202.COV pacs.009.001.10 205 pacs.010.001.03 204 pain.001.001.03 101 pain.001.001.08 101 pain.001.001.09 101 seev.001.001.10 564 seev.002.001.09 564 seev.003.001.09 564 seev.004.001.09 565 seev.005.001.09 565 seev.006.001.09 567 seev.007.001.09 567 seev.008.001.08 568 seev.031.001.03 564 seev.031.001.03 568 seev.031.001.09 564 seev.031.001.10 564 seev.031.001.10 568 seev.031.001.11 564 seev.031.001.11 568 seev.031.001.12 564 seev.031.001.12 568 seev.031.001.13 564 seev.031.001.13 568 seev.031.002.02 564 seev.031.002.02 568 seev.031.002.12 564 seev.031.002.12 568 seev.031.002.13 564 seev.031.002.13 568 seev.032.002.02 567 seev.032.002.08 567 seev.033.002.02 565 seev.033.002.12 565 seev.034.002.02 567 seev.034.002.13 567 seev.035.001.03 564 seev.035.001.10 564 seev.035.001.11 564 seev.035.001.12 564 seev.035.001.13 564 seev.035.001.14 564 seev.035.002.02 564 seev.035.002.12 564 seev.036.001.11 566 seev.036.001.12 566 seev.036.001.13 566 seev.036.001.14 566 seev.036.002.02 566 seev.036.002.06 566 seev.036.002.07 566 seev.036.002.08 566 seev.036.002.09 566 seev.036.002.12 566 seev.037.001.11 566 seev.037.001.12 566 seev.037.001.13 566 seev.037.001.14 566 seev.037.002.02 566 seev.037.002.06 566 seev.037.002.07 566 seev.037.002.08 566 seev.037.002.09 566 seev.037.002.12 566 seev.038.001.03 568 seev.038.002.02 568 seev.038.002.07 568 seev.039.001.03 564 seev.039.001.10 564 seev.039.001.11 564 seev.039.001.12 564 seev.039.002.02 564 seev.039.002.11 564 seev.040.002.02 565 seev.040.002.11 565 seev.041.002.12 567 seev.044.001.03 564 seev.044.001.10 564 seev.044.001.11 564 seev.044.001.12 564 seev.044.002.02 564 seev.044.002.10 564 semt.002.001.10 535 semt.002.001.11 535 semt.002.002.03 535 semt.003.002.03 535 semt.013.002.01 524 semt.014.002.01 548 semt.015.002.01 508 semt.016.002.01 538 semt.017.001.12 536 semt.017.002.01 536 semt.018.001.13 537 semt.018.002.01 537 semt.019.002.01 586 semt.020.001.05 578 semt.020.001.07 578 semt.020.002.01 508 semt.020.002.01 535 semt.020.002.01 536 semt.020.002.01 537 semt.020.002.01 538 semt.020.002.01 544 semt.020.002.01 545 semt.020.002.01 546 semt.020.002.01 547 semt.020.002.01 578 semt.020.002.01 586 semt.021.002.01 549 sese.020.001.06 540 sese.020.001.06 541 sese.020.001.06 542 sese.020.001.06 543 sese.020.001.07 540 sese.020.001.07 541 sese.020.001.07 542 sese.020.001.07 543 sese.020.002.01 524 sese.020.002.01 540 sese.020.002.01 541 sese.020.002.01 542 sese.020.002.01 543 sese.021.002.01 549 sese.022.002.01 548 sese.023.001.09 540 sese.023.001.09 541 sese.023.001.09 542 sese.023.001.09 543 sese.023.001.11 540 sese.023.001.11 541 sese.023.001.11 542 sese.023.001.11 543 sese.023.002.01 540 sese.023.002.01 541 sese.023.002.01 542 sese.023.002.01 543 sese.024.001.09 548 sese.024.001.10 548 sese.024.001.11 548 sese.024.001.12 548 sese.024.002.01 548 sese.025.001.09 544 sese.025.001.09 545 sese.025.001.09 546 sese.025.001.09 547 sese.025.001.11 544 sese.025.001.11 545 sese.025.001.11 546 sese.025.001.11 547 sese.025.002.01 544 sese.025.002.01 545 sese.025.002.01 546 sese.025.002.01 547 sese.026.001.10 544 sese.026.001.10 545 sese.026.001.10 546 sese.026.001.10 547 sese.026.002.01 544 sese.026.002.01 545 sese.026.002.01 546 sese.026.002.01 547 sese.027.001.05 548 sese.027.002.01 548 sese.028.001.08 578 sese.028.001.09 578 sese.028.001.10 578 sese.028.002.01 578 sese.029.001.04 578 sese.029.002.01 578 sese.030.001.08 530 sese.030.002.01 530 sese.031.001.08 548 sese.031.002.01 548 sese.032.002.01 548 sese.033.002.01 540 sese.033.002.01 541 sese.033.002.01 542 sese.033.002.01 543 sese.034.002.01 548 sese.035.002.01 544 sese.035.002.01 545 sese.035.002.01 546 sese.035.002.01 547 sese.036.002.01 540 sese.036.002.01 541 sese.036.002.01 542 sese.036.002.01 543 sese.037.002.01 586 setr.004.001.04 502 setr.004.002.01 502 setr.006.001.04 515 setr.006.002.01 515 setr.010.001.04 502 setr.010.002.01 502 setr.012.001.04 515 setr.012.002.01 515 setr.015.001.04 515.Redemption setr.015.001.04 515.Subscription setr.016.001.04 509 setr.016.002.01 509 setr.017.001.04 509 CBPR Source Target camt.029.001.09 196 camt.029.001.09 296 camt.052.001.08 941 camt.052.001.08 942 camt.053.001.08 940 camt.053.001.08 950 camt.054.001.08 900 camt.054.001.08 910 camt.055.001.08 192 camt.056.001.08 192 camt.056.001.08 292 camt.057.001.06 210 camt.058.001.08 292 camt.060.001.05 920 camt.107.001.01 110 camt.108.001.01 111 camt.109.001.01 112 pacs.002.001.10 199 pacs.002.001.10 299 pacs.003.001.08 104 pacs.003.001.08 107 pacs.004.001.09 103 pacs.004.001.09 202 pacs.004.001.09 205 pacs.008.001.08 102 pacs.008.001.08 103 pacs.008.001.08 103.REMIT pacs.008.001.08STP 102STP pacs.008.001.08STP 103STP pacs.009.001.08 200 pacs.009.001.08 202 pacs.009.001.08 205 pacs.009.001.08.ADV 202 pacs.009.001.08.COV 202.COV pacs.009.001.08.COV 205.COV pacs.010.001.03 204 pain.001.001.09 101 pain.008.001.08 104 SIC_v4_10 Source Target pacs.004.001.09.Ch02 103 pacs.008.001.08.Ch02 103 pacs.009.001.08.Ch03 202 pacs.009.001.08.Ch03 202.COV SWIFTGO Source Target pacs.008.001.08 103 trck.001.001.02 199 trck.002.001.01 199","title":"Available Translations"},{"location":"integrator/translations/translations-avail/#available-translations","text":"The following table contains all out-of-the-box translations. The provided implementations within its internal mapping logic are based on the equivalence tables defined by SWIFT. Notice there is no linear correlation between the source and target of the available translation, meaning that if A can be translated to B, the reverse is not always true. The tables below are only a general reference. New translations are added on a regular basis. For a most accurate and up-to-date list, please check the actual classes available in the com.prowidesoftware.swift.translations package of your distribution, and in the restricted ISO 20022 version subpackages such as com.prowidesoftware.swift.translations.cbpr and com.prowidesoftware.swift.translations.sic .","title":"Available Translations"},{"location":"integrator/translations/translations-avail/#mt-to-mx","text":"","title":"MT to MX"},{"location":"integrator/translations/translations-avail/#iso","text":"Source Target 101 pain.001.001.03 101 pain.001.001.08 101 pain.001.001.09 102 pacs.008.001.08 102 pacs.008.001.09 102 pacs.008.001.10 103 pacs.002.001.10 103 pacs.004.001.09 103 pacs.004.001.10 103 pacs.008.001.02 103 pacs.008.001.06 103 pacs.008.001.07 103 pacs.008.001.08 103 pacs.008.001.09 103 pacs.008.001.10 103.REMIT pacs.008.001.02 103.REMIT pacs.008.001.06 103.REMIT pacs.008.001.07 103.REMIT pacs.008.001.08 103.REMIT pacs.008.001.09 103.REMIT pacs.008.001.10 103.STP pacs.008.001.02 103.STP pacs.008.001.06 103.STP pacs.008.001.07 103.STP pacs.008.001.08 103.STP pacs.008.001.09 104 pacs.003.001.08 104 pacs.003.001.09 104 pacs.003.001.10 104 pain.008.001.08 107 pacs.003.001.08 107 pacs.003.001.09 107 pacs.003.001.10 110 camt.107.001.01 111 camt.108.001.01 112 camt.109.001.01 192 camt.056.001.08 192 camt.056.001.10 192 camt.058.001.08 196 camt.029.001.09 196 camt.029.001.11 199 pacs.002.001.10 200 camt.050.001.05 200 pacs.009.001.08 200 pacs.009.001.09 200 pacs.009.001.10 202 pacs.002.001.10 202 pacs.004.001.09 202 pacs.004.001.10 202 pacs.009.001.02 202 pacs.009.001.06 202 pacs.009.001.07 202 pacs.009.001.08 202 pacs.009.001.09 202 pacs.009.001.10 202.COV pacs.002.001.10 202.COV pacs.009.001.02 202.COV pacs.009.001.06 202.COV pacs.009.001.07 202.COV pacs.009.001.08 202.COV pacs.009.001.09 202.COV pacs.009.001.10 204 pacs.010.001.03 205 pacs.002.001.10 205 pacs.004.001.09 205 pacs.004.001.10 205 pacs.009.001.08 205 pacs.009.001.09 205.COV pacs.002.001.10 205.COV pacs.009.001.08 205.COV pacs.009.001.09 210 camt.057.001.06 292 camt.056.001.08 292 camt.056.001.10 292 camt.058.001.08 296 camt.029.001.09 296 camt.029.001.11 299 pacs.002.001.10 300 fxtr.014.001.03 502 setr.004.002.01 502 setr.010.002.01 508 semt.015.002.01 508 semt.020.002.01 509 setr.016.001.04 509 setr.016.002.01 509 setr.017.001.04 515 setr.006.001.04 515 setr.006.002.01 515 setr.012.001.04 515 setr.012.002.01 524 semt.013.002.01 524 sese.020.002.01 530 sese.030.001.08 530 sese.030.002.01 535 semt.002.001.11 535 semt.002.002.03 535 semt.003.002.03 535 semt.020.002.01 536 semt.017.001.12 536 semt.020.002.01 537 semt.018.001.13 537 semt.018.002.01 537 semt.020.002.01 538 semt.016.002.01 538 semt.020.002.01 540 sese.020.001.06 540 sese.020.001.07 540 sese.020.002.01 540 sese.023.001.09 540 sese.023.001.11 540 sese.023.002.01 540 sese.033.002.01 540 sese.036.002.01 541 sese.020.001.06 541 sese.020.001.07 541 sese.020.002.01 541 sese.023.001.09 541 sese.023.001.11 541 sese.023.002.01 541 sese.033.002.01 541 sese.036.002.01 542 sese.020.001.06 542 sese.020.001.07 542 sese.020.002.01 542 sese.023.001.09 542 sese.023.001.11 542 sese.023.002.01 542 sese.033.002.01 542 sese.036.002.01 543 sese.020.001.06 543 sese.020.001.07 543 sese.020.002.01 543 sese.023.001.09 543 sese.023.001.11 543 sese.023.002.01 543 sese.033.002.01 543 sese.036.002.01 544 semt.020.002.01 544 sese.025.001.09 544 sese.025.001.11 544 sese.025.002.01 544 sese.026.001.10 544 sese.026.002.01 544 sese.035.002.01 545 semt.020.002.01 545 sese.025.001.09 545 sese.025.001.11 545 sese.025.002.01 545 sese.026.001.10 545 sese.026.002.01 545 sese.035.002.01 546 semt.020.002.01 546 sese.025.001.09 546 sese.025.001.11 546 sese.025.002.01 546 sese.026.001.10 546 sese.026.002.01 546 sese.035.002.01 547 semt.020.002.01 547 sese.025.001.09 547 sese.025.001.11 547 sese.025.002.01 547 sese.026.001.10 547 sese.026.002.01 547 sese.035.002.01 548 semt.014.002.01 548 sese.022.002.01 548 sese.024.001.10 548 sese.024.001.11 548 sese.024.001.12 548 sese.024.002.01 548 sese.027.001.05 548 sese.027.002.01 548 sese.031.001.08 548 sese.031.002.01 548 sese.032.002.01 548 sese.034.002.01 549 semt.021.002.01 549 sese.021.002.01 564 seev.031.001.10 564 seev.031.001.11 564 seev.031.002.02 564 seev.031.002.06 564 seev.031.002.12 564 seev.031.002.13 564 seev.035.001.12 564 seev.035.002.02 564 seev.035.002.12 564 seev.039.002.02 564 seev.039.002.06 564 seev.039.002.11 564 seev.044.001.10 564 seev.044.002.02 564 seev.044.002.10 565 seev.033.002.02 565 seev.033.002.12 565 seev.040.002.02 565 seev.040.002.11 566 seev.036.001.12 566 seev.036.002.02 566 seev.036.002.06 566 seev.036.002.07 566 seev.036.002.08 566 seev.036.002.09 566 seev.036.002.12 566 seev.037.001.12 566 seev.037.002.02 566 seev.037.002.06 566 seev.037.002.07 566 seev.037.002.08 566 seev.037.002.09 566 seev.037.002.12 567 seev.032.002.02 567 seev.032.002.08 567 seev.034.002.02 567 seev.034.002.13 567 seev.041.001.10 567 seev.041.002.12 568 seev.031.001.10 568 seev.031.001.11 568 seev.031.002.02 568 seev.031.002.06 568 seev.031.002.12 568 seev.031.002.13 568 seev.038.002.02 568 seev.038.002.07 578 semt.020.001.07 578 semt.020.002.01 578 sese.028.001.08 578 sese.028.002.01 578 sese.029.002.01 586 semt.019.002.01 586 semt.020.002.01 586 sese.037.002.01 900 camt.054.001.02 900 camt.054.001.06 900 camt.054.001.07 900 camt.054.001.08 900 camt.054.001.09 910 camt.054.001.02 910 camt.054.001.06 910 camt.054.001.07 910 camt.054.001.08 910 camt.054.001.09 920 camt.060.001.05 920 camt.060.001.06 940 camt.053.001.02 940 camt.053.001.06 940 camt.053.001.07 940 camt.053.001.08 940 camt.053.001.09 940 camt.053.001.10 940 camt.053.001.11 941 camt.052.001.02 941 camt.052.001.06 941 camt.052.001.07 941 camt.052.001.08 941 camt.052.001.09 942 camt.052.001.02 942 camt.052.001.06 942 camt.052.001.07 942 camt.052.001.08 942 camt.052.001.09 950 camt.053.001.02 950 camt.053.001.06 950 camt.053.001.07 950 camt.053.001.08 950 camt.053.001.09 950 camt.053.001.10 950 camt.053.001.11","title":"ISO"},{"location":"integrator/translations/translations-avail/#cbpr","text":"Source Target 101 pain.001.001.09 102 pacs.008.001.08 102.STP pacs.008.001.08.STP 103 pacs.002.001.10 103 pacs.004.001.09 103 pacs.008.001.08 103.STP pacs.008.001.08.STP 104 pacs.003.001.08 104 pain.008.001.08 107 pacs.003.001.08 110 camt.107.001.01 111 camt.108.001.01 112 camt.109.001.01 192 camt.055.001.08 192 camt.056.001.08 196 camt.029.001.09 199 pacs.002.001.10 200 pacs.009.001.08 201 pacs.009.001.08 202 pacs.002.001.10 202 pacs.004.001.09 202 pacs.009.001.08 202 pacs.009.001.08.ADV 202.COV pacs.002.001.10 202.COV pacs.009.001.08.COV 203 pacs.009.001.08 204 pacs.010.001.03 205 pacs.002.001.10 205 pacs.004.001.09 205 pacs.009.001.08 205.COV pacs.002.001.10 205.COV pacs.009.001.08.COV 210 camt.057.001.06 292 camt.056.001.08 292 camt.058.001.08 296 camt.029.001.09 299 pacs.002.001.10 900 camt.054.001.08 910 camt.054.001.08 920 camt.060.001.05 940 camt.053.001.08 941 camt.052.001.08 942 camt.052.001.08 950 camt.053.001.08","title":"CBPR"},{"location":"integrator/translations/translations-avail/#chats","text":"Source Target 103 pacs.008.001.08 192 camt.056.001.08 202 pacs.009.001.08 202.COV pacs.009.001.08 292 camt.056.001.08","title":"CHATS"},{"location":"integrator/translations/translations-avail/#lynx","text":"Source Target 103 pacs.004.001.09 103 pacs.008.001.08 202 pacs.004.001.09 202 pacs.009.001.08 202.COV pacs.009.001.08 205 pacs.004.001.09 205 pacs.009.001.08","title":"LYNX"},{"location":"integrator/translations/translations-avail/#rits","text":"Source Target 103 pacs.008.001.09 202 pacs.009.001.09 202.COV pacs.009.001.09","title":"RITS"},{"location":"integrator/translations/translations-avail/#scrips","text":"Source Target 103 pacs.008.001.08 202 pacs.009.001.08 202.COV pacs.009.001.08","title":"SCRIPS"},{"location":"integrator/translations/translations-avail/#sic_v4_10","text":"Source Target 103 pacs.008.001.08.Ch02 202 pacs.009.001.08.Ch03 202.COV pacs.009.001.08.Ch03","title":"SIC_v4_10"},{"location":"integrator/translations/translations-avail/#swiftgo","text":"Source Target 103 pacs.008.001.08 199 trck.001.001.02 199 trck.002.001.01","title":"SWIFTGO"},{"location":"integrator/translations/translations-avail/#t2","text":"Source Target 103 pacs.004.001.09 103 pacs.008.001.08 202 pacs.004.001.09 202 pacs.009.001.08 205 pacs.004.001.09 205 pacs.009.001.08","title":"T2"},{"location":"integrator/translations/translations-avail/#mx-to-mt","text":"","title":"MX to MT"},{"location":"integrator/translations/translations-avail/#iso_1","text":"Source Target camt.029.001.09 196 camt.029.001.09 296 camt.029.001.11 196 camt.029.001.11 296 camt.050.001.05 200 camt.052.001.06 941 camt.052.001.06 942 camt.052.001.07 941 camt.052.001.07 942 camt.052.001.08 941 camt.052.001.08 942 camt.052.001.09 941 camt.052.001.09 942 camt.053.001.02 940 camt.053.001.06 940 camt.053.001.06 950 camt.053.001.07 940 camt.053.001.07 950 camt.053.001.08 940 camt.053.001.08 950 camt.053.001.09 940 camt.053.001.09 950 camt.053.001.10 940 camt.053.001.10 950 camt.053.001.11 940 camt.053.001.11 950 camt.054.001.06 900 camt.054.001.06 910 camt.054.001.07 900 camt.054.001.07 910 camt.054.001.08 900 camt.054.001.08 910 camt.054.001.09 900 camt.054.001.09 910 camt.056.001.08 192 camt.056.001.08 292 camt.056.001.10 192 camt.056.001.10 292 camt.057.001.06 210 camt.060.001.05 920 camt.060.001.06 920 camt.107.001.01 110 camt.108.001.01 111 camt.109.001.01 112 pacs.002.001.10 199 pacs.002.001.10 299 pacs.003.001.08 104 pacs.003.001.08 107 pacs.003.001.09 104 pacs.003.001.09 107 pacs.003.001.10 104 pacs.003.001.10 107 pacs.004.001.02 103 pacs.004.001.09 103 pacs.004.001.09 202 pacs.004.001.09 205 pacs.004.001.10 103 pacs.004.001.10 202 pacs.004.001.10 205 pacs.008.001.02 103 pacs.008.001.06 103 pacs.008.001.07 103 pacs.008.001.08 102 pacs.008.001.08 103 pacs.008.001.08 103.REMIT pacs.008.001.09 102 pacs.008.001.09 103 pacs.008.001.10 102 pacs.008.001.10 103 pacs.009.001.02 202 pacs.009.001.02 202.COV pacs.009.001.06 202 pacs.009.001.06 202.COV pacs.009.001.07 202 pacs.009.001.07 202.COV pacs.009.001.08 200 pacs.009.001.08 202 pacs.009.001.08 202.COV pacs.009.001.08 205 pacs.009.001.08 205.COV pacs.009.001.09 200 pacs.009.001.09 202 pacs.009.001.09 202.COV pacs.009.001.09 205 pacs.009.001.10 200 pacs.009.001.10 202 pacs.009.001.10 202.COV pacs.009.001.10 205 pacs.010.001.03 204 pain.001.001.03 101 pain.001.001.08 101 pain.001.001.09 101 seev.001.001.10 564 seev.002.001.09 564 seev.003.001.09 564 seev.004.001.09 565 seev.005.001.09 565 seev.006.001.09 567 seev.007.001.09 567 seev.008.001.08 568 seev.031.001.03 564 seev.031.001.03 568 seev.031.001.09 564 seev.031.001.10 564 seev.031.001.10 568 seev.031.001.11 564 seev.031.001.11 568 seev.031.001.12 564 seev.031.001.12 568 seev.031.001.13 564 seev.031.001.13 568 seev.031.002.02 564 seev.031.002.02 568 seev.031.002.12 564 seev.031.002.12 568 seev.031.002.13 564 seev.031.002.13 568 seev.032.002.02 567 seev.032.002.08 567 seev.033.002.02 565 seev.033.002.12 565 seev.034.002.02 567 seev.034.002.13 567 seev.035.001.03 564 seev.035.001.10 564 seev.035.001.11 564 seev.035.001.12 564 seev.035.001.13 564 seev.035.001.14 564 seev.035.002.02 564 seev.035.002.12 564 seev.036.001.11 566 seev.036.001.12 566 seev.036.001.13 566 seev.036.001.14 566 seev.036.002.02 566 seev.036.002.06 566 seev.036.002.07 566 seev.036.002.08 566 seev.036.002.09 566 seev.036.002.12 566 seev.037.001.11 566 seev.037.001.12 566 seev.037.001.13 566 seev.037.001.14 566 seev.037.002.02 566 seev.037.002.06 566 seev.037.002.07 566 seev.037.002.08 566 seev.037.002.09 566 seev.037.002.12 566 seev.038.001.03 568 seev.038.002.02 568 seev.038.002.07 568 seev.039.001.03 564 seev.039.001.10 564 seev.039.001.11 564 seev.039.001.12 564 seev.039.002.02 564 seev.039.002.11 564 seev.040.002.02 565 seev.040.002.11 565 seev.041.002.12 567 seev.044.001.03 564 seev.044.001.10 564 seev.044.001.11 564 seev.044.001.12 564 seev.044.002.02 564 seev.044.002.10 564 semt.002.001.10 535 semt.002.001.11 535 semt.002.002.03 535 semt.003.002.03 535 semt.013.002.01 524 semt.014.002.01 548 semt.015.002.01 508 semt.016.002.01 538 semt.017.001.12 536 semt.017.002.01 536 semt.018.001.13 537 semt.018.002.01 537 semt.019.002.01 586 semt.020.001.05 578 semt.020.001.07 578 semt.020.002.01 508 semt.020.002.01 535 semt.020.002.01 536 semt.020.002.01 537 semt.020.002.01 538 semt.020.002.01 544 semt.020.002.01 545 semt.020.002.01 546 semt.020.002.01 547 semt.020.002.01 578 semt.020.002.01 586 semt.021.002.01 549 sese.020.001.06 540 sese.020.001.06 541 sese.020.001.06 542 sese.020.001.06 543 sese.020.001.07 540 sese.020.001.07 541 sese.020.001.07 542 sese.020.001.07 543 sese.020.002.01 524 sese.020.002.01 540 sese.020.002.01 541 sese.020.002.01 542 sese.020.002.01 543 sese.021.002.01 549 sese.022.002.01 548 sese.023.001.09 540 sese.023.001.09 541 sese.023.001.09 542 sese.023.001.09 543 sese.023.001.11 540 sese.023.001.11 541 sese.023.001.11 542 sese.023.001.11 543 sese.023.002.01 540 sese.023.002.01 541 sese.023.002.01 542 sese.023.002.01 543 sese.024.001.09 548 sese.024.001.10 548 sese.024.001.11 548 sese.024.001.12 548 sese.024.002.01 548 sese.025.001.09 544 sese.025.001.09 545 sese.025.001.09 546 sese.025.001.09 547 sese.025.001.11 544 sese.025.001.11 545 sese.025.001.11 546 sese.025.001.11 547 sese.025.002.01 544 sese.025.002.01 545 sese.025.002.01 546 sese.025.002.01 547 sese.026.001.10 544 sese.026.001.10 545 sese.026.001.10 546 sese.026.001.10 547 sese.026.002.01 544 sese.026.002.01 545 sese.026.002.01 546 sese.026.002.01 547 sese.027.001.05 548 sese.027.002.01 548 sese.028.001.08 578 sese.028.001.09 578 sese.028.001.10 578 sese.028.002.01 578 sese.029.001.04 578 sese.029.002.01 578 sese.030.001.08 530 sese.030.002.01 530 sese.031.001.08 548 sese.031.002.01 548 sese.032.002.01 548 sese.033.002.01 540 sese.033.002.01 541 sese.033.002.01 542 sese.033.002.01 543 sese.034.002.01 548 sese.035.002.01 544 sese.035.002.01 545 sese.035.002.01 546 sese.035.002.01 547 sese.036.002.01 540 sese.036.002.01 541 sese.036.002.01 542 sese.036.002.01 543 sese.037.002.01 586 setr.004.001.04 502 setr.004.002.01 502 setr.006.001.04 515 setr.006.002.01 515 setr.010.001.04 502 setr.010.002.01 502 setr.012.001.04 515 setr.012.002.01 515 setr.015.001.04 515.Redemption setr.015.001.04 515.Subscription setr.016.001.04 509 setr.016.002.01 509 setr.017.001.04 509","title":"ISO"},{"location":"integrator/translations/translations-avail/#cbpr_1","text":"Source Target camt.029.001.09 196 camt.029.001.09 296 camt.052.001.08 941 camt.052.001.08 942 camt.053.001.08 940 camt.053.001.08 950 camt.054.001.08 900 camt.054.001.08 910 camt.055.001.08 192 camt.056.001.08 192 camt.056.001.08 292 camt.057.001.06 210 camt.058.001.08 292 camt.060.001.05 920 camt.107.001.01 110 camt.108.001.01 111 camt.109.001.01 112 pacs.002.001.10 199 pacs.002.001.10 299 pacs.003.001.08 104 pacs.003.001.08 107 pacs.004.001.09 103 pacs.004.001.09 202 pacs.004.001.09 205 pacs.008.001.08 102 pacs.008.001.08 103 pacs.008.001.08 103.REMIT pacs.008.001.08STP 102STP pacs.008.001.08STP 103STP pacs.009.001.08 200 pacs.009.001.08 202 pacs.009.001.08 205 pacs.009.001.08.ADV 202 pacs.009.001.08.COV 202.COV pacs.009.001.08.COV 205.COV pacs.010.001.03 204 pain.001.001.09 101 pain.008.001.08 104","title":"CBPR"},{"location":"integrator/translations/translations-avail/#sic_v4_11","text":"Source Target pacs.004.001.09.Ch02 103 pacs.008.001.08.Ch02 103 pacs.009.001.08.Ch03 202 pacs.009.001.08.Ch03 202.COV","title":"SIC_v4_10"},{"location":"integrator/translations/translations-avail/#swiftgo_1","text":"Source Target pacs.008.001.08 103 trck.001.001.02 199 trck.002.001.01 199","title":"SWIFTGO"},{"location":"integrator/translations/translations-factory/","text":"Translator factory Generic translation Generic translation calls, without knowing in advance the source message type, can be done in two ways. Using the Translator interface or using the TranslatorFactory . This is particularly useful when translating and inbound queue of receiving a variety of unknown message types. Translator interface All MT and MX translation classes implement the common translation interface Translator . This interface is helpful in situations where generic translation must be implemented, consolidating the translation of several message types in a single processing unit. The following method uses this interface to translate any MT receiving the translation implementation and specific source message as parameters: private static AbstractMX doTranslation ( final Translator translator , final AbstractMT msg ){ AbstractMX mx = null ; try { mx = translator . translate ( msg ); } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } catch ( final TranslationPreconditionException e2 ) { System . out . println ( \"precondition exception: \" + e2 . getMessage ()); } return mx ; } The reverse from MX to MT can be seamlessly achieve. Translator factory In order to get a proper translator instance automatically, a TranslatorFactory is also provided. The factory accepts an MT or MX message instance as a parameter and returns the available matching translator for the message. Translator t = TranslatorFactory . getTranslator ( msg ); The above method, for example, when an MT103 is passed, would return an instance of the MT103_MxPacs00800110_Translation translation implementation. And when the parameter is an MxPacs00800110 message the returned translator will be MxPacs00800110_MT103_Translation . Meaning the same factory is used to either MT to MX or MX to MT translations. Notice the MX version may be different from the example, depending on the latest version available. When converting from MT to MX several translator implementations might be available, to create different versions of the same output MX message type. In this situation, by default, the factory will return the translator for the latest version available. Internally the factory applies different methods in cascade to narrow the available options and to finally select the specific translator instance to return: 1. Existing translation implementation for the specific source message type 2. Logical message criteria applied to the source message type 3. Optional, preconditions check applied to the source message type 4. Optional, preferred specific target message type In any of the steps above if the options are reduced to a single candidate, that translator is returned. Otherwise, the factory returns null. Factory selection criteria The main logic to pickup one translation over another one is by applying the logical message criteria on the source message. These criteria are implemented when the equivalence is not 1 to 1. Most of the available translations are a 1 to one equivalence, but in some exceptional cases, you might have in particular some MT that can be used for multiple functions while in the MX standard there are specific types for each use case. This logic is implemented in each translator classe and is used by the factory to determine which translator instance to create. As a result, the getTranslator call for an MT502 could return either MT502_MxSetr01000201_Translation , MT502_MxSetr00400201_Translation or null depending on the function of the MT message. And by function we refer to the source message content. Thus, the criteria check involves inspecting the source message content. The javadoc for the translator implementations describes the specific criteria for each translator. Complete example: https://github.com/prowide/prowide-integrator-examples/blob/master/src/main/java/com/prowidesoftware/swift/samples/integrator/translations/MtMxTranslationExample3.java Factory preconditions check Besides the logical message criteria, the factory can also check the preconditions (when available for the translator). This check is skipped by default because despite the logical message criteria, a source message could be translated even if it does not meet the preconditions. The host application can always retrieve the translator from the factory, and then check the preconditions itself to handle any errors. When this is not the preferred option, the factory can be configured to use also the precondition check for the translator selection like this: TranslatorFactory . getTranslator ( msg , new TranslatorFactoryConfiguration (). setEvaluatePreconditions ( true )); While this reduces logic in the calling application, the drawback is that the factory might return null when there is no selectable translator instance and the application will not know if the issue comes from a failed logical message criteria or by a failed precondition. The precondition check main goal is to ensure that the translated message will be valid. Preferred specific version The factory accepts a also a parameter to indicate the specific target message type. For example: Translator t = TranslatorFactory . getTranslator ( mt , \"pacs.008.001.08\" ); In the above example, given an MT103 as parameter the translator instance will be the MT103_MxPacs00800108_Translation translation implementation. It is important to notice that the target message type must be a valid equivalence and with a translation implementation available in the library, otherwise the factory will return null. This way of customizing the factoru might be useful for instance in situations where the expected output message type is received as parameter from the user or exported service. On the contrary, it does not make much sense to use this parameter hard-coded in the application, since in that case where the versions are fixed and known, it is better to create the specific translator instance directly. Preferred equivalences As an alternative to the above, there is a much powerful option to customize the overall criteria for the factory using a parameter in the TranslatorFactoryConfiguration like this: TranslatorFactory . getTranslator ( new MT103 (), new TranslatorFactoryConfiguration () . withTranslationMappings ( Collections . singletonList ( \"MT103:pacs.008.001.08\" )); In this example, when translating from an MT103 message, the factory will pick up the 08 version of the MX instead of using the latest available version as default. Or: TranslatorFactory . getTranslator ( new MxPacs00900108 (), new TranslatorFactoryConfiguration () . withTranslationMappings ( Collections . singletonList ( \"pacs.009.001.08:MT200.*\" )); In this other example, when translating from a pacs.009.001.08 the factory will pick up the MT200 as target message type instead of the default MT202 . The TranslationMappings parameter is the key feature to configure the factory criteria in a flexible way. Each entry in this List is a String that defines a mapping from a source message type to one or more target message types. The general format is \"SOURCE : TARGET1, TARGET2,...,TARGETN\". Example: MT103: pacs.008.001.02, pacs.008.002.08 : This mapping indicates that the source message type MT103 is primarily translated to pacs.008.001.02 . If this target is not available, the system attempts to translate to pacs.008.002.08 , and if this too is unavailable, it will resort to any other available target. Flexibility with Wildcards: Wildcards ( * ) are particularly useful in specifying a range of message types. For instance, using * with an MtId or MXid allows the system to select any message type within the specified range, prioritizing the most recent version available. Examples include camt.* to match any camt message, pacs.008.001.* to match any version of pacs.008.001 , and pain.*.*.03 to match any pain message with the version 03 regardless of its business process or functionality. Overall, when a very strict set of versions is required, it is recommended that you implement your own factory logic, and creating the specific instance of Translator needed for each source MT. In the MX to MT case, the situation is simpler since normally there is a single target MT type for any given MX . Thus, the factory can normally be used in most situations. Custom Translator Factory In certain scenarios it might make sense to create your own translator factory. This allows you to dynamically choose the right translation implementation for a given message. A translator factory is basically any class that receives a source message and returns a Translator instance. So there are no restrictions on how to implement it. However, here's an example of how to create a simple translator factory leveraging the translatable method of the translator to apply the logical criteria and preconditions check: public Translator getTranslator ( AbstractMX source , boolean checkPreconditions ) { final String identifier = source . getMxId (). id (); switch ( identifier ) { case \"pacs.004.001.09\" : { MxPacs00400109Ch02_MT103_Translation t = new MxPacs00400109Ch02_MT103_Translation (); if ( t . translatable (( MxPacs00400109Ch02 ) source , checkPreconditions )) { return t ; } break ; } case \"pacs.008.001.08\" : { MxPacs00800108Ch02_MT103_Translation t = new MxPacs00800108Ch02_MT103_Translation (); if ( t . translatable (( MxPacs00800108Ch02 ) source , checkPreconditions )) { return t ; } break ; } case \"pacs.009.001.08\" : { MxPacs00900108Ch03 mx = ( MxPacs00900108Ch03 ) source ; MxPacs00900108Ch03_MT202COV_Translation tCOV = new MxPacs00900108Ch03_MT202COV_Translation (); if ( tCOV . translatable ( mx , checkPreconditions )) { return tCOV ; } MxPacs00900108Ch03_MT202_Translation t = new MxPacs00900108Ch03_MT202_Translation (); if ( t . translatable ( mx , checkPreconditions )) { return t ; } break ; } } return null ; } In this example, the CustomTranslatorFactory class defines a getTranslator method that takes the source MX message and a boolean flag to indicate whether preconditions should be checked. Inside the method, you can use a switch statement or any logic you prefer to select the appropriate translation class based on the message identifier ( identifier ). The translatable method is called for each potential translation class to check if it's suitable for the given source message. In situations such as dealing with pacs.009 messages, where there may be multiple target options, you may want to test each of them to determine the appropriate translation. Additionally, there are cases where multiple target options are available, and the logical criteria check does not provide a clear choice. In such cases, you'll need to make a decision based on your specific requirements. Creating a custom translator factory allows you to dynamically select the most suitable translator class for a given source message, enhancing the adaptability of your translation process. Using the Custom Translator Factory To use the custom translator factory, you can call its getTranslator method when you need to perform a translation: CustomTranslatorFactory factory = new CustomTranslatorFactory (); AbstractMX sourceMessage = // Initialize your source MX message here boolean checkPreconditions = true ; // Set to true if you want to check preconditions Translator translator = factory . getTranslator ( sourceMessage , checkPreconditions ); if ( translator != null ) { // Perform the translation using the selected translator // ... } else { // Handle the case when no suitable translator is found // ... } This approach gives you the flexibility to dynamically choose the appropriate translation class based on the source message type, making your translation process more adaptable to different scenarios. Factories per market type All the topics above apply to the general ISO 20022 translator factory and also for the complementary factories provided by the library for the restricted ISO 20022 standards: such as CBPR+, SIC, CHATS, etc... Those factories can be accessed directly from the specific marget type package, and provide the same API as the general ISO 20022 translator factory. And also by means of the TranslatorFactoryProvider . For more details check the ISO 20022 restricted standards section.","title":"Translator factory"},{"location":"integrator/translations/translations-factory/#translator-factory","text":"","title":"Translator factory"},{"location":"integrator/translations/translations-factory/#generic-translation","text":"Generic translation calls, without knowing in advance the source message type, can be done in two ways. Using the Translator interface or using the TranslatorFactory . This is particularly useful when translating and inbound queue of receiving a variety of unknown message types.","title":"Generic translation"},{"location":"integrator/translations/translations-factory/#translator-interface","text":"All MT and MX translation classes implement the common translation interface Translator . This interface is helpful in situations where generic translation must be implemented, consolidating the translation of several message types in a single processing unit. The following method uses this interface to translate any MT receiving the translation implementation and specific source message as parameters: private static AbstractMX doTranslation ( final Translator translator , final AbstractMT msg ){ AbstractMX mx = null ; try { mx = translator . translate ( msg ); } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } catch ( final TranslationPreconditionException e2 ) { System . out . println ( \"precondition exception: \" + e2 . getMessage ()); } return mx ; } The reverse from MX to MT can be seamlessly achieve.","title":"Translator interface"},{"location":"integrator/translations/translations-factory/#translator-factory_1","text":"In order to get a proper translator instance automatically, a TranslatorFactory is also provided. The factory accepts an MT or MX message instance as a parameter and returns the available matching translator for the message. Translator t = TranslatorFactory . getTranslator ( msg ); The above method, for example, when an MT103 is passed, would return an instance of the MT103_MxPacs00800110_Translation translation implementation. And when the parameter is an MxPacs00800110 message the returned translator will be MxPacs00800110_MT103_Translation . Meaning the same factory is used to either MT to MX or MX to MT translations. Notice the MX version may be different from the example, depending on the latest version available. When converting from MT to MX several translator implementations might be available, to create different versions of the same output MX message type. In this situation, by default, the factory will return the translator for the latest version available. Internally the factory applies different methods in cascade to narrow the available options and to finally select the specific translator instance to return: 1. Existing translation implementation for the specific source message type 2. Logical message criteria applied to the source message type 3. Optional, preconditions check applied to the source message type 4. Optional, preferred specific target message type In any of the steps above if the options are reduced to a single candidate, that translator is returned. Otherwise, the factory returns null.","title":"Translator factory"},{"location":"integrator/translations/translations-factory/#factory-selection-criteria","text":"The main logic to pickup one translation over another one is by applying the logical message criteria on the source message. These criteria are implemented when the equivalence is not 1 to 1. Most of the available translations are a 1 to one equivalence, but in some exceptional cases, you might have in particular some MT that can be used for multiple functions while in the MX standard there are specific types for each use case. This logic is implemented in each translator classe and is used by the factory to determine which translator instance to create. As a result, the getTranslator call for an MT502 could return either MT502_MxSetr01000201_Translation , MT502_MxSetr00400201_Translation or null depending on the function of the MT message. And by function we refer to the source message content. Thus, the criteria check involves inspecting the source message content. The javadoc for the translator implementations describes the specific criteria for each translator. Complete example: https://github.com/prowide/prowide-integrator-examples/blob/master/src/main/java/com/prowidesoftware/swift/samples/integrator/translations/MtMxTranslationExample3.java","title":"Factory selection criteria"},{"location":"integrator/translations/translations-factory/#factory-preconditions-check","text":"Besides the logical message criteria, the factory can also check the preconditions (when available for the translator). This check is skipped by default because despite the logical message criteria, a source message could be translated even if it does not meet the preconditions. The host application can always retrieve the translator from the factory, and then check the preconditions itself to handle any errors. When this is not the preferred option, the factory can be configured to use also the precondition check for the translator selection like this: TranslatorFactory . getTranslator ( msg , new TranslatorFactoryConfiguration (). setEvaluatePreconditions ( true )); While this reduces logic in the calling application, the drawback is that the factory might return null when there is no selectable translator instance and the application will not know if the issue comes from a failed logical message criteria or by a failed precondition. The precondition check main goal is to ensure that the translated message will be valid.","title":"Factory preconditions check"},{"location":"integrator/translations/translations-factory/#preferred-specific-version","text":"The factory accepts a also a parameter to indicate the specific target message type. For example: Translator t = TranslatorFactory . getTranslator ( mt , \"pacs.008.001.08\" ); In the above example, given an MT103 as parameter the translator instance will be the MT103_MxPacs00800108_Translation translation implementation. It is important to notice that the target message type must be a valid equivalence and with a translation implementation available in the library, otherwise the factory will return null. This way of customizing the factoru might be useful for instance in situations where the expected output message type is received as parameter from the user or exported service. On the contrary, it does not make much sense to use this parameter hard-coded in the application, since in that case where the versions are fixed and known, it is better to create the specific translator instance directly.","title":"Preferred specific version"},{"location":"integrator/translations/translations-factory/#preferred-equivalences","text":"As an alternative to the above, there is a much powerful option to customize the overall criteria for the factory using a parameter in the TranslatorFactoryConfiguration like this: TranslatorFactory . getTranslator ( new MT103 (), new TranslatorFactoryConfiguration () . withTranslationMappings ( Collections . singletonList ( \"MT103:pacs.008.001.08\" )); In this example, when translating from an MT103 message, the factory will pick up the 08 version of the MX instead of using the latest available version as default. Or: TranslatorFactory . getTranslator ( new MxPacs00900108 (), new TranslatorFactoryConfiguration () . withTranslationMappings ( Collections . singletonList ( \"pacs.009.001.08:MT200.*\" )); In this other example, when translating from a pacs.009.001.08 the factory will pick up the MT200 as target message type instead of the default MT202 . The TranslationMappings parameter is the key feature to configure the factory criteria in a flexible way. Each entry in this List is a String that defines a mapping from a source message type to one or more target message types. The general format is \"SOURCE : TARGET1, TARGET2,...,TARGETN\". Example: MT103: pacs.008.001.02, pacs.008.002.08 : This mapping indicates that the source message type MT103 is primarily translated to pacs.008.001.02 . If this target is not available, the system attempts to translate to pacs.008.002.08 , and if this too is unavailable, it will resort to any other available target. Flexibility with Wildcards: Wildcards ( * ) are particularly useful in specifying a range of message types. For instance, using * with an MtId or MXid allows the system to select any message type within the specified range, prioritizing the most recent version available. Examples include camt.* to match any camt message, pacs.008.001.* to match any version of pacs.008.001 , and pain.*.*.03 to match any pain message with the version 03 regardless of its business process or functionality. Overall, when a very strict set of versions is required, it is recommended that you implement your own factory logic, and creating the specific instance of Translator needed for each source MT. In the MX to MT case, the situation is simpler since normally there is a single target MT type for any given MX . Thus, the factory can normally be used in most situations.","title":"Preferred equivalences"},{"location":"integrator/translations/translations-factory/#custom-translator-factory","text":"In certain scenarios it might make sense to create your own translator factory. This allows you to dynamically choose the right translation implementation for a given message. A translator factory is basically any class that receives a source message and returns a Translator instance. So there are no restrictions on how to implement it. However, here's an example of how to create a simple translator factory leveraging the translatable method of the translator to apply the logical criteria and preconditions check: public Translator getTranslator ( AbstractMX source , boolean checkPreconditions ) { final String identifier = source . getMxId (). id (); switch ( identifier ) { case \"pacs.004.001.09\" : { MxPacs00400109Ch02_MT103_Translation t = new MxPacs00400109Ch02_MT103_Translation (); if ( t . translatable (( MxPacs00400109Ch02 ) source , checkPreconditions )) { return t ; } break ; } case \"pacs.008.001.08\" : { MxPacs00800108Ch02_MT103_Translation t = new MxPacs00800108Ch02_MT103_Translation (); if ( t . translatable (( MxPacs00800108Ch02 ) source , checkPreconditions )) { return t ; } break ; } case \"pacs.009.001.08\" : { MxPacs00900108Ch03 mx = ( MxPacs00900108Ch03 ) source ; MxPacs00900108Ch03_MT202COV_Translation tCOV = new MxPacs00900108Ch03_MT202COV_Translation (); if ( tCOV . translatable ( mx , checkPreconditions )) { return tCOV ; } MxPacs00900108Ch03_MT202_Translation t = new MxPacs00900108Ch03_MT202_Translation (); if ( t . translatable ( mx , checkPreconditions )) { return t ; } break ; } } return null ; } In this example, the CustomTranslatorFactory class defines a getTranslator method that takes the source MX message and a boolean flag to indicate whether preconditions should be checked. Inside the method, you can use a switch statement or any logic you prefer to select the appropriate translation class based on the message identifier ( identifier ). The translatable method is called for each potential translation class to check if it's suitable for the given source message. In situations such as dealing with pacs.009 messages, where there may be multiple target options, you may want to test each of them to determine the appropriate translation. Additionally, there are cases where multiple target options are available, and the logical criteria check does not provide a clear choice. In such cases, you'll need to make a decision based on your specific requirements. Creating a custom translator factory allows you to dynamically select the most suitable translator class for a given source message, enhancing the adaptability of your translation process.","title":"Custom Translator Factory"},{"location":"integrator/translations/translations-factory/#using-the-custom-translator-factory","text":"To use the custom translator factory, you can call its getTranslator method when you need to perform a translation: CustomTranslatorFactory factory = new CustomTranslatorFactory (); AbstractMX sourceMessage = // Initialize your source MX message here boolean checkPreconditions = true ; // Set to true if you want to check preconditions Translator translator = factory . getTranslator ( sourceMessage , checkPreconditions ); if ( translator != null ) { // Perform the translation using the selected translator // ... } else { // Handle the case when no suitable translator is found // ... } This approach gives you the flexibility to dynamically choose the appropriate translation class based on the source message type, making your translation process more adaptable to different scenarios.","title":"Using the Custom Translator Factory"},{"location":"integrator/translations/translations-factory/#factories-per-market-type","text":"All the topics above apply to the general ISO 20022 translator factory and also for the complementary factories provided by the library for the restricted ISO 20022 standards: such as CBPR+, SIC, CHATS, etc... Those factories can be accessed directly from the specific marget type package, and provide the same API as the general ISO 20022 translator factory. And also by means of the TranslatorFactoryProvider . For more details check the ISO 20022 restricted standards section.","title":"Factories per market type"},{"location":"integrator/translations/translations-general/","text":"General Concepts Translation classes Translations are normally one to one , from a source message into a target message. Each available translation implementation, given a source message type and a target message type, is implemented in a specific class. The message types are explicit in the class names and also in the class parameters for the translation call. For example: Class name Source message type Target message type MT103_STP_MxPacs00800102_Translation MT 103 STP pacs.008.001.02 MxPacs00900102_MT202COV_Translation pacs.009.001.02 MT 202 COV In the most simple use case scenario the translation is called like this: MT103 mt = MT103 . parse ( fin ); try { MxPacs00800108_MT103_Translation t = new MxPacs00800108_MT103_Translation (); MxPacs00800108 mx = t . translate ( mt ); } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } catch ( final TranslationPreconditionException e2 ) { System . out . println ( \"precondition exception: \" + e2 . getMessage ()); } In the code above, we create an instance of the specific translation, and we call the translate method passing the source message as parameter. The result is the target message. And the revers from MX to an MT analogously. Notice translation classes are not thread safe , so a new instance must be created for each translation. The precondition and logical criteria checks are explained in the following sections, but that is basically a way to check if the source message is suitable for the specific translation, and if the target message will be valid after the translation. Logical message criteria The logical message criteria is a condition evaluated on the source message, to know if it is selectable for the specific translation. In most cases, there is only a single available equivalence for the translation. This is mostly the case when converting from MX to MT. However, in some cases, a single message can be translated to more than one target option. This is due to the fact that in the MT standard, there are many message types that can be used for different functions. While in the MX standard, there are specific message types for each function. For example, an MT502 could be a Redemption Order or a Subscription Order, meaning the same MT structure can be used for two different functions. While its MX equivalences have two specific message types for the Redemption and Subscription, setr.004.002.01 or setr.010.002.01. This criteria evaluation is checked automatically when the translation is run. It can be switched off by configuration, and optionally called by the application before the translation. Manual criteria check All translation classes have a translatable method that is used to check the logical criteria. This method checks the content of the source message and returns true or false if it is suitable for the specific translation. MT545 for example could be translated to a sese.025, sese.020, sese.026 or sese.035. Since in the MX standard, there are specific types for each use case, while in the MT all functions are covered by the same message type 545. If you call the translatable method for all possible translations using the same MT source for example: MT545 mt = MT545 . parse ( fin ); MT545_MxSese02500109_Translation t1 = new MT545_MxSese02500109_Translation (); MT545_MxSemt02000201_Translation t2 = new MT545_MxSemt02000201_Translation (); MT545_MxSese02600201_Translation t3 = new MT545_MxSese02600201_Translation (); MT545_MxSese03500201_Translation t4 = new MT545_MxSese03500201_Translation (); t1 . translatable ( mt , true )); t2 . translatable ( mt , true )); t3 . translatable ( mt , true )); t4 . translatable ( mt , true )); Then, for a given valid MT, only one of the options should return true while the others should return false. You can do the above manually, in a sequence of IF/ELSE conditions. Or you can just use the translator factory. The translator factory does exactly that, it checks given a source message what output is translatable. Although, notice there are a few situations where the same input could be translated seamlessly to more than one output. In such cases the translator factory returns a default. Preconditions Each specific translation may implement its own preconditions . This is a condition evaluated on the source message, to make sure the created target message will be valid. It is mainly used when the target message has some mandatory content that is optional in the source message. These preconditions are checked automatically when the translation is run. They can be switched off by configuration, and optionally called by the application before the translation. Manual precondition check Preconditions on the source message can be checked explicitly before attempting the translation, or can be caught from an exception calling the translation method in a try block. The following method will check all the message preconditions and will return a list of precondition errors. final MT564_MxSeev03900202_Translation translator = new MT564_MxSeev03900202_Translation (); final MT564 source = MT564 . parse ( sample ); try { // The precondition being check is: // IF ((B2[*]\\97a Account\\SAFE\\97C\\Account Code ContainsString 'GENR') And ((B2[*]\\95a Party\\ACOW IsPresent) Or ((B2[*]\\94a Place\\SAFE IsPresent) Or (B2[*]\\93a Balance IsPresent)))) // this pseudo-code is available in the translator javadoc List < PreconditionError > p = translator . preconditionsCheck ( source ); if ( p . isEmpty ()) { // Call the translation process final MxSeev03900202 mx = translator . translate ( source ); // Print content from the translated message System . out . println ( \"Cancellation Reason Code: \" + mx . getCorpActnCxlAdvc (). getCxlAdvcGnlInf (). getCxlRsnCd (). name ()); System . out . println ( \"Processing Completness: \" + mx . getCorpActnCxlAdvc (). getCxlAdvcGnlInf (). getPrcgSts (). getEvtSts (). getEvtCmpltnsSts (). name ()); System . out . println ( \"Corporate Action Id: \" + mx . getCorpActnCxlAdvc (). getCorpActnGnlInf (). getCorpActnEvtId ()); System . out . println ( \"Event Type Code: \" + mx . getCorpActnCxlAdvc (). getCorpActnGnlInf (). getEvtTp (). getCd (). name ()); System . out . println ( \"Underlying Security ISIN: \" + mx . getCorpActnCxlAdvc (). getCorpActnGnlInf (). getUndrlygSctyId (). getISIN ()); } else { // Print precondition errors for ( PreconditionError e : p ) { System . out . println ( \"precondition error: \" + e . getCode () + \" \" + e . getDescription ()); } } } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } In the above example the translator is any instance of a Translator implementation. When the translation is from MT to MX the expected parameter is the MT. When the translation is from MX to MT the expected parameter is the MX. If the returned list is empty, the source message satisfies all preconditions. If not, each element in the list will contain a code and a description of the condition that is not satisfied. Compliance In order for the target message to be valid, these premises should be satisfied: The source message should be valid. Notice the translation module will not run full compliance message validation, neither on source nor target messages. However, the Prowide Integrator Validation module can be used for this purpose. The logical message criteria check should pass: meaning the source message should be selectable for the specific translation applied. The preconditions on the source message should pass. Regardless of this contract, since the translation is sensitive to the data, if the translated message is going to be sent through the network it is recommended that as the last step of the process the validation is run on the created message. Headers Regardless of the specific translation mappings, the target message header is always filled with data from the source or with derived content as follows: Translation Source element Target element MT to MX Block 1 Sender Block 2 Receiver Fixed from target message identifier Current date and time Main message reference Trailer PDE AppHdr From AppHdr To AppHdr Message Definition AppHdr Creation Date and Time AppHdr Business Message Identifier AppHdr Possible Duplicate Emission (By default the ISO Business Header is created, not the legacy Application Header) MX to MT AppHdr From * AppHdr To * AppHdr Possible Duplicate Emission Fixed from target message identifier (both ISO Business Header and legacy Application Header are supported) Block 1 Sender Block 2 Receiver Trailer PDE Block 2 message type (Direction is Input by default. The rest of the MT headers data is filled with proper defaults) * If the AppHdr is not present, the translation attempts to use the parties BIC codes in the Group Header element within the MX Document. If none is found, then the MT is populated with default BIC codes. Also, both BIC and DN structures are supported, when the DN is used the BIC is extracted and filled with the default branch code. This default mapping can be overridden by configuration. In the TranslationConfiguration class that can be optionally passed to the translator call, a fixed specific sender and/or receiver can be set. The configuration will take precedence on any other default or mapped value. For example: MT103 mt = translator . translate ( mx , new TranslationConfiguration (). setSender ( new BIC ( \"ABCDARXX\" ))); Message direction In MT messages, the direction is explicit in the message structure because the headers are mandatory and there is one specific header for outgoing messages and another specific header for incoming messages. So when you have an MT payload, you know the direction. This is not true for MX, where the direction is not in the payload (AppHdr + Document), but in the transmission wrapper, and that is dependent on the specific interface. When the message is converted from MX to MT, there is no longer an explicit direction, so by default all translators from MX to MT will generate an input message. An Input message means the message is going to be sent to SWIFT. If in the MX to MT translation process, in your host application, you know the generated MTs should be Output because you have received the original MX from SWIFT then you can use a configuration to switch the direction. This is done passing the optional TranslationConfiguration to the translation call. For example: MT103 mt = translator . translate ( mx , new TranslationConfiguration (). setDirection ( MessageDirection . Output )); The MT content will be the same, but in the headers the sender and receiver will be reconfigured as Output (received) message. Truncation When the source element value does not fit in the target message field, the translation will truncate the content. This could happen specially when translating from MX to MT, where the MT fields are shorter than the MX elements. By default, the truncation is done with evidence, meaning in the translated messages the truncated content will contain an explicit '+' symbol at the end of the field. This is done to indicate that the content has been truncated. Along that, the translation class stores the original and truncated content so that a report can be generated with the truncated elements. This report can be generated by calling the getTruncatedContent() method in the translator. Coverage For MX to MT translations, a coverage report can be generated by calling the getCoverageReport() method in the translator. This report will show the elements of the source MX elements that have been mapped into the target MT. Notice in most situations the coverage report will not be 100% because there are many elements in the source MX that cannot be mapped into the target MT. The idea of the coverage report is to analyse if for certain use cases the key elements in the MX have been mapped. Restricted ISO 20022 versions Depending on the user group, central bank, clearing system, or market infrastructure, different translation implementations might be available for the same pair of message types. This is the case when a restricted version of ISO 20022 is used with custom mappings; for example: CBPR+, ESMIG, SIC, etc\u2026 When these alternative translations are available, the variant or group will be explicit in the translation file name. Support for these restricted versions is a work in progress and will be added as needed. Current restricted versions available: Comprehensive coverage for all CBPR+ (Cross Border Payments) messages Partial translation for SIC (Swiss RGTS) messages Partial translation for RITS (Australian RGTS) messages Partial translation for CHATS (Hong Kong RGTS) messages Partial translation for SCRIPS (MEPS+, Singapore RGTS) messages Partial translations for T2S (TARGET2) messages Partial translations for LYNX (Canadian RGTS) messages Partial translations for SWIFTGO (SWIFT GPI) messages Note here we refer to providing specific translation implementations for the restricted versions. However, since all restricted standards are based on ISO, by default the general ISO 20022 can be used. MX to MT: the general ISO 20022 translation should be OK in most situations since from the output perspective, the MT message is undistinguished. Meaning an MT2103 created from a generic pacs.008 or a T2 pacs.008 will be the same. MT to MX: the general ISO 20022 translation could be use in most cases, and then the created MX output can be tweaked to match the specific requirements of the restricted version. For example, the MT2103 could be translated to a generic pacs.008 and then the specific T2 pacs.008 can be created by adding the missing elements or removing the ones not allowed. When available these translations are available in specific packages. Thus, instead of the translator implementation being located in the com.prowidesoftware.swift.translations package, it will be located in a package with the name of com.prowidesoftware.swift.translations.cbrp , com.prowidesoftware.swift.translations.sic , etc... To facilitate access to these alternative translators, each package contains it own TranslatorFactory class. For example, to get a translator for the CBPR+ pacs.008 to MT103 translation, instead of using the general TranslatorFactory.getTranslator(mx) method, you can use the specific CbprTranslatorFactory.getTranslator(mx) method. Moreover, to implementa a system that automatically translate messages for multiple target markets, there is also a TranslatorFactoryProvider class that will return the specific factory for a given target market. For example: TranslatorFactory factory = TranslatorFactoryProvider . getTranslatorFactory ( MarketType . RITS ); Translator translator = factory . getTranslator ( mt ); The code above with create an instance of the RITS specific translator factory, and from it, will attempt to find a suitable translator for the given MT message. M to N translations Although translation implementations are always one to one , there are some use cases where a single MX message can contain data corresponding to multiple MT messages. In other words, where a business operation, report, or transaction in an MX message cannot be mapped into a single MT because of the limitations of the MT standard. setr.015 to MT515 The switch order confirmation in an MX setr.015 can contain multiple switch operations, and for each it can contain multiple redemption and subscription legs. Thus, the translation to achieve should receive a single setr.015 and convert that into multiple MT515 messages. To keep the translation API simple and consistent, in these situations more than one translation implementation is made available for the given source and target message types. IN the swift order confirmation example, this is achieved by two translators: Class name Source message type Target message type MxSetr01500104_MT515_Redemption_Translation setr.015.001.04 MT 515 MxSetr01500104_MT515_Subscription_Translation setr.015.001.04 MT 515 Where the first translation implementation will convert the redemption leg data from the MX into an MT515 with the instrument sell, and the second translator will convert the subscription leg data from the MX into another MT515 with the instrument buy. The host application or the process running the translation is expected to use both translators, passing as parameters the same source MX message. The first call will create the redemption, while the second call, with the same source MX parameter, will create the subscription. pain.001 to MT101 The payment initiation in a pain.001 can contain multiple payment information elements, each having multiple credit transfers. The default 1 to 1 translation implemented in the MxPain00100103_MT101_Translation class will use as source content only the first payment information element. Each credit transfer in this source element will be mapped into a repetitive sequence B in the target MT. But a single MT will be created. A special 1 to many implementations for this use case is provided in the MxPain00100103_MT101_BulkTranslation class. The translation methods in this class return a List instead of a single instance. This implementation uses internally the one to one mapping, but will process all the available payment information elements in the source MX. For each payment information in the MX a single MT101 is created. As for the credit transfer repetitions within each payment information element, multiple sequences B are created in the corresponding MT101 instance. The 1 to 1 translation implemented in the MxPain00100103_MT101_Translation can be considered a special case of the MxPain00100103_MT101_BulkTranslation where the result will be a list with a single element. The drawback of the special bulk translation is that it cannot implement the generic translator API, thus it will not be recognized by the Translators Factory.","title":"General concepts"},{"location":"integrator/translations/translations-general/#general-concepts","text":"","title":"General Concepts"},{"location":"integrator/translations/translations-general/#translation-classes","text":"Translations are normally one to one , from a source message into a target message. Each available translation implementation, given a source message type and a target message type, is implemented in a specific class. The message types are explicit in the class names and also in the class parameters for the translation call. For example: Class name Source message type Target message type MT103_STP_MxPacs00800102_Translation MT 103 STP pacs.008.001.02 MxPacs00900102_MT202COV_Translation pacs.009.001.02 MT 202 COV In the most simple use case scenario the translation is called like this: MT103 mt = MT103 . parse ( fin ); try { MxPacs00800108_MT103_Translation t = new MxPacs00800108_MT103_Translation (); MxPacs00800108 mx = t . translate ( mt ); } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } catch ( final TranslationPreconditionException e2 ) { System . out . println ( \"precondition exception: \" + e2 . getMessage ()); } In the code above, we create an instance of the specific translation, and we call the translate method passing the source message as parameter. The result is the target message. And the revers from MX to an MT analogously. Notice translation classes are not thread safe , so a new instance must be created for each translation. The precondition and logical criteria checks are explained in the following sections, but that is basically a way to check if the source message is suitable for the specific translation, and if the target message will be valid after the translation.","title":"Translation classes"},{"location":"integrator/translations/translations-general/#logical-message-criteria","text":"The logical message criteria is a condition evaluated on the source message, to know if it is selectable for the specific translation. In most cases, there is only a single available equivalence for the translation. This is mostly the case when converting from MX to MT. However, in some cases, a single message can be translated to more than one target option. This is due to the fact that in the MT standard, there are many message types that can be used for different functions. While in the MX standard, there are specific message types for each function. For example, an MT502 could be a Redemption Order or a Subscription Order, meaning the same MT structure can be used for two different functions. While its MX equivalences have two specific message types for the Redemption and Subscription, setr.004.002.01 or setr.010.002.01. This criteria evaluation is checked automatically when the translation is run. It can be switched off by configuration, and optionally called by the application before the translation.","title":"Logical message criteria"},{"location":"integrator/translations/translations-general/#manual-criteria-check","text":"All translation classes have a translatable method that is used to check the logical criteria. This method checks the content of the source message and returns true or false if it is suitable for the specific translation. MT545 for example could be translated to a sese.025, sese.020, sese.026 or sese.035. Since in the MX standard, there are specific types for each use case, while in the MT all functions are covered by the same message type 545. If you call the translatable method for all possible translations using the same MT source for example: MT545 mt = MT545 . parse ( fin ); MT545_MxSese02500109_Translation t1 = new MT545_MxSese02500109_Translation (); MT545_MxSemt02000201_Translation t2 = new MT545_MxSemt02000201_Translation (); MT545_MxSese02600201_Translation t3 = new MT545_MxSese02600201_Translation (); MT545_MxSese03500201_Translation t4 = new MT545_MxSese03500201_Translation (); t1 . translatable ( mt , true )); t2 . translatable ( mt , true )); t3 . translatable ( mt , true )); t4 . translatable ( mt , true )); Then, for a given valid MT, only one of the options should return true while the others should return false. You can do the above manually, in a sequence of IF/ELSE conditions. Or you can just use the translator factory. The translator factory does exactly that, it checks given a source message what output is translatable. Although, notice there are a few situations where the same input could be translated seamlessly to more than one output. In such cases the translator factory returns a default.","title":"Manual criteria check"},{"location":"integrator/translations/translations-general/#preconditions","text":"Each specific translation may implement its own preconditions . This is a condition evaluated on the source message, to make sure the created target message will be valid. It is mainly used when the target message has some mandatory content that is optional in the source message. These preconditions are checked automatically when the translation is run. They can be switched off by configuration, and optionally called by the application before the translation.","title":"Preconditions"},{"location":"integrator/translations/translations-general/#manual-precondition-check","text":"Preconditions on the source message can be checked explicitly before attempting the translation, or can be caught from an exception calling the translation method in a try block. The following method will check all the message preconditions and will return a list of precondition errors. final MT564_MxSeev03900202_Translation translator = new MT564_MxSeev03900202_Translation (); final MT564 source = MT564 . parse ( sample ); try { // The precondition being check is: // IF ((B2[*]\\97a Account\\SAFE\\97C\\Account Code ContainsString 'GENR') And ((B2[*]\\95a Party\\ACOW IsPresent) Or ((B2[*]\\94a Place\\SAFE IsPresent) Or (B2[*]\\93a Balance IsPresent)))) // this pseudo-code is available in the translator javadoc List < PreconditionError > p = translator . preconditionsCheck ( source ); if ( p . isEmpty ()) { // Call the translation process final MxSeev03900202 mx = translator . translate ( source ); // Print content from the translated message System . out . println ( \"Cancellation Reason Code: \" + mx . getCorpActnCxlAdvc (). getCxlAdvcGnlInf (). getCxlRsnCd (). name ()); System . out . println ( \"Processing Completness: \" + mx . getCorpActnCxlAdvc (). getCxlAdvcGnlInf (). getPrcgSts (). getEvtSts (). getEvtCmpltnsSts (). name ()); System . out . println ( \"Corporate Action Id: \" + mx . getCorpActnCxlAdvc (). getCorpActnGnlInf (). getCorpActnEvtId ()); System . out . println ( \"Event Type Code: \" + mx . getCorpActnCxlAdvc (). getCorpActnGnlInf (). getEvtTp (). getCd (). name ()); System . out . println ( \"Underlying Security ISIN: \" + mx . getCorpActnCxlAdvc (). getCorpActnGnlInf (). getUndrlygSctyId (). getISIN ()); } else { // Print precondition errors for ( PreconditionError e : p ) { System . out . println ( \"precondition error: \" + e . getCode () + \" \" + e . getDescription ()); } } } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } In the above example the translator is any instance of a Translator implementation. When the translation is from MT to MX the expected parameter is the MT. When the translation is from MX to MT the expected parameter is the MX. If the returned list is empty, the source message satisfies all preconditions. If not, each element in the list will contain a code and a description of the condition that is not satisfied.","title":"Manual precondition check"},{"location":"integrator/translations/translations-general/#compliance","text":"In order for the target message to be valid, these premises should be satisfied: The source message should be valid. Notice the translation module will not run full compliance message validation, neither on source nor target messages. However, the Prowide Integrator Validation module can be used for this purpose. The logical message criteria check should pass: meaning the source message should be selectable for the specific translation applied. The preconditions on the source message should pass. Regardless of this contract, since the translation is sensitive to the data, if the translated message is going to be sent through the network it is recommended that as the last step of the process the validation is run on the created message.","title":"Compliance"},{"location":"integrator/translations/translations-general/#headers","text":"Regardless of the specific translation mappings, the target message header is always filled with data from the source or with derived content as follows: Translation Source element Target element MT to MX Block 1 Sender Block 2 Receiver Fixed from target message identifier Current date and time Main message reference Trailer PDE AppHdr From AppHdr To AppHdr Message Definition AppHdr Creation Date and Time AppHdr Business Message Identifier AppHdr Possible Duplicate Emission (By default the ISO Business Header is created, not the legacy Application Header) MX to MT AppHdr From * AppHdr To * AppHdr Possible Duplicate Emission Fixed from target message identifier (both ISO Business Header and legacy Application Header are supported) Block 1 Sender Block 2 Receiver Trailer PDE Block 2 message type (Direction is Input by default. The rest of the MT headers data is filled with proper defaults) * If the AppHdr is not present, the translation attempts to use the parties BIC codes in the Group Header element within the MX Document. If none is found, then the MT is populated with default BIC codes. Also, both BIC and DN structures are supported, when the DN is used the BIC is extracted and filled with the default branch code. This default mapping can be overridden by configuration. In the TranslationConfiguration class that can be optionally passed to the translator call, a fixed specific sender and/or receiver can be set. The configuration will take precedence on any other default or mapped value. For example: MT103 mt = translator . translate ( mx , new TranslationConfiguration (). setSender ( new BIC ( \"ABCDARXX\" )));","title":"Headers"},{"location":"integrator/translations/translations-general/#message-direction","text":"In MT messages, the direction is explicit in the message structure because the headers are mandatory and there is one specific header for outgoing messages and another specific header for incoming messages. So when you have an MT payload, you know the direction. This is not true for MX, where the direction is not in the payload (AppHdr + Document), but in the transmission wrapper, and that is dependent on the specific interface. When the message is converted from MX to MT, there is no longer an explicit direction, so by default all translators from MX to MT will generate an input message. An Input message means the message is going to be sent to SWIFT. If in the MX to MT translation process, in your host application, you know the generated MTs should be Output because you have received the original MX from SWIFT then you can use a configuration to switch the direction. This is done passing the optional TranslationConfiguration to the translation call. For example: MT103 mt = translator . translate ( mx , new TranslationConfiguration (). setDirection ( MessageDirection . Output )); The MT content will be the same, but in the headers the sender and receiver will be reconfigured as Output (received) message.","title":"Message direction"},{"location":"integrator/translations/translations-general/#truncation","text":"When the source element value does not fit in the target message field, the translation will truncate the content. This could happen specially when translating from MX to MT, where the MT fields are shorter than the MX elements. By default, the truncation is done with evidence, meaning in the translated messages the truncated content will contain an explicit '+' symbol at the end of the field. This is done to indicate that the content has been truncated. Along that, the translation class stores the original and truncated content so that a report can be generated with the truncated elements. This report can be generated by calling the getTruncatedContent() method in the translator.","title":"Truncation"},{"location":"integrator/translations/translations-general/#coverage","text":"For MX to MT translations, a coverage report can be generated by calling the getCoverageReport() method in the translator. This report will show the elements of the source MX elements that have been mapped into the target MT. Notice in most situations the coverage report will not be 100% because there are many elements in the source MX that cannot be mapped into the target MT. The idea of the coverage report is to analyse if for certain use cases the key elements in the MX have been mapped.","title":"Coverage"},{"location":"integrator/translations/translations-general/#restricted-iso-20022-versions","text":"Depending on the user group, central bank, clearing system, or market infrastructure, different translation implementations might be available for the same pair of message types. This is the case when a restricted version of ISO 20022 is used with custom mappings; for example: CBPR+, ESMIG, SIC, etc\u2026 When these alternative translations are available, the variant or group will be explicit in the translation file name. Support for these restricted versions is a work in progress and will be added as needed. Current restricted versions available: Comprehensive coverage for all CBPR+ (Cross Border Payments) messages Partial translation for SIC (Swiss RGTS) messages Partial translation for RITS (Australian RGTS) messages Partial translation for CHATS (Hong Kong RGTS) messages Partial translation for SCRIPS (MEPS+, Singapore RGTS) messages Partial translations for T2S (TARGET2) messages Partial translations for LYNX (Canadian RGTS) messages Partial translations for SWIFTGO (SWIFT GPI) messages Note here we refer to providing specific translation implementations for the restricted versions. However, since all restricted standards are based on ISO, by default the general ISO 20022 can be used. MX to MT: the general ISO 20022 translation should be OK in most situations since from the output perspective, the MT message is undistinguished. Meaning an MT2103 created from a generic pacs.008 or a T2 pacs.008 will be the same. MT to MX: the general ISO 20022 translation could be use in most cases, and then the created MX output can be tweaked to match the specific requirements of the restricted version. For example, the MT2103 could be translated to a generic pacs.008 and then the specific T2 pacs.008 can be created by adding the missing elements or removing the ones not allowed. When available these translations are available in specific packages. Thus, instead of the translator implementation being located in the com.prowidesoftware.swift.translations package, it will be located in a package with the name of com.prowidesoftware.swift.translations.cbrp , com.prowidesoftware.swift.translations.sic , etc... To facilitate access to these alternative translators, each package contains it own TranslatorFactory class. For example, to get a translator for the CBPR+ pacs.008 to MT103 translation, instead of using the general TranslatorFactory.getTranslator(mx) method, you can use the specific CbprTranslatorFactory.getTranslator(mx) method. Moreover, to implementa a system that automatically translate messages for multiple target markets, there is also a TranslatorFactoryProvider class that will return the specific factory for a given target market. For example: TranslatorFactory factory = TranslatorFactoryProvider . getTranslatorFactory ( MarketType . RITS ); Translator translator = factory . getTranslator ( mt ); The code above with create an instance of the RITS specific translator factory, and from it, will attempt to find a suitable translator for the given MT message.","title":"Restricted ISO 20022 versions"},{"location":"integrator/translations/translations-general/#m-to-n-translations","text":"Although translation implementations are always one to one , there are some use cases where a single MX message can contain data corresponding to multiple MT messages. In other words, where a business operation, report, or transaction in an MX message cannot be mapped into a single MT because of the limitations of the MT standard.","title":"M to N translations"},{"location":"integrator/translations/translations-general/#setr015-to-mt515","text":"The switch order confirmation in an MX setr.015 can contain multiple switch operations, and for each it can contain multiple redemption and subscription legs. Thus, the translation to achieve should receive a single setr.015 and convert that into multiple MT515 messages. To keep the translation API simple and consistent, in these situations more than one translation implementation is made available for the given source and target message types. IN the swift order confirmation example, this is achieved by two translators: Class name Source message type Target message type MxSetr01500104_MT515_Redemption_Translation setr.015.001.04 MT 515 MxSetr01500104_MT515_Subscription_Translation setr.015.001.04 MT 515 Where the first translation implementation will convert the redemption leg data from the MX into an MT515 with the instrument sell, and the second translator will convert the subscription leg data from the MX into another MT515 with the instrument buy. The host application or the process running the translation is expected to use both translators, passing as parameters the same source MX message. The first call will create the redemption, while the second call, with the same source MX parameter, will create the subscription.","title":"setr.015 to MT515"},{"location":"integrator/translations/translations-general/#pain001-to-mt101","text":"The payment initiation in a pain.001 can contain multiple payment information elements, each having multiple credit transfers. The default 1 to 1 translation implemented in the MxPain00100103_MT101_Translation class will use as source content only the first payment information element. Each credit transfer in this source element will be mapped into a repetitive sequence B in the target MT. But a single MT will be created. A special 1 to many implementations for this use case is provided in the MxPain00100103_MT101_BulkTranslation class. The translation methods in this class return a List instead of a single instance. This implementation uses internally the one to one mapping, but will process all the available payment information elements in the source MX. For each payment information in the MX a single MT101 is created. As for the credit transfer repetitions within each payment information element, multiple sequences B are created in the corresponding MT101 instance. The 1 to 1 translation implemented in the MxPain00100103_MT101_Translation can be considered a special case of the MxPain00100103_MT101_BulkTranslation where the result will be a list with a single element. The drawback of the special bulk translation is that it cannot implement the generic translator API, thus it will not be recognized by the Translators Factory.","title":"pain.001 to MT101"},{"location":"integrator/translations/translations-mt2mx/","text":"MT to MX Translation from MT messages to its MX equivalent is done using the specific classes name MTnnn_Mxmmm_Translation , where nnn corresponds to a specific translatable MT and mmm to its available MX representation. Class selection The first step to perform a message translation is to select the proper translation to use. The specific translation class depends mainly on the message type, but in several cases also on the message content. MT103 for example, has two flavors (STP and not STP) for the source message, while the target MX is the same for both, so the available translation are: MT103_STP_MxPacs00800102_Translation MT103_MxPacs00800102_Translation A different example can be seen for MT564, where the same message type can be translated to several Mx messages depending on the message functionality (deductible from content): MT564_MxSeev03100202_Translation MT564_MxSeev03500202_Translation MT564_MxSeev03900202_Translation MT564_MxSeev04400202_Translation While the selection of a proper translation combination to apply is a responsibility of the calling application, the correctness of the call is checked at several points: First by the translation classes. You cannot invoke an MT103_MxPacs00800102_Translation passing and MT202 as parameters. Also, you cannot assign the result of that translation to an invalid Mx. Second, by the message logical criteria checks. These checks are performed internally by the translation process, and a runtime LogicalMessageCriteriaException is thrown if the criteria is not satisfied. For example in the MT564 example, these criteria checks are mainly based on the function of the corporate action message, defined in field 23G, so that a \"cancellation\" won't be translated into a \"confirmation\". Third, by the message preconditions. When all the above is correct, numerous content preconditions are checked to ensure that the source message can be effectively translated to the target message. Translation call The translation procedure is invoked with the translation method of the specific translation class. The following example shows how to translate an MT 564 into its corresponding MX seev.039.002.02: The MT is parsed into an MT564 object using any of the providing parsing methods: final MT564 source = MT564 . parse ( sample ); A proper instance of translation is created: MT564_MxSeev03900202_Translation translator = new MT564_MxSeev03900202_Translation (); And finally, the translation method is invoked in a try to catch the logical message criteria and preconditions exceptions. try { final MxSeev03900202 mx = ( MxSeev03900202 ) translator . translate ( source ); } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } catch ( final TranslationPreconditionException e2 ) { System . out . println ( \"precondition exception: \" + e2 . getMessage ()); } If the MT564 satisfies all preconditions, the mx variable will contain the resulting MX message. Then all the MX API can be used to retrieve content from the converted message, or it can be serialized to its XML representation. System . out . println ( \"Cancellation Reason Code:\" + mx . getCorpActnCxlAdvc (). getCxlAdvcGnlInf (). getCxlRsnCd (). name ()); System . out . println ( mx . message ()); 4 Business Header Depending on the source MT, some fields might be mapped to the target MX business header, which is optional. To check the created header in XML: In the created MX object, the message() or document() calls will serialize just the Document portion of the MX, while header() will serialize the header if it is present. Alternatively, you can call message(String, boolean) which will generate both header (if present) and document in a single XML under the indicated wrapper element. To check header in Java model: The getBusinessHeader() will return the model representation with the header. Complete example: https://github.com/prowide/prowide-integrator-examples/blob/master/src/main/java/com/prowidesoftware/swift/samples/integrator/translations/MtMxTranslationExample1.java","title":"MT to MX"},{"location":"integrator/translations/translations-mt2mx/#mt-to-mx","text":"Translation from MT messages to its MX equivalent is done using the specific classes name MTnnn_Mxmmm_Translation , where nnn corresponds to a specific translatable MT and mmm to its available MX representation.","title":"MT to MX"},{"location":"integrator/translations/translations-mt2mx/#class-selection","text":"The first step to perform a message translation is to select the proper translation to use. The specific translation class depends mainly on the message type, but in several cases also on the message content. MT103 for example, has two flavors (STP and not STP) for the source message, while the target MX is the same for both, so the available translation are: MT103_STP_MxPacs00800102_Translation MT103_MxPacs00800102_Translation A different example can be seen for MT564, where the same message type can be translated to several Mx messages depending on the message functionality (deductible from content): MT564_MxSeev03100202_Translation MT564_MxSeev03500202_Translation MT564_MxSeev03900202_Translation MT564_MxSeev04400202_Translation While the selection of a proper translation combination to apply is a responsibility of the calling application, the correctness of the call is checked at several points: First by the translation classes. You cannot invoke an MT103_MxPacs00800102_Translation passing and MT202 as parameters. Also, you cannot assign the result of that translation to an invalid Mx. Second, by the message logical criteria checks. These checks are performed internally by the translation process, and a runtime LogicalMessageCriteriaException is thrown if the criteria is not satisfied. For example in the MT564 example, these criteria checks are mainly based on the function of the corporate action message, defined in field 23G, so that a \"cancellation\" won't be translated into a \"confirmation\". Third, by the message preconditions. When all the above is correct, numerous content preconditions are checked to ensure that the source message can be effectively translated to the target message.","title":"Class selection"},{"location":"integrator/translations/translations-mt2mx/#translation-call","text":"The translation procedure is invoked with the translation method of the specific translation class. The following example shows how to translate an MT 564 into its corresponding MX seev.039.002.02: The MT is parsed into an MT564 object using any of the providing parsing methods: final MT564 source = MT564 . parse ( sample ); A proper instance of translation is created: MT564_MxSeev03900202_Translation translator = new MT564_MxSeev03900202_Translation (); And finally, the translation method is invoked in a try to catch the logical message criteria and preconditions exceptions. try { final MxSeev03900202 mx = ( MxSeev03900202 ) translator . translate ( source ); } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } catch ( final TranslationPreconditionException e2 ) { System . out . println ( \"precondition exception: \" + e2 . getMessage ()); } If the MT564 satisfies all preconditions, the mx variable will contain the resulting MX message. Then all the MX API can be used to retrieve content from the converted message, or it can be serialized to its XML representation. System . out . println ( \"Cancellation Reason Code:\" + mx . getCorpActnCxlAdvc (). getCxlAdvcGnlInf (). getCxlRsnCd (). name ()); System . out . println ( mx . message ()); 4","title":"Translation call"},{"location":"integrator/translations/translations-mt2mx/#business-header","text":"Depending on the source MT, some fields might be mapped to the target MX business header, which is optional. To check the created header in XML: In the created MX object, the message() or document() calls will serialize just the Document portion of the MX, while header() will serialize the header if it is present. Alternatively, you can call message(String, boolean) which will generate both header (if present) and document in a single XML under the indicated wrapper element. To check header in Java model: The getBusinessHeader() will return the model representation with the header. Complete example: https://github.com/prowide/prowide-integrator-examples/blob/master/src/main/java/com/prowidesoftware/swift/samples/integrator/translations/MtMxTranslationExample1.java","title":"Business Header"},{"location":"integrator/translations/translations-mx2mt/","text":"MX to MT Translation from MX messages to its MT equivalent is done using the specific classes name Mxmmm_MTnnn_Translation , where mmmm corresponds to a specific translatable MX and nn to its available MT representation. Class selection The first step to perform a message translation is to select the proper translation to use. The specific translation class depends mainly on the message type, but in several cases also on the message content. MxPacs00800102 for example can only be translated into an MT103. However, MxPacs00900102 can be used to create MT202 in both flavors; STP and not STP, so the available translation are: MxPacs00800102_MT103_Translation MxPacs00900102_MT202_Translation MxPacs00900102_MT202COV_Translation In the above example, a different set of preconditions apply to create the MT202 for STP or not. A different example can be seen for MxSeev03100202, where the same message type can be translated to several target MT messages: MxSeev03100202_MT564_Translation MxSeev03100202_MT568_Translation While the selection of a proper translation combination to apply is a responsibility of the calling application, the correctness of the call is checked at several points: First by the translation classes. You cannot invoke an MxSeev03100202_MT564_Translation passing anything different from a MxSeev03100202 as source message parameter. Also, you cannot assign the result of that translation to an invalid MT. Second, by the message logical criteria checks. These checks are performed internally by the translation process, and a runtime LogicalMessageCriteriaException is thrown if the criteria is not satisfied. Third, by the message preconditions. When all the above is correct, many content preconditions are checked to ensure that the source message can be effectively translated to the target message. Translation call The translation procedure is invoked with the translation method of the specific translation class. The following example shows how to translate a MxSeev03400202 into its corresponding MT 567: The source message can be created using the MX API or parsing its content from an XML file or string. MxSeev03400202 mx = new MxSeev03400202 (); mx . setBusinessHeader ( new BusinessHeader ( new BusinessApplicationHeaderV01 ())); mx . getBusinessHeader (). getBusinessApplicationHeader (). setBizMsgIdr ( \"MYID\" ); mx . setCorpActnInstrStsAdvc ( new CorporateActionInstructionStatusAdviceV02Subset ()); mx . getCorpActnInstrStsAdvc (). setCorpActnGnlInf ( new CorporateActionGeneralInformation13 ()); mx . getCorpActnInstrStsAdvc (). getCorpActnGnlInf (). setCorpActnEvtId ( \"777\" ); A proper instance of translation is created: MxSeev03400202_MT567_Translation translator = new MxSeev03400202_MT567_Translation (); And finally, the translation method is invoked in a try to catch the logical message criteria and preconditions exceptions. try { final MT567 mt = ( MT567 ) translator . translate ( mx ); } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } catch ( final TranslationPreconditionException e2 ) { System . out . println ( \"precondition exception: \" + e2 . getMessage ()); } If the MX satisfies all preconditions, the mt variable will contain the resulting MT message. Then all the MT API can be used to retrieve content from the converted message, or it can be serialized to its SWIFT FIN representation. System . out . println ( mt . message ()); Complete example: https://github.com/prowide/prowide-integrator-examples/blob/master/src/main/java/com/prowidesoftware/swift/samples/integrator/translations/MxMtTranslationExample1.java Truncation For situations where the element in the target message is limited to a certain size and the content read from the source message is larger, truncation is produced. Whenever truncation occurs during the translation process, the translator class collects the original and the truncated content in the object. The truncated content list can be retrieved by API: MxSeev03400202_MT567_Translation translator = new MxSeev03400202_MT567_Translation (); final MT567 mt = ( MT567 ) translator . translate ( mx ); for ( Truncation truncation : translator . getTruncatedContent ()) { System . out . println ( truncation . getOriginal () + \u201c -> \u201c + truncation . getTruncated ()); } When there is no truncation, the truncated content list in the translator class will be empty. Along with this internal report, the truncation is made explicit in the target message by adding a '+' symbol at the end of the truncated content. For example, this MX element with a long text: Lorem ipsum dolor sit amet, ut has choro rationibus. Cum denique consequat et. Est reque meliore platonem te. Te vim commodo ornatus delicatissimi. Pri eu graeco theophrastus intellegebat, inani vivendo suscipit sit id. Might be mapped into this truncated narrative in the target MT: :70D::REAS//Lorem ipsum dolor sit amet, ut has choro rationibus. Cum denique conse quat et. Est reque meliore platonem te. Te vim commodo ornatus delicat issimi. Pri eu graeco theophrastus intellegebat, inani vivendo suscip+ Where the text was wrapped into the available lines of 35 characters length, and the last character of the last line contains the '+' symbol to evidence that content was truncated. Notice, the '+' symbol will only be added if the target element supports the symbol in its character set. If the element for example only allows alphanumeric characters, then the '+' will not be used and the content will be just trimmed without explicit evidence. This evidence behavior can also be switched off as a flag in the optional TranslatorConfiguration that can be passed to the translation call. The internal truncation report will always be available, regardless of the evidence symbol being used or not in the content of the target message. Meaning if the symbol is not used because the element does not allow it or because the evidence has been switched off, in the truncation report you will still have the complete list of original and truncated content. Here is an example of the truncation behavior: public void testTruncateReferenceMxToMt () { String xml = \"\" + \"\" //... + \" \" + \" \" + \" VeryLargeReferenceInTheSource\" + \" \" //... + \" \" + \" Uhrengrosshandel Buxtehude Very Large Name\" + \" \" //... + \"\" ; MxPacs00800102 mxPacs00800102 = MxPacs00800102 . parse ( xml ); final MT103 mt103 = new MxPacs00800102_MT103_Translation (). translate ( mxPacs00800102 ); List < Truncation > truncatedContent = new MxPacs00800102_MT103_Translation (). getTruncatedContent (); //Original values assertEquals ( \"VeryLargeRefere+\" , mt103 . getField20 (). getValue ()); assertEquals ( \" Buxtehude Very La+\" , mt103 . getField50K (). getComponent2 ()); //Truncated Content 1 Truncation t1 = truncatedContent . get ( 0 ); assertEquals ( \"VeryLargeReferenceInTheSource\" , t1 . getOriginal ()); assertEquals ( \"nceInTheSource\" , t1 . getTruncated ()); //Truncated Content 2 Truncation t2 = truncatedContent . get ( 1 ); assertEquals ( \"Uhrengrosshandel Buxtehude Very Large Name\" , t2 . getOriginal ()); assertEquals ( \"rge Name\" , t2 . getTruncated ()); assertFalse ( t2 . isReference ()); } The translator configuration parameter must be adjusted to enable or disable truncation with evidence using the + symbol. For those fields that are reference ones, the Truncation object will have the isReference() method returning true. While returning false for those fields that are not reference ones. This is important to know because the truncation will have more impact in the first field types. To disable the truncation evidence, use the setTruncationEvidenceEnabled(false) method in the configuration object. new MxPacs00800102_MT103_Translation (). translate ( mxPacs00800102 , new TranslatorConfiguration (). setTruncateWithEvidence ( false )); Same example but with truncation evidence disabled, note that + symbol is not present in the result and the truncation slightly changed by one character. public void testTruncateReferenceMxToMt () { String xml = \"\" + \"\" //... + \" \" + \" \" + \" VeryLargeReferenceInTheSource\" + \" \" //... + \" \" + \" Uhrengrosshandel Buxtehude Very Large Name\" + \" \" //... + \"\" ; MxPacs00800102 mxPacs00800102 = MxPacs00800102 . parse ( xml ); //THIS IS THE IMPORTANT PART final MT103 mt103 = new MxPacs00800102_MT103_Translation (). translate ( mxPacs00800102 , new TranslatorConfiguration (). setTruncateWithEvidence ( false )); List < Truncation > truncatedContent = new MxPacs00800102_MT103_Translation (). getTruncatedContent (); //Original values assertEquals ( \"VeryLargeReferen\" , mt103 . getField20 (). getValue ()); assertEquals ( \" Buxtehude Very Lar\" , mt103 . getField50K (). getComponent2 ()); //Truncated Content 1 NO PLUS SIGN BUT CHAR Truncation t1 = truncatedContent . get ( 0 ); assertEquals ( \"VeryLargeReferenceInTheSource\" , t1 . getOriginal ()); assertEquals ( \"ceInTheSource\" , t1 . getTruncated ()); //Truncated Content 2 ONE CHAR SHORTER Truncation t2 = truncatedContent . get ( 1 ); assertEquals ( \"Uhrengrosshandel Buxtehude Very Large Name\" , t2 . getOriginal ()); assertEquals ( \"ge Name\" , t2 . getTruncated ()); assertFalse ( t2 . isReference ()); } For MX to MT translations, the translator class can provide a coverage report. During the translation process the accessed elements in the source XML are flagged as read, thus after the translation the covered and not covered elements can be queries. This flagging and the resulting report is available by default, but can be switched off with the TranslatorConfiguration parameter if needed for performance reasons. The report is encapsulated in a class with several methods that basically indicate if the header elements were covered, if the document elements were covered, and the list of elements including the path and value for each group. For example: MxSeev03400202 mx = MxSeev03400202 . parse ( xml ); MxSeev03400202_MT567_Translation translator = new MxSeev03400202_MT567_Translation (); MT567 mt = translator . translate ( mx ); MxCoverageReport report = translator . getCoverageReport (); if ( ! report . isDocumentCovered ()) { System . out . println ( \"Document not covered elements\" ); for ( MxCoverageReportElement element : report . getDocumentNotCovered ()) { System . out . println ( element . getPath () + \" = \" + element . getValue ()); } } Producing and output such as: Document not covered elements: /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/ApldOptnInd = false /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/CshMvmntDtls/RateAndAmtDtls/EarlySlctnFeeRate/Amt = 2345 /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/CshMvmntDtls/RateAndAmtDtls/EarlySlctnFeeRate/Amt/Ccy = USD /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/RateAndAmtDtls/NetDvddRate/RateTpAndAmtAndRateSts/Amt = 23423 /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/RateAndAmtDtls/NetDvddRate/RateTpAndAmtAndRateSts/Amt/Ccy = USD /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/RateAndAmtDtls/NetDvddRate/RateTpAndAmtAndRateSts/RateSts/Cd = ACTU /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/RateAndAmtDtls/NetDvddRate/RateTpAndAmtAndRateSts/RateTp/Cd = FLFR /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/SctiesQty/MaxQtyToInst/Unit = 234234 /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/SctiesQty/MinMltplQtyToInst/Unit = 23423 /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/SctiesQty/MinQtyToInst/Unit = 23423 With the key value pair of elements in the source MX that has not been read during the translation. Notice covered elements do not strictly mean the content will appear in the target MT, but its element value was read as part of the translation process. Depending on the specific mappings, the translation process is not just moving data from one place to the other, in many cases decisions are made based on the source content and for this coverage report those elements are considered read. Notice as well, due to the richness of the ISO 20022 standard compared to the MT, full coverage is an exceptional case to achieve and not the normal case. IN most scenarios, you will find elements in the MX that have no equivalent in the MT or that are not processed as part of the translation logic. Sanitize After translating from MX to MT, the translator will sanitize the content of the source MX to ensure the resulting MT is valid. This is done by removing invalid characters and replacing them with a valid character. The default character is the '.' (dot) character, and the invalida characters are '&' (ampersand), '\"' (double quote), '<' (less than symbol) and '>' (greater than symbol). Furthermore, in multiline fields, any ':' (colon) or '-' (hyphen) character found at the beginning of each line starting from the second line will be substituted with a '.' (dot). However, if a line begins with multiple consecutive hyphen or colon characters, only the first one will be replaced. Finally, the translator will verify if specific fields have a mandatory component and assign a default value in case they are missing it. This function is particularly useful for fields containing a party identifier that does not include the name and address. The sanitization process is done by default, but can be switched off with the TranslatorConfiguration parameter if needed. MxPacs00800102_MT103_Translation translator = new MxPacs00800102_MT103_Translation (); final MT103 mt = translator . translate ( source , new TranslatorConfiguration (). setMxToMtCharsetConversionEnabled ( false )); All the process described above is done by using the MtSanitizer class. This class is a helper to manipulate and fix fields in an MT messages. So it can be used to sanitize any MT message, not just the ones translated by the library.","title":"MX to MT"},{"location":"integrator/translations/translations-mx2mt/#mx-to-mt","text":"Translation from MX messages to its MT equivalent is done using the specific classes name Mxmmm_MTnnn_Translation , where mmmm corresponds to a specific translatable MX and nn to its available MT representation.","title":"MX to MT"},{"location":"integrator/translations/translations-mx2mt/#class-selection","text":"The first step to perform a message translation is to select the proper translation to use. The specific translation class depends mainly on the message type, but in several cases also on the message content. MxPacs00800102 for example can only be translated into an MT103. However, MxPacs00900102 can be used to create MT202 in both flavors; STP and not STP, so the available translation are: MxPacs00800102_MT103_Translation MxPacs00900102_MT202_Translation MxPacs00900102_MT202COV_Translation In the above example, a different set of preconditions apply to create the MT202 for STP or not. A different example can be seen for MxSeev03100202, where the same message type can be translated to several target MT messages: MxSeev03100202_MT564_Translation MxSeev03100202_MT568_Translation While the selection of a proper translation combination to apply is a responsibility of the calling application, the correctness of the call is checked at several points: First by the translation classes. You cannot invoke an MxSeev03100202_MT564_Translation passing anything different from a MxSeev03100202 as source message parameter. Also, you cannot assign the result of that translation to an invalid MT. Second, by the message logical criteria checks. These checks are performed internally by the translation process, and a runtime LogicalMessageCriteriaException is thrown if the criteria is not satisfied. Third, by the message preconditions. When all the above is correct, many content preconditions are checked to ensure that the source message can be effectively translated to the target message.","title":"Class selection"},{"location":"integrator/translations/translations-mx2mt/#translation-call","text":"The translation procedure is invoked with the translation method of the specific translation class. The following example shows how to translate a MxSeev03400202 into its corresponding MT 567: The source message can be created using the MX API or parsing its content from an XML file or string. MxSeev03400202 mx = new MxSeev03400202 (); mx . setBusinessHeader ( new BusinessHeader ( new BusinessApplicationHeaderV01 ())); mx . getBusinessHeader (). getBusinessApplicationHeader (). setBizMsgIdr ( \"MYID\" ); mx . setCorpActnInstrStsAdvc ( new CorporateActionInstructionStatusAdviceV02Subset ()); mx . getCorpActnInstrStsAdvc (). setCorpActnGnlInf ( new CorporateActionGeneralInformation13 ()); mx . getCorpActnInstrStsAdvc (). getCorpActnGnlInf (). setCorpActnEvtId ( \"777\" ); A proper instance of translation is created: MxSeev03400202_MT567_Translation translator = new MxSeev03400202_MT567_Translation (); And finally, the translation method is invoked in a try to catch the logical message criteria and preconditions exceptions. try { final MT567 mt = ( MT567 ) translator . translate ( mx ); } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } catch ( final TranslationPreconditionException e2 ) { System . out . println ( \"precondition exception: \" + e2 . getMessage ()); } If the MX satisfies all preconditions, the mt variable will contain the resulting MT message. Then all the MT API can be used to retrieve content from the converted message, or it can be serialized to its SWIFT FIN representation. System . out . println ( mt . message ()); Complete example: https://github.com/prowide/prowide-integrator-examples/blob/master/src/main/java/com/prowidesoftware/swift/samples/integrator/translations/MxMtTranslationExample1.java","title":"Translation call"},{"location":"integrator/translations/translations-mx2mt/#truncation","text":"For situations where the element in the target message is limited to a certain size and the content read from the source message is larger, truncation is produced. Whenever truncation occurs during the translation process, the translator class collects the original and the truncated content in the object. The truncated content list can be retrieved by API: MxSeev03400202_MT567_Translation translator = new MxSeev03400202_MT567_Translation (); final MT567 mt = ( MT567 ) translator . translate ( mx ); for ( Truncation truncation : translator . getTruncatedContent ()) { System . out . println ( truncation . getOriginal () + \u201c -> \u201c + truncation . getTruncated ()); } When there is no truncation, the truncated content list in the translator class will be empty. Along with this internal report, the truncation is made explicit in the target message by adding a '+' symbol at the end of the truncated content. For example, this MX element with a long text: Lorem ipsum dolor sit amet, ut has choro rationibus. Cum denique consequat et. Est reque meliore platonem te. Te vim commodo ornatus delicatissimi. Pri eu graeco theophrastus intellegebat, inani vivendo suscipit sit id. Might be mapped into this truncated narrative in the target MT: :70D::REAS//Lorem ipsum dolor sit amet, ut has choro rationibus. Cum denique conse quat et. Est reque meliore platonem te. Te vim commodo ornatus delicat issimi. Pri eu graeco theophrastus intellegebat, inani vivendo suscip+ Where the text was wrapped into the available lines of 35 characters length, and the last character of the last line contains the '+' symbol to evidence that content was truncated. Notice, the '+' symbol will only be added if the target element supports the symbol in its character set. If the element for example only allows alphanumeric characters, then the '+' will not be used and the content will be just trimmed without explicit evidence. This evidence behavior can also be switched off as a flag in the optional TranslatorConfiguration that can be passed to the translation call. The internal truncation report will always be available, regardless of the evidence symbol being used or not in the content of the target message. Meaning if the symbol is not used because the element does not allow it or because the evidence has been switched off, in the truncation report you will still have the complete list of original and truncated content. Here is an example of the truncation behavior: public void testTruncateReferenceMxToMt () { String xml = \"\" + \"\" //... + \" \" + \" \" + \" VeryLargeReferenceInTheSource\" + \" \" //... + \" \" + \" Uhrengrosshandel Buxtehude Very Large Name\" + \" \" //... + \"\" ; MxPacs00800102 mxPacs00800102 = MxPacs00800102 . parse ( xml ); final MT103 mt103 = new MxPacs00800102_MT103_Translation (). translate ( mxPacs00800102 ); List < Truncation > truncatedContent = new MxPacs00800102_MT103_Translation (). getTruncatedContent (); //Original values assertEquals ( \"VeryLargeRefere+\" , mt103 . getField20 (). getValue ()); assertEquals ( \" Buxtehude Very La+\" , mt103 . getField50K (). getComponent2 ()); //Truncated Content 1 Truncation t1 = truncatedContent . get ( 0 ); assertEquals ( \"VeryLargeReferenceInTheSource\" , t1 . getOriginal ()); assertEquals ( \"nceInTheSource\" , t1 . getTruncated ()); //Truncated Content 2 Truncation t2 = truncatedContent . get ( 1 ); assertEquals ( \"Uhrengrosshandel Buxtehude Very Large Name\" , t2 . getOriginal ()); assertEquals ( \"rge Name\" , t2 . getTruncated ()); assertFalse ( t2 . isReference ()); } The translator configuration parameter must be adjusted to enable or disable truncation with evidence using the + symbol. For those fields that are reference ones, the Truncation object will have the isReference() method returning true. While returning false for those fields that are not reference ones. This is important to know because the truncation will have more impact in the first field types. To disable the truncation evidence, use the setTruncationEvidenceEnabled(false) method in the configuration object. new MxPacs00800102_MT103_Translation (). translate ( mxPacs00800102 , new TranslatorConfiguration (). setTruncateWithEvidence ( false )); Same example but with truncation evidence disabled, note that + symbol is not present in the result and the truncation slightly changed by one character. public void testTruncateReferenceMxToMt () { String xml = \"\" + \"\" //... + \" \" + \" \" + \" VeryLargeReferenceInTheSource\" + \" \" //... + \" \" + \" Uhrengrosshandel Buxtehude Very Large Name\" + \" \" //... + \"\" ; MxPacs00800102 mxPacs00800102 = MxPacs00800102 . parse ( xml ); //THIS IS THE IMPORTANT PART final MT103 mt103 = new MxPacs00800102_MT103_Translation (). translate ( mxPacs00800102 , new TranslatorConfiguration (). setTruncateWithEvidence ( false )); List < Truncation > truncatedContent = new MxPacs00800102_MT103_Translation (). getTruncatedContent (); //Original values assertEquals ( \"VeryLargeReferen\" , mt103 . getField20 (). getValue ()); assertEquals ( \" Buxtehude Very Lar\" , mt103 . getField50K (). getComponent2 ()); //Truncated Content 1 NO PLUS SIGN BUT CHAR Truncation t1 = truncatedContent . get ( 0 ); assertEquals ( \"VeryLargeReferenceInTheSource\" , t1 . getOriginal ()); assertEquals ( \"ceInTheSource\" , t1 . getTruncated ()); //Truncated Content 2 ONE CHAR SHORTER Truncation t2 = truncatedContent . get ( 1 ); assertEquals ( \"Uhrengrosshandel Buxtehude Very Large Name\" , t2 . getOriginal ()); assertEquals ( \"ge Name\" , t2 . getTruncated ()); assertFalse ( t2 . isReference ()); } For MX to MT translations, the translator class can provide a coverage report. During the translation process the accessed elements in the source XML are flagged as read, thus after the translation the covered and not covered elements can be queries. This flagging and the resulting report is available by default, but can be switched off with the TranslatorConfiguration parameter if needed for performance reasons. The report is encapsulated in a class with several methods that basically indicate if the header elements were covered, if the document elements were covered, and the list of elements including the path and value for each group. For example: MxSeev03400202 mx = MxSeev03400202 . parse ( xml ); MxSeev03400202_MT567_Translation translator = new MxSeev03400202_MT567_Translation (); MT567 mt = translator . translate ( mx ); MxCoverageReport report = translator . getCoverageReport (); if ( ! report . isDocumentCovered ()) { System . out . println ( \"Document not covered elements\" ); for ( MxCoverageReportElement element : report . getDocumentNotCovered ()) { System . out . println ( element . getPath () + \" = \" + element . getValue ()); } } Producing and output such as: Document not covered elements: /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/ApldOptnInd = false /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/CshMvmntDtls/RateAndAmtDtls/EarlySlctnFeeRate/Amt = 2345 /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/CshMvmntDtls/RateAndAmtDtls/EarlySlctnFeeRate/Amt/Ccy = USD /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/RateAndAmtDtls/NetDvddRate/RateTpAndAmtAndRateSts/Amt = 23423 /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/RateAndAmtDtls/NetDvddRate/RateTpAndAmtAndRateSts/Amt/Ccy = USD /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/RateAndAmtDtls/NetDvddRate/RateTpAndAmtAndRateSts/RateSts/Cd = ACTU /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/RateAndAmtDtls/NetDvddRate/RateTpAndAmtAndRateSts/RateTp/Cd = FLFR /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/SctiesQty/MaxQtyToInst/Unit = 234234 /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/SctiesQty/MinMltplQtyToInst/Unit = 23423 /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/SctiesQty/MinQtyToInst/Unit = 23423 With the key value pair of elements in the source MX that has not been read during the translation. Notice covered elements do not strictly mean the content will appear in the target MT, but its element value was read as part of the translation process. Depending on the specific mappings, the translation process is not just moving data from one place to the other, in many cases decisions are made based on the source content and for this coverage report those elements are considered read. Notice as well, due to the richness of the ISO 20022 standard compared to the MT, full coverage is an exceptional case to achieve and not the normal case. IN most scenarios, you will find elements in the MX that have no equivalent in the MT or that are not processed as part of the translation logic.","title":"Truncation"},{"location":"integrator/translations/translations-mx2mt/#sanitize","text":"After translating from MX to MT, the translator will sanitize the content of the source MX to ensure the resulting MT is valid. This is done by removing invalid characters and replacing them with a valid character. The default character is the '.' (dot) character, and the invalida characters are '&' (ampersand), '\"' (double quote), '<' (less than symbol) and '>' (greater than symbol). Furthermore, in multiline fields, any ':' (colon) or '-' (hyphen) character found at the beginning of each line starting from the second line will be substituted with a '.' (dot). However, if a line begins with multiple consecutive hyphen or colon characters, only the first one will be replaced. Finally, the translator will verify if specific fields have a mandatory component and assign a default value in case they are missing it. This function is particularly useful for fields containing a party identifier that does not include the name and address. The sanitization process is done by default, but can be switched off with the TranslatorConfiguration parameter if needed. MxPacs00800102_MT103_Translation translator = new MxPacs00800102_MT103_Translation (); final MT103 mt = translator . translate ( source , new TranslatorConfiguration (). setMxToMtCharsetConversionEnabled ( false )); All the process described above is done by using the MtSanitizer class. This class is a helper to manipulate and fix fields in an MT messages. So it can be used to sanitize any MT message, not just the ones translated by the library.","title":"Sanitize"},{"location":"integrator/validation/","text":"Prowide Integrator Validation - Overview The Validation library provides a set of APIs to validate SWIFT messages (MT and ISO 20022) against the standard rules. By making sure the messages are valid, the library helps to avoid sending messages that will be rejected by the SWIFT network, or the counter-party applications; preventing NAKs. For MT messages, all SWIFT format validations are implemented, including: Structure : mandatory sequences and fields, sequence and fields ordering, sequence and fields repetitions. Fields : fields mandatory components, components length, character sets, specific codeword qualifiers. Semantic validations (network rules). BIC codes against directory, ISO country and currency codes, IBAN numbers, custom rules. For MX messages (ISO 20022), the library validates: Message structure using the XSD schema . ISO external code sets . Cross-element rules, for a subset of messages types. BIC codes against directory, ISO country and currency codes, IBAN numbers, custom rules. The different steps of the validation process can be tuned up, for example, using specific message schema definitions, adding or removing validation rules, and filtering the resulting problem list. Custom rules can also be added to the validation process, to implement specific validations for a given message type. Javadoc Online javadoc Prowide Integrator Validation Javadoc SRU2023-9.4.x","title":"Prowide Integrator Validation - Overview"},{"location":"integrator/validation/#prowide-integrator-validation-overview","text":"The Validation library provides a set of APIs to validate SWIFT messages (MT and ISO 20022) against the standard rules. By making sure the messages are valid, the library helps to avoid sending messages that will be rejected by the SWIFT network, or the counter-party applications; preventing NAKs. For MT messages, all SWIFT format validations are implemented, including: Structure : mandatory sequences and fields, sequence and fields ordering, sequence and fields repetitions. Fields : fields mandatory components, components length, character sets, specific codeword qualifiers. Semantic validations (network rules). BIC codes against directory, ISO country and currency codes, IBAN numbers, custom rules. For MX messages (ISO 20022), the library validates: Message structure using the XSD schema . ISO external code sets . Cross-element rules, for a subset of messages types. BIC codes against directory, ISO country and currency codes, IBAN numbers, custom rules. The different steps of the validation process can be tuned up, for example, using specific message schema definitions, adding or removing validation rules, and filtering the resulting problem list. Custom rules can also be added to the validation process, to implement specific validations for a given message type.","title":"Prowide Integrator Validation - Overview"},{"location":"integrator/validation/#javadoc","text":"Online javadoc Prowide Integrator Validation Javadoc SRU2023-9.4.x","title":"Javadoc"},{"location":"integrator/validation/validation-bic/","text":"BIC validation To avoid false positives when validating BIC codes due to a possible un-updated BIC dictionary, this validation is turned off by default. If this is set to true, when validating a BIC code, the internal database will be used and validation will pass only if the exact BIC exists in the internal catalog, checking the full BIC code including institution code, location and branch. If left false, the BIC validation will just check that the code has 8 or 11 characters. To turn this validation on, the Configuration object in the Validation Engine can be used: engine . getConfig (). setBicDatabaseEnabled ( true ); By default the BIC directory that is used, is the Derby embedded database included in the pw-swift-integrator-data-1.X.X.jar file that can be added as a regular dependency to the project. A custom BIC directory can be provided by implementing the IBICDirectory interface and providing an instance to the SdkConfiguration class: SdkConfiguration . setCustomIBICDirectory ( customInstance ); Country and currency validation As for the elements containing country and currency codes, the validation engine will use the internal list of valid codes. This list is initialized with values from the underlying Java library, but can be extended with custom values using the IsoUtils class.","title":"BIC validation"},{"location":"integrator/validation/validation-bic/#bic-validation","text":"To avoid false positives when validating BIC codes due to a possible un-updated BIC dictionary, this validation is turned off by default. If this is set to true, when validating a BIC code, the internal database will be used and validation will pass only if the exact BIC exists in the internal catalog, checking the full BIC code including institution code, location and branch. If left false, the BIC validation will just check that the code has 8 or 11 characters. To turn this validation on, the Configuration object in the Validation Engine can be used: engine . getConfig (). setBicDatabaseEnabled ( true ); By default the BIC directory that is used, is the Derby embedded database included in the pw-swift-integrator-data-1.X.X.jar file that can be added as a regular dependency to the project. A custom BIC directory can be provided by implementing the IBICDirectory interface and providing an instance to the SdkConfiguration class: SdkConfiguration . setCustomIBICDirectory ( customInstance );","title":"BIC validation"},{"location":"integrator/validation/validation-bic/#country-and-currency-validation","text":"As for the elements containing country and currency codes, the validation engine will use the internal list of valid codes. This list is initialized with values from the underlying Java library, but can be extended with custom values using the IsoUtils class.","title":"Country and currency validation"},{"location":"integrator/validation/validation-mt/","text":"MT message validation MT message structure validation Message structure validation is the first step in the MT validation process, and it's almost the most important for MT messages. The structure validation rules validate the overall message structure. They check that the message has the mandatory and optional blocks and that the blocks are in correct order. For block 4, they validate each field and each defined sequence of fields checking presence if it is mandatory, allowed repetitions and ordering. The structure is done by a heuristic of field matching against a defined message scheme. The structure of a message is defined in a proprietary XML scheme. The library includes schemes for all SWIFT MT messages, and any of them can be customized. For detailed information regarding schemes, please check the SDK developer guide . During the validation process the engine can automatically detect a suitable scheme to apply, but the user may overwrite this indicating a specific scheme to use by API. As a general use case the scheme to use will map the mt number of the message as indicated at block 2 plus the optional message variant (STP, COV, REMIT) indicated in block 3. The following example is similar to the previous one, but a specific scheme is indicated in the validation call. ValidationEngine engine = new ValidationEngine (); engine . initialize (); Scheme scheme = SRU2016MtType . MT103_REMIT . sheme (); List < ValidationProblem > r = engine . validateMessage ( msg , scheme ); engine . dispose (); The scheme parameter is optional. There are two situations where indicating a specific scheme becomes handy: When the Scheme object has been dynamically modified to achieve custom validations. To achieve maximum performance, releasing the engine from the auto-detection and loading of corresponding schemes. Ignoring structure problems On occasions, messages may be written on purpose with invalid values or received from internal back-office applications with local information not suitable for SWIFT. One common use case of this is the usage given to the Logical Terminal (LT) identifier in the header block. According to SWIFT the LT identifier is used when the institution runs more than one terminal, and in that case letters A, B or C are used, while X is explicitly forbidden (X's padding should be only used for the branch). Nevertheless, an institution may be using \u2018X\u2019 on testing or load balancing environments and may need to bypass such validation to prevent processes abortion due to validation error. Another common use case is the session and sequence number generated with invalid data. Therefore, this feature is a quick way to bypass message structure validations by means of API, using the ValidationConfiguration . For the example above, the following code will indicate the engine to ignore the validation of the LT identifier at the header block (block 1): engine . getConfig (). addIgnoreValidatorProblemKey ( StructureProblem . H10 ); All problems in StructureProblem that start with BLOCK1_ and BLOCK2_ may be added to the ignore list. Attempts to add other problem types will be ignored, issuing just a log message. More validation examples can be found at https://github.com/prowide/ MT message field validation The field validation rules check the internal component structure of each field in a message. For each combination of field number and letter option, the compliance to specific validation pattern is verified, checking: Presence of mandatory components. Components length and charset Specific format subfunctions, for example DATE2, DATE4, TIME2, AMOUNT15, CUR, etc.. The number and size of lines (including not allowed characters starting a line). Since version 7.8 this validation rules are implemented into a single processing unit, in the FieldValidationRule class. For information regarding the allowed pattern and internal components of each field, please refer to the javadoc for each FieldNN implementation. MT message semantic and network rules validation The semantic (a.k.a. network rules) rules are validation constraints that usually involve more than a field in a message. There are hundreds of semantic validations defined by SWIFT and implemented by the validation module. This semantic checks are defined per message type and can involve among other things: Validating conditional presence of fields and sequences based on other fields or sequences. Validating conditional presence of fields and sequences based on fields qualifiers. Validating conditional allowed qualifiers between fields. Validating cross-referenced dates. Validating currencies' consistency. Validating sum of amounts between transactions and fields with totes. There are 300 semantic validations checks. The relation between a specific message type and the semantica validation that are applied is defined in the message Scheme. ERI (Euro Related Info) validation On top of the default generic format, some fields are validated against the ERI constraints when the ERI data is present. ERI refers to the original currency in the transaction. If no specific fields are available to specify the original currency and amount, ERI data may be added in a free text field with the codewords: OCMT and CHGS . By default, the ERI is validated in fields 72, field 77A (MTs 416, 455 and 456), field 79 (MT 986) and fields 86 and 61 (MTs 940 and 942). ERI validation is reported with standard error codes such as T47, T52 and T40. Since the specification of ERI is always optional, this special constraint checks can be easily switched off with a parameter in the validation engine configuration: engine . getConfig (). setEriValidationEnabled ( false ); This switch is the recommended way to disable all ERI related checks if the constraints must not be checked in your business context. IBAN validation Multiple MT fields could contain an account number, such as the first component in field 59. The default validation for these account numbers is just based on the allowed characters and total length, which in general for account numbers is 34x. When these account components are used with IBAN numbers, an additional constraint can be enforced so that the full IBAN number validation is applied. In the validation configuration, you need to first enable IBAN validation in general with the flag: engine . getConfig (). setIBANValidationEnabled ( true ); Then you need to explicitly identify the specific field components where the IBAN validation should apply. These are configured using MtPath expressions like this: engine . getConfig (). addMtIbanPath ( MtPathExpression . parse ( \"50K/1\" )); engine . getConfig (). addMtIbanPath ( MtPathExpression . parse ( \"59/1\" )); For information on the MtPath expressions syntax and capabilities, please check the SDK developer guide. Custom MT validation The validation engine supports three different ways to customize the validation. These together allow you to define any custom constraint over the standard. Structure validations can be modified by means of the scheme structure definition, and other types of rules can be added or removed from the validation process. Customizing schemes To change mandatory and optional fields, supported letter options, field and sequences repetitions, and expected qualifiers, a modified scheme can be used in the validation call. ValidationEngine .validateMessage can accept just the SwiftMessage object to validate, or the message object plus a specific Scheme object if the default behaviour is being overwritten. The custom scheme can be created in Java, from scratch, or by modifying one of the out-of-the-box default Scheme classes provided. Schemes can also be defined in XML and read as Scheme objects using the SchemeXmlReader . The scheme object defines the overall structure of a message, including its nested sequences (if any) and all the fields and letter options combination that the message accepts. By means of a custom scheme, you can for example restrict several letter options on specific fields, or reduce or extend the expected qualifiers for any field. Most common use cases demanding some kind of custom validation can be entirely covered by customizing schemes. For more information on schemes, please check the SDK Developer Guide. Adding a custom rule Custom rules can be injected in the validation to perform any additional check not covered by the standard validation. Being implemented as Java classes, this custom rules can do anything you need. Custom rules will be evaluated after all standard rules, and are implemented in your own application as normal Java classes meeting the following simple requisites: Extend ValidationRule directly or indirectly. Override implementation of the method eval(SwiftMessage, String) to perform any check on the message without limitations. The method must return the list of validation problems found or an empty list if the message satisfies the validation. Example 1: Custom rule to check the reference prefix The following example implements a rule to check that the message reference is prefixed \"MYREF\", so if the message reference is not present or not prefixed with \"MYREF\" this rule will report a validation problem: public class MyRule extends ValidationRule { @Override protected List < ValidationProblem > eval ( SwiftMessage msg , String mt ) { List < ValidationProblem > result = new ArrayList < ValidationProblem > (); if ( msg . getBlock4 () != null ) { Tag reference = msg . getBlock4 (). getTagByName ( \"20\" ); if ( reference == null || ! StringUtils . startsWith ( reference . getValue (), \"MYREF\" )) { result . add ( new ValidationProblem ( \"BAD_REFERENCE\" , \"the reference must start with MYREF\" )); } } return result ; } } Example 2: Custom rule to check the presence of the trailer block The example below demonstrates a rule for verifying the presence of the trailer block in the message. According to the standard, Block 5, if included, must always contain the CHK tag. However, the checksum calculation algorithm is proprietary and not disclosed by SWIFT. Therefore, without a method for users to compute the checksum, adding validation for it is not feasible. For that reason it is a good practice to check the presence of the trailer block and the CHK tag in a custom rule. public class TrailerCHKValidationRule extends ValidationRule { @Override protected List < ValidationProblem > eval ( SwiftMessage msg , String mt ) { List < ValidationProblem > result = new ArrayList <> (); SwiftBlock5 block5 = msg . getBlock5 (); if ( block5 != null && ! block5 . getTags (). isEmpty ()) { Tag chk = block5 . getTagByName ( \"CHK\" ); if ( chk == null ) { result . add ( new ValidationProblem ( StructureProblem . Z04 ). setBundleKey ( \"Z04.missing\" )); } } return result ; } } All found errors should be returned as ValidationProblem objects, and it is a good practice that custom rules create custom validation problems, since the standard ValidationProblem class is not intended to be a general purpose class. Custom validation problems may be created by extending the ValidationProblem or can be generated dynamically in your own rule just by creating a generic ValidationProblem instance, providing a custom error key and error message. Once the validation rule is implemented, it must be injected in the engine configuration. All rules are associated with messages by scheme names (where scheme names by default is a composition of the message type and the message variant). If the same rule should be applied to more than one message type, it must explicitly be added into the custom rules map for each corresponding message type. The following example adds the above rules to an engine instance for messages MT103 REMIT and MT 202: engine . getConfig (). addCustomRule ( \"103_REMIT\" , new MyRule ()); engine . getConfig (). addCustomRule ( \"202\" , new TrailerCHKValidationRule ()); Notice in the example, we use the MT types enumeration to provide valid scheme names. The plain string with the message type number can also be used for this purpose if you don\u2019t use specific message variants. Elaborated examples can be found at https://github.com/prowide/prowide-integrator-examples/blob/master/src/com/prowidesoftware/swift/samples/integrator/validation/MessageValidationWithCustomRulesExample.java Ignoring specific validation rules When instead of adding a new constraint over the standard, there is a need to be more flexible, reducing the constraint already implemented, you can indicate that some validation problems should be ignored. This is done by a dynamic setting in the validation engine configuration instance, where you can mark as many problems as you need. Validation problems are uniquely identified by its error keys, so the available enumerations are used to clearly identify the problem to ignore. The following example shows how to mark several types of validation problems for ignore, including general, structure, field, and semantic checks. In a real use case scenario, this is used to filter just a few specific constraints depending on the nature of the messages being validation and the need for some flexibility over the default standard constraints. engine . getConfig (). addIgnoredValidationProblem ( GeneralProblem . EXTRA_DATA_IN_MESSAGE ); engine . getConfig (). addIgnoredValidationProblem ( StructureProblem . INVALID_FIELD_QUALIFIER ); engine . getConfig (). addIgnoredValidationProblem ( StructureProblem . BLOCK1_APPLICATION_ID ); engine . getConfig (). addIgnoredValidationProblem ( FieldProblem . COMPONENT_BAD_SIZE ); engine . getConfig (). addIgnoredValidationProblem ( FieldProblem . BAD_CURRENCY ); engine . getConfig (). addIgnoredValidationProblem ( FieldProblem . COMPONENT_NOT_BIC ); engine . getConfig (). addIgnoredValidationProblem ( SemanticProblem . D75 ); Notice some special problems are blocking for the validation and cannot be ignored; the ones related to the license ( UNLICENSED_BIC, UNLICENSED_MT, LICENSE_PROBLEM) and the major blocking issues (UNSUPPORTED_MESSAGE, UNRECOGNIZED, MISSING_BLOCK1, MISSING_BLOCK2, MISSING_BLOCK4). A complete example can be found at https://github.com/prowide/prowide-integrator-examples/blob/master/src/com/prowidesoftware/swift/samples/integrator/validation/MessageValidationIgnoringCustomExample.java","title":"MT message validation"},{"location":"integrator/validation/validation-mt/#mt-message-validation","text":"","title":"MT message validation"},{"location":"integrator/validation/validation-mt/#mt-message-structure-validation","text":"Message structure validation is the first step in the MT validation process, and it's almost the most important for MT messages. The structure validation rules validate the overall message structure. They check that the message has the mandatory and optional blocks and that the blocks are in correct order. For block 4, they validate each field and each defined sequence of fields checking presence if it is mandatory, allowed repetitions and ordering. The structure is done by a heuristic of field matching against a defined message scheme. The structure of a message is defined in a proprietary XML scheme. The library includes schemes for all SWIFT MT messages, and any of them can be customized. For detailed information regarding schemes, please check the SDK developer guide . During the validation process the engine can automatically detect a suitable scheme to apply, but the user may overwrite this indicating a specific scheme to use by API. As a general use case the scheme to use will map the mt number of the message as indicated at block 2 plus the optional message variant (STP, COV, REMIT) indicated in block 3. The following example is similar to the previous one, but a specific scheme is indicated in the validation call. ValidationEngine engine = new ValidationEngine (); engine . initialize (); Scheme scheme = SRU2016MtType . MT103_REMIT . sheme (); List < ValidationProblem > r = engine . validateMessage ( msg , scheme ); engine . dispose (); The scheme parameter is optional. There are two situations where indicating a specific scheme becomes handy: When the Scheme object has been dynamically modified to achieve custom validations. To achieve maximum performance, releasing the engine from the auto-detection and loading of corresponding schemes.","title":"MT message structure validation"},{"location":"integrator/validation/validation-mt/#ignoring-structure-problems","text":"On occasions, messages may be written on purpose with invalid values or received from internal back-office applications with local information not suitable for SWIFT. One common use case of this is the usage given to the Logical Terminal (LT) identifier in the header block. According to SWIFT the LT identifier is used when the institution runs more than one terminal, and in that case letters A, B or C are used, while X is explicitly forbidden (X's padding should be only used for the branch). Nevertheless, an institution may be using \u2018X\u2019 on testing or load balancing environments and may need to bypass such validation to prevent processes abortion due to validation error. Another common use case is the session and sequence number generated with invalid data. Therefore, this feature is a quick way to bypass message structure validations by means of API, using the ValidationConfiguration . For the example above, the following code will indicate the engine to ignore the validation of the LT identifier at the header block (block 1): engine . getConfig (). addIgnoreValidatorProblemKey ( StructureProblem . H10 ); All problems in StructureProblem that start with BLOCK1_ and BLOCK2_ may be added to the ignore list. Attempts to add other problem types will be ignored, issuing just a log message. More validation examples can be found at https://github.com/prowide/","title":"Ignoring structure problems"},{"location":"integrator/validation/validation-mt/#mt-message-field-validation","text":"The field validation rules check the internal component structure of each field in a message. For each combination of field number and letter option, the compliance to specific validation pattern is verified, checking: Presence of mandatory components. Components length and charset Specific format subfunctions, for example DATE2, DATE4, TIME2, AMOUNT15, CUR, etc.. The number and size of lines (including not allowed characters starting a line). Since version 7.8 this validation rules are implemented into a single processing unit, in the FieldValidationRule class. For information regarding the allowed pattern and internal components of each field, please refer to the javadoc for each FieldNN implementation.","title":"MT message field validation"},{"location":"integrator/validation/validation-mt/#mt-message-semantic-and-network-rules-validation","text":"The semantic (a.k.a. network rules) rules are validation constraints that usually involve more than a field in a message. There are hundreds of semantic validations defined by SWIFT and implemented by the validation module. This semantic checks are defined per message type and can involve among other things: Validating conditional presence of fields and sequences based on other fields or sequences. Validating conditional presence of fields and sequences based on fields qualifiers. Validating conditional allowed qualifiers between fields. Validating cross-referenced dates. Validating currencies' consistency. Validating sum of amounts between transactions and fields with totes. There are 300 semantic validations checks. The relation between a specific message type and the semantica validation that are applied is defined in the message Scheme.","title":"MT message semantic and network rules validation"},{"location":"integrator/validation/validation-mt/#eri-euro-related-info-validation","text":"On top of the default generic format, some fields are validated against the ERI constraints when the ERI data is present. ERI refers to the original currency in the transaction. If no specific fields are available to specify the original currency and amount, ERI data may be added in a free text field with the codewords: OCMT and CHGS . By default, the ERI is validated in fields 72, field 77A (MTs 416, 455 and 456), field 79 (MT 986) and fields 86 and 61 (MTs 940 and 942). ERI validation is reported with standard error codes such as T47, T52 and T40. Since the specification of ERI is always optional, this special constraint checks can be easily switched off with a parameter in the validation engine configuration: engine . getConfig (). setEriValidationEnabled ( false ); This switch is the recommended way to disable all ERI related checks if the constraints must not be checked in your business context.","title":"ERI (Euro Related Info) validation"},{"location":"integrator/validation/validation-mt/#iban-validation","text":"Multiple MT fields could contain an account number, such as the first component in field 59. The default validation for these account numbers is just based on the allowed characters and total length, which in general for account numbers is 34x. When these account components are used with IBAN numbers, an additional constraint can be enforced so that the full IBAN number validation is applied. In the validation configuration, you need to first enable IBAN validation in general with the flag: engine . getConfig (). setIBANValidationEnabled ( true ); Then you need to explicitly identify the specific field components where the IBAN validation should apply. These are configured using MtPath expressions like this: engine . getConfig (). addMtIbanPath ( MtPathExpression . parse ( \"50K/1\" )); engine . getConfig (). addMtIbanPath ( MtPathExpression . parse ( \"59/1\" )); For information on the MtPath expressions syntax and capabilities, please check the SDK developer guide.","title":"IBAN validation"},{"location":"integrator/validation/validation-mt/#custom-mt-validation","text":"The validation engine supports three different ways to customize the validation. These together allow you to define any custom constraint over the standard. Structure validations can be modified by means of the scheme structure definition, and other types of rules can be added or removed from the validation process.","title":"Custom MT validation"},{"location":"integrator/validation/validation-mt/#customizing-schemes","text":"To change mandatory and optional fields, supported letter options, field and sequences repetitions, and expected qualifiers, a modified scheme can be used in the validation call. ValidationEngine .validateMessage can accept just the SwiftMessage object to validate, or the message object plus a specific Scheme object if the default behaviour is being overwritten. The custom scheme can be created in Java, from scratch, or by modifying one of the out-of-the-box default Scheme classes provided. Schemes can also be defined in XML and read as Scheme objects using the SchemeXmlReader . The scheme object defines the overall structure of a message, including its nested sequences (if any) and all the fields and letter options combination that the message accepts. By means of a custom scheme, you can for example restrict several letter options on specific fields, or reduce or extend the expected qualifiers for any field. Most common use cases demanding some kind of custom validation can be entirely covered by customizing schemes. For more information on schemes, please check the SDK Developer Guide.","title":"Customizing schemes"},{"location":"integrator/validation/validation-mt/#adding-a-custom-rule","text":"Custom rules can be injected in the validation to perform any additional check not covered by the standard validation. Being implemented as Java classes, this custom rules can do anything you need. Custom rules will be evaluated after all standard rules, and are implemented in your own application as normal Java classes meeting the following simple requisites: Extend ValidationRule directly or indirectly. Override implementation of the method eval(SwiftMessage, String) to perform any check on the message without limitations. The method must return the list of validation problems found or an empty list if the message satisfies the validation. Example 1: Custom rule to check the reference prefix The following example implements a rule to check that the message reference is prefixed \"MYREF\", so if the message reference is not present or not prefixed with \"MYREF\" this rule will report a validation problem: public class MyRule extends ValidationRule { @Override protected List < ValidationProblem > eval ( SwiftMessage msg , String mt ) { List < ValidationProblem > result = new ArrayList < ValidationProblem > (); if ( msg . getBlock4 () != null ) { Tag reference = msg . getBlock4 (). getTagByName ( \"20\" ); if ( reference == null || ! StringUtils . startsWith ( reference . getValue (), \"MYREF\" )) { result . add ( new ValidationProblem ( \"BAD_REFERENCE\" , \"the reference must start with MYREF\" )); } } return result ; } } Example 2: Custom rule to check the presence of the trailer block The example below demonstrates a rule for verifying the presence of the trailer block in the message. According to the standard, Block 5, if included, must always contain the CHK tag. However, the checksum calculation algorithm is proprietary and not disclosed by SWIFT. Therefore, without a method for users to compute the checksum, adding validation for it is not feasible. For that reason it is a good practice to check the presence of the trailer block and the CHK tag in a custom rule. public class TrailerCHKValidationRule extends ValidationRule { @Override protected List < ValidationProblem > eval ( SwiftMessage msg , String mt ) { List < ValidationProblem > result = new ArrayList <> (); SwiftBlock5 block5 = msg . getBlock5 (); if ( block5 != null && ! block5 . getTags (). isEmpty ()) { Tag chk = block5 . getTagByName ( \"CHK\" ); if ( chk == null ) { result . add ( new ValidationProblem ( StructureProblem . Z04 ). setBundleKey ( \"Z04.missing\" )); } } return result ; } } All found errors should be returned as ValidationProblem objects, and it is a good practice that custom rules create custom validation problems, since the standard ValidationProblem class is not intended to be a general purpose class. Custom validation problems may be created by extending the ValidationProblem or can be generated dynamically in your own rule just by creating a generic ValidationProblem instance, providing a custom error key and error message. Once the validation rule is implemented, it must be injected in the engine configuration. All rules are associated with messages by scheme names (where scheme names by default is a composition of the message type and the message variant). If the same rule should be applied to more than one message type, it must explicitly be added into the custom rules map for each corresponding message type. The following example adds the above rules to an engine instance for messages MT103 REMIT and MT 202: engine . getConfig (). addCustomRule ( \"103_REMIT\" , new MyRule ()); engine . getConfig (). addCustomRule ( \"202\" , new TrailerCHKValidationRule ()); Notice in the example, we use the MT types enumeration to provide valid scheme names. The plain string with the message type number can also be used for this purpose if you don\u2019t use specific message variants. Elaborated examples can be found at https://github.com/prowide/prowide-integrator-examples/blob/master/src/com/prowidesoftware/swift/samples/integrator/validation/MessageValidationWithCustomRulesExample.java","title":"Adding a custom rule"},{"location":"integrator/validation/validation-mt/#ignoring-specific-validation-rules","text":"When instead of adding a new constraint over the standard, there is a need to be more flexible, reducing the constraint already implemented, you can indicate that some validation problems should be ignored. This is done by a dynamic setting in the validation engine configuration instance, where you can mark as many problems as you need. Validation problems are uniquely identified by its error keys, so the available enumerations are used to clearly identify the problem to ignore. The following example shows how to mark several types of validation problems for ignore, including general, structure, field, and semantic checks. In a real use case scenario, this is used to filter just a few specific constraints depending on the nature of the messages being validation and the need for some flexibility over the default standard constraints. engine . getConfig (). addIgnoredValidationProblem ( GeneralProblem . EXTRA_DATA_IN_MESSAGE ); engine . getConfig (). addIgnoredValidationProblem ( StructureProblem . INVALID_FIELD_QUALIFIER ); engine . getConfig (). addIgnoredValidationProblem ( StructureProblem . BLOCK1_APPLICATION_ID ); engine . getConfig (). addIgnoredValidationProblem ( FieldProblem . COMPONENT_BAD_SIZE ); engine . getConfig (). addIgnoredValidationProblem ( FieldProblem . BAD_CURRENCY ); engine . getConfig (). addIgnoredValidationProblem ( FieldProblem . COMPONENT_NOT_BIC ); engine . getConfig (). addIgnoredValidationProblem ( SemanticProblem . D75 ); Notice some special problems are blocking for the validation and cannot be ignored; the ones related to the license ( UNLICENSED_BIC, UNLICENSED_MT, LICENSE_PROBLEM) and the major blocking issues (UNSUPPORTED_MESSAGE, UNRECOGNIZED, MISSING_BLOCK1, MISSING_BLOCK2, MISSING_BLOCK4). A complete example can be found at https://github.com/prowide/prowide-integrator-examples/blob/master/src/com/prowidesoftware/swift/samples/integrator/validation/MessageValidationIgnoringCustomExample.java","title":"Ignoring specific validation rules"},{"location":"integrator/validation/validation-mx/","text":"MX message validation Analogously to MT message validation, for MX messages the validation check is handled through the validation engine. The validation is performed on the XML representation of the message against the corresponding XSD schemas. On top of the schema constraints, the validation can check the BIC codes, currency, and country codes against the internal catalog. The message can contain any of the given structure combinations: Single Document element Single Document element within envelope/wrapper elements Single AppHdr element Single AppHdr element within any envelope/wrapper elements Both AppHdr and Document elements within any root element Both AppHdr and Document elements within any envelope/wrapper element In any case, the validation will strip the Document and the optional AppHdr and will run the validation for that segment of the parameter XML. The envelope/wrapper elements, if present, will be silently ignored. If the parameter for the validation is already in XML because it was read from a String or File, the validation is run directly over the given text. Otherwise, if the validation is called on an MX model object, it is serialized into its XML representation and then the constraints are verified on the resulting XML text. The result of the validation process is a list of ValidationProblem objects that, in case of error, include a specific indication of the invalid or missing content and the xpath within the XML where the problem is found. The following example initializes the validation engine and calls the validation process. The first one assumes the message is being created with a model object, and the second one has the MX message already in xml format. Validation methods The validation engine exports several methods to validate a message, accepting different parameters. Validating from XML or File This is always the preferred entry point for validation. The specific MX type will be automatically detected and the XML content will be checked against the corresponding schema. The following example validates a message from a String with its XML content. A similar method is provided to validate the message from a File . String xml = \"\" ; ValidationEngine engine = new ValidationEngine (); engine . initialize (); List < ValidationProblem > r = engine . validateMxMessage ( xml ); engine . dispose (); This validation will first detect and report malformed XML messages. If the message is well-formed as an XML, the specific message type is detected from the Document namespace. If an AppHdr is also present in the message, it will be validated as well, against the corresponding header schema. For convenience, specific methods are provided in the validation engine to validate the header in its two versions: ISO business application header and legacy swift application header. If the message payload (header and document) are surrounded by an envelope, the elements in the envelope will be silently ignored. Notice when both header and document elements are present in a message, these elements are siblings, so they must be encapsulated under a common wrapper element. This wrapper or envelope in MX is network specific, so it cannot be validated by the library. This is handy when you need to validate Mx messages received from different (even unknown) sources where the header and document content is embedded under non-standard envelopes. Validating from MX objects For messages created using the builder API, meaning the MX objects and the MX business dictionary objects, a specific validation method is provided. This validation will serialize the Document and optional header into XML and will apply the schema for the specific MX passed to the validation. MxAcmt00100103 mx = new MxAcmt00100103 (); mx . setAcctOpngInstr ( new AccountOpeningInstructionV03 ()); ValidationEngine engine = new ValidationEngine (); engine . initialize (); List < ValidationProblem > r = engine . validateMxMessage ( mx ); engine . dispose (); If the MX message object or the XML contains the optional business application header (AppHdr), the found header will also be validated. IMPORTANT : When validated messages from XML, do not parse them into the MX object to call validation because the parser will drop invalid content from the source XML, therefore some errors may not be reported. If the message to validate is already in XML or read from a File , the validation from String and File should be used. ISO 20022 external code set validation Some ISO 20022 messages use external code sets which are not included in the default message schema, thus the code is not validated by default. In the group header of a pacs.008 for example, the Cd element could be any uppercase 4 letters string such as ABCD: INDA MyIdentifier ABCD However, if you apply the external code set validation, the Cd element for this particular message type can only contain BBAN , CUID , AIIN , UPIC , such as: INDA MyIdentifier BBAN The listed codes can be used in specific elements of the messages as indicated in the documents published at: https://www.iso20022.org/catalogue-messages/additional-content-messages/external-code-sets The purpose of externalizing these codes is to be able to update the code sets (for example, add new codes) without impacting the messages themselves and, hence, without requiring the development of a new version of the messages that use these code sets. The external code set validation is not enabled by default, but you can switch it on with a flag in the ValidationConfiguration : engine . getConfig (). setExternalCodeSetValidationEnabled ( true ); The actual external code sets used for the validation are embedded in the jar file as an XSD resource with a fixed name, ExternalCodeSet.xsd. This XSD is the machine-readable file from 18 October 2019 published at the iSO site. The resource will be updated from time to time but if you need to check a specific codeset that is not included in this default XSD, you are expected to override the XSD file as needed. IBAN validation In ISO 20022 messages the IBAN (International Bank Account Number) elements are clearly identified. Thus the IBAN structure format is automatically validated during the process. Custom MX validation The validation engine supports three different ways to customize the validation. These together allows you to define any custom constraint over the standard. A custom XSD schema can be provided for the validation, additional custom rules can be added to the process, and default rules can be removed (marked to be ignored). Customizing XSD schemas By default, the validation will use the default standard ISO schema corresponding to the message type (when validating a Mx object) or XML namespace (when validating XML content). If you need to use a customized version of a schema, instead of the default ISO version, you can pass the XSD schema as parameter for the validation. The easiest way to pass your custom schema to the engine is to include it in the validation call using either of these calls: validateMxMessage ( final String xml , SchemaProvider schemaProvider ) validateMxMessage ( final String xml , StreamSource schema ) It is also posible to load the schema from a xsd file. That could be achieved as follows (in this case for a pacs.008.001.08 MX message): Path filePath = Paths . get ( \"your_path_to_file/pacs.008.001.08.xsd\" ); PathSchemaProvider pathSchemaProvider = new PathSchemaProvider ( filePath ); engine . validateMxMessage ( xml_to_validate , pathSchemaProvider ); Another option, if you need to use many customized schemas, is to implement your own XsdRegistry . This registry has a method to return the schema given the message category, functionality, variant, and version. In order to continue using the default schemas for the message types that you are not overwriting, the easiest way of implementing this is by extending the default registry implementation like this: public class MyRegistry extends XsdRegistryImpl { @Override public StreamSource find ( String category , Integer functionality , Integer variant , Integer version ) { if ( category . equals ( MxBusinessProcess . pain . name ()) && functionality == 1 && variant == 1 && version == 7 ) { return new StreamSource ( new StringReader ( yourXSD ))); } return super . find ( category , functionality , variant , version ); } } In this example, the custom registry provides a custom XSD for pain.001.001.07 while returning all default data for the rest of message types. Once you have the registry implementation, you can inject it to the validation engine using the setXsdRegistry method in the ValidationConfiguration class. Adding a custom rule Custom rules can be injected in the validation to perform any additional check not covered by the standard validation. Being implemented as Java classes, this custom rules can do anything you need. Custom rules will be evaluated after all standard rules, and are implemented in your own application as normal Java classes implementing the MxCustomValidationRule interface. The custom rule must implement the eval(String, MxNode, MxStuctureInfo) to perform any check on the message without limitations. The method must return the list of validation problems found or an empty list if the message satisfies the validation. The parameters for the eval method are redundant for convenience: The first parameter is the raw XML content as it was passed to the validation engine. The second parameter contains the same XML content, but already parsed into a model structure. The MxNode object provides a useful API to get content from the XML using XPath expressions. Finally, the MxStructureInfo provides some metadata from the XML All found errors should be returned as ValidationProblem objects, and it is a good practice that custom rules create custom validation problems, since the standard ValidationProblem class is not intended to be a general purpose class. Custom validation problems may be created by extending the ValidationProblem or can be generated dynamically in your own rule just by creating a generic ValidationProblem instance, providing a custom error key and error message. Once the validation rule is implemented, it must be injected in the engine configuration. A custom rule can be applied to a specific message type such as pain.001.001.03, or you can also associate the rule to all versions of the message type, pain.001.001.* or even to all MX message types. This relation between your custom rule and the message types to which the rule will be applied is defined using MxId objects. The MxId can be created for a specific type providing all its properties (business process, functionality, variant and version) or you can create an MxId and just set the business process, or the business process and the functionality, or any other combination of properties. The attributes in the MxId that are not set, will be used as a wildcard when the engine loads the custom rules to apply to a particular message. The following example adds a rule for all messages in the pacs category, and another rule for the pain.001.002.*: engine . getConfig (). addCustomMxRule ( new MxId (). setBusinessProcess ( MxBusinessProcess . pain ), new MyRule1 ()); engine . getConfig (). addCustomMxRule ( new MxId ( \"pain\" , \"001\" , \"002\" , null ), new MyRule2 ()); Ignoring specific validation rules When instead of adding a new constraint over the standard, there is a need to be more flexible, reducing the constraint already implemented, you can indicate that some validation problems should be ignored. This is done by a dynamic setting in the validation engine configuration instance, where you can mark as many problems as you need. Validation problems are uniquely identified by its error keys, so the available enumerations are used to clearly identify the problem to ignore. The following example shows how to mark the bad currency problems for ignore: engine . getConfig (). addIgnoredValidationProblem ( MxProblem . BAD_CURRENCY ); Cross-element validation The MX standard define for each ISO 20022 message a set of semantic rules that must be satisfied by the message. These rules cannot be specified in the XSD schema because they normally involve more than one element in the XML. For example \"If GrpHdr/InstgAgt is present, then CdtTrfTxInf/InstgAgt is not allowed.\" is a cross-element rule. The error code for this rules is normally prefixed with an \"X\" such as \"X00050\". Since the total variiaty of message types in the comprehensive ISO 20022 set is very large (note that each message type such as pacs.008 could have multiple variants and versions), then the validation engine does not implement all the cross-element rules. The subset of messages for with the cross-element rules are implemented are the ones that are used in the CBPR+ restricted, plus the newer versions of all those mesasge types. This subset is and will be a work in progress and will be extended as needed.","title":"MX message validation"},{"location":"integrator/validation/validation-mx/#mx-message-validation","text":"Analogously to MT message validation, for MX messages the validation check is handled through the validation engine. The validation is performed on the XML representation of the message against the corresponding XSD schemas. On top of the schema constraints, the validation can check the BIC codes, currency, and country codes against the internal catalog. The message can contain any of the given structure combinations: Single Document element Single Document element within envelope/wrapper elements Single AppHdr element Single AppHdr element within any envelope/wrapper elements Both AppHdr and Document elements within any root element Both AppHdr and Document elements within any envelope/wrapper element In any case, the validation will strip the Document and the optional AppHdr and will run the validation for that segment of the parameter XML. The envelope/wrapper elements, if present, will be silently ignored. If the parameter for the validation is already in XML because it was read from a String or File, the validation is run directly over the given text. Otherwise, if the validation is called on an MX model object, it is serialized into its XML representation and then the constraints are verified on the resulting XML text. The result of the validation process is a list of ValidationProblem objects that, in case of error, include a specific indication of the invalid or missing content and the xpath within the XML where the problem is found. The following example initializes the validation engine and calls the validation process. The first one assumes the message is being created with a model object, and the second one has the MX message already in xml format.","title":"MX message validation"},{"location":"integrator/validation/validation-mx/#validation-methods","text":"The validation engine exports several methods to validate a message, accepting different parameters.","title":"Validation methods"},{"location":"integrator/validation/validation-mx/#validating-from-xml-or-file","text":"This is always the preferred entry point for validation. The specific MX type will be automatically detected and the XML content will be checked against the corresponding schema. The following example validates a message from a String with its XML content. A similar method is provided to validate the message from a File . String xml = \"\" ; ValidationEngine engine = new ValidationEngine (); engine . initialize (); List < ValidationProblem > r = engine . validateMxMessage ( xml ); engine . dispose (); This validation will first detect and report malformed XML messages. If the message is well-formed as an XML, the specific message type is detected from the Document namespace. If an AppHdr is also present in the message, it will be validated as well, against the corresponding header schema. For convenience, specific methods are provided in the validation engine to validate the header in its two versions: ISO business application header and legacy swift application header. If the message payload (header and document) are surrounded by an envelope, the elements in the envelope will be silently ignored. Notice when both header and document elements are present in a message, these elements are siblings, so they must be encapsulated under a common wrapper element. This wrapper or envelope in MX is network specific, so it cannot be validated by the library. This is handy when you need to validate Mx messages received from different (even unknown) sources where the header and document content is embedded under non-standard envelopes.","title":"Validating from XML or File"},{"location":"integrator/validation/validation-mx/#validating-from-mx-objects","text":"For messages created using the builder API, meaning the MX objects and the MX business dictionary objects, a specific validation method is provided. This validation will serialize the Document and optional header into XML and will apply the schema for the specific MX passed to the validation. MxAcmt00100103 mx = new MxAcmt00100103 (); mx . setAcctOpngInstr ( new AccountOpeningInstructionV03 ()); ValidationEngine engine = new ValidationEngine (); engine . initialize (); List < ValidationProblem > r = engine . validateMxMessage ( mx ); engine . dispose (); If the MX message object or the XML contains the optional business application header (AppHdr), the found header will also be validated. IMPORTANT : When validated messages from XML, do not parse them into the MX object to call validation because the parser will drop invalid content from the source XML, therefore some errors may not be reported. If the message to validate is already in XML or read from a File , the validation from String and File should be used.","title":"Validating from MX objects"},{"location":"integrator/validation/validation-mx/#iso-20022-external-code-set-validation","text":"Some ISO 20022 messages use external code sets which are not included in the default message schema, thus the code is not validated by default. In the group header of a pacs.008 for example, the Cd element could be any uppercase 4 letters string such as ABCD: INDA MyIdentifier ABCD However, if you apply the external code set validation, the Cd element for this particular message type can only contain BBAN , CUID , AIIN , UPIC , such as: INDA MyIdentifier BBAN The listed codes can be used in specific elements of the messages as indicated in the documents published at: https://www.iso20022.org/catalogue-messages/additional-content-messages/external-code-sets The purpose of externalizing these codes is to be able to update the code sets (for example, add new codes) without impacting the messages themselves and, hence, without requiring the development of a new version of the messages that use these code sets. The external code set validation is not enabled by default, but you can switch it on with a flag in the ValidationConfiguration : engine . getConfig (). setExternalCodeSetValidationEnabled ( true ); The actual external code sets used for the validation are embedded in the jar file as an XSD resource with a fixed name, ExternalCodeSet.xsd. This XSD is the machine-readable file from 18 October 2019 published at the iSO site. The resource will be updated from time to time but if you need to check a specific codeset that is not included in this default XSD, you are expected to override the XSD file as needed.","title":"ISO 20022 external code set validation"},{"location":"integrator/validation/validation-mx/#iban-validation","text":"In ISO 20022 messages the IBAN (International Bank Account Number) elements are clearly identified. Thus the IBAN structure format is automatically validated during the process.","title":"IBAN validation"},{"location":"integrator/validation/validation-mx/#custom-mx-validation","text":"The validation engine supports three different ways to customize the validation. These together allows you to define any custom constraint over the standard. A custom XSD schema can be provided for the validation, additional custom rules can be added to the process, and default rules can be removed (marked to be ignored).","title":"Custom MX validation"},{"location":"integrator/validation/validation-mx/#customizing-xsd-schemas","text":"By default, the validation will use the default standard ISO schema corresponding to the message type (when validating a Mx object) or XML namespace (when validating XML content). If you need to use a customized version of a schema, instead of the default ISO version, you can pass the XSD schema as parameter for the validation. The easiest way to pass your custom schema to the engine is to include it in the validation call using either of these calls: validateMxMessage ( final String xml , SchemaProvider schemaProvider ) validateMxMessage ( final String xml , StreamSource schema ) It is also posible to load the schema from a xsd file. That could be achieved as follows (in this case for a pacs.008.001.08 MX message): Path filePath = Paths . get ( \"your_path_to_file/pacs.008.001.08.xsd\" ); PathSchemaProvider pathSchemaProvider = new PathSchemaProvider ( filePath ); engine . validateMxMessage ( xml_to_validate , pathSchemaProvider ); Another option, if you need to use many customized schemas, is to implement your own XsdRegistry . This registry has a method to return the schema given the message category, functionality, variant, and version. In order to continue using the default schemas for the message types that you are not overwriting, the easiest way of implementing this is by extending the default registry implementation like this: public class MyRegistry extends XsdRegistryImpl { @Override public StreamSource find ( String category , Integer functionality , Integer variant , Integer version ) { if ( category . equals ( MxBusinessProcess . pain . name ()) && functionality == 1 && variant == 1 && version == 7 ) { return new StreamSource ( new StringReader ( yourXSD ))); } return super . find ( category , functionality , variant , version ); } } In this example, the custom registry provides a custom XSD for pain.001.001.07 while returning all default data for the rest of message types. Once you have the registry implementation, you can inject it to the validation engine using the setXsdRegistry method in the ValidationConfiguration class.","title":"Customizing XSD schemas"},{"location":"integrator/validation/validation-mx/#adding-a-custom-rule","text":"Custom rules can be injected in the validation to perform any additional check not covered by the standard validation. Being implemented as Java classes, this custom rules can do anything you need. Custom rules will be evaluated after all standard rules, and are implemented in your own application as normal Java classes implementing the MxCustomValidationRule interface. The custom rule must implement the eval(String, MxNode, MxStuctureInfo) to perform any check on the message without limitations. The method must return the list of validation problems found or an empty list if the message satisfies the validation. The parameters for the eval method are redundant for convenience: The first parameter is the raw XML content as it was passed to the validation engine. The second parameter contains the same XML content, but already parsed into a model structure. The MxNode object provides a useful API to get content from the XML using XPath expressions. Finally, the MxStructureInfo provides some metadata from the XML All found errors should be returned as ValidationProblem objects, and it is a good practice that custom rules create custom validation problems, since the standard ValidationProblem class is not intended to be a general purpose class. Custom validation problems may be created by extending the ValidationProblem or can be generated dynamically in your own rule just by creating a generic ValidationProblem instance, providing a custom error key and error message. Once the validation rule is implemented, it must be injected in the engine configuration. A custom rule can be applied to a specific message type such as pain.001.001.03, or you can also associate the rule to all versions of the message type, pain.001.001.* or even to all MX message types. This relation between your custom rule and the message types to which the rule will be applied is defined using MxId objects. The MxId can be created for a specific type providing all its properties (business process, functionality, variant and version) or you can create an MxId and just set the business process, or the business process and the functionality, or any other combination of properties. The attributes in the MxId that are not set, will be used as a wildcard when the engine loads the custom rules to apply to a particular message. The following example adds a rule for all messages in the pacs category, and another rule for the pain.001.002.*: engine . getConfig (). addCustomMxRule ( new MxId (). setBusinessProcess ( MxBusinessProcess . pain ), new MyRule1 ()); engine . getConfig (). addCustomMxRule ( new MxId ( \"pain\" , \"001\" , \"002\" , null ), new MyRule2 ());","title":"Adding a custom rule"},{"location":"integrator/validation/validation-mx/#ignoring-specific-validation-rules","text":"When instead of adding a new constraint over the standard, there is a need to be more flexible, reducing the constraint already implemented, you can indicate that some validation problems should be ignored. This is done by a dynamic setting in the validation engine configuration instance, where you can mark as many problems as you need. Validation problems are uniquely identified by its error keys, so the available enumerations are used to clearly identify the problem to ignore. The following example shows how to mark the bad currency problems for ignore: engine . getConfig (). addIgnoredValidationProblem ( MxProblem . BAD_CURRENCY );","title":"Ignoring specific validation rules"},{"location":"integrator/validation/validation-mx/#cross-element-validation","text":"The MX standard define for each ISO 20022 message a set of semantic rules that must be satisfied by the message. These rules cannot be specified in the XSD schema because they normally involve more than one element in the XML. For example \"If GrpHdr/InstgAgt is present, then CdtTrfTxInf/InstgAgt is not allowed.\" is a cross-element rule. The error code for this rules is normally prefixed with an \"X\" such as \"X00050\". Since the total variiaty of message types in the comprehensive ISO 20022 set is very large (note that each message type such as pacs.008 could have multiple variants and versions), then the validation engine does not implement all the cross-element rules. The subset of messages for with the cross-element rules are implemented are the ones that are used in the CBPR+ restricted, plus the newer versions of all those mesasge types. This subset is and will be a work in progress and will be extended as needed.","title":"Cross-element validation"},{"location":"integrator/validation/validation-process/","text":"Validation process The validation process can be seen as a pipeline where rules evaluation is performed in the fixed order: structure, fields, semantic and custom. The validation process always perform the following tasks: Loads a proper message scheme definition, based on invocation parameters or using the message type information of the actual message. Evaluates the structure validation rules, matching the message scheme with the actual message content. For each field in the message, evaluate the corresponding field validation rule. Evaluates all semantic rules associated with the validating message type. Evaluates all user defined rules, if any, for the particular message type. The following sections describe each of the validation steps, specifically for MT, where the validation is more fragmented. For MX standard, based on XML, the process has fewer steps and a smaller rule set. Validation Engine The entry point for the validation process is the ValidationEngine . In the simplest scenario the validation involves initiating the engine, passing the message to validate, checking the result and disposing of the engine. The following example performs validation of a message contained in the variable \"msg\": ValidationEngine engine = new ValidationEngine (); engine . initialize (); List < ValidationProblem > r = engine . validateMessage ( msg ); engine . dispose (); This call will initialize the validation engine and will apply the specific validation rule set for the message. If the resulting list is empty, the message is SWIFT standard compliance. Regarding the message parameter, the API supports different options, each for a different use case scenario. In short, there are options to validate messages when the specific message type is unknown, passing the content as String or model; and there are options to validate known messages contained in a model object (for example: MT103). Quick API reference The following table synthesize the API entry point for common use case scenarios: Use Case API validate an message read from String \u2022 validationEngine.validateMtMessage(String) \u2022 validationEngine.validateMxMessage(String) validate a swift message built from API \u2022 validationEngine.validateMessage(MT103) \u2022 validationEngine.validateMessage(SwiftMessage, Scheme) \u2022 validationEngine.validateMessage(MxSecl00100101) Engine configuration Several behaviour of the validation engine can be configured in the enclosed ValidationConfiguration object. This configuration class enables for example to indicate wheater the BIC codes should be validated against a directory, if the IBAN validation should be anabled, if the MT set is GPI or not, and so on. The configuration object is initialized with default values, that can be change at any time before a validation call. ValidationEngine engine = new ValidationEngine (); engine . initialize (); engine . getConfig (). setBicDatabaseEnabled ( true ); List < ValidationProblem > r = engine . validateMessage ( msg ); Engine cache This engine requires initialization and disposal, because it caches several internal structures that are reused acrross validation calls. So it is important when validating large bursts of messages to reuse the engine instance , for example by using a singleton pattern. Since the engine behaviour can be slightly customize with a ValidationConfiguration it could be that different message flows require a different configuration. In this use case scenario multiple instances of the engine can be created, each with its own configuration. But creating a new ValidationEngine per validation call is discouraged, as it will be slower and will consume more memory. Schema cache To enhance the efficiency of the MX validation process, a Schema cache is implemented to significantly reduce the time required for schema creation, which is inherently time-consuming. This cache ensures that schemas are loaded only once and reused throughout the validation operations, leading to faster processing times. To activate this feature, you have to enable the cache in your validation engine instance: ValidationEngine engine = new ValidationEngine (); engine . initialize (); engine . getConfig (). setCache ( new SchemaCacheImpl ()); List < ValidationProblem > r = engine . validateMessage ( msg ); The SchemaCacheImpl is the default implementation of the SchemaCache interface, and it uses a simple Map to store the cached schemas, with no eviction. If you have specific caching requirements, you can tailor the caching behavior by creating your own implementation of the SchemaCache interface. You can for example use a third-party caching library, such as Ehcache, Caffeine or Guava; to provide more advanced caching features. Handling Validation Errors During the validation process a list of validation problems found is created. Note that by default the validation process is not stopped when the first problem is found, but it continues until the end of the validation process. The ValidationProblem object is the container for each validation error found during the evaluation. Its main attributes are: Error Key : A unique validation problem identifier. For MT messages this error code matches the FIN Service alphabetic error codes such as T13, H10, D20. Problem Type : The problem type is coupled to the validation implementation, and provides a classification indication where in the process the issue was found. The available types are: General, Structure, Field, Semantic and Mx. This attribute does not add much value to the final user, it is intended for programmatic error handling. Error Message : An error description suitable for user interface, these messages are fully configured by means of a property file and provided in English, Spanish, Italian, French, and Russian. Specific attributes for MT validation: Field Index: the position of the field with the encountered issue within block 4 (starting with zero at first block 4 field). Specific attributes for MX validation: Line and Column : when the error comes directly from XML parsing Path : Containing the full XPATH where the error is found Examples for MT validation: Problem Type : Structure Problem Key : T13 Error Message : Missing required field: 20 Problem Type : Structure Problem Key : T13 Error Message : Unexpected 99 field found Notice in the above cases, both problems share the same error key, but the description is slightly different. This is because FIN Error codes are very specific in some cases but very wide in others, catching multiple error conditions with a single code. Problem Type : Field Problem Key : T17 Error Message : Field 53A: If the slash ('/') is present, it's following party field information cannot be empty. Problem Type : Semantic Problem Key : E04 Error Message : If field 23B contains one of the code words SPRI, SSTD or SPAY and field 53a is present with option B, then the party identifier (component 1) must be present in that field 53B. Problem Type : Semantic Problem Key : C05 Error Message : The BIC at field 52A must not be a BEI. Problem Type : Semantic Problem Key : D20 Error Message : Field 71A must be present either in sequence A or in each occurrence of sequence B, but it must never be present in both sequences, nor be absent from both sequences. Examples for MX validation: Problem Type : Mx Problem Key : XSD_ERROR Error Message : Invalid content was found starting with element 'TxId'. One of '{\"urn:iso:std:iso:20022:tech:xsd: pacs.008.001.04\":EndToEndId}' is expected. Path : /Document/FIToFICstmrCdtTrf/CdtTrfTxInf/PmtId Line, Column : 29, 11 Validating files versus validating objects It is important to notice the difference when the message to validate comes from a file or from a message object. Where a message from a file means a message that it is already in swift format (fin for MT or xml for MX), for example a message in a String variable (not necessarily a file system file). And a message object is a swift message created with the builder API, populating the swift message object. This is particularly important for MX messages because malformed/incorrect XML messages cannot always fit the java structure. Imagine inserting arbitrary tags in an MX message, there is no Java support for that in the model, since they do not belong to the message definition. So the parser will ignore those tags and the validation of the resulting MX swift object will not detect the errors. Analogously for MT, a not well-formed FIN messages could be although parsed into an MTnnn object, and the validation of the resulting object will not be able to detect some errors, for example unrecognized blocks, wrong CRLFs, incomplete headers. The following code samples illustrate these alternatives: MT message object created with builder API: MT103 mt = new MT103 (); m . addField ( new Field20 ( \"REFERENCE\" )); List < ValidationProblem > r = engine . validateMessage ( mt ); MT message already in FIN format, in a String , delegating parsing to the engine: String mt = \"{1:F01BIC...}\" ; List < ValidationProblem > r = engine . validateMtMessage ( mt ); MT message already in FIN format, in a File , delegating reading and parsing to the engine: File mt = new File \"/tmp/out-103.fin\" ; List < ValidationProblem > r = engine . validateMtMessage ( mt ); MX message created with builder API: MxAcmt00100103 mx = new MxAcmt00100103 (); mx . setAcctOpngInstr ( new AccountOpeningInstructionV03 ()); List < ValidationProblem > r = engine . validateMessage ( mx ); MX message from xml content, in a String , delegating parsing to the engine: String xml = \"\" ; List < ValidationProblem > r = engine . validateMxMessage ( xml ); MX message from xml content, in a File , delegating reading and parsing to the engine: File xml = new File ( \"/tmp/camt.001.01.01.xml\" ; List < ValidationProblem > r = engine . validateMxMessage ( xml ); For a complete set of options, please check the engine javadoc at: http://api.prowidesoftware.com/integrator/com/prowidesoftware/swift/validator/ValidationEngine.html","title":"Validation process"},{"location":"integrator/validation/validation-process/#validation-process","text":"The validation process can be seen as a pipeline where rules evaluation is performed in the fixed order: structure, fields, semantic and custom. The validation process always perform the following tasks: Loads a proper message scheme definition, based on invocation parameters or using the message type information of the actual message. Evaluates the structure validation rules, matching the message scheme with the actual message content. For each field in the message, evaluate the corresponding field validation rule. Evaluates all semantic rules associated with the validating message type. Evaluates all user defined rules, if any, for the particular message type. The following sections describe each of the validation steps, specifically for MT, where the validation is more fragmented. For MX standard, based on XML, the process has fewer steps and a smaller rule set.","title":"Validation process"},{"location":"integrator/validation/validation-process/#validation-engine","text":"The entry point for the validation process is the ValidationEngine . In the simplest scenario the validation involves initiating the engine, passing the message to validate, checking the result and disposing of the engine. The following example performs validation of a message contained in the variable \"msg\": ValidationEngine engine = new ValidationEngine (); engine . initialize (); List < ValidationProblem > r = engine . validateMessage ( msg ); engine . dispose (); This call will initialize the validation engine and will apply the specific validation rule set for the message. If the resulting list is empty, the message is SWIFT standard compliance. Regarding the message parameter, the API supports different options, each for a different use case scenario. In short, there are options to validate messages when the specific message type is unknown, passing the content as String or model; and there are options to validate known messages contained in a model object (for example: MT103).","title":"Validation Engine"},{"location":"integrator/validation/validation-process/#quick-api-reference","text":"The following table synthesize the API entry point for common use case scenarios: Use Case API validate an message read from String \u2022 validationEngine.validateMtMessage(String) \u2022 validationEngine.validateMxMessage(String) validate a swift message built from API \u2022 validationEngine.validateMessage(MT103) \u2022 validationEngine.validateMessage(SwiftMessage, Scheme) \u2022 validationEngine.validateMessage(MxSecl00100101)","title":"Quick API reference"},{"location":"integrator/validation/validation-process/#engine-configuration","text":"Several behaviour of the validation engine can be configured in the enclosed ValidationConfiguration object. This configuration class enables for example to indicate wheater the BIC codes should be validated against a directory, if the IBAN validation should be anabled, if the MT set is GPI or not, and so on. The configuration object is initialized with default values, that can be change at any time before a validation call. ValidationEngine engine = new ValidationEngine (); engine . initialize (); engine . getConfig (). setBicDatabaseEnabled ( true ); List < ValidationProblem > r = engine . validateMessage ( msg );","title":"Engine configuration"},{"location":"integrator/validation/validation-process/#engine-cache","text":"This engine requires initialization and disposal, because it caches several internal structures that are reused acrross validation calls. So it is important when validating large bursts of messages to reuse the engine instance , for example by using a singleton pattern. Since the engine behaviour can be slightly customize with a ValidationConfiguration it could be that different message flows require a different configuration. In this use case scenario multiple instances of the engine can be created, each with its own configuration. But creating a new ValidationEngine per validation call is discouraged, as it will be slower and will consume more memory.","title":"Engine cache"},{"location":"integrator/validation/validation-process/#schema-cache","text":"To enhance the efficiency of the MX validation process, a Schema cache is implemented to significantly reduce the time required for schema creation, which is inherently time-consuming. This cache ensures that schemas are loaded only once and reused throughout the validation operations, leading to faster processing times. To activate this feature, you have to enable the cache in your validation engine instance: ValidationEngine engine = new ValidationEngine (); engine . initialize (); engine . getConfig (). setCache ( new SchemaCacheImpl ()); List < ValidationProblem > r = engine . validateMessage ( msg ); The SchemaCacheImpl is the default implementation of the SchemaCache interface, and it uses a simple Map to store the cached schemas, with no eviction. If you have specific caching requirements, you can tailor the caching behavior by creating your own implementation of the SchemaCache interface. You can for example use a third-party caching library, such as Ehcache, Caffeine or Guava; to provide more advanced caching features.","title":"Schema cache"},{"location":"integrator/validation/validation-process/#handling-validation-errors","text":"During the validation process a list of validation problems found is created. Note that by default the validation process is not stopped when the first problem is found, but it continues until the end of the validation process. The ValidationProblem object is the container for each validation error found during the evaluation. Its main attributes are: Error Key : A unique validation problem identifier. For MT messages this error code matches the FIN Service alphabetic error codes such as T13, H10, D20. Problem Type : The problem type is coupled to the validation implementation, and provides a classification indication where in the process the issue was found. The available types are: General, Structure, Field, Semantic and Mx. This attribute does not add much value to the final user, it is intended for programmatic error handling. Error Message : An error description suitable for user interface, these messages are fully configured by means of a property file and provided in English, Spanish, Italian, French, and Russian. Specific attributes for MT validation: Field Index: the position of the field with the encountered issue within block 4 (starting with zero at first block 4 field). Specific attributes for MX validation: Line and Column : when the error comes directly from XML parsing Path : Containing the full XPATH where the error is found Examples for MT validation: Problem Type : Structure Problem Key : T13 Error Message : Missing required field: 20 Problem Type : Structure Problem Key : T13 Error Message : Unexpected 99 field found Notice in the above cases, both problems share the same error key, but the description is slightly different. This is because FIN Error codes are very specific in some cases but very wide in others, catching multiple error conditions with a single code. Problem Type : Field Problem Key : T17 Error Message : Field 53A: If the slash ('/') is present, it's following party field information cannot be empty. Problem Type : Semantic Problem Key : E04 Error Message : If field 23B contains one of the code words SPRI, SSTD or SPAY and field 53a is present with option B, then the party identifier (component 1) must be present in that field 53B. Problem Type : Semantic Problem Key : C05 Error Message : The BIC at field 52A must not be a BEI. Problem Type : Semantic Problem Key : D20 Error Message : Field 71A must be present either in sequence A or in each occurrence of sequence B, but it must never be present in both sequences, nor be absent from both sequences. Examples for MX validation: Problem Type : Mx Problem Key : XSD_ERROR Error Message : Invalid content was found starting with element 'TxId'. One of '{\"urn:iso:std:iso:20022:tech:xsd: pacs.008.001.04\":EndToEndId}' is expected. Path : /Document/FIToFICstmrCdtTrf/CdtTrfTxInf/PmtId Line, Column : 29, 11","title":"Handling Validation Errors"},{"location":"integrator/validation/validation-process/#validating-files-versus-validating-objects","text":"It is important to notice the difference when the message to validate comes from a file or from a message object. Where a message from a file means a message that it is already in swift format (fin for MT or xml for MX), for example a message in a String variable (not necessarily a file system file). And a message object is a swift message created with the builder API, populating the swift message object. This is particularly important for MX messages because malformed/incorrect XML messages cannot always fit the java structure. Imagine inserting arbitrary tags in an MX message, there is no Java support for that in the model, since they do not belong to the message definition. So the parser will ignore those tags and the validation of the resulting MX swift object will not detect the errors. Analogously for MT, a not well-formed FIN messages could be although parsed into an MTnnn object, and the validation of the resulting object will not be able to detect some errors, for example unrecognized blocks, wrong CRLFs, incomplete headers. The following code samples illustrate these alternatives: MT message object created with builder API: MT103 mt = new MT103 (); m . addField ( new Field20 ( \"REFERENCE\" )); List < ValidationProblem > r = engine . validateMessage ( mt ); MT message already in FIN format, in a String , delegating parsing to the engine: String mt = \"{1:F01BIC...}\" ; List < ValidationProblem > r = engine . validateMtMessage ( mt ); MT message already in FIN format, in a File , delegating reading and parsing to the engine: File mt = new File \"/tmp/out-103.fin\" ; List < ValidationProblem > r = engine . validateMtMessage ( mt ); MX message created with builder API: MxAcmt00100103 mx = new MxAcmt00100103 (); mx . setAcctOpngInstr ( new AccountOpeningInstructionV03 ()); List < ValidationProblem > r = engine . validateMessage ( mx ); MX message from xml content, in a String , delegating parsing to the engine: String xml = \"\" ; List < ValidationProblem > r = engine . validateMxMessage ( xml ); MX message from xml content, in a File , delegating reading and parsing to the engine: File xml = new File ( \"/tmp/camt.001.01.01.xml\" ; List < ValidationProblem > r = engine . validateMxMessage ( xml ); For a complete set of options, please check the engine javadoc at: http://api.prowidesoftware.com/integrator/com/prowidesoftware/swift/validator/ValidationEngine.html","title":"Validating files versus validating objects"},{"location":"open-source/","text":"Prowide open source libraries The Prowide Core and Prowide ISO 20022 are open source Java libraries for managing SWIFT MT and ISO 20022 messages. The projects are: Actively maintained to the latest standard releases Hosted at public GitHub repositories Released under the Apache License 2.0 Production ready and commercially supported Compatible with Java 8+ Download coordinates Download Prowide Core Download Prowide ISO 20022","title":"Prowide open source libraries"},{"location":"open-source/#prowide-open-source-libraries","text":"The Prowide Core and Prowide ISO 20022 are open source Java libraries for managing SWIFT MT and ISO 20022 messages. The projects are: Actively maintained to the latest standard releases Hosted at public GitHub repositories Released under the Apache License 2.0 Production ready and commercially supported Compatible with Java 8+ Download coordinates Download Prowide Core Download Prowide ISO 20022","title":"Prowide open source libraries"},{"location":"open-source/core/","text":"Prowide Core Overview Prowide Core implements the foundation classes to handle SWIFT MT (FIN) messages in Java. The library provides a comprehensive model for all MT message categories. The API features include parsing messages from FIN format to Java, serializing Java model objects into the FIN format and the conversion between FIN messages and XML and JSON formats. The library implements the general ISO 20022 standard. Complementary packages with restricted ISO versions such as CBPR+, SEPA, and SIC are provided in the complementary, proprietary (not open source) library Prowide Integrator. Finally, this library is based on some components from the Prowide Core library. So in order to use this, you will also need the dependency for Prowide Core. Quick API reference The tables below synthesizes, by pseudocode, the entry point for common MT read/write use case scenarios. The use case is usually determined by whether you are creating a new SWIFT message or reading an existing SWIFT message. And in the case of reading, different API exists depending on whether you are processing messages generically, or if you are reading specific known type. Use Case API Parse a known MT message into a specific message model new MT103 ( String / InputStream fin ) MT103 . parse ( String / File / InputStream fin ) Read specific MT message content MT103 + getters Parse unknown MT message into generic swift model AbstractMT . parse ( String / InputStream fin ) Specialize generic MT message new MT103 ( MtSwiftMessage ) MT103 . parse ( MtSwiftMessage ) ( MT103 ) AbstractMT Load and persist an unknown MT message new MtSwiftMessage ( String / InputStream fin ) MtSwiftMessage . parse ( String / InputStream fin ) Build a new MT message new MT103 () + append ( Field ) Write a new MT message to swift string MT103 + message () -> fin Write a new MT message to swift file or stream MT103 + write ( OutputStream fin ) Javadoc Online javadoc Prowide Core Javadoc","title":"Prowide Core"},{"location":"open-source/core/#prowide-core","text":"","title":"Prowide Core"},{"location":"open-source/core/#overview","text":"Prowide Core implements the foundation classes to handle SWIFT MT (FIN) messages in Java. The library provides a comprehensive model for all MT message categories. The API features include parsing messages from FIN format to Java, serializing Java model objects into the FIN format and the conversion between FIN messages and XML and JSON formats. The library implements the general ISO 20022 standard. Complementary packages with restricted ISO versions such as CBPR+, SEPA, and SIC are provided in the complementary, proprietary (not open source) library Prowide Integrator. Finally, this library is based on some components from the Prowide Core library. So in order to use this, you will also need the dependency for Prowide Core.","title":"Overview"},{"location":"open-source/core/#quick-api-reference","text":"The tables below synthesizes, by pseudocode, the entry point for common MT read/write use case scenarios. The use case is usually determined by whether you are creating a new SWIFT message or reading an existing SWIFT message. And in the case of reading, different API exists depending on whether you are processing messages generically, or if you are reading specific known type. Use Case API Parse a known MT message into a specific message model new MT103 ( String / InputStream fin ) MT103 . parse ( String / File / InputStream fin ) Read specific MT message content MT103 + getters Parse unknown MT message into generic swift model AbstractMT . parse ( String / InputStream fin ) Specialize generic MT message new MT103 ( MtSwiftMessage ) MT103 . parse ( MtSwiftMessage ) ( MT103 ) AbstractMT Load and persist an unknown MT message new MtSwiftMessage ( String / InputStream fin ) MtSwiftMessage . parse ( String / InputStream fin ) Build a new MT message new MT103 () + append ( Field ) Write a new MT message to swift string MT103 + message () -> fin Write a new MT message to swift file or stream MT103 + write ( OutputStream fin )","title":"Quick API reference"},{"location":"open-source/core/#javadoc","text":"Online javadoc Prowide Core Javadoc","title":"Javadoc"},{"location":"open-source/core/mt-ack/","text":"Processing ACK/NAK Model and API to process SWIFT ACK notifications The acknowledge (ACK) or non-acknowledge (NAK) are service messages sent by the SWIFT interface to the user application to notify an outgoing message was accepted or not. The acceptance mainly depends on the message being standard compliant. Note that receiving an ACK does not mean the message was effectively delivered to the receiver, it is just a notification indicating if the SWIFT interface accepted the message as valid and entered the message in the network. In order to handle the acknowledges, for instance to change the message status in your application, you have to do some matching of the received notifications and the original sent message. This matching process is not provided as an out-of-the-box feature because it involves querying the application database or file system to find candidates. Anyway, the building blocks to accomplish this task is well supported by the API. ACK structure The structure of a service message is similar to the structure of the regular user message, with a different service id and the block 4 composed of inner sub-blocks instead of fields in lines. Within the service messages the ACK/NAK notifications are identified with service id 21. The following example is the basic structure of a an ACK message: {1:F21LITEBEBBAXXX0066000079}{4:{177:1104180901}{451:0}} Field 451 in the system message indicates whether the message was acked (0) or nacked (1). When nacked the field 405 will also contain a field indicating the error code. For example: {405:T33002} The SwiftParser can seamlessly parse this messages and the SwiftMessage objects provides the same API to retrieve the service message fields as in a regular user message. The methods SwiftMessage#isAck() and SwiftMessage#isNack() can be used to determine in the message is a notification and if it is positive or not. Depending on the SWIFT interface, the file containing the notification can be different. However, in all cases it is composed of the service message plus some reference of the original message. This reference can be for the original message MUR or a full copy of the original message. Matching ACK with full copy of original message The most common structure is the system message with the ACK/NAK followed by a full copy of the original message as in this example: {1:F21LITEBEBBAXXX0066000079}{4:{177:1104180901}{451:0}}{1:F01LITEBEBBAXXX0066000079}{2:I999LITEBEBBXXXXN}{4: :20:TESTREF1 :79:This is text line 1 -}{5:{CHK:7602B010CF31}{TNG:}} The following section describe the normal procedure to detect and pair the acknowledge with the original message and the convenient API to use for the task. First step would be to determine if a received message is and ACK/NAK. Once the message is parsed as SwiftMessage, this methods can be use to verify if it is a regular FIN user to user message or if it is an ACK/NAK notification: SwiftMessage . isServiceMessage21 () SwiftMessage . isAck () SwiftMessage . isNack () Second step would be to split the ACK/NAK information from the identification of the original message. This example uses the most common format which is the ACK/NAK message followed by the full copy of the original message (this is the for example the format used by SAA AFT, or SA Lite autoclient). To parse both the ACK/NAK and the original copy: Swiftparser parser = new SwiftParser () SwiftMessage ack = parser . parse ( msg ) SwiftMessage original = parser . parse ( ack . getUnparsedTexts (). getAsFINString ()) Finally, to match the acked/nacked message with its original message, a query on candidates must be done (usually searching for messages for the same day and same message type). Finding candidates is not covered here because it involves searching the application database or reading the sent messages from a file system directory. Once the candidates are retrieved, the matching can be accomplished like this: AckMessageComparator comparator = new AckMessageComparator (); for ( SwiftMessage candidate : candidates ) { if ( comparator . compare ( original , candidate ) == 0 ) { //candidate is the message acked/nacked } } Matching ACK with MUR Depending on the acknowledge notification source the structure of the message may differ. For instance the full copy of the original message could be missing. However, other kind of reference to the original acked/nacked message must be there, for example the MUR (Message User Reference) like this: {1:F21LITEBEBBAXXX0066000079}{4:{177:1104180901}{451:0}{108:FOO16101900001}} So to match the original message, instead of using the full message copy and the AckMessageComparator , a message with the same MUR must be found: for ( SwiftMessage candidate : candidates ) { if ( StringUtils . equals ( ack . getMUR (), candidate . getMUR ())) { candidate is the message acked / nacked } } Matching ACK with UUID If neither the original message copy nor the MUR are present in the ACK/NAK, the UUID (Unique Identifier) may be present. In this scenario the first step is to strip relevant information from the UUID such as the receiver address, message type and the reference. This fields should then be enough to perform a direct query in the application database to retrieve the unique original message matching the criteria. Related API documentation can be found online at SwiftMessage .","title":"Processing ACK/NAK"},{"location":"open-source/core/mt-ack/#processing-acknak","text":"Model and API to process SWIFT ACK notifications The acknowledge (ACK) or non-acknowledge (NAK) are service messages sent by the SWIFT interface to the user application to notify an outgoing message was accepted or not. The acceptance mainly depends on the message being standard compliant. Note that receiving an ACK does not mean the message was effectively delivered to the receiver, it is just a notification indicating if the SWIFT interface accepted the message as valid and entered the message in the network. In order to handle the acknowledges, for instance to change the message status in your application, you have to do some matching of the received notifications and the original sent message. This matching process is not provided as an out-of-the-box feature because it involves querying the application database or file system to find candidates. Anyway, the building blocks to accomplish this task is well supported by the API.","title":"Processing ACK/NAK"},{"location":"open-source/core/mt-ack/#ack-structure","text":"The structure of a service message is similar to the structure of the regular user message, with a different service id and the block 4 composed of inner sub-blocks instead of fields in lines. Within the service messages the ACK/NAK notifications are identified with service id 21. The following example is the basic structure of a an ACK message: {1:F21LITEBEBBAXXX0066000079}{4:{177:1104180901}{451:0}} Field 451 in the system message indicates whether the message was acked (0) or nacked (1). When nacked the field 405 will also contain a field indicating the error code. For example: {405:T33002} The SwiftParser can seamlessly parse this messages and the SwiftMessage objects provides the same API to retrieve the service message fields as in a regular user message. The methods SwiftMessage#isAck() and SwiftMessage#isNack() can be used to determine in the message is a notification and if it is positive or not. Depending on the SWIFT interface, the file containing the notification can be different. However, in all cases it is composed of the service message plus some reference of the original message. This reference can be for the original message MUR or a full copy of the original message.","title":"ACK structure"},{"location":"open-source/core/mt-ack/#matching-ack-with-full-copy-of-original-message","text":"The most common structure is the system message with the ACK/NAK followed by a full copy of the original message as in this example: {1:F21LITEBEBBAXXX0066000079}{4:{177:1104180901}{451:0}}{1:F01LITEBEBBAXXX0066000079}{2:I999LITEBEBBXXXXN}{4: :20:TESTREF1 :79:This is text line 1 -}{5:{CHK:7602B010CF31}{TNG:}} The following section describe the normal procedure to detect and pair the acknowledge with the original message and the convenient API to use for the task. First step would be to determine if a received message is and ACK/NAK. Once the message is parsed as SwiftMessage, this methods can be use to verify if it is a regular FIN user to user message or if it is an ACK/NAK notification: SwiftMessage . isServiceMessage21 () SwiftMessage . isAck () SwiftMessage . isNack () Second step would be to split the ACK/NAK information from the identification of the original message. This example uses the most common format which is the ACK/NAK message followed by the full copy of the original message (this is the for example the format used by SAA AFT, or SA Lite autoclient). To parse both the ACK/NAK and the original copy: Swiftparser parser = new SwiftParser () SwiftMessage ack = parser . parse ( msg ) SwiftMessage original = parser . parse ( ack . getUnparsedTexts (). getAsFINString ()) Finally, to match the acked/nacked message with its original message, a query on candidates must be done (usually searching for messages for the same day and same message type). Finding candidates is not covered here because it involves searching the application database or reading the sent messages from a file system directory. Once the candidates are retrieved, the matching can be accomplished like this: AckMessageComparator comparator = new AckMessageComparator (); for ( SwiftMessage candidate : candidates ) { if ( comparator . compare ( original , candidate ) == 0 ) { //candidate is the message acked/nacked } }","title":"Matching ACK with full copy of original message"},{"location":"open-source/core/mt-ack/#matching-ack-with-mur","text":"Depending on the acknowledge notification source the structure of the message may differ. For instance the full copy of the original message could be missing. However, other kind of reference to the original acked/nacked message must be there, for example the MUR (Message User Reference) like this: {1:F21LITEBEBBAXXX0066000079}{4:{177:1104180901}{451:0}{108:FOO16101900001}} So to match the original message, instead of using the full message copy and the AckMessageComparator , a message with the same MUR must be found: for ( SwiftMessage candidate : candidates ) { if ( StringUtils . equals ( ack . getMUR (), candidate . getMUR ())) { candidate is the message acked / nacked } }","title":"Matching ACK with MUR"},{"location":"open-source/core/mt-ack/#matching-ack-with-uuid","text":"If neither the original message copy nor the MUR are present in the ACK/NAK, the UUID (Unique Identifier) may be present. In this scenario the first step is to strip relevant information from the UUID such as the receiver address, message type and the reference. This fields should then be enough to perform a direct query in the application database to retrieve the unique original message matching the criteria. Related API documentation can be found online at SwiftMessage .","title":"Matching ACK with UUID"},{"location":"open-source/core/mt-build/","text":"MT Builder (Java to FIN MT) Functionality to create a new SWIFT message by populating Java objects, and writing the result in SWIFT FIN format The creation of a new message basically consists of creating an MT object for the specific message type, and the subsequent addition of fields in an orderly manner. The order of the fields is very important and should be done accordingly to the standard, the model does not prevent creating incorrect content (Standard compliance validation can be checked with Prowide Integrator). The following sections provides explanation by examples, creating messages in different common scenarios: Creating a message with MT classes The following example shows how to create a new MT103 message using the MT and Field helper classes. This is the easiest and recommended way to create a new message from scratch because the API will automatically fill mandatory header information with proper default values. The first step is to create the specific MT object and set its general attributes: final MT103 m = new MT103 (); m . setSender ( \"FOOSEDR0AXXX\" ); m . setReceiver ( \"FOORECV0XXXX\" ); In the above code you can use either a full logical terminal address as parameter (12 characters) or just a plain BIC code (8 or 11 characters) At this point all message blocks are initialized, and by default the message will be an outgoing message (input to SWIFT) with normal priority. The next step is adding the message fields. For simple fields the final value can be directly provided as a single String value, and for more complex fields with several subfields (components) the Field helper classes may be used. m . addField ( new Field20 ( \"REFERENCE\" )); m . addField ( new Field23B ( \"CRED\" )); Field32A f32A = new Field32A () . setDate ( Calendar . getInstance ()) . setCurrency ( \"EUR\" ) . setAmount ( \"1234567,89\" ); m . addField ( f32A ); Field50A f50A = new Field50A () . setAccount ( \"12345678901234567890\" ) . setBIC ( \"FOOBANKXXXXX\" ); m . addField ( f50A ); Field59 f59 = new Field59 () . setAccount ( \"12345678901234567890\" ) . setNameAndAddress ( \"JOE DOE\" ); m . addField ( f59 ); m . addField ( new Field71A ( \"OUR\" )); Finally the message() method converts the object into its SWIFT representation: System . out . println ( m . message ()); The output of the above example is: {1:F01FOOSEDR0AXXX0000000000}{2:IFOORECV0XXXXN}{4: :20:REFERENCE :23B:CRED :32A:1303EUR1234567,89 :50A:/12345678901234567890 FOOBANKXXXXX :59:/12345678901234567890 JOE DOE :71A:OUR -} Notice for instance how field 50A was serializing into a proper value including the slash prefix for the account number and the line feed between the account and the BIC code. /12345678901234567890 [CRLF] FOOBANKXXXXX The same procedure is used to create any type of message, changing the MT103 by any other available implementation. Creating inner sequences For more complex messages where fields must be contained in sequences (or sub blocks) some helper API is also provided by the message model. The following example shows how to append a General Information sequence A to an MT542: SequenceA A = MT542 . SequenceA . newInstance ( Field20C . tag ( \":SEME//2005071800000923\" ), Field23G . tag ( \"NEWM\" )); m . append ( A ); For boundary based sequences the opening and closing fields 16R and 16S will be automatically included. When the message is converted to FIN, the above sample code will generate the following SWIFT content: :16R:GENL :20C::SEME//2005071800000923 :23G:NEWM :16S:GENL Notice sequences should be appended in the correct order, as well as fields inside the sequence block. The API will not control the correctness of the content being generated. The main reason to use this helper sequences API is the constraint provided in the MTnnn classes where only the proper SequenceX inner classes will exist, this way you can rest assure that the appended sequences are part of the specific message type. Nested sequences can be also created with a similar API. The following example creates a complete MT517 with nested sequences A and A1: MT517 mt = new MT517 (). append ( MT517 . SequenceA . newInstance ( new SwiftTagListBlock () . append ( Field20C . tag ( \":SEME//2005071800000923\" )) . append ( Field23G . tag ( \"NEWM/CODU\" )) . append ( Field95P . tag ( \":AFFM//MGTCDE55\" )) . append ( MT517 . SequenceA1 . newInstance ( Field13A . tag ( \"LINK//515\" ), Field20C . tag ( \":RELA//FRTJ12CONF0002\" ))) . append ( MT517 . SequenceA1 . newInstance ( Field13A . tag ( \"LINK//512\" ), Field20C . tag (: RELA //FRTJ12CONF0003))) ) ); Notice how in order to append both Field and sequence objects to the container A sequence, we create a generic SwiftTagListBlock on the fly. The created FIN content for the above snippet is: {1:F01TESTUS00AXXX0000000000}{2:I517TESTUS00XXXXN}{4: :16R:GENL :20C::SEME//2005071800000923 :23G:NEWM/CODU :95P::AFFM//MGTCDE55 :16R:LINK :13A:LINK//515 :20C::RELA//FRTJ12CONF0002 :16S:LINK :16R:LINK :13A:LINK//512 :20C::RELA//FRTJ12CONF0003 :16S:LINK :16S:GENL -} Creating a message with specific header content To create headers with special information, the block's API can be accessed directly. The following example illustrates how to create a message using the low level model layer to create specific headers, overriding the ones created by default in the MT103 constructor. MT103 m = new MT103 (); SwiftBlock1 b1 = new SwiftBlock1 (); b1 . setApplicationId ( \"F\" ); b1 . setServiceId ( \"01\" ); b1 . setLogicalTerminal ( \"BICFOOYYAXXX\" ); b1 . setSessionNumber ( \"1234\" ); b1 . setSequenceNumber ( \"123456\" ); m . getSwiftMessage (). setBlock1 ( b1 ); SwiftBlock2Input b2 = new SwiftBlock2Input (); b2 . setMessageType ( \"103\" ); b2 . setReceiverAddress ( \"BICFOARXXXXX\" ); b2 . setDeliveryMonitoring ( \"1\" ); m . getSwiftMessage (). setBlock2 ( b2 ); m . getSwiftMessage (). setBlock3 ( new SwiftBlock3 ()); m . getSwiftMessage (). getBlock3 (). addTag ( Field113 . tag ( \"NOMT\" )); m . getSwiftMessage (). getBlock3 (). addTag ( Field108 . tag ( \"P22ABCD43C6J3XYZ\" )); In the above example a new and empty message object is created. The basic header (block 1) information is set with specific information, the application header (block 2) is created directly from a suitable string value with all its corresponding attributes pre set, and final an optional user header (block 3) is constructed by adding its tags. Since the MTnnn classes uses a SwiftMessage instance inside, both level API can be combined; the MTnnn and Fieldnnn classes can be use to create the main content of the message and then the SwiftMessage object can be accessed to add or change specific header or trailer information. Adding a message trailer block In most situations there is no need to create the trailer block because it will be added automatically by the FIN interface. However, the API allows the creation of the trailer block as well as any other optional message block as follows: MT103 m = new MT103 (); SwiftBlock5 block5 = new SwiftBlock5 (); block5 . addTag ( new Tag ( \"MAC\" , \"00000000\" )); block5 . addTag ( new Tag ( \"PDE\" , \"\" )); m . getSwiftMessage (). addBlock ( block5 ); The resulting block when the object is serialized to FIN will be: {5:{MAC:00000000}{PDE:}} Adding optional blocks Analogously to the description for Block 5, the same API can be used to create the optional User Header Block (block 3) or to add additional trailers. In particular for the block 3, a SwiftBlock3Builder helper class was introduced to ensure only valid fields are added to the block, and that fields are added in proper order. For backward compatibility we have kept the SwiftBlock3 structure which is a List but the new builder provides specific setters for each available block 3 field. The builder instance is created directly from the block and works as a decorator on the underlying list of tags. SwiftBlock3 b = new SwiftBlock3 (); b . builder () . setField121 ( new Field121 ( \"value121\" )) . setField106 ( new Field106 ( \"value106\" )) . setField165 ( new Field165 ( \"value165\" )) . setField106 ( new Field106 ( \"finalValue106\" )) . setField108 ( new Field108 ( \"value108\" )); Regardless of the setField calls order or repetition, the internal block 3 will be always consistent, and in the above example will produce this output: {3:{108:value108}{106:finalValue106}{121:value121}{165:value165}} The same applies when the message is created with an MT class. For instance if you need to add the MUR field 108 you can use the following: MT103_STP mt = new MT103_STP ( sender , receiver ); mt . getSwiftMessage (). getSwiftBlock3 (). builder (). setField108 ( value108 ); And the output will be: {3:{108:value108}{119:STP}{121:value121}} Notice, fields 119 and 121 were automatically added when the MT instance was created, and the manually added field 108 was placed in the correct position in the existing block 3. Finally this examples appends an optional application trailer block: SwiftBlockUser blockUser = new SwiftBlockUser ( \"S\" ); blockUser . addTag ( new Tag ( \"SAC\" , \"\" )); blockUser . addTag ( new Tag ( \"COP\" , \"P\" )); m . getSwiftMessage (). addBlock ( blockUser );","title":"MT Builder (Java to FIN MT)"},{"location":"open-source/core/mt-build/#mt-builder-java-to-fin-mt","text":"Functionality to create a new SWIFT message by populating Java objects, and writing the result in SWIFT FIN format The creation of a new message basically consists of creating an MT object for the specific message type, and the subsequent addition of fields in an orderly manner. The order of the fields is very important and should be done accordingly to the standard, the model does not prevent creating incorrect content (Standard compliance validation can be checked with Prowide Integrator). The following sections provides explanation by examples, creating messages in different common scenarios:","title":"MT Builder (Java to FIN MT)"},{"location":"open-source/core/mt-build/#creating-a-message-with-mt-classes","text":"The following example shows how to create a new MT103 message using the MT and Field helper classes. This is the easiest and recommended way to create a new message from scratch because the API will automatically fill mandatory header information with proper default values. The first step is to create the specific MT object and set its general attributes: final MT103 m = new MT103 (); m . setSender ( \"FOOSEDR0AXXX\" ); m . setReceiver ( \"FOORECV0XXXX\" ); In the above code you can use either a full logical terminal address as parameter (12 characters) or just a plain BIC code (8 or 11 characters) At this point all message blocks are initialized, and by default the message will be an outgoing message (input to SWIFT) with normal priority. The next step is adding the message fields. For simple fields the final value can be directly provided as a single String value, and for more complex fields with several subfields (components) the Field helper classes may be used. m . addField ( new Field20 ( \"REFERENCE\" )); m . addField ( new Field23B ( \"CRED\" )); Field32A f32A = new Field32A () . setDate ( Calendar . getInstance ()) . setCurrency ( \"EUR\" ) . setAmount ( \"1234567,89\" ); m . addField ( f32A ); Field50A f50A = new Field50A () . setAccount ( \"12345678901234567890\" ) . setBIC ( \"FOOBANKXXXXX\" ); m . addField ( f50A ); Field59 f59 = new Field59 () . setAccount ( \"12345678901234567890\" ) . setNameAndAddress ( \"JOE DOE\" ); m . addField ( f59 ); m . addField ( new Field71A ( \"OUR\" )); Finally the message() method converts the object into its SWIFT representation: System . out . println ( m . message ()); The output of the above example is: {1:F01FOOSEDR0AXXX0000000000}{2:IFOORECV0XXXXN}{4: :20:REFERENCE :23B:CRED :32A:1303EUR1234567,89 :50A:/12345678901234567890 FOOBANKXXXXX :59:/12345678901234567890 JOE DOE :71A:OUR -} Notice for instance how field 50A was serializing into a proper value including the slash prefix for the account number and the line feed between the account and the BIC code. /12345678901234567890 [CRLF] FOOBANKXXXXX The same procedure is used to create any type of message, changing the MT103 by any other available implementation.","title":"Creating a message with MT classes"},{"location":"open-source/core/mt-build/#creating-inner-sequences","text":"For more complex messages where fields must be contained in sequences (or sub blocks) some helper API is also provided by the message model. The following example shows how to append a General Information sequence A to an MT542: SequenceA A = MT542 . SequenceA . newInstance ( Field20C . tag ( \":SEME//2005071800000923\" ), Field23G . tag ( \"NEWM\" )); m . append ( A ); For boundary based sequences the opening and closing fields 16R and 16S will be automatically included. When the message is converted to FIN, the above sample code will generate the following SWIFT content: :16R:GENL :20C::SEME//2005071800000923 :23G:NEWM :16S:GENL Notice sequences should be appended in the correct order, as well as fields inside the sequence block. The API will not control the correctness of the content being generated. The main reason to use this helper sequences API is the constraint provided in the MTnnn classes where only the proper SequenceX inner classes will exist, this way you can rest assure that the appended sequences are part of the specific message type. Nested sequences can be also created with a similar API. The following example creates a complete MT517 with nested sequences A and A1: MT517 mt = new MT517 (). append ( MT517 . SequenceA . newInstance ( new SwiftTagListBlock () . append ( Field20C . tag ( \":SEME//2005071800000923\" )) . append ( Field23G . tag ( \"NEWM/CODU\" )) . append ( Field95P . tag ( \":AFFM//MGTCDE55\" )) . append ( MT517 . SequenceA1 . newInstance ( Field13A . tag ( \"LINK//515\" ), Field20C . tag ( \":RELA//FRTJ12CONF0002\" ))) . append ( MT517 . SequenceA1 . newInstance ( Field13A . tag ( \"LINK//512\" ), Field20C . tag (: RELA //FRTJ12CONF0003))) ) ); Notice how in order to append both Field and sequence objects to the container A sequence, we create a generic SwiftTagListBlock on the fly. The created FIN content for the above snippet is: {1:F01TESTUS00AXXX0000000000}{2:I517TESTUS00XXXXN}{4: :16R:GENL :20C::SEME//2005071800000923 :23G:NEWM/CODU :95P::AFFM//MGTCDE55 :16R:LINK :13A:LINK//515 :20C::RELA//FRTJ12CONF0002 :16S:LINK :16R:LINK :13A:LINK//512 :20C::RELA//FRTJ12CONF0003 :16S:LINK :16S:GENL -}","title":"Creating inner sequences"},{"location":"open-source/core/mt-build/#creating-a-message-with-specific-header-content","text":"To create headers with special information, the block's API can be accessed directly. The following example illustrates how to create a message using the low level model layer to create specific headers, overriding the ones created by default in the MT103 constructor. MT103 m = new MT103 (); SwiftBlock1 b1 = new SwiftBlock1 (); b1 . setApplicationId ( \"F\" ); b1 . setServiceId ( \"01\" ); b1 . setLogicalTerminal ( \"BICFOOYYAXXX\" ); b1 . setSessionNumber ( \"1234\" ); b1 . setSequenceNumber ( \"123456\" ); m . getSwiftMessage (). setBlock1 ( b1 ); SwiftBlock2Input b2 = new SwiftBlock2Input (); b2 . setMessageType ( \"103\" ); b2 . setReceiverAddress ( \"BICFOARXXXXX\" ); b2 . setDeliveryMonitoring ( \"1\" ); m . getSwiftMessage (). setBlock2 ( b2 ); m . getSwiftMessage (). setBlock3 ( new SwiftBlock3 ()); m . getSwiftMessage (). getBlock3 (). addTag ( Field113 . tag ( \"NOMT\" )); m . getSwiftMessage (). getBlock3 (). addTag ( Field108 . tag ( \"P22ABCD43C6J3XYZ\" )); In the above example a new and empty message object is created. The basic header (block 1) information is set with specific information, the application header (block 2) is created directly from a suitable string value with all its corresponding attributes pre set, and final an optional user header (block 3) is constructed by adding its tags. Since the MTnnn classes uses a SwiftMessage instance inside, both level API can be combined; the MTnnn and Fieldnnn classes can be use to create the main content of the message and then the SwiftMessage object can be accessed to add or change specific header or trailer information.","title":"Creating a message with specific header content"},{"location":"open-source/core/mt-build/#adding-a-message-trailer-block","text":"In most situations there is no need to create the trailer block because it will be added automatically by the FIN interface. However, the API allows the creation of the trailer block as well as any other optional message block as follows: MT103 m = new MT103 (); SwiftBlock5 block5 = new SwiftBlock5 (); block5 . addTag ( new Tag ( \"MAC\" , \"00000000\" )); block5 . addTag ( new Tag ( \"PDE\" , \"\" )); m . getSwiftMessage (). addBlock ( block5 ); The resulting block when the object is serialized to FIN will be: {5:{MAC:00000000}{PDE:}}","title":"Adding a message trailer block"},{"location":"open-source/core/mt-build/#adding-optional-blocks","text":"Analogously to the description for Block 5, the same API can be used to create the optional User Header Block (block 3) or to add additional trailers. In particular for the block 3, a SwiftBlock3Builder helper class was introduced to ensure only valid fields are added to the block, and that fields are added in proper order. For backward compatibility we have kept the SwiftBlock3 structure which is a List but the new builder provides specific setters for each available block 3 field. The builder instance is created directly from the block and works as a decorator on the underlying list of tags. SwiftBlock3 b = new SwiftBlock3 (); b . builder () . setField121 ( new Field121 ( \"value121\" )) . setField106 ( new Field106 ( \"value106\" )) . setField165 ( new Field165 ( \"value165\" )) . setField106 ( new Field106 ( \"finalValue106\" )) . setField108 ( new Field108 ( \"value108\" )); Regardless of the setField calls order or repetition, the internal block 3 will be always consistent, and in the above example will produce this output: {3:{108:value108}{106:finalValue106}{121:value121}{165:value165}} The same applies when the message is created with an MT class. For instance if you need to add the MUR field 108 you can use the following: MT103_STP mt = new MT103_STP ( sender , receiver ); mt . getSwiftMessage (). getSwiftBlock3 (). builder (). setField108 ( value108 ); And the output will be: {3:{108:value108}{119:STP}{121:value121}} Notice, fields 119 and 121 were automatically added when the MT instance was created, and the manually added field 108 was placed in the correct position in the existing block 3. Finally this examples appends an optional application trailer block: SwiftBlockUser blockUser = new SwiftBlockUser ( \"S\" ); blockUser . addTag ( new Tag ( \"SAC\" , \"\" )); blockUser . addTag ( new Tag ( \"COP\" , \"P\" )); m . getSwiftMessage (). addBlock ( blockUser );","title":"Adding optional blocks"},{"location":"open-source/core/mt-json/","text":"MT-JSON Conversion Back and forth conversion between MT messages and JSON Different JSON structures are created depending on the model object where the toJson is invoked. SwiftMessage JSON When SwiftMessage#toJson() in the backbone model is used, the generated JSON contains a generic structure with plain name/value tuples for the text block as in the example below. { \"version\" : 1 , \"timestamp\" : ' 2017-06-05 04 : 32 -0300 ' , \"data\" : { \"block1\" : { \"applicationId\" : \"F\" , \"serviceId\" : \"01\" , \"logicalTerminal\" : \"BICFOOYYAXXX\" , \"sessionNumber\" : \"8683\" , \"sequenceNumber\" : \"497519\" } , \"block2\" : { \"messageType\" : \"103\" , \"senderInputTime\" : \"1535\" , \"MIRDate\" : \"051028\" , \"MIRLogicalTerminal\" : \"ESPBESMMAXXX\" , \"MIRSessionNumber\" : \"5423\" , \"MIRSequenceNumber\" : \"752247\" , \"receiverOutputDate\" : \"051028\" , \"receiverOutputTime\" : \"1535\" , \"messagePriority\" : \"N\" } , \"block4\" : [ { \"20\" : \"0061350113089908\" }, { \"13C\" : \"/RNCTIME/1534+0000\" }, (...) { \"72\" : \"/BNF/TRANSF. BCO. FOO\" } ] } } AbstractMT JSON If the message is parsed into the AbstractMT using AbstractMT#parse or by creating any of the subclasses such as the MT103 , then a call to toJson() generates a similar structure, but for the text block each field is serialized into a specific structure. { \"type\" : \"MT\" , \"basicHeaderBlock\" : { \"applicationId\" : \"F\" , \"serviceId\" : \"01\" , \"logicalTerminal\" : \"AAAABEBBAXXX\" , \"sessionNumber\" : \"0001\" , \"sequenceNumber\" : \"000001\" }, \"applicationHeaderBlock\" : { \"receiverAddress\" : \"BBBBBEBBXBIL\" , \"messagePriority\" : \"N\" , \"messageType\" : \"565\" , \"blockType\" : \"I\" , \"direction\" : \"I\" }, \"userHeaderBlock\" : { \"fields\" : [ { \"name\" : \"108\" , \"mUR\" : \"495\" } ] }, \"textBlock\" : { \"fields\" : [ { \"name\" : \"16R\" , \"blockName\" : \"GENL\" }, { \"name\" : \"20C\" , \"qualifier\" : \"CORP\" , \"reference\" : \"ABCD1234\" }, { \"name\" : \"20C\" , \"qualifier\" : \"SEME\" , \"reference\" : \"123456789124001\" }, { \"name\" : \"23G\" , \"function\" : \"NEWM\" }, { \"name\" : \"22F\" , \"qualifier\" : \"CAEV\" , \"indicator\" : \"CONV\" }, { \"name\" : \"98C\" , \"qualifier\" : \"PREP\" , \"date\" : \"20210912\" , \"time\" : \"123111\" }, { \"name\" : \"16R\" , \"blockName\" : \"LINK\" }, { \"name\" : \"22F\" , \"qualifier\" : \"LINK\" , \"indicator\" : \"INFO\" }, { \"name\" : \"13A\" , \"qualifier\" : \"LINK\" , \"numberId\" : \"564\" }, { \"name\" : \"20C\" , \"qualifier\" : \"RELA\" , \"reference\" : \"NONREF\" }, { \"name\" : \"16S\" , \"blockName\" : \"LINK\" }, { \"name\" : \"16S\" , \"blockName\" : \"GENL\" }, { \"name\" : \"16R\" , \"blockName\" : \"CAINST\" }, { \"name\" : \"13A\" , \"qualifier\" : \"CAON\" , \"numberId\" : \"002\" }, { \"name\" : \"22F\" , \"qualifier\" : \"CAOP\" , \"indicator\" : \"CONY\" }, { \"name\" : \"35B\" , \"qualifier\" : \"ISIN\" , \"iSIN\" : \"LU0123456789\" , \"description\" : \"ABCD CORP ORD SHS\" }, { \"name\" : \"36B\" , \"qualifier\" : \"QINS\" , \"quantityTypeCode\" : \"FAMT\" , \"quantity\" : \"50000,\" }, { \"name\" : \"16S\" , \"blockName\" : \"CAINST\" } ] } } NarrativeContainer fields JSON When serializing the field into its specific structure, Field#toJson() in the backbone model is used, there is a special treatment if the field is a NarrativeContainer . These fields support having a simple unstructured content split in lines and also a structured version with codewords. The codewords are separated with slashes and can be used to categorize part of the narrative content. When the structured option is used, different line formats are supported depending on the actual field. In most of the fields the only element in the structured format is the actual text. Some fields can include bank code, currency and amount, country codes or the narrative partitioned as a main narrative and a supplement. Supported line formats are: Format 1 Line 1: /8a/[additional information] (Code)(Narrative) Lines 2-n: /8a/[additional information] (Code)(Narrative) or [//continuation of additional information] (Narrative) Format 2 Line 1: /8c/[additional information] (Code)(Narrative) Lines 2-n: /8c/[additional information] (Code)(Narrative) or [//continuation of additional information] (Narrative) Format 3 Line 1: /8c/[3!a13d][additional information] (Code)(Currency)(Amount)(Narrative) Lines 2-6: /8c/[3!a13d][additional information] (Code)(Currency)(Amount)(Narrative) or [//continuation of additional information] (Narrative) Format 4 Line 1: /8c/[additional information] (Code)(Narrative) Lines 2-3: [//continuation of additional information] (Narrative) Variant for cat 1 with country Line 1: /8c/2!a[//additional information] (Code)(Country)(Narrative) Lines 2-3: [//continuation of additional information] (Narrative) Format 5 Line 1: /2n/[supplement 1][/supplement2] (Query Number)(Narrative 1)(Narrative 2) Lines 2-6: /2n/[supplement 1][/supplement2] or [//continuation of supplementary information] Format 6 Line 1: /6c/[additional information] (Code)(Narrative) Lines 2-100: /6c/[additional information] (Code)(Narrative) or [continuation of additional information] (Narrative) (cannot start with slash) Format 7 Code between slashes at the beginning of a line Format 8 Free format codes in slashes, not necessary on new lines Thus the JSON conversion, will include both the plain narrative lines, and also the result of serializing into JSON the same content parsed into Narrative model, returning for example this JSON content: { \"name\" : \"71B\" , \"narrative\" : \"/WITX/CAPITAL GAINS TAX RELATING TO\\n//THE PERIOD 1999-01-01 2022-10-30\\n//REF 009524780123\\n//BANCA DEL TEST\\n//(REF. ART. 6 DL 461/97)\" , \"structured\" :[ { \"narrativeFragments\" :[ \"CAPITAL GAINS TAX RELATING TO\" , \"THE PERIOD 1999-01-01 2022-10-30\" , \"REF 009524780123\" , \"BANCA DEL TEST\" , \"(REF. ART. 6 DL 461/97)\" ], \"narrativeSupplementFragments\" :[], \"codeword\" : \"WITX\" } ], \"unstructuredFragments\" :[] } As for the reverse conversion, the from JSON method can consume either the plain narrative line elements or the structured narrative elements. Meaning the reverse can consume also a JSON with this structure: { \"name\" : \"71B\" , \"narrative\" : \"/WITX/CAPITAL GAINS TAX RELATING TO\\n//THE PERIOD 1999-01-01 2022-10-30\\n//REF 009524780123\\n//BANCA DEL TEST\\n//(REF. ART. 6 DL 461/97)\" , } And also this other version, producing the same Field71B instance: { \"name\" : \"71B\" , \"structured\" :[ { \"narrativeFragments\" :[ \"CAPITAL GAINS TAX RELATING TO\" , \"THE PERIOD 1999-01-01 2022-10-30\" , \"REF 009524780123\" , \"BANCA DEL TEST\" , \"(REF. ART. 6 DL 461/97)\" ], \"narrativeSupplementFragments\" :[], \"codeword\" : \"WITX\" } ], \"unstructuredFragments\" :[] } Finally for backward compatibility, the JSON unmarshaller can also consume a JSON with the plain narrative lines split into individual elements such as: { \"name\" : \"71B\" , \"narrative\" : \"/WITX/CAPITAL GAINS TAX RELATING TO\" , \"narrative2\" : \"//THE PERIOD 1999-01-01 2022-10-30\" , \"narrative3\" : \"//REF 009524780123\" , \"narrative4\" : \"//BANCA DEL TEST\" , \"narrative\" : \"//(REF. ART. 6 DL 461/97)\" } MtSwiftMessage JSON Finally, there also exists yet another JSON structure if serialization is done using the persistence model MtSwiftMessage. Given the following message content: {1:F01AAAAUSC0ADDD0344000050}{2:I103BBBBUSC0XFFFN}{4: :20:TBEXO200909031 :23B:CRED :32A:090903USD23453, :50K:/01111001759234567890 JOE DOE R00000V0574734 :53B:/00010013800002001234 MI BANCO :59:/00013500510020179998 FOO CORP R00000V000034534 :71A:OUR :72:/TIPO/422 -}{5:{PDE:FOO}} If the message is parsed into an MtSwiftMessage model structure, and some status info and message notes are added, the JSON representation would be like this: { \"pde\" : \"FOO\" , \"uuid\" : \"IBBBBUSC0FFF103TBEXO200909031\" , \"identifier\" : \"fin.103\" , \"sender\" : \"AAAAUSC0DDD\" , \"receiver\" : \"BBBBUSC0FFF\" , \"message\" : \"{1:F01AAAAUSC0ADDD0344000050}{2:I103BBBBUSC0XFFFN}{4:\\n:20:TBEXO200909031\\n:23B:CRED\\n:32A:090903USD23453,\\n:50K:/01111001759234567890\\nJOE DOE\\nR00000V0574734\\n:53B:/00010013800002001234\\nMI BANCO\\n:59:/00013500510020179998\\nFOO CORP\\nR00000V000034534\\n:71A:OUR\\n:72:/TIPO/422\\n-}{5:{PDE:FOO}}\" , \"direction\" : \"outgoing\" , \"checksum\" : \"5c15a3803c4d91d7241534b01a9cf624\" , \"checksumBody\" : \"d4e96cd0c1684cfc218089875d64187b\" , \"lastModified\" : { \"year\" : 2022 , \"month\" : 10 , \"dayOfMonth\" : 17 , \"hourOfDay\" : 14 , \"minute\" : 36 , \"second\" : 28 }, \"creationDate\" : { \"year\" : 2022 , \"month\" : 10 , \"dayOfMonth\" : 17 , \"hourOfDay\" : 14 , \"minute\" : 36 , \"second\" : 27 }, \"statusTrail\" : [ { \"name\" : \"name\" , \"comments\" : \"comments\" , \"creationDate\" : { \"year\" : 2022 , \"month\" : 10 , \"dayOfMonth\" : 17 , \"hourOfDay\" : 14 , \"minute\" : 36 , \"second\" : 28 }, \"creationUser\" : \"creationUser\" , \"data\" : \"data\" } ], \"notes\" : [ { \"creationDate\" : { \"year\" : 2022 , \"month\" : 10 , \"dayOfMonth\" : 17 , \"hourOfDay\" : 14 , \"minute\" : 36 , \"second\" : 28 }, \"creationUser\" : \"creationUser\" , \"text\" : \"text\" } ], \"properties\" : { }, \"fileFormat\" : \"FIN\" , \"reference\" : \"TBEXO200909031\" , \"currency\" : \"USD\" , \"amount\" : 23453 , \"revisions\" : [ ], \"valueDate\" : { \"year\" : 2009 , \"month\" : 8 , \"dayOfMonth\" : 3 , \"hourOfDay\" : 0 , \"minute\" : 0 , \"second\" : 0 } }","title":"MT-JSON Conversion"},{"location":"open-source/core/mt-json/#mt-json-conversion","text":"Back and forth conversion between MT messages and JSON Different JSON structures are created depending on the model object where the toJson is invoked.","title":"MT-JSON Conversion"},{"location":"open-source/core/mt-json/#swiftmessage-json","text":"When SwiftMessage#toJson() in the backbone model is used, the generated JSON contains a generic structure with plain name/value tuples for the text block as in the example below. { \"version\" : 1 , \"timestamp\" : ' 2017-06-05 04 : 32 -0300 ' , \"data\" : { \"block1\" : { \"applicationId\" : \"F\" , \"serviceId\" : \"01\" , \"logicalTerminal\" : \"BICFOOYYAXXX\" , \"sessionNumber\" : \"8683\" , \"sequenceNumber\" : \"497519\" } , \"block2\" : { \"messageType\" : \"103\" , \"senderInputTime\" : \"1535\" , \"MIRDate\" : \"051028\" , \"MIRLogicalTerminal\" : \"ESPBESMMAXXX\" , \"MIRSessionNumber\" : \"5423\" , \"MIRSequenceNumber\" : \"752247\" , \"receiverOutputDate\" : \"051028\" , \"receiverOutputTime\" : \"1535\" , \"messagePriority\" : \"N\" } , \"block4\" : [ { \"20\" : \"0061350113089908\" }, { \"13C\" : \"/RNCTIME/1534+0000\" }, (...) { \"72\" : \"/BNF/TRANSF. BCO. FOO\" } ] } }","title":"SwiftMessage JSON"},{"location":"open-source/core/mt-json/#abstractmt-json","text":"If the message is parsed into the AbstractMT using AbstractMT#parse or by creating any of the subclasses such as the MT103 , then a call to toJson() generates a similar structure, but for the text block each field is serialized into a specific structure. { \"type\" : \"MT\" , \"basicHeaderBlock\" : { \"applicationId\" : \"F\" , \"serviceId\" : \"01\" , \"logicalTerminal\" : \"AAAABEBBAXXX\" , \"sessionNumber\" : \"0001\" , \"sequenceNumber\" : \"000001\" }, \"applicationHeaderBlock\" : { \"receiverAddress\" : \"BBBBBEBBXBIL\" , \"messagePriority\" : \"N\" , \"messageType\" : \"565\" , \"blockType\" : \"I\" , \"direction\" : \"I\" }, \"userHeaderBlock\" : { \"fields\" : [ { \"name\" : \"108\" , \"mUR\" : \"495\" } ] }, \"textBlock\" : { \"fields\" : [ { \"name\" : \"16R\" , \"blockName\" : \"GENL\" }, { \"name\" : \"20C\" , \"qualifier\" : \"CORP\" , \"reference\" : \"ABCD1234\" }, { \"name\" : \"20C\" , \"qualifier\" : \"SEME\" , \"reference\" : \"123456789124001\" }, { \"name\" : \"23G\" , \"function\" : \"NEWM\" }, { \"name\" : \"22F\" , \"qualifier\" : \"CAEV\" , \"indicator\" : \"CONV\" }, { \"name\" : \"98C\" , \"qualifier\" : \"PREP\" , \"date\" : \"20210912\" , \"time\" : \"123111\" }, { \"name\" : \"16R\" , \"blockName\" : \"LINK\" }, { \"name\" : \"22F\" , \"qualifier\" : \"LINK\" , \"indicator\" : \"INFO\" }, { \"name\" : \"13A\" , \"qualifier\" : \"LINK\" , \"numberId\" : \"564\" }, { \"name\" : \"20C\" , \"qualifier\" : \"RELA\" , \"reference\" : \"NONREF\" }, { \"name\" : \"16S\" , \"blockName\" : \"LINK\" }, { \"name\" : \"16S\" , \"blockName\" : \"GENL\" }, { \"name\" : \"16R\" , \"blockName\" : \"CAINST\" }, { \"name\" : \"13A\" , \"qualifier\" : \"CAON\" , \"numberId\" : \"002\" }, { \"name\" : \"22F\" , \"qualifier\" : \"CAOP\" , \"indicator\" : \"CONY\" }, { \"name\" : \"35B\" , \"qualifier\" : \"ISIN\" , \"iSIN\" : \"LU0123456789\" , \"description\" : \"ABCD CORP ORD SHS\" }, { \"name\" : \"36B\" , \"qualifier\" : \"QINS\" , \"quantityTypeCode\" : \"FAMT\" , \"quantity\" : \"50000,\" }, { \"name\" : \"16S\" , \"blockName\" : \"CAINST\" } ] } }","title":"AbstractMT JSON"},{"location":"open-source/core/mt-json/#narrativecontainer-fields-json","text":"When serializing the field into its specific structure, Field#toJson() in the backbone model is used, there is a special treatment if the field is a NarrativeContainer . These fields support having a simple unstructured content split in lines and also a structured version with codewords. The codewords are separated with slashes and can be used to categorize part of the narrative content. When the structured option is used, different line formats are supported depending on the actual field. In most of the fields the only element in the structured format is the actual text. Some fields can include bank code, currency and amount, country codes or the narrative partitioned as a main narrative and a supplement. Supported line formats are: Format 1 Line 1: /8a/[additional information] (Code)(Narrative) Lines 2-n: /8a/[additional information] (Code)(Narrative) or [//continuation of additional information] (Narrative) Format 2 Line 1: /8c/[additional information] (Code)(Narrative) Lines 2-n: /8c/[additional information] (Code)(Narrative) or [//continuation of additional information] (Narrative) Format 3 Line 1: /8c/[3!a13d][additional information] (Code)(Currency)(Amount)(Narrative) Lines 2-6: /8c/[3!a13d][additional information] (Code)(Currency)(Amount)(Narrative) or [//continuation of additional information] (Narrative) Format 4 Line 1: /8c/[additional information] (Code)(Narrative) Lines 2-3: [//continuation of additional information] (Narrative) Variant for cat 1 with country Line 1: /8c/2!a[//additional information] (Code)(Country)(Narrative) Lines 2-3: [//continuation of additional information] (Narrative) Format 5 Line 1: /2n/[supplement 1][/supplement2] (Query Number)(Narrative 1)(Narrative 2) Lines 2-6: /2n/[supplement 1][/supplement2] or [//continuation of supplementary information] Format 6 Line 1: /6c/[additional information] (Code)(Narrative) Lines 2-100: /6c/[additional information] (Code)(Narrative) or [continuation of additional information] (Narrative) (cannot start with slash) Format 7 Code between slashes at the beginning of a line Format 8 Free format codes in slashes, not necessary on new lines Thus the JSON conversion, will include both the plain narrative lines, and also the result of serializing into JSON the same content parsed into Narrative model, returning for example this JSON content: { \"name\" : \"71B\" , \"narrative\" : \"/WITX/CAPITAL GAINS TAX RELATING TO\\n//THE PERIOD 1999-01-01 2022-10-30\\n//REF 009524780123\\n//BANCA DEL TEST\\n//(REF. ART. 6 DL 461/97)\" , \"structured\" :[ { \"narrativeFragments\" :[ \"CAPITAL GAINS TAX RELATING TO\" , \"THE PERIOD 1999-01-01 2022-10-30\" , \"REF 009524780123\" , \"BANCA DEL TEST\" , \"(REF. ART. 6 DL 461/97)\" ], \"narrativeSupplementFragments\" :[], \"codeword\" : \"WITX\" } ], \"unstructuredFragments\" :[] } As for the reverse conversion, the from JSON method can consume either the plain narrative line elements or the structured narrative elements. Meaning the reverse can consume also a JSON with this structure: { \"name\" : \"71B\" , \"narrative\" : \"/WITX/CAPITAL GAINS TAX RELATING TO\\n//THE PERIOD 1999-01-01 2022-10-30\\n//REF 009524780123\\n//BANCA DEL TEST\\n//(REF. ART. 6 DL 461/97)\" , } And also this other version, producing the same Field71B instance: { \"name\" : \"71B\" , \"structured\" :[ { \"narrativeFragments\" :[ \"CAPITAL GAINS TAX RELATING TO\" , \"THE PERIOD 1999-01-01 2022-10-30\" , \"REF 009524780123\" , \"BANCA DEL TEST\" , \"(REF. ART. 6 DL 461/97)\" ], \"narrativeSupplementFragments\" :[], \"codeword\" : \"WITX\" } ], \"unstructuredFragments\" :[] } Finally for backward compatibility, the JSON unmarshaller can also consume a JSON with the plain narrative lines split into individual elements such as: { \"name\" : \"71B\" , \"narrative\" : \"/WITX/CAPITAL GAINS TAX RELATING TO\" , \"narrative2\" : \"//THE PERIOD 1999-01-01 2022-10-30\" , \"narrative3\" : \"//REF 009524780123\" , \"narrative4\" : \"//BANCA DEL TEST\" , \"narrative\" : \"//(REF. ART. 6 DL 461/97)\" }","title":"NarrativeContainer fields JSON"},{"location":"open-source/core/mt-json/#mtswiftmessage-json","text":"Finally, there also exists yet another JSON structure if serialization is done using the persistence model MtSwiftMessage. Given the following message content: {1:F01AAAAUSC0ADDD0344000050}{2:I103BBBBUSC0XFFFN}{4: :20:TBEXO200909031 :23B:CRED :32A:090903USD23453, :50K:/01111001759234567890 JOE DOE R00000V0574734 :53B:/00010013800002001234 MI BANCO :59:/00013500510020179998 FOO CORP R00000V000034534 :71A:OUR :72:/TIPO/422 -}{5:{PDE:FOO}} If the message is parsed into an MtSwiftMessage model structure, and some status info and message notes are added, the JSON representation would be like this: { \"pde\" : \"FOO\" , \"uuid\" : \"IBBBBUSC0FFF103TBEXO200909031\" , \"identifier\" : \"fin.103\" , \"sender\" : \"AAAAUSC0DDD\" , \"receiver\" : \"BBBBUSC0FFF\" , \"message\" : \"{1:F01AAAAUSC0ADDD0344000050}{2:I103BBBBUSC0XFFFN}{4:\\n:20:TBEXO200909031\\n:23B:CRED\\n:32A:090903USD23453,\\n:50K:/01111001759234567890\\nJOE DOE\\nR00000V0574734\\n:53B:/00010013800002001234\\nMI BANCO\\n:59:/00013500510020179998\\nFOO CORP\\nR00000V000034534\\n:71A:OUR\\n:72:/TIPO/422\\n-}{5:{PDE:FOO}}\" , \"direction\" : \"outgoing\" , \"checksum\" : \"5c15a3803c4d91d7241534b01a9cf624\" , \"checksumBody\" : \"d4e96cd0c1684cfc218089875d64187b\" , \"lastModified\" : { \"year\" : 2022 , \"month\" : 10 , \"dayOfMonth\" : 17 , \"hourOfDay\" : 14 , \"minute\" : 36 , \"second\" : 28 }, \"creationDate\" : { \"year\" : 2022 , \"month\" : 10 , \"dayOfMonth\" : 17 , \"hourOfDay\" : 14 , \"minute\" : 36 , \"second\" : 27 }, \"statusTrail\" : [ { \"name\" : \"name\" , \"comments\" : \"comments\" , \"creationDate\" : { \"year\" : 2022 , \"month\" : 10 , \"dayOfMonth\" : 17 , \"hourOfDay\" : 14 , \"minute\" : 36 , \"second\" : 28 }, \"creationUser\" : \"creationUser\" , \"data\" : \"data\" } ], \"notes\" : [ { \"creationDate\" : { \"year\" : 2022 , \"month\" : 10 , \"dayOfMonth\" : 17 , \"hourOfDay\" : 14 , \"minute\" : 36 , \"second\" : 28 }, \"creationUser\" : \"creationUser\" , \"text\" : \"text\" } ], \"properties\" : { }, \"fileFormat\" : \"FIN\" , \"reference\" : \"TBEXO200909031\" , \"currency\" : \"USD\" , \"amount\" : 23453 , \"revisions\" : [ ], \"valueDate\" : { \"year\" : 2009 , \"month\" : 8 , \"dayOfMonth\" : 3 , \"hourOfDay\" : 0 , \"minute\" : 0 , \"second\" : 0 } }","title":"MtSwiftMessage JSON"},{"location":"open-source/core/mt-model/","text":"Java model for MT messages The message model for MT messages is a set of Java classes representing the structure and content of a SWIFT MT (ISO 15022) message. The message model is a central part of the library suited for message creation, parsing and persistence. It is designed in three layers of specific use; each provides a different level of abstraction. Persistence - Lightweight Layer The upper layer is a generic representation for all messages mainly intended for message persistence. The model includes specific attributes for header and trailer information, while the body content (business payload) is kept as a single String attribute (not parsed). Since this model is generic, message objects can be instantiated without prior knowledge of the specific type of message. This design is therefore optimal for database persistence because all message types can share a simple and efficient database structure. It can be thought of as a wrapper of a swift message file. Besides message content, the model provides several metadata containers very useful for a message management application, such as a holder for message status, attached notes and extendable properties. The main classes for this layer are the AbstractSwiftMessage and MtSwiftMessage . Parse/Build - Functional Layer The middle layer is a functional view of a specific message, for example an MT103 . The provided API allows you to read data from a known message easily, as well as API to build new messages. This layer provides a specific class for each message type, with getters for its inner sequences and fields. Also a specific class for each possible field of the message, for example Field32A , with methods to retrieve any internal component (subfield), for example the Calendar , Currency and Amount of Field32A . These specific classes can be thought of as a facade or view of the internal message content. The entry point for this layer is the AbstractMT and all its subclasses that represent a specific message type. Notice these objects are not intended for message modification because when you read content with a getFieldNN the returned object is detached from the underlying model. Details on how to modify a message are described later in this document. NarrativeContainer fields Some fields, such as Field71B , implements the NarrativeContainer interface and provide methods to access the narrative content in a structured way. These fields support having a simple unstructured content split in lines and also a structured version with codewords. Where the codewords are separated with slashes and can be used to categorize part of the narrative content. The internal component structure for these fields is just a plain single String with the whole value. But the structured content can be retrieve using: Narrative narrative = f . narrative (); Where the Narrative object provides methods to access the different parts of the narrative by the codewords. The NarrativeResolver parser can automatically detect the narrative structure and create the Narrative depending on the field value. In most of the fields the only element in the structured format is the actual text. however, some fields can include bank code, currency and amount, country codes or the narrative partitioned as a main narrative and a supplement fragments. Supported line formats are: Format 1 Line 1: /8a/[additional information] (Code)(Narrative) Lines 2-n: /8a/[additional information] (Code)(Narrative) or [//continuation of additional information] (Narrative) Format 2 Line 1: /8c/[additional information] (Code)(Narrative) Lines 2-n: /8c/[additional information] (Code)(Narrative) or [//continuation of additional information] (Narrative) Format 3 Line 1: /8c/[3!a13d][additional information] (Code)(Currency)(Amount)(Narrative) Lines 2-6: /8c/[3!a13d][additional information] (Code)(Currency)(Amount)(Narrative) or [//continuation of additional information] (Narrative) Format 4 Line 1: /8c/[additional information] (Code)(Narrative) Lines 2-3: [//continuation of additional information] (Narrative) Variant for cat 1 with country Line 1: /8c/2!a[//additional information] (Code)(Country)(Narrative) Lines 2-3: [//continuation of additional information] (Narrative) Format 5 Line 1: /2n/[supplement 1][/supplement2] (Query Number)(Narrative 1)(Narrative 2) Lines 2-6: /2n/[supplement 1][/supplement2] or [//continuation of supplementary information] Format 6 Line 1: /6c/[additional information] (Code)(Narrative) Lines 2-100: /6c/[additional information] (Code)(Narrative) or [continuation of additional information] (Narrative) (cannot start with slash) Format 7 Code between slashes at the beginning of a line Format 8 Free format codes in slashes, not necessary on new lines The same Narrative model can be used to create this fields content when building messages from scratch. Backbone - Structure Layer The lower layer is the internal backbone of the upper one, and in most cases there is no need to use this API from an application. The message representation at this level handles the message content as simple tuples of field name and field value and implements low level handling of sequences and blocks. This model is quite simple, generic and loosely coupled to specific messages, therefore being very efficient and requiring minimal construction constraints. Messages in this layer are represented by the SwiftMessage class, with its internal name-value tuples modeled by the Tag class. This layer is also the one used for content modification.","title":"Domain model"},{"location":"open-source/core/mt-model/#java-model-for-mt-messages","text":"The message model for MT messages is a set of Java classes representing the structure and content of a SWIFT MT (ISO 15022) message. The message model is a central part of the library suited for message creation, parsing and persistence. It is designed in three layers of specific use; each provides a different level of abstraction.","title":"Java model for MT messages"},{"location":"open-source/core/mt-model/#persistence-lightweight-layer","text":"The upper layer is a generic representation for all messages mainly intended for message persistence. The model includes specific attributes for header and trailer information, while the body content (business payload) is kept as a single String attribute (not parsed). Since this model is generic, message objects can be instantiated without prior knowledge of the specific type of message. This design is therefore optimal for database persistence because all message types can share a simple and efficient database structure. It can be thought of as a wrapper of a swift message file. Besides message content, the model provides several metadata containers very useful for a message management application, such as a holder for message status, attached notes and extendable properties. The main classes for this layer are the AbstractSwiftMessage and MtSwiftMessage .","title":"Persistence - Lightweight Layer"},{"location":"open-source/core/mt-model/#parsebuild-functional-layer","text":"The middle layer is a functional view of a specific message, for example an MT103 . The provided API allows you to read data from a known message easily, as well as API to build new messages. This layer provides a specific class for each message type, with getters for its inner sequences and fields. Also a specific class for each possible field of the message, for example Field32A , with methods to retrieve any internal component (subfield), for example the Calendar , Currency and Amount of Field32A . These specific classes can be thought of as a facade or view of the internal message content. The entry point for this layer is the AbstractMT and all its subclasses that represent a specific message type. Notice these objects are not intended for message modification because when you read content with a getFieldNN the returned object is detached from the underlying model. Details on how to modify a message are described later in this document.","title":"Parse/Build - Functional Layer"},{"location":"open-source/core/mt-model/#narrativecontainer-fields","text":"Some fields, such as Field71B , implements the NarrativeContainer interface and provide methods to access the narrative content in a structured way. These fields support having a simple unstructured content split in lines and also a structured version with codewords. Where the codewords are separated with slashes and can be used to categorize part of the narrative content. The internal component structure for these fields is just a plain single String with the whole value. But the structured content can be retrieve using: Narrative narrative = f . narrative (); Where the Narrative object provides methods to access the different parts of the narrative by the codewords. The NarrativeResolver parser can automatically detect the narrative structure and create the Narrative depending on the field value. In most of the fields the only element in the structured format is the actual text. however, some fields can include bank code, currency and amount, country codes or the narrative partitioned as a main narrative and a supplement fragments. Supported line formats are: Format 1 Line 1: /8a/[additional information] (Code)(Narrative) Lines 2-n: /8a/[additional information] (Code)(Narrative) or [//continuation of additional information] (Narrative) Format 2 Line 1: /8c/[additional information] (Code)(Narrative) Lines 2-n: /8c/[additional information] (Code)(Narrative) or [//continuation of additional information] (Narrative) Format 3 Line 1: /8c/[3!a13d][additional information] (Code)(Currency)(Amount)(Narrative) Lines 2-6: /8c/[3!a13d][additional information] (Code)(Currency)(Amount)(Narrative) or [//continuation of additional information] (Narrative) Format 4 Line 1: /8c/[additional information] (Code)(Narrative) Lines 2-3: [//continuation of additional information] (Narrative) Variant for cat 1 with country Line 1: /8c/2!a[//additional information] (Code)(Country)(Narrative) Lines 2-3: [//continuation of additional information] (Narrative) Format 5 Line 1: /2n/[supplement 1][/supplement2] (Query Number)(Narrative 1)(Narrative 2) Lines 2-6: /2n/[supplement 1][/supplement2] or [//continuation of supplementary information] Format 6 Line 1: /6c/[additional information] (Code)(Narrative) Lines 2-100: /6c/[additional information] (Code)(Narrative) or [continuation of additional information] (Narrative) (cannot start with slash) Format 7 Code between slashes at the beginning of a line Format 8 Free format codes in slashes, not necessary on new lines The same Narrative model can be used to create this fields content when building messages from scratch.","title":"NarrativeContainer fields"},{"location":"open-source/core/mt-model/#backbone-structure-layer","text":"The lower layer is the internal backbone of the upper one, and in most cases there is no need to use this API from an application. The message representation at this level handles the message content as simple tuples of field name and field value and implements low level handling of sequences and blocks. This model is quite simple, generic and loosely coupled to specific messages, therefore being very efficient and requiring minimal construction constraints. Messages in this layer are represented by the SwiftMessage class, with its internal name-value tuples modeled by the Tag class. This layer is also the one used for content modification.","title":"Backbone - Structure Layer"},{"location":"open-source/core/mt-modify/","text":"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 . 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\" ))","title":"MT content modification"},{"location":"open-source/core/mt-modify/#mt-content-modification","text":"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.","title":"MT content modification"},{"location":"open-source/core/mt-modify/#updating-a-field-value","text":"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.","title":"Updating a field value"},{"location":"open-source/core/mt-modify/#inserting-new-fields-in-mt-message","text":"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 . 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.","title":"Inserting new fields in MT message"},{"location":"open-source/core/mt-modify/#using-the-tag-index","text":"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","title":"Using the tag index"},{"location":"open-source/core/mt-modify/#using-the-swiftblock3builder","text":"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\" ))","title":"Using the SwiftBlock3Builder"},{"location":"open-source/core/mt-parser/","text":"Parser (FIN MT to Java) The parser provides functionality to convert SWIFT messages FIN text into the Java message model By doing this, you can work with SWIFT messages focusing on the data and not having to deal with low level syntax details. The parser always performs a best effort heuristic to parse the message even if it is not well formed. All the information is read and put in a suitable object of the message model regardless of the message being SWIFT compliant. The parser functionality has different entry point depending on the use case: Generic processing of unknown messages In situations where the message type is unknown, the easiest and recommended way to read and parse messages is by means of the abstract class AbstractMT. This class provides static methods to parse an unknown message from a String or InputStream . For example consider the following SWIFT message example: {1:F01BANKDEFMAXXX2039063581}{2:O1031609050901BANKDEFXAXXX89549829458949811609N}{4: :20:007505327853 :23B:CRED :32A:050902JPY3520000, :33B:JPY3520000, :50K:EUROXXXEI :52A:FEBXXXM1 :53A:MHCXXXJT :54A:FOOBICXX :59:/13212312 RECEIVER NAME S.A :70:FUTURES :71A:SHA :71F:EUR12,00 :71F:EUR2,34 -} Assuming the message is in a String variable \"fin\", the following code will parse the FIN message into a message object object, where several getters are available to read message header information. AbstractMT msg = AbstractMT . parse ( fin ); String sender = msg . getSender (); String type = msg . getMessageType (); Even though the message type is unknown the returned object will be parsed into its specific MTnnn model object. So once the message type is known a simple cast is enough to access detail information of the text block for reading or manipulating its content. In the example: System . out . println ( msg . getMessageType ()); if ( msg . isType ( 103 )) { MT103 mt = ( MT103 ) msg ; // print the message reference System . out . println ( \"Reference: \" + mt . getField20 (). getValue ()); // read components of a specific field Field32A f = mt . getField32A (); Calendar date = f . getComponent1AsCalendar (); Number amount = f . getComponent3AsNumber (); } Notice MTnnn classes provide API that is exclusively related to the fields that can be present in each message type. Parsing an unknown message for persistence While in the context of a parsing an unknown message, if the ultimate requirement is to read just headers information, persist the message into a database or to process large bursts of messages, the recommended way to read and parse messages is by means of the MtSwiftMessage class. This class also implements several ways to create the message instance from String , InputStream ; but only header information is read and the model is kept generic after the parse. Assuming the message is in a String or InputStream variable \"fin\" , the following code will parse the FIN message into a MtSwiftMessage object, and getters are used to access message header information. MtSwiftMessage msg = MtSwftMessage . parse ( fin ); String sender = msg . getSender (); String type = msg . getMessageType (); The MtSwiftMessage is a lightweight representation of the message where only the header and trailer blocks are parsed and modeled, while the text block (the actual business payload) is kept in its raw unparsed format. Specializing an unkown message The above way of reading messages is the most efficient in terms of performance and it is useful to process large burst of messages; but it is limited for content manipulation. However, once the message object is created and properly identified, it can be specialize to access the specific text block content, for example: MT103 mt = new MT103 ( msg ); Field32A f = mt . getField32A (); Calendar date = f . getComponent1AsCalendar (); Number amount = f . getComponent3AsNumber (); Notice that specializing a generic message from an AbstractMT requires only a cast to the specific MTnnn , while doing the same from an MtSwiftMessage requires a constructor. Another important thing to know when deciding to use the AbstractMT or the MtSwiftMessage is that parsing by an AbstractMT implies that the message type can be determined from the block 2 header, that's because internally the parser will create the corresponding message type object ( MTnnn ). While parsing by an MtSwiftMessage does not impose anything to the message content, that could be malformed or incomplete and the message object will be created anyway. Specific processing of a known message type When the message to parse is known, the specific model class can be used directly to parse and read the content. For example: MT103 model = MT103 . parse ( fin ); Where the fin parameter can be a String or InputStream with the message in its FIN format, and the parsing can be called using the static parse method (as in the example) or by an MTnnn constructor. Once the object is created all its specific content can be read using getters for specific sequences and fields. Parsing message with ACK There is a frequent misunderstanding of the FIN messages format when the actual message is preceded by a system ACK, and the expected behavior of Prowide Core parser when reading such messages. The following example is actually a service message for ACK, followed by the original MT940 sent: {1:F21FOOLHKH0AXXX0304009999}{4:{177:1608140809}{451:0}}{1:F01FOOLHKH0AXXX0304009999}{2:O9401609160814FOOLHKH0AXXX03040027341608141609N}{4: :20:USD940NO1 :21:123456/DEV :25:USD234567 :28C:1/1 :60F:C160418USD672, :61:160827C642,S1032 :86:ANDY :61:160827D42,S1032 :86:BANK CHARGES :62F:C160418USD1872, :64:C160418USD1872, -}{5:{CHK:0FEC1E4AEC53}{TNG:}}{S:{COP:S}} If you pass the above content to the parse method, by default the parser will get the first FIN message found in the file (the ACK service message), leaving the rest of the text into the UnparsedTextList structure. This is just fine when reading plain user to user messages, but when the message is preceded by a service message as in the example, the resulting parsed object may not be the expected one. When dealing with this scenario it is the user responsibility to check whether the message is a service message or not, and proceed accordingly, depending on the particular use case and application needs. If you are trying to match and process the ACK/NAK notifications you may be interested on the service message. However, if this is the way you receive the messages from the SWIFT interface and you need the actual user message following the ACK, then you have to do something else. The following example will parse the FIN content, check for the service id, and if it is a system message it will then gather the actual MT from the unparsed content: SwiftMessage sm = SwiftMessage . parse ( fin ); if ( sm . isServiceMessage ()) { sm = SwiftMessage . parse ( sm . getUnparsedTexts (). getAsFINString ()); } At this point the sm variable will contain the actual user to user message, regardless if it was preceded by and ACK. For more information on the ACK/NAK structure see Processing ACK/NAK. Direct usage of the SwiftParser Finally, the actual parser implementation class is another option to translate a raw message in its Java model object. SwiftMessage m = ( new SwiftParser ()). parse ( fin ); Direct usage of the SwiftParser class is discouraged but in may be useful on certain conditions where the lenient mode of the parser must be explicitly controlled by your application. The result of the parser is the backbone model implemented by the SwiftMessage class. So the parser will basically split the message content into the three primary elements that defines an MT message; the message itself, it's blocks, and the tag (or fields) inside each block. Reading fields like simple tuples of name and value makes the parser very efficient, while additional content parsing can be done with the message model in a following step. For the example, the following code can be use to gather some fields of the parsed message using the generic low level model: String val32a = m . getBlock4 (). getTagValue ( \"32A\" ); //get a simple value tag String [] list71 = m . getBlock4 (). getTagValues ( \"71F\" ); //get a repeated value tag The \"val32a\" String will contain the value \"050902JPY3520000,\" and \"list71\" will contains a list of String with values \"EUR12,00\" and \"EUR2,34\". The SwiftBlock4 object basically contains an ordered List of fields found content body of the SWIFT message and provides several API to manipulate and get the tags individually or by sub blocks. At this API level the message body can be think of as a text string, where instead of characters we found message fields and we can get for example all Tags before a given one, Tags between boundaries, etc.. This API is the base foundation of the high level Sequences API.","title":"MT Parser (FIN MT to Java)"},{"location":"open-source/core/mt-parser/#parser-fin-mt-to-java","text":"The parser provides functionality to convert SWIFT messages FIN text into the Java message model By doing this, you can work with SWIFT messages focusing on the data and not having to deal with low level syntax details. The parser always performs a best effort heuristic to parse the message even if it is not well formed. All the information is read and put in a suitable object of the message model regardless of the message being SWIFT compliant. The parser functionality has different entry point depending on the use case:","title":"Parser (FIN MT to Java)"},{"location":"open-source/core/mt-parser/#generic-processing-of-unknown-messages","text":"In situations where the message type is unknown, the easiest and recommended way to read and parse messages is by means of the abstract class AbstractMT. This class provides static methods to parse an unknown message from a String or InputStream . For example consider the following SWIFT message example: {1:F01BANKDEFMAXXX2039063581}{2:O1031609050901BANKDEFXAXXX89549829458949811609N}{4: :20:007505327853 :23B:CRED :32A:050902JPY3520000, :33B:JPY3520000, :50K:EUROXXXEI :52A:FEBXXXM1 :53A:MHCXXXJT :54A:FOOBICXX :59:/13212312 RECEIVER NAME S.A :70:FUTURES :71A:SHA :71F:EUR12,00 :71F:EUR2,34 -} Assuming the message is in a String variable \"fin\", the following code will parse the FIN message into a message object object, where several getters are available to read message header information. AbstractMT msg = AbstractMT . parse ( fin ); String sender = msg . getSender (); String type = msg . getMessageType (); Even though the message type is unknown the returned object will be parsed into its specific MTnnn model object. So once the message type is known a simple cast is enough to access detail information of the text block for reading or manipulating its content. In the example: System . out . println ( msg . getMessageType ()); if ( msg . isType ( 103 )) { MT103 mt = ( MT103 ) msg ; // print the message reference System . out . println ( \"Reference: \" + mt . getField20 (). getValue ()); // read components of a specific field Field32A f = mt . getField32A (); Calendar date = f . getComponent1AsCalendar (); Number amount = f . getComponent3AsNumber (); } Notice MTnnn classes provide API that is exclusively related to the fields that can be present in each message type.","title":"Generic processing of unknown messages"},{"location":"open-source/core/mt-parser/#parsing-an-unknown-message-for-persistence","text":"While in the context of a parsing an unknown message, if the ultimate requirement is to read just headers information, persist the message into a database or to process large bursts of messages, the recommended way to read and parse messages is by means of the MtSwiftMessage class. This class also implements several ways to create the message instance from String , InputStream ; but only header information is read and the model is kept generic after the parse. Assuming the message is in a String or InputStream variable \"fin\" , the following code will parse the FIN message into a MtSwiftMessage object, and getters are used to access message header information. MtSwiftMessage msg = MtSwftMessage . parse ( fin ); String sender = msg . getSender (); String type = msg . getMessageType (); The MtSwiftMessage is a lightweight representation of the message where only the header and trailer blocks are parsed and modeled, while the text block (the actual business payload) is kept in its raw unparsed format.","title":"Parsing an unknown message for persistence"},{"location":"open-source/core/mt-parser/#specializing-an-unkown-message","text":"The above way of reading messages is the most efficient in terms of performance and it is useful to process large burst of messages; but it is limited for content manipulation. However, once the message object is created and properly identified, it can be specialize to access the specific text block content, for example: MT103 mt = new MT103 ( msg ); Field32A f = mt . getField32A (); Calendar date = f . getComponent1AsCalendar (); Number amount = f . getComponent3AsNumber (); Notice that specializing a generic message from an AbstractMT requires only a cast to the specific MTnnn , while doing the same from an MtSwiftMessage requires a constructor. Another important thing to know when deciding to use the AbstractMT or the MtSwiftMessage is that parsing by an AbstractMT implies that the message type can be determined from the block 2 header, that's because internally the parser will create the corresponding message type object ( MTnnn ). While parsing by an MtSwiftMessage does not impose anything to the message content, that could be malformed or incomplete and the message object will be created anyway.","title":"Specializing an unkown message"},{"location":"open-source/core/mt-parser/#specific-processing-of-a-known-message-type","text":"When the message to parse is known, the specific model class can be used directly to parse and read the content. For example: MT103 model = MT103 . parse ( fin ); Where the fin parameter can be a String or InputStream with the message in its FIN format, and the parsing can be called using the static parse method (as in the example) or by an MTnnn constructor. Once the object is created all its specific content can be read using getters for specific sequences and fields.","title":"Specific processing of a known message type"},{"location":"open-source/core/mt-parser/#parsing-message-with-ack","text":"There is a frequent misunderstanding of the FIN messages format when the actual message is preceded by a system ACK, and the expected behavior of Prowide Core parser when reading such messages. The following example is actually a service message for ACK, followed by the original MT940 sent: {1:F21FOOLHKH0AXXX0304009999}{4:{177:1608140809}{451:0}}{1:F01FOOLHKH0AXXX0304009999}{2:O9401609160814FOOLHKH0AXXX03040027341608141609N}{4: :20:USD940NO1 :21:123456/DEV :25:USD234567 :28C:1/1 :60F:C160418USD672, :61:160827C642,S1032 :86:ANDY :61:160827D42,S1032 :86:BANK CHARGES :62F:C160418USD1872, :64:C160418USD1872, -}{5:{CHK:0FEC1E4AEC53}{TNG:}}{S:{COP:S}} If you pass the above content to the parse method, by default the parser will get the first FIN message found in the file (the ACK service message), leaving the rest of the text into the UnparsedTextList structure. This is just fine when reading plain user to user messages, but when the message is preceded by a service message as in the example, the resulting parsed object may not be the expected one. When dealing with this scenario it is the user responsibility to check whether the message is a service message or not, and proceed accordingly, depending on the particular use case and application needs. If you are trying to match and process the ACK/NAK notifications you may be interested on the service message. However, if this is the way you receive the messages from the SWIFT interface and you need the actual user message following the ACK, then you have to do something else. The following example will parse the FIN content, check for the service id, and if it is a system message it will then gather the actual MT from the unparsed content: SwiftMessage sm = SwiftMessage . parse ( fin ); if ( sm . isServiceMessage ()) { sm = SwiftMessage . parse ( sm . getUnparsedTexts (). getAsFINString ()); } At this point the sm variable will contain the actual user to user message, regardless if it was preceded by and ACK. For more information on the ACK/NAK structure see Processing ACK/NAK.","title":"Parsing message with ACK"},{"location":"open-source/core/mt-parser/#direct-usage-of-the-swiftparser","text":"Finally, the actual parser implementation class is another option to translate a raw message in its Java model object. SwiftMessage m = ( new SwiftParser ()). parse ( fin ); Direct usage of the SwiftParser class is discouraged but in may be useful on certain conditions where the lenient mode of the parser must be explicitly controlled by your application. The result of the parser is the backbone model implemented by the SwiftMessage class. So the parser will basically split the message content into the three primary elements that defines an MT message; the message itself, it's blocks, and the tag (or fields) inside each block. Reading fields like simple tuples of name and value makes the parser very efficient, while additional content parsing can be done with the message model in a following step. For the example, the following code can be use to gather some fields of the parsed message using the generic low level model: String val32a = m . getBlock4 (). getTagValue ( \"32A\" ); //get a simple value tag String [] list71 = m . getBlock4 (). getTagValues ( \"71F\" ); //get a repeated value tag The \"val32a\" String will contain the value \"050902JPY3520000,\" and \"list71\" will contains a list of String with values \"EUR12,00\" and \"EUR2,34\". The SwiftBlock4 object basically contains an ordered List of fields found content body of the SWIFT message and provides several API to manipulate and get the tags individually or by sub blocks. At this API level the message body can be think of as a text string, where instead of characters we found message fields and we can get for example all Tags before a given one, Tags between boundaries, etc.. This API is the base foundation of the high level Sequences API.","title":"Direct usage of the SwiftParser"},{"location":"open-source/core/mt-rje/","text":"RJE Reader/Writer Reader and Writer for FIN MT bulk messages files in RJE and PPC formats RJE Reader/Writer The RJE, remote job entry, file format is a text file containing multiple FIN messages separated by the '$' symbol. The RJEReader and RJEWriter are used to read and write bulk files containing multiple FIN MT messages in RJE format with ease. The RJEReader can be used as an iterator to read the bulk file and access each of the individual messages. The reader can be initialized with a File , Stream or String and it implements the Iterable and Iterator Java interfaces to loop the found messages with ease. The messages can be retrieve in the plain FIN MT format and also parsed into MT objects. The RJEWriter can take a list of FIN MT message objects and create as output the RJE file. Messages are converted into its FIN representation and written into the output file with proper delimiters and length. The writer can be used in two different ways: Writing messages directly into given Writer object, using the static write call method. Instantiating the writer for a particular File or stream, calling the write methods and closing the writer when all messages has been written PPC Reader/Writer The DOS-PCC is a legacy FIN MT file format. The files can contain multiple messages, as in RJE, but in a more complex structure with specific binary separators and fixed length constraints. The PPCReader and PPCWriter are used to read and write bulk files containing multiple FIN MT messages in PPC format. The API is analogous to the one provided to read and write RJE files. Related API documentation can be found online at RJEReader, RJEWriter","title":"RJE Reader/Writer"},{"location":"open-source/core/mt-rje/#rje-readerwriter","text":"Reader and Writer for FIN MT bulk messages files in RJE and PPC formats","title":"RJE Reader/Writer"},{"location":"open-source/core/mt-rje/#rje-readerwriter_1","text":"The RJE, remote job entry, file format is a text file containing multiple FIN messages separated by the '$' symbol. The RJEReader and RJEWriter are used to read and write bulk files containing multiple FIN MT messages in RJE format with ease. The RJEReader can be used as an iterator to read the bulk file and access each of the individual messages. The reader can be initialized with a File , Stream or String and it implements the Iterable and Iterator Java interfaces to loop the found messages with ease. The messages can be retrieve in the plain FIN MT format and also parsed into MT objects. The RJEWriter can take a list of FIN MT message objects and create as output the RJE file. Messages are converted into its FIN representation and written into the output file with proper delimiters and length. The writer can be used in two different ways: Writing messages directly into given Writer object, using the static write call method. Instantiating the writer for a particular File or stream, calling the write methods and closing the writer when all messages has been written","title":"RJE Reader/Writer"},{"location":"open-source/core/mt-rje/#ppc-readerwriter","text":"The DOS-PCC is a legacy FIN MT file format. The files can contain multiple messages, as in RJE, but in a more complex structure with specific binary separators and fixed length constraints. The PPCReader and PPCWriter are used to read and write bulk files containing multiple FIN MT messages in PPC format. The API is analogous to the one provided to read and write RJE files. Related API documentation can be found online at RJEReader, RJEWriter","title":"PPC Reader/Writer"},{"location":"open-source/core/mt-xml/","text":"MT-XML Conversion Back and forth conversion between MT messages and proprietary XML For MT to MX (ISO 20022) standard translations please check the Prowide Integrator MT-MX Translations module. To facilitate integration with other platforms and systems, MT format can be converted to XML. This XML format is proprietary and not part of the SWIFT standard, and basically consists of a linear translation of the hierarchical structure of blocks and fields of an MT swift message to XML. The main entry point for this feature is the AbstractMT class (actually any of its subclasses, for example MT103 ) where a simple call to the xml() method will return the message content in XML. The following example illustrates the XML format for the message headers: F 01 BICFOOYYAXXX 8683 497519 103 1535 051028 ESPBESMMAXXX 5423 752247 051028 1535 N ... A similar serialization is performed for user and trailer blocks. For the message text block (block 4) two different XML formats are supported, each related to a model layer. The simpler one serializes fields as simple name-value tuples, and the enriched one serializes each field component in individual XML tags. For example a Field13C instance in the enriched version will be splitted as: 13C RNCTIME 1534 + 0000 While in the compressed format this will be just: 13C RNCTIME1534+0000 The xml() method mentioned will return the enriched version. Additional XML related features are contained in the ConversionService class. The analogous translation from this XML into a SWIFT message is provided there, as well the serialization into the comprised XML format. The parser implementation can seamlessly read both plain and enriched formats.","title":"MT-XML Conversion"},{"location":"open-source/core/mt-xml/#mt-xml-conversion","text":"Back and forth conversion between MT messages and proprietary XML For MT to MX (ISO 20022) standard translations please check the Prowide Integrator MT-MX Translations module. To facilitate integration with other platforms and systems, MT format can be converted to XML. This XML format is proprietary and not part of the SWIFT standard, and basically consists of a linear translation of the hierarchical structure of blocks and fields of an MT swift message to XML. The main entry point for this feature is the AbstractMT class (actually any of its subclasses, for example MT103 ) where a simple call to the xml() method will return the message content in XML. The following example illustrates the XML format for the message headers: F 01 BICFOOYYAXXX 8683 497519 103 1535 051028 ESPBESMMAXXX 5423 752247 051028 1535 N ... A similar serialization is performed for user and trailer blocks. For the message text block (block 4) two different XML formats are supported, each related to a model layer. The simpler one serializes fields as simple name-value tuples, and the enriched one serializes each field component in individual XML tags. For example a Field13C instance in the enriched version will be splitted as: 13C RNCTIME 1534 + 0000 While in the compressed format this will be just: 13C RNCTIME1534+0000 The xml() method mentioned will return the enriched version. Additional XML related features are contained in the ConversionService class. The analogous translation from this XML into a SWIFT message is provided there, as well the serialization into the comprised XML format. The parser implementation can seamlessly read both plain and enriched formats.","title":"MT-XML Conversion"},{"location":"open-source/core/safexmlutils/","text":"SafeXmlUtils SafeXmlUtils is a class used in our library, in projects like iso20022 and Integrator. This class provides mechanisms for creating secure XML parsers and transformers, focusing on mitigating XXE (XML External Entity) attacks. The features of SafeXmlUtils are dependent on the implementation of XML APIs and have known issues with various versions of Xerces and Xalan. If an error occurs due to a feature not present in the environment, you can examine the XML-related dependencies and replace those that do not support the necessary feature. Configuration for Ignoring Unsupported Features In situations where dependencies cannot be modified to support a required XML feature, SafeXmlUtils allows for the bypassing of unsupported features by adding a property file to the classpath. Configuration Steps: Property File: Create a file named pw-swift-core.properties and place it in the classpath of your project. Properties Definition: Define the property safeXmlUtils.ignore in this file. Assign to this property a comma-separated list of XML features that should be ignored by SafeXmlUtils . For example: safeXmlUtils.ignore=http://xml.org/sax/features/external-general-entities,http://apache.org/xml/features/disallow-doctype-decl By listing features in this property, SafeXmlUtils will skip them, thereby preventing exceptions related to these features not being available in the runtime environment. Implementation Details SafeXmlUtils includes several methods tailored to create various types of XML parsers and transformers with safety configurations. These methods apply or bypass specific XML features based on the project\u2019s environment and needs. Key methods include: documentBuilder(boolean namespaceAware): Configures a DocumentBuilder with safety features. reader(boolean namespaceAware, Schema schema): Creates a SAX parser with customized features. inputFactory(): Sets up a StAX parser with specific security settings. transformer(): Provides a Transformer with restricted access to external DTD and Stylesheets. schemaFactory(): Configures a SchemaFactory with limited external DTD access. validator(Schema schema): Creates a Validator with controlled access to external DTD and Schema. Each of these methods handles specific XML features like \"http://xml.org/sax/features/external-general-entities\", \"http://apache.org/xml/features/disallow-doctype-decl\", and others, ensuring that only secure and supported XML processing features are utilized.","title":"SafeXmlUtils"},{"location":"open-source/core/safexmlutils/#safexmlutils","text":"SafeXmlUtils is a class used in our library, in projects like iso20022 and Integrator. This class provides mechanisms for creating secure XML parsers and transformers, focusing on mitigating XXE (XML External Entity) attacks. The features of SafeXmlUtils are dependent on the implementation of XML APIs and have known issues with various versions of Xerces and Xalan. If an error occurs due to a feature not present in the environment, you can examine the XML-related dependencies and replace those that do not support the necessary feature.","title":"SafeXmlUtils"},{"location":"open-source/core/safexmlutils/#configuration-for-ignoring-unsupported-features","text":"In situations where dependencies cannot be modified to support a required XML feature, SafeXmlUtils allows for the bypassing of unsupported features by adding a property file to the classpath. Configuration Steps: Property File: Create a file named pw-swift-core.properties and place it in the classpath of your project. Properties Definition: Define the property safeXmlUtils.ignore in this file. Assign to this property a comma-separated list of XML features that should be ignored by SafeXmlUtils . For example: safeXmlUtils.ignore=http://xml.org/sax/features/external-general-entities,http://apache.org/xml/features/disallow-doctype-decl By listing features in this property, SafeXmlUtils will skip them, thereby preventing exceptions related to these features not being available in the runtime environment.","title":"Configuration for Ignoring Unsupported Features"},{"location":"open-source/core/safexmlutils/#implementation-details","text":"SafeXmlUtils includes several methods tailored to create various types of XML parsers and transformers with safety configurations. These methods apply or bypass specific XML features based on the project\u2019s environment and needs. Key methods include: documentBuilder(boolean namespaceAware): Configures a DocumentBuilder with safety features. reader(boolean namespaceAware, Schema schema): Creates a SAX parser with customized features. inputFactory(): Sets up a StAX parser with specific security settings. transformer(): Provides a Transformer with restricted access to external DTD and Stylesheets. schemaFactory(): Configures a SchemaFactory with limited external DTD access. validator(Schema schema): Creates a Validator with controlled access to external DTD and Schema. Each of these methods handles specific XML features like \"http://xml.org/sax/features/external-general-entities\", \"http://apache.org/xml/features/disallow-doctype-decl\", and others, ensuring that only secure and supported XML processing features are utilized.","title":"Implementation Details"},{"location":"open-source/iso20022/","text":"Prowide ISO20022 Overview Prowide ISO 20022 implements the foundation classes to handle ISO 2022 (MX) messages in Java. The library provides a comprehensive model for all ISO 20022 message categories and versions. The API features include parsing messages from XML format to Java, serializing Java model objects into the XML format and the conversion between the model and JSON. Quick API reference The tables below synthesizes, by pseudocode, the entry point for common MX read/write use case scenarios. The use case is usually determined by whether you are creating a new SWIFT message or reading an existing SWIFT message. And in the case of reading, different API exists depending on whether you are processing messages generically, or if you are reading specific known type. Use Case API Parse a known MX message into a specific message model new MxPacs00800109 ( String / InputStream xml ) MxPacs00800109 . parse ( String xml ) Read specific MX message content MxPacs00800109 + getters Parse unknown MX message AbstractMX . parse ( String xml ) Specialize generic MX message new MxPacs00800109 ( MxSwiftMessage ) ( MxPacs00800109 ) AbstractMX Load and persist an unknown MX message new MxSwiftMessage ( String / InputStream xml ) MxSwiftMessage . parse ( String / InputStream xml ) Build a new MX message new MxPacs00800109 () + specific setters Write a new MX message to swift string MxPacs00800109 + message () -> xml Write a new MX message to swift file or stream MxPacs00800109 + write ( OutputStream xml ) Javadoc Online javadoc Prowide ISO 20022 Javadoc","title":"Prowide ISO20022"},{"location":"open-source/iso20022/#prowide-iso20022","text":"","title":"Prowide ISO20022"},{"location":"open-source/iso20022/#overview","text":"Prowide ISO 20022 implements the foundation classes to handle ISO 2022 (MX) messages in Java. The library provides a comprehensive model for all ISO 20022 message categories and versions. The API features include parsing messages from XML format to Java, serializing Java model objects into the XML format and the conversion between the model and JSON.","title":"Overview"},{"location":"open-source/iso20022/#quick-api-reference","text":"The tables below synthesizes, by pseudocode, the entry point for common MX read/write use case scenarios. The use case is usually determined by whether you are creating a new SWIFT message or reading an existing SWIFT message. And in the case of reading, different API exists depending on whether you are processing messages generically, or if you are reading specific known type. Use Case API Parse a known MX message into a specific message model new MxPacs00800109 ( String / InputStream xml ) MxPacs00800109 . parse ( String xml ) Read specific MX message content MxPacs00800109 + getters Parse unknown MX message AbstractMX . parse ( String xml ) Specialize generic MX message new MxPacs00800109 ( MxSwiftMessage ) ( MxPacs00800109 ) AbstractMX Load and persist an unknown MX message new MxSwiftMessage ( String / InputStream xml ) MxSwiftMessage . parse ( String / InputStream xml ) Build a new MX message new MxPacs00800109 () + specific setters Write a new MX message to swift string MxPacs00800109 + message () -> xml Write a new MX message to swift file or stream MxPacs00800109 + write ( OutputStream xml )","title":"Quick API reference"},{"location":"open-source/iso20022/#javadoc","text":"Online javadoc Prowide ISO 20022 Javadoc","title":"Javadoc"},{"location":"open-source/iso20022/iso20022-adapters/","text":"DateTime adapters The standard defines different types for representing date and time elements. For some of them multiple options are compliant for their string representation in the XML. To accommodate the flexibility and variability in representing date and time elements as per ISO standards and specific usage guidelines, the library employs type adapters. The Java model is annotated with generic type adapters, allowing multiple implementation options for marshalling and unmarshalling the different date and time values. Default Adapters The default implementations of these type adapters are designed to handle the most common cases. These default adapters ensure that date and time elements are serialized and deserialized in a manner that aligns with ISO conventions. For example, the default implementation for IsoDateTimeAdapter ensures that date-time values are represented as local time with a UTC offset in the format YYYY-MM-DDThh:mm:ss[.sss]+/-hh:mm . Similarly, the IsoDateAdapter handles date values in the format YYY-MM-DD , and the IsoTimeAdapter manages time values in the format hh:mm:ss[.sss]+/-hh:mm . This implementation by default will replace the Zulu indicator Z with the +00:00 offset, and will also trim meaningless zeros in the fractional seconds. However, you can customize this behavior by providing your own adapter. Customization for Specific Use Cases While the default adapters cover a wide range of scenarios, there may be cases where you need to tailor the serialization and/or deserialization of date and time elements to meet specific requirements. In such situations, the library allows you to override or replace the default adapters with your custom implementations. By creating custom adapters, you can precisely control how date and time values are represented in XML. This customization is particularly valuable when your XML documents need to adhere to specific standards or conventions that deviate from the default representations. The TypeAdaptersConfiguration holder DTO is used to set up a collection of adapters. This configuration is then used by the MxWriteConfiguration and MxReadConfiguration to set up the adapters in the JaxbContext. There are many ways to create custom adapters by just implementing the XmlAdapter interface. The following example leverage the default adapters to create custom adapters that preserve the default behavior but add additional customization with a simple string replace to preserve the Zulu indicator Z for offset date times in UTC. public class CustomDateTimeAdapter extends OffsetDateTimeAdapter { @Override public String marshal ( OffsetDateTime offsetDateTime ) throws Exception { return StringUtils . replace ( super . marshal ( offsetDateTime ), \"+00:00\" , \"Z\" ); } } The custom implementation can then be passed to the MxWriteConfiguration to override the default adapter. MxWriteConfiguration config = new MxWriteConfiguration (); config . adapters . dateTimeAdapter = new IsoDateTimeAdapter ( new CustomDateTimeAdapter ()); xml = mx . message ( config );","title":"DateTime adapters"},{"location":"open-source/iso20022/iso20022-adapters/#datetime-adapters","text":"The standard defines different types for representing date and time elements. For some of them multiple options are compliant for their string representation in the XML. To accommodate the flexibility and variability in representing date and time elements as per ISO standards and specific usage guidelines, the library employs type adapters. The Java model is annotated with generic type adapters, allowing multiple implementation options for marshalling and unmarshalling the different date and time values.","title":"DateTime adapters"},{"location":"open-source/iso20022/iso20022-adapters/#default-adapters","text":"The default implementations of these type adapters are designed to handle the most common cases. These default adapters ensure that date and time elements are serialized and deserialized in a manner that aligns with ISO conventions. For example, the default implementation for IsoDateTimeAdapter ensures that date-time values are represented as local time with a UTC offset in the format YYYY-MM-DDThh:mm:ss[.sss]+/-hh:mm . Similarly, the IsoDateAdapter handles date values in the format YYY-MM-DD , and the IsoTimeAdapter manages time values in the format hh:mm:ss[.sss]+/-hh:mm . This implementation by default will replace the Zulu indicator Z with the +00:00 offset, and will also trim meaningless zeros in the fractional seconds. However, you can customize this behavior by providing your own adapter.","title":"Default Adapters"},{"location":"open-source/iso20022/iso20022-adapters/#customization-for-specific-use-cases","text":"While the default adapters cover a wide range of scenarios, there may be cases where you need to tailor the serialization and/or deserialization of date and time elements to meet specific requirements. In such situations, the library allows you to override or replace the default adapters with your custom implementations. By creating custom adapters, you can precisely control how date and time values are represented in XML. This customization is particularly valuable when your XML documents need to adhere to specific standards or conventions that deviate from the default representations. The TypeAdaptersConfiguration holder DTO is used to set up a collection of adapters. This configuration is then used by the MxWriteConfiguration and MxReadConfiguration to set up the adapters in the JaxbContext. There are many ways to create custom adapters by just implementing the XmlAdapter interface. The following example leverage the default adapters to create custom adapters that preserve the default behavior but add additional customization with a simple string replace to preserve the Zulu indicator Z for offset date times in UTC. public class CustomDateTimeAdapter extends OffsetDateTimeAdapter { @Override public String marshal ( OffsetDateTime offsetDateTime ) throws Exception { return StringUtils . replace ( super . marshal ( offsetDateTime ), \"+00:00\" , \"Z\" ); } } The custom implementation can then be passed to the MxWriteConfiguration to override the default adapter. MxWriteConfiguration config = new MxWriteConfiguration (); config . adapters . dateTimeAdapter = new IsoDateTimeAdapter ( new CustomDateTimeAdapter ()); xml = mx . message ( config );","title":"Customization for Specific Use Cases"},{"location":"open-source/iso20022/iso20022-build/","text":"Builder API (Java to XML) The MX messages builder API is provided to create new MX messages from Java, and serialize its content into XML. The creation of a new message basically consists of creating an object that represents the message, and the subsequent addition of inner elements. The order is not important because the model is already constrained to the correspondent tree structure of the XML. Although this does not mean the builder API will verify validation constraints of the message but the model will naturally allow only proper elements to be appended. This Sample code shows how to create an MX ACMT.001.001.03 message: MxAcmt00100103 mx = new MxAcmt00100103 () . setAcctOpngInstr ( new AccountOpeningInstructionV03 () . setAcctPties ( new AccountParties6 () . setAdmstr ( new InvestmentAccountOwnershipInformation6 () . setClntId ( \"clntId\" )) . setPrncplAcctPty ( new AccountParties1Choice () . setNmnee ( new InvestmentAccountOwnershipInformation6 () . setPty ( new Party14Choice (). setOrg ( new Organisation13 (). setNm ( \"orgName\" )) ) ) ) ) ); String mxXml = mx . message (); System . out . println ( mxXml ); To simplify the resulting builder code, all setters in the business dictionary allow chained method calls. Also inner element class names match the exact names as defined in the MX standard documentation. The resulting XML is: orgName clntId Customization The builder API is designed to be flexible and allow customization of the resulting XML. This example shows how to customize the previous result. MxAcmt00100103 mx = new MxAcmt00100103 () . setAcctOpngInstr ( new AccountOpeningInstructionV03 () . setAcctPties ( new AccountParties6 () . setAdmstr ( new InvestmentAccountOwnershipInformation6 () . setClntId ( \"clntId\" )) . setPrncplAcctPty ( new AccountParties1Choice () . setNmnee ( new InvestmentAccountOwnershipInformation6 () . setPty ( new Party14Choice (). setOrg ( new Organisation13 (). setNm ( \"orgName\" )) ) ) ) ) ); MxWriteConfiguration conf = new MxWriteConfiguration (); conf . documentPrefix = null ; // remove the default Doc: prefix conf . indent = \" \" ; // use 1 space for indentation conf . includeXMLDeclaration = false ; // remove the default XML declaration String mxXml = mx . message ( conf ); System . out . println ( mxXml ); This will result in the following XML: orgName clntId Refer to the MxWriteConfiguration javadoc to review all the available customization options.","title":"MX Build (Java to XML)"},{"location":"open-source/iso20022/iso20022-build/#builder-api-java-to-xml","text":"The MX messages builder API is provided to create new MX messages from Java, and serialize its content into XML. The creation of a new message basically consists of creating an object that represents the message, and the subsequent addition of inner elements. The order is not important because the model is already constrained to the correspondent tree structure of the XML. Although this does not mean the builder API will verify validation constraints of the message but the model will naturally allow only proper elements to be appended. This Sample code shows how to create an MX ACMT.001.001.03 message: MxAcmt00100103 mx = new MxAcmt00100103 () . setAcctOpngInstr ( new AccountOpeningInstructionV03 () . setAcctPties ( new AccountParties6 () . setAdmstr ( new InvestmentAccountOwnershipInformation6 () . setClntId ( \"clntId\" )) . setPrncplAcctPty ( new AccountParties1Choice () . setNmnee ( new InvestmentAccountOwnershipInformation6 () . setPty ( new Party14Choice (). setOrg ( new Organisation13 (). setNm ( \"orgName\" )) ) ) ) ) ); String mxXml = mx . message (); System . out . println ( mxXml ); To simplify the resulting builder code, all setters in the business dictionary allow chained method calls. Also inner element class names match the exact names as defined in the MX standard documentation. The resulting XML is: orgName clntId ","title":"Builder API (Java to XML)"},{"location":"open-source/iso20022/iso20022-build/#customization","text":"The builder API is designed to be flexible and allow customization of the resulting XML. This example shows how to customize the previous result. MxAcmt00100103 mx = new MxAcmt00100103 () . setAcctOpngInstr ( new AccountOpeningInstructionV03 () . setAcctPties ( new AccountParties6 () . setAdmstr ( new InvestmentAccountOwnershipInformation6 () . setClntId ( \"clntId\" )) . setPrncplAcctPty ( new AccountParties1Choice () . setNmnee ( new InvestmentAccountOwnershipInformation6 () . setPty ( new Party14Choice (). setOrg ( new Organisation13 (). setNm ( \"orgName\" )) ) ) ) ) ); MxWriteConfiguration conf = new MxWriteConfiguration (); conf . documentPrefix = null ; // remove the default Doc: prefix conf . indent = \" \" ; // use 1 space for indentation conf . includeXMLDeclaration = false ; // remove the default XML declaration String mxXml = mx . message ( conf ); System . out . println ( mxXml ); This will result in the following XML: orgName clntId Refer to the MxWriteConfiguration javadoc to review all the available customization options.","title":"Customization"},{"location":"open-source/iso20022/iso20022-model/","text":"Java model for MX messages The message model for MX messages is a set of Java classes representing the structure and content of a SWIFT MX (ISO 20022) message. Being the MX standard based on XML, the Java model is an abstraction of the different XMLs defined by the standard with Java classes to represent each possible MX message. A business objects dictionary is part of the MX message model, representing any possible content element of an MX message. The scope of the message model for MX is the payload composed by the Application Header and the Document (with the actual body of the message). The overhead xml wrappers with transport information are not part of the model and if present, it will be ignored by the parser. In general the model was designed to mirror as much as possible the Prowide Core API for MT messages. In this sense there are two independent layers or levels of abstraction. The lower one being a generic tree representation of the XML with a node per XML tag. And a more business oriented layer with an implementation of each possible MX message type and business content. Unless explicitly remarked this document refers to the business model. Basically all MX model code is concentrated in two main packages: com.prowidesoftware.swift.model.mx for all classes that are a main entry point to MX messages, that is, the root class of the message. Reading and Writing a MX message starts by picking a class from this package which represents the message that will be used. com.prowidesoftware.swift.model.mx.dic supporting classes and reused objects for MX classes. These classes are used inside MX root classes. And for MX system messages another two packages has been added: * com.prowidesoftware.swift.model.mx.sys for the MX system message main classes. * com.prowidesoftware.swift.model.mx.sys.dic for the system messages data dictionary. Our class model for MX is generated from the standard XSD schemas. However it is not the default output of a jaxb compilation. The process uses several custom plugins in order to produce a special API in the Mx classes to parse XMLs sources with ease. And we also have a special process in the generation to merge the complex types implementation classes into a consolidated single dic package, this is important to avoid producing thousands or repetitive classes (notice the standard schemas does not include any common library for the types so a default jaxb generation per namespace is not feasible when targeting the complete set of message categories and versions). Class naming MX messages have this naming structure : Message bbbb.fff.vvv.nn maps to class MxBbbfffvvvnn where: bbbb: four characters indicating the business process of the message, all available business process can be found in the enum com.prowidesoftware.swift.model.MxBusinessProcess fff: 3 digits indicating the message functionality vvv: 3 digits indicating the message variant nn: 2 digits indicating the message version For example: MX message trea.001.001.02 is mapped to class MxTrea00100102 MX message camt.003.001.02 is mapped to class MxCamt00300102 The inner elements of the messages are composed by instances of the business dictionary where the model provides a class for each possible type defined in the MX standard for example: AccountParties6 , InvestmentAccountOwnershipInformation6 , AccountOpeningType1Code , etc... Supported MX Versions The library accumulates all historic versions for all message categories. And it is yearly updated with new versions of messages added per SRU.","title":"MX Model"},{"location":"open-source/iso20022/iso20022-model/#java-model-for-mx-messages","text":"The message model for MX messages is a set of Java classes representing the structure and content of a SWIFT MX (ISO 20022) message. Being the MX standard based on XML, the Java model is an abstraction of the different XMLs defined by the standard with Java classes to represent each possible MX message. A business objects dictionary is part of the MX message model, representing any possible content element of an MX message. The scope of the message model for MX is the payload composed by the Application Header and the Document (with the actual body of the message). The overhead xml wrappers with transport information are not part of the model and if present, it will be ignored by the parser. In general the model was designed to mirror as much as possible the Prowide Core API for MT messages. In this sense there are two independent layers or levels of abstraction. The lower one being a generic tree representation of the XML with a node per XML tag. And a more business oriented layer with an implementation of each possible MX message type and business content. Unless explicitly remarked this document refers to the business model. Basically all MX model code is concentrated in two main packages: com.prowidesoftware.swift.model.mx for all classes that are a main entry point to MX messages, that is, the root class of the message. Reading and Writing a MX message starts by picking a class from this package which represents the message that will be used. com.prowidesoftware.swift.model.mx.dic supporting classes and reused objects for MX classes. These classes are used inside MX root classes. And for MX system messages another two packages has been added: * com.prowidesoftware.swift.model.mx.sys for the MX system message main classes. * com.prowidesoftware.swift.model.mx.sys.dic for the system messages data dictionary. Our class model for MX is generated from the standard XSD schemas. However it is not the default output of a jaxb compilation. The process uses several custom plugins in order to produce a special API in the Mx classes to parse XMLs sources with ease. And we also have a special process in the generation to merge the complex types implementation classes into a consolidated single dic package, this is important to avoid producing thousands or repetitive classes (notice the standard schemas does not include any common library for the types so a default jaxb generation per namespace is not feasible when targeting the complete set of message categories and versions).","title":"Java model for MX messages"},{"location":"open-source/iso20022/iso20022-model/#class-naming","text":"MX messages have this naming structure : Message bbbb.fff.vvv.nn maps to class MxBbbfffvvvnn where: bbbb: four characters indicating the business process of the message, all available business process can be found in the enum com.prowidesoftware.swift.model.MxBusinessProcess fff: 3 digits indicating the message functionality vvv: 3 digits indicating the message variant nn: 2 digits indicating the message version For example: MX message trea.001.001.02 is mapped to class MxTrea00100102 MX message camt.003.001.02 is mapped to class MxCamt00300102 The inner elements of the messages are composed by instances of the business dictionary where the model provides a class for each possible type defined in the MX standard for example: AccountParties6 , InvestmentAccountOwnershipInformation6 , AccountOpeningType1Code , etc...","title":"Class naming"},{"location":"open-source/iso20022/iso20022-model/#supported-mx-versions","text":"The library accumulates all historic versions for all message categories. And it is yearly updated with new versions of messages added per SRU.","title":"Supported MX Versions"},{"location":"open-source/iso20022/iso20022-parser/","text":"Parser (XML to Java) The parser's main usage is to access the business content of the MX message from a business oriented Java model instead of dealing with the underlying xml structure. Therefore the parser allows the conversion of an XML message into a Java model that represents the message and provides specific getters to retrieve the elements read from the XML. It is important to remark that the parser will only accept well structured XML files (all tags properly closed) and it will only read the portions according to the corresponding MX message, meaning any unexpected xml content will be dropped. Also to remark, the parser does not perform any content validation regarding tags repetitions, charsets, qualifiers or semantics. There are several entry points for the MX parsing feature depending on the use case: Parsing a specific known message type When the specific MX message type is known a specific MX message object can be created from String or InputStream , as follows: MxCamt00300104 mx = MxCamt00300104 . parse ( xml ); The above code is also available in constructors. This is the more efficient way to read the message if the specific version is known in advance. The parser will read into the output object both the Document and the AppHdr (if present). The implementation is based on the JAXB2 unmarshaller. Parsing an unknown message type When the specific category and version of the message to read is unknown you can use the base calss of the message hierarchy to do the parsing, then cast if necessary to extract specific data. AbstractMX mx = AbstractMX . parse ( xml ); if ( \"camt.048.001.03\" . equals ( mx . getMxId (). id ())) { MxCamt04800103 camt = ( MxCamt04800103 ) mx ; System . out . println ( \"Message id: \" + camt . getModfyRsvatn (). getMsgHdr (). getMsgId ()); } The MX message model classes, such as MxPacs00800108 , that extend the AbstractMX are designed to parse and create specific message types . The AbstractMX is simply the parent class of the model hierarchy, and it is abstract . Thus, it is not intended to create messages from scratch, and in fact, you cannot create a new empty instance of it. It is only created in parse method calls . If you parse an XML with a specific model class, any element in the XML that does not belong to the specific schema is automatically dropped. This is because the model classes are designed for specific types. This means that you cannot parse an element such as /Document/GrpHdr/InstrctdAgt into a model if that model does not define such a path or element. When you parse an XML with the AbstractMX , the API internally autodetects the message type from the namespace and parses the XML with a specific model class. The AbstractMX is just a way to process messages without autodetecting or creating specific instances yourself. Parsing many unknown message types When you need to parse many unknown message types and just store the content in a database or read generic metadata that is common to all messages (such as the message type, sender, receiver and reference) you can use the generic MxSwiftMessage class for parsing: MxSwiftMessage msg = MxSwftMessage . parse ( xml ); The class implements several constructors and static methods to create the instance from different sources; String, InputStream, AbstractMX, etc... Only the header will be parsed in order into structured attributes, while the plain input XML will be stored as a String. This model object is also suited for persistence because it can be stored in a simple common table for all message types. If you need to read specific attributes not available in the generic metadata, you can use the specific classes such as MxSese02300201 to read specific data. Reading specific attributes from many message types Finally, you have yet another option if you need to read many attributes (not available in the MtSwiftMessage metadata) from many known or unknown message types. This is an alternative, low-level approach where the model objects are not used, and the underlying XML structure is directly traversed. MxNode n = MxNode . parse ( document ); String amount = n . singlePathValue ( \"/Document/etc\" ); This MxNode is a generic, lightweight, and fast XML tree representation that can be used to traverse or build any XML. You can think of it as a simplified DOM. It lacks several features of a full DOM but is much faster and lighter. The MxNode model and all its methods are part of a generic XML API. Its purpose is to provide an easy-to-use, generic XML handling API to avoid using Java's native APIs such as DOM, SAX, Stax, etc. The MxNode model is not specific to ISO 20022. You can use it to parse or create any XML structure. In particular, you can use the MxNode model to generically parse or create MX messages. However, the model itself does not impose any restrictions on what you can do. Performance: JaxbContext cache The parse methods available in the specific classes such as MxCamt00300104 or in the AbstractMX class uses JAXB unmarshaller. By default implementation will create a new JAXBContext for each parse invocation. While this is fine when you need to parse a low number of messages it might become a considerable performance issue for larger volumes. To deal with it the implementation supports injecting a cache for the JaxbContext . This is managed by a singleton class JaxbContextLoader like this: JaxbContextLoader . INSTANCE . setCacheImpl ( new JaxbContextCacheImpl ()); When a cache implementation is set in the loader, the created JAXBContext will be cached and re-used between parse and write calls. Meaning if you parse a sese.023.002.01, the first time the context will be initialized, but afterwards each time you parse another sese.023.002.01 the available context will be reused. The JaxbContextCacheImpl is a default out-of-the-box cache implementation based on a simple ConcurrentHashMap , with no eviction. This implementation is aimed to avoid additional third party dependencies. Meaning it can be used right away and it is a fair solution for the performance issue. However, since it has no eviction, if you process a wide variety of message types the cache will grow, consuming a lot of memory. For a more robust solution You can easily implement your own cache with Guava, Ehcache, Caffeine or any other cache library. For instance if your application already has the Guava library, you can write a Guava based cache like this: public class GuavaJaxbContextCache implements JaxbContextCache { private final Cache < Class , JAXBContext > cache = CacheBuilder . newBuilder (). maximumSize ( 100 ). build (); public JAXBContext get ( final Class messageClass , final Class [] classes ) throws ExecutionException { return cache . get ( messageClass , () -> JAXBContext . newInstance ( classes )); } } And then inject this implementation to the loader with: JaxbContextLoader . INSTANCE . setCacheImpl ( new GuavaJaxbContextCache ()); The Guava based example code is available at: https://github.com/prowide/prowide-iso20022-examples/","title":"MX Parser (XML to Java)"},{"location":"open-source/iso20022/iso20022-parser/#parser-xml-to-java","text":"The parser's main usage is to access the business content of the MX message from a business oriented Java model instead of dealing with the underlying xml structure. Therefore the parser allows the conversion of an XML message into a Java model that represents the message and provides specific getters to retrieve the elements read from the XML. It is important to remark that the parser will only accept well structured XML files (all tags properly closed) and it will only read the portions according to the corresponding MX message, meaning any unexpected xml content will be dropped. Also to remark, the parser does not perform any content validation regarding tags repetitions, charsets, qualifiers or semantics. There are several entry points for the MX parsing feature depending on the use case:","title":"Parser (XML to Java)"},{"location":"open-source/iso20022/iso20022-parser/#parsing-a-specific-known-message-type","text":"When the specific MX message type is known a specific MX message object can be created from String or InputStream , as follows: MxCamt00300104 mx = MxCamt00300104 . parse ( xml ); The above code is also available in constructors. This is the more efficient way to read the message if the specific version is known in advance. The parser will read into the output object both the Document and the AppHdr (if present). The implementation is based on the JAXB2 unmarshaller.","title":"Parsing a specific known message type"},{"location":"open-source/iso20022/iso20022-parser/#parsing-an-unknown-message-type","text":"When the specific category and version of the message to read is unknown you can use the base calss of the message hierarchy to do the parsing, then cast if necessary to extract specific data. AbstractMX mx = AbstractMX . parse ( xml ); if ( \"camt.048.001.03\" . equals ( mx . getMxId (). id ())) { MxCamt04800103 camt = ( MxCamt04800103 ) mx ; System . out . println ( \"Message id: \" + camt . getModfyRsvatn (). getMsgHdr (). getMsgId ()); } The MX message model classes, such as MxPacs00800108 , that extend the AbstractMX are designed to parse and create specific message types . The AbstractMX is simply the parent class of the model hierarchy, and it is abstract . Thus, it is not intended to create messages from scratch, and in fact, you cannot create a new empty instance of it. It is only created in parse method calls . If you parse an XML with a specific model class, any element in the XML that does not belong to the specific schema is automatically dropped. This is because the model classes are designed for specific types. This means that you cannot parse an element such as /Document/GrpHdr/InstrctdAgt into a model if that model does not define such a path or element. When you parse an XML with the AbstractMX , the API internally autodetects the message type from the namespace and parses the XML with a specific model class. The AbstractMX is just a way to process messages without autodetecting or creating specific instances yourself.","title":"Parsing an unknown message type"},{"location":"open-source/iso20022/iso20022-parser/#parsing-many-unknown-message-types","text":"When you need to parse many unknown message types and just store the content in a database or read generic metadata that is common to all messages (such as the message type, sender, receiver and reference) you can use the generic MxSwiftMessage class for parsing: MxSwiftMessage msg = MxSwftMessage . parse ( xml ); The class implements several constructors and static methods to create the instance from different sources; String, InputStream, AbstractMX, etc... Only the header will be parsed in order into structured attributes, while the plain input XML will be stored as a String. This model object is also suited for persistence because it can be stored in a simple common table for all message types. If you need to read specific attributes not available in the generic metadata, you can use the specific classes such as MxSese02300201 to read specific data.","title":"Parsing many unknown message types"},{"location":"open-source/iso20022/iso20022-parser/#reading-specific-attributes-from-many-message-types","text":"Finally, you have yet another option if you need to read many attributes (not available in the MtSwiftMessage metadata) from many known or unknown message types. This is an alternative, low-level approach where the model objects are not used, and the underlying XML structure is directly traversed. MxNode n = MxNode . parse ( document ); String amount = n . singlePathValue ( \"/Document/etc\" ); This MxNode is a generic, lightweight, and fast XML tree representation that can be used to traverse or build any XML. You can think of it as a simplified DOM. It lacks several features of a full DOM but is much faster and lighter. The MxNode model and all its methods are part of a generic XML API. Its purpose is to provide an easy-to-use, generic XML handling API to avoid using Java's native APIs such as DOM, SAX, Stax, etc. The MxNode model is not specific to ISO 20022. You can use it to parse or create any XML structure. In particular, you can use the MxNode model to generically parse or create MX messages. However, the model itself does not impose any restrictions on what you can do.","title":"Reading specific attributes from many message types"},{"location":"open-source/iso20022/iso20022-parser/#performance-jaxbcontext-cache","text":"The parse methods available in the specific classes such as MxCamt00300104 or in the AbstractMX class uses JAXB unmarshaller. By default implementation will create a new JAXBContext for each parse invocation. While this is fine when you need to parse a low number of messages it might become a considerable performance issue for larger volumes. To deal with it the implementation supports injecting a cache for the JaxbContext . This is managed by a singleton class JaxbContextLoader like this: JaxbContextLoader . INSTANCE . setCacheImpl ( new JaxbContextCacheImpl ()); When a cache implementation is set in the loader, the created JAXBContext will be cached and re-used between parse and write calls. Meaning if you parse a sese.023.002.01, the first time the context will be initialized, but afterwards each time you parse another sese.023.002.01 the available context will be reused. The JaxbContextCacheImpl is a default out-of-the-box cache implementation based on a simple ConcurrentHashMap , with no eviction. This implementation is aimed to avoid additional third party dependencies. Meaning it can be used right away and it is a fair solution for the performance issue. However, since it has no eviction, if you process a wide variety of message types the cache will grow, consuming a lot of memory. For a more robust solution You can easily implement your own cache with Guava, Ehcache, Caffeine or any other cache library. For instance if your application already has the Guava library, you can write a Guava based cache like this: public class GuavaJaxbContextCache implements JaxbContextCache { private final Cache < Class , JAXBContext > cache = CacheBuilder . newBuilder (). maximumSize ( 100 ). build (); public JAXBContext get ( final Class messageClass , final Class [] classes ) throws ExecutionException { return cache . get ( messageClass , () -> JAXBContext . newInstance ( classes )); } } And then inject this implementation to the loader with: JaxbContextLoader . INSTANCE . setCacheImpl ( new GuavaJaxbContextCache ()); The Guava based example code is available at: https://github.com/prowide/prowide-iso20022-examples/","title":"Performance: JaxbContext cache"},{"location":"release-notes/","text":"Release Notes This section contains the current and historic changelogs for all Prowide library artifacts within the SRU2023-9.4.x distribution branch. Notice this information is public, however, the Prowide Integrator artifacts are not open source, thus download and usage is restricted to licensed customers. Versions compatibility To keep the libraries up-to-date and compatible with the latest technologies and frameworks, we started the migration to Java 11 and Jakarta EE 10. To give all users time to migrate their systems, the existing versions will also be maintained. The following table summarizes versioning for current and upcoming releases, and the corresponding SRU and Java/Jakarta EE versions. Version SRU Java Jakarta EE 9.4.x 2023 8 Jaxb 2 10.1.x 2023 11 10 SRU stands for the SWIFT Standards Release Update . It reflects the messaging standard the libraries are compatible with. Notice the middle version is normally updated along a SRU change. Check the Versioning page for further details. As for the migration to Jakarta, overall, the migration process involves replacing the Java EE packages in your source code (javax) with their Jakarta EE counterparts (jakarta) and updating your application's dependencies to their Jakarta EE versions. The exact steps and level of effort required will depend on the specifics of your application and its dependencies. We believe that the benefits of these updates far outweigh any temporary inconvenience.","title":"Release Notes"},{"location":"release-notes/#release-notes","text":"This section contains the current and historic changelogs for all Prowide library artifacts within the SRU2023-9.4.x distribution branch. Notice this information is public, however, the Prowide Integrator artifacts are not open source, thus download and usage is restricted to licensed customers.","title":"Release Notes"},{"location":"release-notes/#versions-compatibility","text":"To keep the libraries up-to-date and compatible with the latest technologies and frameworks, we started the migration to Java 11 and Jakarta EE 10. To give all users time to migrate their systems, the existing versions will also be maintained. The following table summarizes versioning for current and upcoming releases, and the corresponding SRU and Java/Jakarta EE versions. Version SRU Java Jakarta EE 9.4.x 2023 8 Jaxb 2 10.1.x 2023 11 10 SRU stands for the SWIFT Standards Release Update . It reflects the messaging standard the libraries are compatible with. Notice the middle version is normally updated along a SRU change. Check the Versioning page for further details. As for the migration to Jakarta, overall, the migration process involves replacing the Java EE packages in your source code (javax) with their Jakarta EE counterparts (jakarta) and updating your application's dependencies to their Jakarta EE versions. The exact steps and level of effort required will depend on the specifics of your application and its dependencies. We believe that the benefits of these updates far outweigh any temporary inconvenience.","title":"Versions compatibility"},{"location":"release-notes/changelog-cbpr/","text":"Prowide Integrator CBPR+ - CHANGELOG Model extension for CBPR+ messages (Cross Border and Payments Regulation) 9.4.3 - SNAPSHOT Renamed validationKey() to businessService() in the CbprMessageType enum 9.4.2 - April 2024 Added a log when the CBPR+ message factory is used and the message sample contains a header other than BAH v2 9.4.1 - November 2023 (PW-1691) Fixed specific business service for each message type 9.4.0 - July 2023 Version aligned with Prowide Integrator 9.4.x for SRU2023 (PW-1444) Added model and parser for the CBPR+ pacs.010.001.03 Margin Collection message type 2.3.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 2.2.0 - March 2023 (PW-1300) Updated model to the CBPR+ 2023 release 2.1.9 - March 2023 (PW-1261) Enhanced the CbprMessageType.of(AppHdr) to work even if the MsgDefIdr contains a redundant variant such as pacs.008.001.08STP 2.1.8 - February 2023 Minor javadoc fixes 2.1.7 - February 2022 Prowide dependencies update 2.1.6 - December 2022 Switched to semantic versioning 2.1u5 - November 2022 Internal implementation enhancements 2.1u4 - November 2022 Updated Apache Commons Text dependency to 1.10 to fix reported CVE 2.1u3 - September 2022 Added the current SRU to the version number for consistent SRU based BOM and dependency with other Integrator artifacts 2.1u2 - April 2022 Internal schema compress to reduce jar size 2.1u1 - March 2022 Added the specific BAH v2 schema for CBPR+ along a CbprHeaderSchemaResolver util class to retrieve it (PW-863) Added support for customizable date and time adapters in the XML marshalling/unmarshalling 2.1 - January 2022 Updated implementation for the CBPR+ release 2.1 (effective in November 2022) 2.0u4 - January 2022 Added a CbprMessageFactory to create CBPR+ message objects from XML with type and variant auto detection Added CbprMessageType#of(AppHdr appHdr) to detect the type from an application header instance 2.0u3 - January 2022 Prowide Integrator SDK and Prowide Core updates 2.0u2 - December 2021 Added com.prowidesoftware.integrator.cbpr as automatic module name in the MANIFEST for JPMS support 2.0u1 - December 2021 Added a custom marshaller for date time elements to be compliant with CBPR_DateTime ('+00:00' offset instead of 'Z') 2.0 - November 2021 Updated implementation for the 17 message types in the CBPR+ release 2.0 (effective in November 2022) 1.2u2 - October 2020 Removed the CopyableTo implementation from the generated model Added a method to return the MxId and the targetNamespace in the CbprMessageType enumeration 1.2u1 - September 2020 Added phase II message types: pacs.010.001.03 and pacs.008.001.08_STP 1.2 Initial implementation for the CBPR+ releease 1.2","title":"Prowide Integrator CBPR+"},{"location":"release-notes/changelog-cbpr/#prowide-integrator-cbpr-changelog","text":"Model extension for CBPR+ messages (Cross Border and Payments Regulation)","title":"Prowide Integrator CBPR+ - CHANGELOG"},{"location":"release-notes/changelog-cbpr/#943-snapshot","text":"Renamed validationKey() to businessService() in the CbprMessageType enum","title":"9.4.3 - SNAPSHOT"},{"location":"release-notes/changelog-cbpr/#942-april-2024","text":"Added a log when the CBPR+ message factory is used and the message sample contains a header other than BAH v2","title":"9.4.2 - April 2024"},{"location":"release-notes/changelog-cbpr/#941-november-2023","text":"(PW-1691) Fixed specific business service for each message type","title":"9.4.1 - November 2023"},{"location":"release-notes/changelog-cbpr/#940-july-2023","text":"Version aligned with Prowide Integrator 9.4.x for SRU2023 (PW-1444) Added model and parser for the CBPR+ pacs.010.001.03 Margin Collection message type","title":"9.4.0 - July 2023"},{"location":"release-notes/changelog-cbpr/#230-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"2.3.0 - May 2023"},{"location":"release-notes/changelog-cbpr/#220-march-2023","text":"(PW-1300) Updated model to the CBPR+ 2023 release","title":"2.2.0 - March 2023"},{"location":"release-notes/changelog-cbpr/#219-march-2023","text":"(PW-1261) Enhanced the CbprMessageType.of(AppHdr) to work even if the MsgDefIdr contains a redundant variant such as pacs.008.001.08STP","title":"2.1.9 - March 2023"},{"location":"release-notes/changelog-cbpr/#218-february-2023","text":"Minor javadoc fixes","title":"2.1.8 - February 2023"},{"location":"release-notes/changelog-cbpr/#217-february-2022","text":"Prowide dependencies update","title":"2.1.7 - February 2022"},{"location":"release-notes/changelog-cbpr/#216-december-2022","text":"Switched to semantic versioning","title":"2.1.6 - December 2022"},{"location":"release-notes/changelog-cbpr/#21u5-november-2022","text":"Internal implementation enhancements","title":"2.1u5 - November 2022"},{"location":"release-notes/changelog-cbpr/#21u4-november-2022","text":"Updated Apache Commons Text dependency to 1.10 to fix reported CVE","title":"2.1u4 - November 2022"},{"location":"release-notes/changelog-cbpr/#21u3-september-2022","text":"Added the current SRU to the version number for consistent SRU based BOM and dependency with other Integrator artifacts","title":"2.1u3 - September 2022"},{"location":"release-notes/changelog-cbpr/#21u2-april-2022","text":"Internal schema compress to reduce jar size","title":"2.1u2 - April 2022"},{"location":"release-notes/changelog-cbpr/#21u1-march-2022","text":"Added the specific BAH v2 schema for CBPR+ along a CbprHeaderSchemaResolver util class to retrieve it (PW-863) Added support for customizable date and time adapters in the XML marshalling/unmarshalling","title":"2.1u1 - March 2022"},{"location":"release-notes/changelog-cbpr/#21-january-2022","text":"Updated implementation for the CBPR+ release 2.1 (effective in November 2022)","title":"2.1 - January 2022"},{"location":"release-notes/changelog-cbpr/#20u4-january-2022","text":"Added a CbprMessageFactory to create CBPR+ message objects from XML with type and variant auto detection Added CbprMessageType#of(AppHdr appHdr) to detect the type from an application header instance","title":"2.0u4 - January 2022"},{"location":"release-notes/changelog-cbpr/#20u3-january-2022","text":"Prowide Integrator SDK and Prowide Core updates","title":"2.0u3 - January 2022"},{"location":"release-notes/changelog-cbpr/#20u2-december-2021","text":"Added com.prowidesoftware.integrator.cbpr as automatic module name in the MANIFEST for JPMS support","title":"2.0u2 - December 2021"},{"location":"release-notes/changelog-cbpr/#20u1-december-2021","text":"Added a custom marshaller for date time elements to be compliant with CBPR_DateTime ('+00:00' offset instead of 'Z')","title":"2.0u1 - December 2021"},{"location":"release-notes/changelog-cbpr/#20-november-2021","text":"Updated implementation for the 17 message types in the CBPR+ release 2.0 (effective in November 2022)","title":"2.0 - November 2021"},{"location":"release-notes/changelog-cbpr/#12u2-october-2020","text":"Removed the CopyableTo implementation from the generated model Added a method to return the MxId and the targetNamespace in the CbprMessageType enumeration","title":"1.2u2 - October 2020"},{"location":"release-notes/changelog-cbpr/#12u1-september-2020","text":"Added phase II message types: pacs.010.001.03 and pacs.008.001.08_STP","title":"1.2u1 - September 2020"},{"location":"release-notes/changelog-cbpr/#12","text":"Initial implementation for the CBPR+ releease 1.2","title":"1.2"},{"location":"release-notes/changelog-consolidated/","text":"Consolidated releases This section contains the current and historic changelogs for all Prowide library artifacts within the SRU2023-9.4.x distribution branch. Bill of materials (BOM) This section lists the latest version for all libraries. Library Version Prowide Core SRU2023-9.4.16 Prowide ISO 20022 SRU2023-9.4.5 Prowide Integrator SDK SRU2023-9.4.25 Prowide Integrator Validation SRU2023-9.4.23 Prowide Integrator Translations SRU2023-9.4.39 Prowide Integrator MyFormat SRU2023-9.4.5 Prowide Integrator CBPR+ SRU2023-9.4.2 Prowide Integrator SEPA SRU2023-9.4.0 Prowide Integrator SIC SRU2023-9.4.1 Prowide Integrator SCORE SRU2023-9.4.7 Prowide GUI Tools 9.4.3","title":"Consolidated releases"},{"location":"release-notes/changelog-consolidated/#consolidated-releases","text":"This section contains the current and historic changelogs for all Prowide library artifacts within the SRU2023-9.4.x distribution branch.","title":"Consolidated releases"},{"location":"release-notes/changelog-consolidated/#bill-of-materials-bom","text":"This section lists the latest version for all libraries. Library Version Prowide Core SRU2023-9.4.16 Prowide ISO 20022 SRU2023-9.4.5 Prowide Integrator SDK SRU2023-9.4.25 Prowide Integrator Validation SRU2023-9.4.23 Prowide Integrator Translations SRU2023-9.4.39 Prowide Integrator MyFormat SRU2023-9.4.5 Prowide Integrator CBPR+ SRU2023-9.4.2 Prowide Integrator SEPA SRU2023-9.4.0 Prowide Integrator SIC SRU2023-9.4.1 Prowide Integrator SCORE SRU2023-9.4.7 Prowide GUI Tools 9.4.3","title":"Bill of materials (BOM)"},{"location":"release-notes/changelog-core/","text":"Prowide Core - CHANGELOG 9.4.16 - May 2024 (PW-1862) Added NarrativeFragment class for detailed line information in StructuredNarrative fragments Fixed SwiftMessage getPDE(): return empty value instead of null when codeword exists and has no value Added isPercentage() helper method to field 37K 9.4.15 - March 2024 (PW-1812) Updated the narrative resolver, format 2 (used in field 72 for example), to allow empty values as part of the narrative fragment Updated validators for BIC, country, and currency constraints to utilize keywords for i18n-compatible messages Deprecated unnecessary methods in the SafeXmlUtils class 9.4.14 - December 2023 (PW-1718) Changed the getComponentLabel(component) in Field59F to be dynamic based on the line identifiers (similar to existing API in Field50F) 9.4.13 - November 2023 (PW-1697) Fixed validation/parse pattern in field 29O (PW-1697) MT306 changes in field 30I Added DistinguishedName with Builder in order to encapsulate the BIC branch name logic 9.4.12 - November 2023 (PW-1697) Fixed validation pattern in fields 14[H,K,L,M,N,O] and 29J 9.4.11 - November 2023 (PW-1695) Fixed a stack overflow in the fields fromJson implementation when a malformed JSON input contains empty field names (PW-1688) Added missing field labels for SRU2023 changes in the pw_swift_*.properties file 9.4.10 - October 2023 (PW-1675) update to Field 31R to support also two date components as requested by SCORE messages Added 36B and 36D getters to MT543 9.4.9 - October 2023 (PW-1659) Field 24G deprecated Name and Address for Narrative 9.4.8 - October 2023 Added default methods for sender, receiver, and identifier extraction to the MessageExtractionStrategy Added JSON to the FileFormat enumeration 9.4.7 - September 2023 (PW-1478) Fixed Field 44J parse and getValue to enable proper data preservation when the field contains multiline content 9.4.6 - September 2023 Added support for an optional pw-swift-core.properties to customize the behavior of the SafeXmlUtils class 9.4.5 - August 2023 (PW-1478) Field 44J parse and getValue fix 9.4.4 - August 2023 (PW-1478) Field 44J format fixed to allow multiline 9.4.3 - July 2023 (PW-1461) Remove deprecation of field 31R model since is it used back in SRU2023 (PW-1405) Trim original String payload when creating an AbstractSwiftMessage 9.4.2 - June 2023 (GH-163) Remove unnecessary padding in sender and receiver in AbstractMT#creeate(number, sender, receiver) method (PW-1323) Fixing getValue method for pattern issue in Field44J 9.4.1 - June 2023 (PW-1323) Fixing missing pattern issue in Field44J 9.4.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 9.3.15 - May 2023 (PW-1341) Avoid log pollution with exception stacktrace in Field#formatAccount method (PW-1264) Added distinguishedName(boolean includeDefaultBranch) method to BIC in order to return default branch name 9.3.14 - March 2023 (PW-1182) Fixed MT internal Loops API, when strategy is GENERATED_FIXED_WITH_OPTIONAL_TAIL and the tail part contains repetitive fields, such as MT920 (PW-1241) Added addUnstructuredStrict method to Narrative in order to strictly wrap unstructured input 9.3.13 - March 2023 Deprecated all fields that are only used in SCORE messages and not in the general MT standard as they will eventually be removed from the library 9.3.12 - February 2023 (PW-1109) Changed Narrative Resolver to validate minimum codeword length of 1 char (GH-148) Fixed parser of Field61 amount component when number starts with the decimal comma (implicit zero in amount lower than 1) Added getComponent(String componentName) to retrieve the component based on the name instead of the number Added componentNameToNumber(String componentName) to retrieve the component number based on the component name 9.3.11 - January 2023 (PW-1152) Preserve line breaks when creating NarrativeContainer fields from JSON with legacy structure: narrative1, narrative2, etc... Fixed duplicate elements when serializing NarrativeContainer fields into JSON 9.3.10 - January 2023 (PW-1150) Added field model class for 31M (required in SCORE MT798_753) (PW-1150) Added field model class for 71E (required in SCORE MT798_755 and MT798_757) 9.3.9 - December 2022 (PW-1078) StructuredNarrative: Fixed parser to treat the optional [3!a13d] part as a unit block, both currency and amount present or missing 9.3.8 - November 2022 (GH-127) Enhanced field JSON serialization to include detailed structure when the field is a NarrativeContainer 9.3.7 - November 2022 (PW-1101) Fix field 35C labels to match the FIN xsd: Identification Of Instrument, Description Of Instrument 9.3.6 - November 2022 (PW-1086) Fixed typo in field 36D accessors (PW-1078) StructuredNarrative: Added getBankCode() methods in order to allow direct access to data (used in SCORE messages) (GH-88) Added missing constants for ISO 15022 codes MT540 and MT548 added missing getter for Field99C Added removeRepeatedBoundaries method in order to remove repeated tag boundaries 9.3.5 - October 2022 SRU2022 updates review: field 35C validation pattern changed to 9.3.4 - September 2022 Added getCADETL method for \"CADETL\" separator sequences (GH-119) MT566: Fixed repetitions of sequence USECU/FIA that is not repetitive Added sequence getters using the boundary field qualifier, for example getSequenceGENL() as equivalent to the existing getSequenceA() 9.3.3 - August 2022 (PW-1015) Added field model classes for 47E, 49D and 49F (required in SCORE MT798_774) 9.3.2 - July 2022 (PW-977) Changed the MT203 and MT210 inner structure from regular sequence to inner loop named Loop1 Added Loop1 getter API to MTs: 110, 201, 203, 210, 410, 412, 420, 422, 450, 456, 604, 605, 801, 920, 973 9.3.1 - July 2022 (PW-976) Added new MonetaryAmountContainer interface for fields having both an Amount and Currency (PW-969) Modified field 12E, 12K and 12R labels (PW-969) Added an optional narrative component to field 12R (required when the field is used in SCORE messages) (PW-898) Changed the heuristic to retrieve sequence B1 from MT300 and MT304 to be more efficient even if the message structure is invalid (PW-867) Enhanced the parsing of party fields A, B and D, to be more strict when splitting the /D/ or /C/ prefix from the account Enhanced MtId constructor with regex matching Added method namespaceURI() in the MtId class to return for example \"urn:swift:xsd:fin.103.2021\" for the MT103 9.3.0 - May 2022 SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Updated gson dependency to 2.9.0 9.2.13 - April 2022 (PW-892) Fixed AbstractMT#create when the message type number is less than 100 Added a convenient String message() method in the SwiftMessage object to get the FIN serialization of the message Fixed error in Field 94G getValue 9.2.12 - March 2022 (GH-103) fixed invalid ConstraintValidator annotation on CurrencyValidator (GH-95) patterns getters are now non-final to avoid overwriting; static constants have been deprecated RJE and PPC readers, added a constructor with explicit charset (same in swift parser from input stream) Validate.notNull -> Objects.requireNonNull Spotbugs code review 9.2.11 - January 2022 Added LineWrapper (utils) to replace Apache's WordUtils.wrap and thus the commons-text dependency Added convenient method in the envelop message MT798 to get the sub-message type as a SwiftMessage Added a copy constructor to the Tag class 9.2.10 - January 2022 (PW-815) Fixed getValue in field 12H (SCORE) where narrative is optional (GH-89) MT530: Fixed repetition of sequence C ADDINFO Updated dependency: gson:2.8.8 -> gson:2.8.9 Java 11 and 17 compatibility updates Added plugins for automatic versioning and code quality reporting 9.2.9 - December 2021 (GH-78) Fixed MT537#getSequenceBList where sequence B delimiter \"STAT\" overlaps with C3 and D1a1B1a delimiters (GH-74) Fixed parser for Field48 and similar cases to avoid trimming content when the component contains also the slash separator as part of the value (GH-62) Added com.prowidesoftware.core as automatic module name in the MANIFEST for JPMS support Fields getComponentLabel is now public, returning the specific label for each field component Fixed bug in PartyIdentifierUtils.getPartyIdentifier Fixes in field component names and optional status Fixes in field parsing Incompatible change in field 71N (changed from 7 Narrative lines to Code + 6 Narrative lines) Incompatible change for field 11T to have two lines (MT new-line DATE + TIME) Fixed Structured Narrative parsing to return an empty Narrative object with null string values 9.2.8 - November 2021 (PW-764) Added new variant values (RFDD, ISLFIN) (PW-703) Block 2 parser: lenient parser to avoid duplicate error when exception on invalid Input/Output indicator (CR-23) Enhanced getValueDisplay for fields (no decimal separator for numbers that are not amounts) 9.2.7 - October 2021 Field 98D, 98E and 98G: removed invalid get{Component4|Sign}AsCurrency and set{Component4|Sign}(Currency) as no currency applies to these fields Fields 94L and 85L: separated component 2 (Legal Entity Identifier) into two (Legal Entity Identifier Code and Legal Entity Identifier Number). Kept get/setLegalEntityIdentifier for backwards compatibility Field 94H: second component now has get{name}AsBIC and set{name}(BIC) methods Field 56B: now inherits from OptionBPartyField (to have get/setPartyIdentifier) Field 26C: separated component 5 into 5 (Denomination) and 6 (Form) for compatibility with Swift. Kept get/setDenominationForm for backwards compatibility Field 26A: now has 2 components (Number 1 and Number 2) for compatibility with Swift. get/setNumber is kept for backwards compatibility Field 23: fixed getValue and parse to properly handle missing intermediate fields Field 14S: has 4 new compatibility methods: getRateSource/setRateSource for Source and Number components and getTimeAndLocation/setTimeAndLocation for Time and Location components Field 12: component is now of expected to have a numeric type Code cleanup for Fields and Date|BIC|Amount|Currency Container Added support for BigDecimal and Long component types (instead of just Number) in several fields Fixed display text generation for fields having a date with pattern MMDD (only the month was included in the text) OptionAPartyField: added set/getPartyIdentifier (for components 1 and 2) and renamed BIC to IdentifierCode. Affects fields 42A, 51A, 52A, 53A, 54A, 55A, 56A, 57A, 58A, 81A, 82A, 83A, 84A, 85A, 86A, 87A, 88A, 89A, 91A and 96A OptionDPartyField: added set/getPartyIdentifier (for components 1 and 2). Affects fields 42D, 50D, 51D, 52D, 53D, 54D, 55D, 56D, 57D, 58D, 81D, 82D, 83D, 84D, 85D, 86D, 87D, 88D, 89D, 91D and 96D OptionBPartyField: added set/getPartyIdentifier (for components 1 and 2). Affects fields 52B, 53B, 54B, 55B, 57B, 58B, 82B, 84B, 85B, 86B, 87B and 88B Prepared Option A, B and D classes to support the PartyIdentifier interface with methods getPartyIdentifier and setPartyIdentifier Enhanced Block2 creation by enriching Block Type to \"O\" or \"I\". (PW-746) Fixed MT reference extraction for 20C in categories other than 5, and with MUR as fallback option (CR-23) Added SwiftMessage#getMOR Updated dependency: Apache Commons Lang 3.8.1 -> 3.12.0 Updated dependency: Apache Commons Text 1.6 -> 1.9 Updated dependency: Gson 2.8.2 -> 2.8.8 9.2.6 - October 2021 (GH-60) Enhanced parser for field 98C (PW-703) Enhanced SwiftParser in order to validate \"Input\" or \"Output\" Block 2 type Enhanced the MtId to automatically extract the variant from String identifiers such as \"fin.103.STP\" or \"202.COV\" 9.2.5 - September 2021 (PW-664) Parser enhancement to be lenient on LF before block identifier 9.2.4 - August 2021 MultiLineField: preserve starting component separator when getting lines with offset 9.2.3 - August 2021 Added user assigned country codes (example \"XE\") as valid codes in the IsoUtils country validation Added field classes for SCORE messages: 11T, 12[S,R], 25G, 31[J,K,T], 34[D,K,L,M,S,T,U,X,V,W], 49[J,K,L] (to be used in the proprietary payload of the MT798 envelop) MT564: Minor scheme fix, 92a TAXR and WITL can be repeated in CASHMOVE (E2) 9.2.2 - July 2021 (PW-627) fixed Narrative.builder() to compute \"//\" size in the lines wrapping (PW-581) the MultiLineField API now preserves any starting and trailing spaces in field lines MT565: fixed repetition of sequence B2 (multiple to single) MT548: Minor scheme fix, added letter option \"C\" in field \"98C:SCTS\" in sequence \"C1a1B1\" 9.2.1 - June 2021 Added \"ignore block 3\" and \"ignore priority\" options to the SwiftMessageComparator Added field classes for SCORE messages: 12[H,K,L], 20E, 25F, 29[D,F], 31R, 78B (to be used in the proprietary payload of the MT798 envelop) Enhanced parser for LogicalTerminalAddress when the parameter has 9 characters (PW-534) allowed null value for the Tag constructor 9.2.0 - May 2021 SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Fixed the getSequence API in MT classes when the sequence boundary field is repetitive, in some scenarios produced invalid results (PW-519) Field92H: Added \"Rate Status\" accessors (PW-519) Field92J: Replaced \"Narrative\" accessors by \"Rate Status\" accessors 9.1.4 - April 2021 Fixed getConditionalQualifier in fields 69C, 69D and 92H Fixed field 41D isOptional(component) method (PW-510) Fixed parser of field 90L (PW-508) Fixed validator pattern in field 98K Added MultiLineField interface implementation to fields: 45C, 45L and 49Z Removed MultiLineField interface implementation to field 77H since its value is always a single line (PW-501) Added getNarrative(deli), getNameAndAddress(deli) and similar getters in Field classes to get a concatenation of the relevant components with a specific delimiter (PW-501) Fixed the getNarrative(), getNameAndAddress() and similar getters in Field classes to do a simple join of the relevant components, without CRLF and without components value trim (PW-505) Fixed SwiftFormatUtils#decimalsInAmount(BigDecimal) NPE prevention in AbstractMT.getFields() when the parsed FIN content is invalid Added UETRUtils to generate the GPI unique end-to-end transaction reference, mandatory for several payment messages Added customizable strategies to set the MtSwiftMessage metadata fields: reference, main amount, value date, etc... Added field classes for SCORE messages: 13E, 21S, 21T, 27A, 29P, 29S, 29U, 49Z (to be used in the proprietary payload of the MT798 envelop) (PW-451) Added backward compatible implementation in setComponent and SetNarrative API of narrative container fields: 29A, 37N, 70, 71B, 71D, 72Z, 72, 73A, 73, 74, 75, 76, 77A, 77B, 77D, 77 (PW-445) Added backward compatible fromJson for narrative container fields: 29A, 37N, 45B, 46B, 49M, 49N, 70, 71B, 71D, 72Z, 72, 73A, 73, 74, 75, 76, 77A, 77B, 77D, 77J, 77 Added Direction to the SwiftBlock2Field enumeration Added more message type cases to the SwiftMessageUtils valueDate Minor fixes in MT530 model: fields B/22F and C/90[A,B] 9.1.3 - December 2020 Changed SwiftMessage#isGpi() to be true for: 103, 199, 299, 192, 196, 202COV or 205COV (mandatory outgoing GPI types) Removed the indexes from the AbstractSwiftMessage JPA mapping (can be created directly in the DB as needed) Added options in the MT message comparator to ignore the LT identifier or test flag when comparing header LT addresses Added asTestBic in BIC to create a test BIC by setting the second component of the location to zero Added API in the SwiftBlock2Output to set the MIR date and receiver date time fields from Calendar object 9.1.2 - October 2020 Fixed set of MUR when an MtSwiftMessage is created from an acknowledge (service 21 message) Changed AbstractSwiftMessage JPA mapping to EAGER load the status trail and the properties Added a new MessageDirection enum as alternative to the legacy MessageIOType 9.1.1 - September 2020 Fixed parser for fields 94L and 95L Added MurMessageComparator to match ACKs based on the MUR Changed the SwiftMessage#getMUR to retrieve field 108 from either block 3 or block 4 (system messages) Enhanced the AckMessageComparator to still match on differences in block 2 optional fields or block 4 EOL characters Minor refactor in MtSwiftMessage update from model (SwiftMessage) Added a trim to the content parsed from the RJE reader Fixed setPdm in MtSwiftMessage that was over writing the pde field Minor changes in the MtSwiftMessage to avoid log warnings when setting metadata from message model Added convenient field getters in the ServiceMessage21 (ACK/NAK) model class and made the getMtId() return \"gpa.021\" 9.1.0 - May 2020 SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Enhanced components namings in field 98[DEGH] Added rich API to parse and build narrative fields: 29A, 37N, 45B, 46B, 49M, 49N, 70, 71B, 71D, 72Z, 72, 73A, 73, 74, 75, 76, 77A, 77B, 77D, 77J, 77 Mx related classes moved to the prowide-iso20022 project (open source since October 2020) 8.0.2 - April 2019 Added IBAN validation for Seychelles Added field setters API in the SwiftBlock5 Added SwiftBlock5Field enumeration with commonly used block 5 trailer fields (CR #235) Added SafeXmlUtils to disallow XXE in all XML parsing code Fixed parser for fields 70[C,D,E,G], 94E, 95V when first line second component contains slashes Changed default root element for Mx from message to RequestPayload Fixed month day parsing in SwiftFormatUtils for leap years Added MxParser#containsLegacyHeader() to check weather the message uses the legacy SWIFT header or the ISO business header Added MtSwiftMessage constructor from AbstractMT Fixed parser to preserve trailing lines in field values, even if the lines are empty (empty trailing lines were trimmed before) (CR #203) Enhanced parser for party fields, explicit /D/ and /C/ is parsed as mark, otherwise any content following the / is parsed as account Fixed field 108 order and overwrite if exist logic in SwiftBlock3#generateMUR (CR #207) Added optional parameter in SwiftWriter and FINWriterVisitor to control whether field values should be trimmed 8.0.1 - October 2019 Added SwiftMessageUtils#currencyAmount to retrieve the main currency and amount from a message (CR #192) Fixed ConversionService#getFIN(SwiftMessage) to avoid altering the message parameter when removing empty blocks Added an optional SwiftWriter#writeMessage with ignoreEmptyBlocks parameter SwiftMessage#setUserBlocks(List) made public Removed the trim to field values in the XML to enable consistent round trip conversion between FIN and XML Explicit UTF-8 encoding was added where necessary to ensure portability Added MultiLineField implementation to 45D, 49G, 49M and 49N 8.0.0 - May 2019 JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Added common hierarchy for option J party fields 7.10.4 - May 2019 Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Added copy constructors to MT header blocks Added setDate(Calendar) to MIR object (Issue #25) Fixed padding in PPCWriter Added helper API SwiftTagListBlock#splitByTagName to get sub-blocks by field boundary Fixed IOB exception in SwiftBlock2Output#setMIR in lenient mode SwiftParser#tagStarts changed to protected to allow overwriting in custom parsers for non-compliant messages Moved getMessageType from MtSwiftMessage to parent class AbstractSwiftMessage Added getVariant and getMtId to MtSwiftMessage; added getMxId to MxSwiftMessage Added setMUR in SwiftMessage Added helper method in SwiftWriter to ensure break lines of any String has CRLF Added setSignature and getSignature to SwiftMessage and AbstractMT to set and retrieve MDG tag in S block (LAU computation available in Prowide Integrator) Added propertyValue to AbstractSwiftMessage to check if a property is set with a given value Changed IsoUtils implementation to use Currency.getAvailableCurrencies() in the initialization Deprecated AckSystemMessage in favor of ServiceMessage21 Fixed negative index bug in AbstractSwiftMessage#getPreviousStatusInfo when message has less than two statuses in the trail Fixed getLines API in Fields that in some cases was trimming the first line starting slash from the result Fixed eventual NPE produced in MxSwiftMessage#updateFromMessage() when creating MxSwiftMessage from XML document Fixed column length for \"variant\" in MxSwiftMessage persistence mapping Added a fields() method in SwiftTagListBlock to get all block Tag objects as Field objects Added API to field 50F and 59F to get structured content for the line numbers 7.10.3 - October 2018 License changed from LGPL to the more permissive Apache License 2.0 Fixed serialization of field 48 Completed SwiftMessageUtils#currencyAmount for missing MTs Fixed NPE in SwiftBlock4.removeEmptySequences with fields 15A as sequence boundary (Issue #15) MxParser.java typo analiseMessage -> analyseMessage Added getFields() to MT classes Added bean validation annotations for BIC, IBAN, ISO country and currency Enhanced the BIC internal model to allow accessor for all subfields Enhanced the BIC validation with enum to report the specific validation problem found Changed the default SwiftParser behavior to lenient, meaning by default it will not throw any IllegalArgumentException when headers size is invalid Fixed FIN writer to preserve trailing spaces in tag value Added JPA annotations to the SWIFT model intended for persistence (AbstractSwiftMessage and subclasses) Removed the old Hibernate XML mapping AbstractSwiftMessage.hbm.xml (in favor of generic JPA annotations in model) Added SwiftTagListBlock#removeSubBlocks to remove all instances of a given subblock (Issue #13) Fixed SwifttagListBlock#removeSubBlock Added JsonSerializable interface to all model classes implementing toJson() Added toJson and fromJson to MT and Field classes Added toJson and fromJson to the MtSwiftMessage and MxSwiftMessage model Added field 434 in SwiftBlock3Builder 7.10.2 - May 2018 Revamped the JSON API implementation using Gson, added missing fromJson methods 7.10.1 - April 2018 FIN writer: reverted the trim in tag values introduced in 7.8.9 7.10.0 - April 2018 SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Added API in SwiftMessage for the SWIFT gpi service: getters and setters for the service type identifier and UETR Added an automatically generated UETR when creating new MT instances for 103, 103 STP, 103 REMIT, 202, 202 COV, 205, or 205 COV Added API in SwiftMessage to set the variant (STP, REMIT, COV) New helper API for block 3 (SwiftBlock3Builder) to ensure only expected fields are added and in proper order 7.9.7 - April 2018 Dependencies: added gson 2.8.2 Added full IBAN validation including control digits and custom account numbers per country Added SwiftCharset and SwiftCharsetUtils helper API to validate SWIFT related charsets. Added SwiftTagListBlock#getFieldByQualifiers(name, qualifier, conditionalQualifier) to gather generic fields based on qualifiers content Added addTag(index, tag) and setTag(index, tag) in SwiftTagListBlock to insert new field in specific positions Added Field#is(String ...) to test component 1 of fields against a list of possible values Added non-ISO country code XK (Kosovo) to IsoUtils Added API in IsoUtils to add custom codes for countries and currencies Added read-only properties in AbstractSwiftMessage for the message creation year, month and day of moth Added support for custom split char in RJE reader/writer Fixed missing repetitive 35B in MT549 Build migrated to Gradle 7.9.6 - December 2017 Fixed conversion to XML with compressed parameter true in ConversionService 7.9.5 - December 2017 Fixed getValueDisplay in field 50F to strip the starting slash in the account number Added getLabelForLineNumber(String subfieldNumber) in Field50F to return the labels for the structured line identifiers Enhanced getComponentLabel(final int number) in Field50F to return proper dynamic labels based on line number identifiers Added getCorrespondentBIC to SwiftMessage and AbstractSwiftMessage Expanded sender/receiver in MtSwiftMessage and MxSwiftMessage from BIC8 to BIC11 in order to keep branch information in those cached attributes Added checksumBody to AbstractSwiftMessage for proprietary checksum calculated on the body only, as a complement to the existing checksum on the whole message Fixed AbstractSwiftMessage#copyTo(msg) implementation to perform hard copy of list objects (similar to a copy constructor implementation) Expanded precision in getValueDisplay for all numeric fields to preserve the decimal digits present in the original value Implemented SwiftMessage#getUUID and added getUID(Calendar, Long) Implemented SwiftMessageUtils#calculateChecksum as MD5 hash on whole FIN message content and added new checksum for the text block only 7.9.4 - November 2017 Internal code maintenance release 7.9.3 - October 2017 JRE requirement increased to Java 1.6 Added API in BIC to return the distinguished name (DN) for a BIC Added equalsIgnoreCR in Tag to compare values regardless of carriage return character being present or not in new lines Fixed MxParser#parseBusinessApplicationHeaderV01 (it was setting the FinInstnId/Nm as BIC) Removed invalid component in field 86J Fixed order of components in fields 98J and 98K Completed the component labels for all fields Changed field 22C structure into individual components for the function Enhanced fields parse/serialization to preserve any whitespace in a component 7.9.2 - August 2017 Fixed FINWriterVisitor to prevent printing 'null' tag values Deprecated custom resource properties for currency and country codes, in favor of Java nativa API in Currency and Locale Removed package-info.class from target jar to avoid class modifier issue in Java8 runtime Fixed serialization of field 50F to allow the first line without a starting forward slash 7.9.1 - June 2017 (Issue #5) Enhanced performance in SwiftParser Removed sequence API for inner loops (non sequence) in MTs 306, 320, 340, 360, 361, 362, 410, 412, 420, 422, 450, 456 7.9.0 - May 2017 SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX) (Issue #2) maven build issues (Issue #3) Field61 component 5 treated as amount (Issue #4) Field72 structure fixed to allow 6 components at most Field99A implements AmountContainer Field95L implements BICContainer 7.8.9 - May 2017 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Added convenient isType(int) to SwiftMessage Fixed amounts() in AmountContainer fields 7.8.8 - March 2017 Added hashcode and equals to MxId Added MUR generation in block 3 Added a multi-purpose SwiftMessageComparator for MT, as an abstraction of the existing AckMessageComparator Added helper API to remove empty sequences in block 4 Added ACK/NAK identifier constants and API in AbstractSwiftMessage Added getDateAsCalendar in MIR/MOR Added MtCategory enum for MT message categories and convenient category API in SwiftMessage Added support for system and service messages in metadata gathered from SwiftMesasge in MtSwiftMessage Added isServiceMessage in SwiftMessage Added static factory method parse to SwiftMessage Added new fields in AbstractSwiftMessage to hold main currency and amount, automatically set for most MTs from fields 32a, 33a, 34a, 19a and 62a Added conversion to and from LT address in SwiftFormatUtils (CR #10) Added comprehensive implementation of MT and Field classes for system messages (category 0) Added custom name for internal loop sequences in MTs 110, 360, 361, 604, 605, 609, 824, 920, 935, 940, 942, 971 and 973 Added more options to retrieve information from the status trail in AbstractSwiftMessage Reduced visibility from public to protected for MTs inner sequence classes mutable fields; START, END, TAIL. Fixed analyze and strip API in MxParser to support nested Document elements Fixed MT500 removed invalid fields after GENL linkage sequence Fixed AckMessageComparator to cover all fields in block 2 input and output Fixed getSender and getReceiver for service messages in SwiftMessage Fixed MT600, removed invalid fields 26F, 34G, 31C in sequence A Fixed parse for DATE1 (MMDD) to handle properly leap years Fixed RJEWriter to avoid writing the split character '$' and the end of the file, afterwards the last message Expanded helper API in AckSystemMessage TagListBlock tags field made private instead of package protected Enabled mutability of LogicalTerminalAddress objects, allowing setting the branch from superclass BIC Enhanced parser for fields 11R, 11S and 37H (NPE prevention) Removed invalid generated code for internal loops (non-sequence) in MTs: 110, 201, 360, 361, 559, 604, 605, 609, 824, 920, 935, 940, 942, 971, 973 Enhanced from() and to() methods in BusinessHeader to catch more options 7.8.7 - December 2016 Fixed getMessageType in MT103_STP, MT102_STP, MT103_REMIT, MT202COV and MT205COV to return the number without the validation flag (as expected per javadoc definition) MT518 fixed fieldset for Field 70 MT330 fixed qualifier in Field 22 MT513 and MT514 Field 11 moved outside previous fieldset MT541 to MT547 Field 90[A,B] changed to fieldset. MT564 fixed fieldset items in Field93[B,C] MT565 to MT567 Sequence D, fixed field 13 MT609 and MT798_763 fixed qualifiers in Field 29 When creating MT instances, the validation flag (STP, REMIT, COV) will be automatically created as block 3 field 119 when applies for the created MT Log warning when creating MTnnn objects from invalid message types, for example calling MT103.parse(fin) and passing FIN content for an MT 202 Ignore validation flag (STP, REMIT, COV) if it is not valid for the message type, when creating MT object from SwiftMessage (to avoid ClassNotFoundException) Enhanced semantic in AckMessageComparator when a blocks are null or empty (see javadoc for details on how blank blocks are handled in comparison) 7.8.6 - November 2016 MxParser; IOB exception prevention in strip methods when XML has empty header or document Prevention for IOB exception in ensureEOLS when converting MT message from model into FIN text Expanded API in SwiftParser with static parse methods for each MT block Expanded API in SwiftWriter to serialize any MT block into its native SWIFT representation, also made visit API in SwiftMessage static 7.8.5 - October 2016 Added getSubBlockByTagNames and getSubBlocksByTagNames in SwiftTagListBlock to retrieve subblocks based on comprehensive list or tag names Added API in BusinessHeader to create valid BAH from simple parameters Added API in BIC to get the branch and institution Added API to match message identifier by regex, for example fin.*STP Added API to strip header and document portion of Mx message in XML format Added analizeMessage in MxParser, lightweight API to retrieve structure information from an MX messages Added enumerations for message priority and delivery monitoring in MT block 2 Added json() to AbstractMT Added getComponentLabel(int) in Field classes Added updateFrom AbstractMT to MtSwiftMessage Added reference as class attribute in AbstractSwiftMessage (set by subclasses) Added FileFormat attribute to AbstractSwiftMessage for clear identification of content in implementing subclasses Added constructor of MxSwiftMessage from AbstracMX Added API to get BIC codes from DN in Mx messages Added MtId class, analogous to the existing MxId for MX messages SwiftParser parsing of block 4 published as static public method Added AbstractMessage as base class for specific MTnnn and MXmmm model hierarchy Added MessageStandardType with MT and MX values and ServiceIdType for header service id values Added nextSwiftMessage in RJE/PPC readers for system messages support Added valuesNumeric to MT enumeration MtType Added getValueDisplay with optional locale parameter to display formatted field and individual components values Added MTVariant enum and getVariant API in swift messages Added CONDITIONAL_QUALIFIER component number as static class field for all generic fields (fields implementing the GenericField interface) Added BusinessHeader serialization into xml and Element objects Added business header parse from Element object in MxParser Added RJEReader and RJEWriter to create MT message files in RJE format Added PPCWriter to create MT message files in DOS-PPC format (also enhanced API for the existing PPCFileReader) Added path() API in MxNode Added MtType, an enumeration of all available MTnnn implementations Added parse to Field classes to update field components from full value Added append lists of Tag or Field to TagListBlock Added support for attributes in MxNode Added generic setters for attributes in header blocks 1 and 2 using qualified names (#setField) Added write XML method for MX business header Added validName as static method in Field, to validate field names Added getField static API in Field to create new instances with reflection given the field name and value Added reference(msg) to SwiftMessageUtils to get the sender reference from messages that contain a reference field Added SwiftMessageRevision to the swift messages model, to hold and track changes in swift messages Fixed parser for field 98F Fixed field 61 parse allowing EC and ED as credit/debit mark subfield Fixed from() and to() methods in BusinessHeader to return the BIC code for both possible header types FIxed serialization of component 1 in field 50F Fixed parser and serialization in Field98F Fixed SwiftMessage.toJson single quote to double quote in timestamp field Fixed getLabel when used with the parameters combination of a valid mt and a null sequence Fixed getValue in Field61, Added proper implementation for isOptional(component) in Field61 Fixed components trim to null in parser for several fields when the component value is not present Fixed separators trim in getLine API Fixed setComponentN(Number) when component is not a SWIFT amount, Number is now serialized as an integer (without decimal separator) Fixed MT parser to allow additional lines in a field start with colon ':' Fixed field 32R second component changed from currency to string to allow codewords \u2019FOZ\u2019, \u2019GOZ\u2019, \u2019GRM\u2019, \u2019KLO\u2019, \u2018LIT\u2019, \u2019LOT\u2019, \u2018OTH\u2019, \u2018PND\u2019, \u2019TAL\u2019, \u2019TOL\u2019, \u2018TON\u2019, \u2018TOZ\u2019, \u2019UNT\u2019 Fixed field 33B first component changed from currency to string to allow codeword \u2019PCT\u2019 used in MT601 Fixed API inconsistencies in MtSwiftMessage when updating from SwiftMessage objects. Bugfix MT506 added mandatory field 28E Added missing getters for Sequence E1 in MT300 Changed MX messages detection in MxParser to lighter implementation using Stax Normalized Input/Output Outgoing/Incoming API in AbstractMT and SwiftMessage SwiftMessage.toJson changed timestamp format to the recommended ISO 8601 MxSwiftMessage meta-data (sender, receiver, reference, identifier) read and set from raw XML content Added support in XmlParser for the field version of Core proprietary XML format for MTs, the parser now reads both formats seamlessly Better header API in MxSwiftMessage to support both ISO and SWIFT business headers Elaborated identifier in MtSwiftMessage, using fin.type.variant instead of just the message type Added comprehensive sequence names into pw_swift_label property files Added translations of pw_swift_label property files to FR, DE and IT (complementing the existent EN, ES and RU files) Completed pw_swift_label property files for all field + mt + sequence combinations Complete application header parsing in MxParser Better application header detection in MxParser based on namespaces Added component labels for field 13K Fields 11R and 11S component 3 split into two independent components. In Field61, component 6 was splitted into two independent components to hold the \"transaction type\" and the \"identification code\" as stated in the standard definition for function Added SwiftParserConfiguration to encapsulate several parsing options, allowing fast parsing of AbstractMT by reading the text block in raw format 7.7.0 - October 2015 valueDate in SwiftMessageUtils isType(int...) in SwiftMessage Enhanced the getSequence API in MT classes with support to nested sequences, allowing for ex: getSequenceE1(getSequenceEList().get(n)) getLine API for FieldNN classes based on semantic lines number identification Copy constructors for FieldNN classes, performing a deep copy of the components' list MxParser message detection New generic XML model and API, as backbone for MX messages. Headers Blocks: new generic getters in blocks 1 and 2 to retrieve attributes using full qualified names from enums; for example getField(SwiftBlock1Field.LogicalTerminal) Static labels for subfields in FieldNN classes to allow for example getComponent(Field93B.BALANCE) BIC: API to check for live and non-live bics MxParser: parseApplicationHeader and constructors from several sources Added missing labels' API to fields: 36E, 69A, 69C, 69D, 70C, 70D, 70G, 90F, 90J, 92D, 92L, 92M, 92N, 92R Added the ApplicationHeader attribute to AbstractMX Added API to search nodes or content by path or name in the MxNode tree returned by the MxParser Added json() and xml() methods to MT classes Added write to file and output streams to AbstractMT and AbstractMX Added consistent constructors from String, File or InputStream to MTnnn classes Added static parse methods to create MTnnn objects from String, File, InputStream or MtSwiftMessage Added consistent constructors from String, File or InputStream to AbstractSwiftMessage and subclasses MtSwiftMessage and MxSwiftMessage Added static parse methods to create MtSwiftMessage and MxSwiftMessage objects from String, File or InputStream Lib: added read from input streams NPE prevention in SwiftFormatUtils.getCurrency Fixed getSender and getReceiver for MTxxx to return accurate information regardless the message being of type input or output (also to be consistent with analogous methods in SwiftMessage) Added CR and LF to charset z and x at SwiftcharsetUtils Fixed validation of fields 70F, 77S and 77T that unnecessary restricted the allowed amount of lines (not it is unlimited because charset Z allows CRLF). Fixed OutOfBound exception at MxNode findFirst implementation when a node has multiple children Fixed getDescription for Field35B, now returning component 3 instead of 2 Better API consistency between MT and MX implementations, with common ways to parse and build. Changed sender and receiver attributes for MtSwiftMessage to hold BIC8 instead of full LT identifiers. Deprecated the use of model message inside MtSwiftMessage Simplified distribution zip with -sources and -javadoc jars 7.6.0 - October 2014 New BIC API: isTestAndTraining(), getLogicalTerminalIdentifier(), bic8() and bic11() New model for LT addresses, and its related API in header classes New SwiftMessage API: AbstractMT toMT() New AbstractMT API: getSequence(name), getSequenceList(name) Added builder API: constructors and append methods to add content with chaining support Added missing getValue() implementations to field classes. Example: Field26C Added annotations to MTNNN classes to identify sequence split strategy involved (more traceable code) SRU 2014. Affected MTs: 300, 304, 305, 306, 340, 341, 360, 361, 380, 381, 502, 506, 508, 509, 513, 514, 515, 518, 527, 530, 536, 537, 538, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 558, 564, 565, 566, 567, 568, 569, 575, 600, 601, 942 Added description and release javadoc comments to MT classes Added MX Generic model support Added MX parse Added MT300.getSequenceE() Minor fix in MT300 sequences structure, B1 and B2 inside B, and named D's subsequence as D1 SwiftTagListBlock implements Iterable Bugfix SwitTagListBlock.countTagsStarsWith(string,string) was ignoring tagnames in count 7.5.0 - August 2014 Added toJson in SwiftMessage and SwiftTagListBlock, SwiftBlock1 and 2 Added to SwiftTagListBlock getFieldByName(String, being) Added to SwiftTagListBlock getFieldByName(String, being, component2) Added to SwiftTagListBlock getFieldByNumber(int , being) Added START_TAG and END_TAG constant to Sequence inner classes Added Sequence.newInstance() method Added static method Field.emptyTag() Added to SwiftTagListBlock append(SwiftTagListBlock) Changed SwiftFormatUtils.getNumber(Number) to allow variable amount of decimal parts without the previous limit of two Added support for national clearing system codes in party identifier components: example 52A starting with //AT123 JSON serialization: fixed missing quotes escaping and newline in some occasions, getSequenceA() incorrectly returned null instead of empty sequence as stated in javadoc Refactored Field77A to include 20 independent components instead of just one (current implementation is similar to Field79) Deprecated isAnyOf(String ... names) and added isNameAnyOf(String ... names) semantics of method more clear with its name Changed the semantic of getAccount methods to remove starting slashes if any Some javadoc for BICRecord Added serialization timestamp to JSON generation In Field* void set changed to Class set so we can support the code style new Field().setThis().setThat().setThatToo() Added Field.asTag() Added option in XMLWriterVisitor to serialize field instead of tag 7.4.0 - March 2014 In BIC added subtype attribute and getBranch method ReaderIterator to read a file from a classpath resource and split its content by the '$' symbol In SwiftMessage new API to check and get linkages sequences In AbstractSwiftMessage new constructor using MTSwiftMessage as parameter In MTSwiftMessage updateFromModel and updateFromFIN using internal attributes Several helper methods to parse field content using SwiftParseUtils Field classes implementation for fields belonging to System and Service Messages (i.e. 451) Resource bundle labels for System and Service Messages fields MOR class to represent the message output reference (inherited from the MIR) SwiftParseUtils: getTokenSecond and getTokenSecondLast with prefix getAll(SwiftMessage) in every FieldNN class getAll(SwiftTagListBlock) in every FieldNN class New constant in Field suitable for import static SwiftTagListBlock: constructors made public SwiftTagListBlock: added filterByNameOrdered(String ...) SwiftTagListBlock: added getFieldsByNumber(int) SwiftTagListBlock: added removeSubBlock(String) SwiftTagListBlock: deprecated int getTagCount(String) SwiftTagListBlock: added int countByName(String) SwiftTagListBlock: deprecated int getTagCount() SwiftTagListBlock: added int countAll() SwiftTagListBlock: added method boolean containsAllOf(String...) Improved toString in SwiftTagListBlock and Tag Javadoc improvements Fixed SwiftBlock1 constructor to allow LTs missing the optional A, B or C identifier (11 characters length); ex. FOOOAR22XXX Fixed getStatusInfo and getPreviousStatus in messages base class that was causing IOB exceptions Issue 39: missing trimToEmpty in getComponent2 in 50H MT207: fixed maximum repetitions of sequence B from 1 to unlimited 7.3.0 - January 2014 removed log4j.properties New API: Field.isAnyOf(String...) Added many methods in SwiftTagListBlock in resemblance to String manipulation API SwiftTagListBlock added: getTagsByNumber(int), SwiftTagListBlock removeAfterFirst(String, boolean) Added Tag.startsWith Added Tag.contains Added PPCFileReader iterator to read and split pc connect files 7.2.0 - September 2013 Added Field.letterOption Added SwiftTagListBlock.getSubBlockBeforeFirst Added SwiftTagListBlock.filterByName Fixed Field.appendInLines that was causing the getValue of several fields (ex 35B) to start with unexpected EOL Fixed NPE in XMLParser with null value in tags Fixed Avoid usage of double in amount resolver 7.0.0 - August 2013 Enhanced messages model with base support for MX messages. New messages meta-data model to handle additional information: Status history, User notes, Properties list. Useful API to SwiftMessage to get: direction, PDE, PDM, UUID, MIR, MUR and getTypeInt Complete FieldNN implementation classes Complete MT helper classes, covering all message types Added model and API to handle Sequences at MT classes, covering all sequences based on 16R/16S boundaries. New API to handle sub blocks: SwiftTagListBlock.removeUntilFirst, SwiftTagListBlock.containsAnyOf Ensuring of SWIFT EOL at ConversionService.getFIN Fixed getValue of several fields to prevent printing of null Fixed getValue of several fields with missing slash separator on optional components Added missing field getters for MT classes with fieldsets: for example 93B at MT564. getValue for Field35B. Thanks to Raghu rathorr@users.sf.net getCalendar bug related to unused format parameter Changed Field26C parser and subfields structure to split the string before the VAR-SEQU into independent components Removed deprecated net.sourceforge classes Removed unimplemented method amounts() in AmountContainer 6.4.0 - March 2013 Added visitor API on tag list block New interface to identify and use generic fields (notice DSS methods are not part of non-generic fields) Added API on MT classes to simplify messages creation Comprehensive getters and setter API for field classes using functional names Added PatternContainer interface and implemented in field Better CurrencyContainer API Added API to SwiftFormatUtils to get String components from Calendar using different SWIFT date/time formats Implemented API for CurrencyContainer for all Fields Added MT helper classes for MTs: 518, 549, 800, 801, 802, 824, 600, 601, 604, 605, 606, 607, 608, 609 Added Field implementations for 33G, 35U, 86B, 68A, 68B, 68C, 94C, 31F, 37a, 34J, 35H, 31X Added API to simplify messages creation; defaults for header blocks attributes, addField to Block4, setSender at Block1 6.3.0 - October 2012 Added MT helper classes for MTs: 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 565 Fixed getAsCalendar for year component of field 77H Fixed parsing of field 50F Added field class for: 26C Support to identify which sequence a tag belongs to Added API to FieldNN classes to get the DSS field Added API to FieldNN classes to get the qualifier and conditional qualifier components Added API to FieldNN classes to determine if field is generic or non generic Field class made abstract FieldNN isOptional: method to check if a given component is optional for the field Field getLabel: support for label exceptions per mt and sequence SwiftParser changes to distinguish the presence of brackets when they are block boundaries or part of an invalid field value Improved parsing of Field35B, first and second components are set only if \"ISIN \" is present SR2012 update: deprecated fields 23C, 23F. Updated MT300, MT304, MT305 with field changes. Added serialization for: 20E, 29G, 31G, 36E, 50G, 50H, 69B, 69D, 69F, 77H, 90F, 90J, 90K, 92D, 92L, 92M, 92N, 94D, 94G, 95T, 98F Fixed serialization of field 59A 6.2.0 - June 2012 Purged and some tunning of parser log Added getField* API con block4 Added Tag API: public boolean contains(String ... values) Added more API to get subblocks based on tag number boundaries regardless of letter options Fixed Tag.isNumber to consider the whole number and not just the prefix, isNumber(58) returns true to 58A but not to 5 Added Tag.getNumber() API Fixed build to include MTs and FieldNN source codes in the package Fixed parser for fields: 94D, 50H, 50G and 52G Added MT helper classes for MTs: 567, 900, 910, 920, 935, 941, 970, 971, 972, 973, 985, 986 Added API for getLabel at Field objects, to retrieve business oriented names from resource bundles 6.1.0 - March 2012 Added BICContainer interface Added MT helper classes for MTs: 360, 361, 362, 364, 365, 381, n90, n92, n95, n96, n98, 420, 422, 430, 450, 455, 456, 701, 705, 711, 720, 721, 732, 734, 740, 742, 747, 750, 752, 754, 756, 768 Added getValue for Field13E Fixed getValue for Field31R (2nd component is optional) 6.0.0 - February 2012 Merged patches from Walter Birch SwiftParser: fix for parse error with malformed tag 72 Implemented getValue for Fields: 19B, 31D, 31P, 31R, 39P, 40B, 41D, 92F, 93B, 98E and others with the same parser pattern Changed packages in Hibernate mappings from sourceforge to prowidesoftware Added SwiftMessageUtils class Added date container interface to Fields to better support higher level model expressions Added currency container interface to Fields to better support higher level model expressions SWIFT standard update (Nov 2011) Fixed field parser for 35B Changed SwiftParser log level Build: consistent release in jar, sources and javadocs jars, include dependent jars in lib directory API to create FieldNN objects from Tag objects Fixed field parser for 35B when first component is an ISIN number Added DATE1 support for fields parser (fixes Field61) SwiftMessage API to get sender and receiver addresses from message headers Added MT helper classes for MTs: 101, 104, 105, 107, 110, 111, 112, 200, 201, 204, 205, 205COV, 207, 256, 300, 305, 306, 307, 330, 340, 341, 350, 540, 541, 542, 543, 564, 566 MT helper classes 102_not_STP and 103_not_STP with inheritance from defaults MT103 and MT102 classes Added Field implementations for 36E, 69B, 69D, 69F, 90F, 90J, 93B, 93C, 94G, 95T, 95S, 98E, 98F, 98L, 67A, 77J, 92E, 98D, 95S, 50G, 50H, 52G, 31G, 77H TIME3 implementation to format utils Suppress warnings for unused imports in eclipse 6.0.0-RC5 - August 2011 Fixed parser for Field20E Added Field implementations for 90K, 92D, 92L, 92M, 92N 6.0.0-RC4 - July 2011 Added MT helper classes for MTs (SCORE): 798<743>, 798<745>, 798<760>, 798<761>, 798<762>, 798<763>, 798<764>, 798<766>, 798<767>, 798<769>, 798<779>, 798<788>, 798<789>, 798<790>, 798<791>, 798<793>, 798<794>, 798<799> Added MT helper classes for MTs: 191, 291, 391, 399, 491, 535, 591, 691, 699, 707, 760, 767, 769, 790, 791, 891, 991, 999 Added Field implementations for 13E, 20E, 22L, 23X, 24E, 27A, 29D, 29G, 29S, 31R, 39D, 39P, 49H, 49J, 50M, 72C, 77C, 77E, 78B 6.0.0-RC3 - April 2011 Added MT helper classes for MTs: 304, 320, 321, 210, 599 Added Field implementations for 19B, 32H, 32R, 34E, 37G, 37M, 37R, 38J, 92F, 62A, 62B 6.0.0-RC2 - February 2011 Added Field implementation for 15 (A,B,C,D,E,F,G,H,I,J,K,L,M,N) Added MT helper classes for MTs: 300, 400, 410, 412, 416, 499, 544, 545, 546, 547, 548, 700, 710, 730, 799 Added Field implementations for 31D, 31P, 40B, 41A, 41D, 45A, 45B, 46A, 46B, 47A, 47B field serialization from components values into SWIFT single string value Removed log4.properties from distribution jar MTs API: fixed field mutiplicity when a field becomes repetitive being present on multiple sequences or at repetitive sequences. Hibernate mappings: removed confusing/commented blocktype mappings at SwiftBlock.hbm.xml Hibernate mappings: package rename 6.0.0-RC1 - October 2010 Migrated src code to java 1.5 (binary distribution is still 1.4 compatible by means of http://retroweaver.sourceforge.net/) Java 1.4 compatibility changes normalization of linefeeds to CRLF at Tag creation from XML parsing Removed deprecated API Added new package io with subpackages parser and writer; added new package utils. Renamed all packages to com.prowidesoftware (backward compatibility maintained with facades) Added implementation for MTs 102 not STP, 102 STP, 103 not STP, 103 STP, 195, 199, 202, 202COV, 203, 295, 299, 940, 942, 950 Added new SWIFT MT high level generated API, with classes for specific message types New source package for generated swift model Merged project \"prowide SWIFT Fields\" into \"WIFE\" Added comparison options to AckMessageComparator Removed old and incorrect charset validator class net.sourceforge.wife.swift.MessageValidator Fix in remove user block method, thanks to Herman's contribution and patience Parser API for (new SwiftParser()).parse(messageToParse); Replaced commons-lang-2.3 -> 2.4 Fixed message writer: system messages' block4 generated with inline tags SwiftMessage API to check if it's Straight Through Processing (STP), based on the content of the User Header SwiftMessage API to check if it's a cover payment (COV), based on the content of the User Header SwiftTagListBlock API to check if contains a specific Tag Removed unimplemented and confusing package net.sourceforge.wife.validation Deprecated old and unused validation-related classes Added AckMessageComparator which is useful of identify the ack of a given message. SwiftTagListBlock API to get a sub block given its name or its starting and ending Tag SwiftTagListBlock API to get tags by content, given its exact or partial value Helper methods from Block4 moved to SwiftTagListBlock SwiftTagListBlock is no longer abstract, so it can be used to create instances for subblocks Required JVM upgrade to 1.5 Initial update of upload-sf target for release to sourceforge 5.2.0 - February 2009 Added missing hashcode and equals Javadocs improvements Revised and tested hibernate mappings Added getBlockType Added length to unparsed text persistence mappings Fixed persistence mapping for block2 inheritance Updated hibernate libs to version 3.2.6 Added isOutput isInput made concrete, not abstract Added abstract isInput() method to SwiftBlock2 for safer casting subblocks when input/output is unknown 5.1.0 - July 2007 Migrated logging to java logging api Removed SwiftBlock's deprecated methods. Moved some common methods in SwiftBlock2Input/SwiftBlock2Output to parent class SwiftBlock2. Upgraded commons-lang to version 2.3 Improved persistence mapping. Move persistence (helper) package to wife-test project. Minor javadoc fixes. Fixed some warnings. 5.0.0 - June 2007 Improved Hibernate mapping for simplified and more efficient data base schema. Added support for unparsed text to model, persistence mapping and conversion services (needed for some MT0xx for example). XML to SwiftMessage parsing methods moved from ConversionService to XMLParser in \"parser\" package. New package created for parser classes \"net.sourceforge.wife.swift.parser\". Made abstract intermediate classes of blocks object hierarchy. Added support for user custom blocks in model, persistence mapping and conversion services. Improved overall test cases coverage and source/resources structure. Fixed some warnings. Swift Parser enhancements; don't throw exception on unrecognized data, but preserve an internal list of errors. Added reference to current message in parser, so it can take decisions based on parsed data. Added constant for possible values for application id to SwiftBlock1. Updated dependency: hsqldb 1.8.0.4 -> hsqldb 1.8.0.7. Updated dependency: hibernate 3.1.3 -> hibernate 3.2.3.ga. 4.0.0 - April 2007 Moving to junit 4 - some new tests are being written with junit4, this should make testing some features singificantly easier. Move size and isEmpty methods to subclasses. Improved deprecated exception messages and javadoc. Added useful getter for the MIR field in Block 2 output. Added support for optional fields in Block 2 input. Method specific to each block moved to each block class, when possible compatibility methods were left in old places, marked as deprecated to provide a smoother migration path. Removed deprecated API in SwiftBlock. Adapted parser to new model refactor. More javadoc in parser. Improved xml writer (more clean tabs and EOL). Refactored and fixed XML parsing for blocks 3 and 5. Fixed build.xml to include resources in generated jar files. Improved javadoc and validations in fin writer. Completed basic internal XML parsing. Added more tests for XML conversion. Implemented XML conversion parsing for all blocks (except 4). Updated passing test in conversion service. 3.4.0 - March 2007 Added license header to source files. Minor fixes in build system. Enhanced IBAN validation routine. Added numerous tests for IBAN validation. Added JSValidationUnit backed by Rhino, to support easy extension of validations. Made all loggers private static transient final. Enhanced overview documentation. Javadoc updates. Code clean up. Added many tag specific validation units targeting MT103 validation. Removed ant junit fork since it broke in ant 1.7. 3.3.0 - January 2007 Initiated MT103 validation rule. Validation framework core classes written. Utility classes for validation. Removed old and deprecated/replaces writer component. Dependencies clean up, ant downloads less libs now. Added Currency ISO Codes (needed for validations). VF: implemented TagExists and ConditionalTagPresence validation units. Started implementation of validation units. Initial implementation of BIC validation. Initial implementation of IBAN validation. Added ISO Countries for IBAN validation. Fixed issue in writer with block5 as mentioned in bug 1601122. Fixed issue 1595631. 3.2.0 - 2006 Parser logging information cleanup. Migrating to log4j 1.2.8 for better compatibility (issued with trace method on some servers). Fixed build to properly include current timestamp in dist target when property release.name is not set. Fixed bug in parser/writer integration which included double block number when using the writer with an object of a just parsed message(1595589). Updated code to fix issue mentioned in https://sourceforge.net/forum/message.php?msg_id=4001538. 3.1.1 - 2006 Small fixes for java 1.4 compatibility. 3.1.0 - 2006 Fixes to compile for java 1.4 by default. Fixed test for bug 1540294, typo in block number. Use system EOL in XML writer. Added compile timestamp to manifest in created jars. 3.0.0 - 2006 Build: Added release.name property to manifest. Build: added selection of tests known to fail and those known to pass. Fixed persistence mapping. Improved build and added control to exclude tests that are know to fail. Model simplification: SwiftBlockN classes are being removed in favor of base class SwiftBlock removed list of blocks in message which was confusing when not all blocks present. SwiftBlock (base class) and subclasses are mapped and persisted ok, either the base class or the subclasses. Added many tests for Hibernate persistence of SwiftMessage hierarchy. Added XML Visitor to write a swift message to an XML representation. Added ConversionService class which encapsulates many services conveniently. 2.0.0 - 2006 New parser component highly tested on production and unit tests. Writer component usable. while it has many limitations, it can be used as it is now. Work in progress swift message persistence mapping. Work in progress swift expression <-> regular expression conversion.","title":"Prowide Core"},{"location":"release-notes/changelog-core/#prowide-core-changelog","text":"","title":"Prowide Core - CHANGELOG"},{"location":"release-notes/changelog-core/#9416-may-2024","text":"(PW-1862) Added NarrativeFragment class for detailed line information in StructuredNarrative fragments Fixed SwiftMessage getPDE(): return empty value instead of null when codeword exists and has no value Added isPercentage() helper method to field 37K","title":"9.4.16 - May 2024"},{"location":"release-notes/changelog-core/#9415-march-2024","text":"(PW-1812) Updated the narrative resolver, format 2 (used in field 72 for example), to allow empty values as part of the narrative fragment Updated validators for BIC, country, and currency constraints to utilize keywords for i18n-compatible messages Deprecated unnecessary methods in the SafeXmlUtils class","title":"9.4.15 - March 2024"},{"location":"release-notes/changelog-core/#9414-december-2023","text":"(PW-1718) Changed the getComponentLabel(component) in Field59F to be dynamic based on the line identifiers (similar to existing API in Field50F)","title":"9.4.14 - December 2023"},{"location":"release-notes/changelog-core/#9413-november-2023","text":"(PW-1697) Fixed validation/parse pattern in field 29O (PW-1697) MT306 changes in field 30I Added DistinguishedName with Builder in order to encapsulate the BIC branch name logic","title":"9.4.13 - November 2023"},{"location":"release-notes/changelog-core/#9412-november-2023","text":"(PW-1697) Fixed validation pattern in fields 14[H,K,L,M,N,O] and 29J","title":"9.4.12 - November 2023"},{"location":"release-notes/changelog-core/#9411-november-2023","text":"(PW-1695) Fixed a stack overflow in the fields fromJson implementation when a malformed JSON input contains empty field names (PW-1688) Added missing field labels for SRU2023 changes in the pw_swift_*.properties file","title":"9.4.11 - November 2023"},{"location":"release-notes/changelog-core/#9410-october-2023","text":"(PW-1675) update to Field 31R to support also two date components as requested by SCORE messages Added 36B and 36D getters to MT543","title":"9.4.10 - October 2023"},{"location":"release-notes/changelog-core/#949-october-2023","text":"(PW-1659) Field 24G deprecated Name and Address for Narrative","title":"9.4.9 - October 2023"},{"location":"release-notes/changelog-core/#948-october-2023","text":"Added default methods for sender, receiver, and identifier extraction to the MessageExtractionStrategy Added JSON to the FileFormat enumeration","title":"9.4.8 - October 2023"},{"location":"release-notes/changelog-core/#947-september-2023","text":"(PW-1478) Fixed Field 44J parse and getValue to enable proper data preservation when the field contains multiline content","title":"9.4.7 - September 2023"},{"location":"release-notes/changelog-core/#946-september-2023","text":"Added support for an optional pw-swift-core.properties to customize the behavior of the SafeXmlUtils class","title":"9.4.6 - September 2023"},{"location":"release-notes/changelog-core/#945-august-2023","text":"(PW-1478) Field 44J parse and getValue fix","title":"9.4.5 - August 2023"},{"location":"release-notes/changelog-core/#944-august-2023","text":"(PW-1478) Field 44J format fixed to allow multiline","title":"9.4.4 - August 2023"},{"location":"release-notes/changelog-core/#943-july-2023","text":"(PW-1461) Remove deprecation of field 31R model since is it used back in SRU2023 (PW-1405) Trim original String payload when creating an AbstractSwiftMessage","title":"9.4.3 - July 2023"},{"location":"release-notes/changelog-core/#942-june-2023","text":"(GH-163) Remove unnecessary padding in sender and receiver in AbstractMT#creeate(number, sender, receiver) method (PW-1323) Fixing getValue method for pattern issue in Field44J","title":"9.4.2 - June 2023"},{"location":"release-notes/changelog-core/#941-june-2023","text":"(PW-1323) Fixing missing pattern issue in Field44J","title":"9.4.1 - June 2023"},{"location":"release-notes/changelog-core/#940-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"9.4.0 - May 2023"},{"location":"release-notes/changelog-core/#9315-may-2023","text":"(PW-1341) Avoid log pollution with exception stacktrace in Field#formatAccount method (PW-1264) Added distinguishedName(boolean includeDefaultBranch) method to BIC in order to return default branch name","title":"9.3.15 - May 2023"},{"location":"release-notes/changelog-core/#9314-march-2023","text":"(PW-1182) Fixed MT internal Loops API, when strategy is GENERATED_FIXED_WITH_OPTIONAL_TAIL and the tail part contains repetitive fields, such as MT920 (PW-1241) Added addUnstructuredStrict method to Narrative in order to strictly wrap unstructured input","title":"9.3.14 - March 2023"},{"location":"release-notes/changelog-core/#9313-march-2023","text":"Deprecated all fields that are only used in SCORE messages and not in the general MT standard as they will eventually be removed from the library","title":"9.3.13 - March 2023"},{"location":"release-notes/changelog-core/#9312-february-2023","text":"(PW-1109) Changed Narrative Resolver to validate minimum codeword length of 1 char (GH-148) Fixed parser of Field61 amount component when number starts with the decimal comma (implicit zero in amount lower than 1) Added getComponent(String componentName) to retrieve the component based on the name instead of the number Added componentNameToNumber(String componentName) to retrieve the component number based on the component name","title":"9.3.12 - February 2023"},{"location":"release-notes/changelog-core/#9311-january-2023","text":"(PW-1152) Preserve line breaks when creating NarrativeContainer fields from JSON with legacy structure: narrative1, narrative2, etc... Fixed duplicate elements when serializing NarrativeContainer fields into JSON","title":"9.3.11 - January 2023"},{"location":"release-notes/changelog-core/#9310-january-2023","text":"(PW-1150) Added field model class for 31M (required in SCORE MT798_753) (PW-1150) Added field model class for 71E (required in SCORE MT798_755 and MT798_757)","title":"9.3.10 - January 2023"},{"location":"release-notes/changelog-core/#939-december-2022","text":"(PW-1078) StructuredNarrative: Fixed parser to treat the optional [3!a13d] part as a unit block, both currency and amount present or missing","title":"9.3.9 - December 2022"},{"location":"release-notes/changelog-core/#938-november-2022","text":"(GH-127) Enhanced field JSON serialization to include detailed structure when the field is a NarrativeContainer","title":"9.3.8 - November 2022"},{"location":"release-notes/changelog-core/#937-november-2022","text":"(PW-1101) Fix field 35C labels to match the FIN xsd: Identification Of Instrument, Description Of Instrument","title":"9.3.7 - November 2022"},{"location":"release-notes/changelog-core/#936-november-2022","text":"(PW-1086) Fixed typo in field 36D accessors (PW-1078) StructuredNarrative: Added getBankCode() methods in order to allow direct access to data (used in SCORE messages) (GH-88) Added missing constants for ISO 15022 codes MT540 and MT548 added missing getter for Field99C Added removeRepeatedBoundaries method in order to remove repeated tag boundaries","title":"9.3.6 - November 2022"},{"location":"release-notes/changelog-core/#935-october-2022","text":"SRU2022 updates review: field 35C validation pattern changed to","title":"9.3.5 - October 2022"},{"location":"release-notes/changelog-core/#934-september-2022","text":"Added getCADETL method for \"CADETL\" separator sequences (GH-119) MT566: Fixed repetitions of sequence USECU/FIA that is not repetitive Added sequence getters using the boundary field qualifier, for example getSequenceGENL() as equivalent to the existing getSequenceA()","title":"9.3.4 - September 2022"},{"location":"release-notes/changelog-core/#933-august-2022","text":"(PW-1015) Added field model classes for 47E, 49D and 49F (required in SCORE MT798_774)","title":"9.3.3 - August 2022"},{"location":"release-notes/changelog-core/#932-july-2022","text":"(PW-977) Changed the MT203 and MT210 inner structure from regular sequence to inner loop named Loop1 Added Loop1 getter API to MTs: 110, 201, 203, 210, 410, 412, 420, 422, 450, 456, 604, 605, 801, 920, 973","title":"9.3.2 - July 2022"},{"location":"release-notes/changelog-core/#931-july-2022","text":"(PW-976) Added new MonetaryAmountContainer interface for fields having both an Amount and Currency (PW-969) Modified field 12E, 12K and 12R labels (PW-969) Added an optional narrative component to field 12R (required when the field is used in SCORE messages) (PW-898) Changed the heuristic to retrieve sequence B1 from MT300 and MT304 to be more efficient even if the message structure is invalid (PW-867) Enhanced the parsing of party fields A, B and D, to be more strict when splitting the /D/ or /C/ prefix from the account Enhanced MtId constructor with regex matching Added method namespaceURI() in the MtId class to return for example \"urn:swift:xsd:fin.103.2021\" for the MT103","title":"9.3.1 - July 2022"},{"location":"release-notes/changelog-core/#930-may-2022","text":"SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Updated gson dependency to 2.9.0","title":"9.3.0 - May 2022"},{"location":"release-notes/changelog-core/#9213-april-2022","text":"(PW-892) Fixed AbstractMT#create when the message type number is less than 100 Added a convenient String message() method in the SwiftMessage object to get the FIN serialization of the message Fixed error in Field 94G getValue","title":"9.2.13 - April 2022"},{"location":"release-notes/changelog-core/#9212-march-2022","text":"(GH-103) fixed invalid ConstraintValidator annotation on CurrencyValidator (GH-95) patterns getters are now non-final to avoid overwriting; static constants have been deprecated RJE and PPC readers, added a constructor with explicit charset (same in swift parser from input stream) Validate.notNull -> Objects.requireNonNull Spotbugs code review","title":"9.2.12 - March 2022"},{"location":"release-notes/changelog-core/#9211-january-2022","text":"Added LineWrapper (utils) to replace Apache's WordUtils.wrap and thus the commons-text dependency Added convenient method in the envelop message MT798 to get the sub-message type as a SwiftMessage Added a copy constructor to the Tag class","title":"9.2.11 - January 2022"},{"location":"release-notes/changelog-core/#9210-january-2022","text":"(PW-815) Fixed getValue in field 12H (SCORE) where narrative is optional (GH-89) MT530: Fixed repetition of sequence C ADDINFO Updated dependency: gson:2.8.8 -> gson:2.8.9 Java 11 and 17 compatibility updates Added plugins for automatic versioning and code quality reporting","title":"9.2.10 - January 2022"},{"location":"release-notes/changelog-core/#929-december-2021","text":"(GH-78) Fixed MT537#getSequenceBList where sequence B delimiter \"STAT\" overlaps with C3 and D1a1B1a delimiters (GH-74) Fixed parser for Field48 and similar cases to avoid trimming content when the component contains also the slash separator as part of the value (GH-62) Added com.prowidesoftware.core as automatic module name in the MANIFEST for JPMS support Fields getComponentLabel is now public, returning the specific label for each field component Fixed bug in PartyIdentifierUtils.getPartyIdentifier Fixes in field component names and optional status Fixes in field parsing Incompatible change in field 71N (changed from 7 Narrative lines to Code + 6 Narrative lines) Incompatible change for field 11T to have two lines (MT new-line DATE + TIME) Fixed Structured Narrative parsing to return an empty Narrative object with null string values","title":"9.2.9 - December 2021"},{"location":"release-notes/changelog-core/#928-november-2021","text":"(PW-764) Added new variant values (RFDD, ISLFIN) (PW-703) Block 2 parser: lenient parser to avoid duplicate error when exception on invalid Input/Output indicator (CR-23) Enhanced getValueDisplay for fields (no decimal separator for numbers that are not amounts)","title":"9.2.8 - November 2021"},{"location":"release-notes/changelog-core/#927-october-2021","text":"Field 98D, 98E and 98G: removed invalid get{Component4|Sign}AsCurrency and set{Component4|Sign}(Currency) as no currency applies to these fields Fields 94L and 85L: separated component 2 (Legal Entity Identifier) into two (Legal Entity Identifier Code and Legal Entity Identifier Number). Kept get/setLegalEntityIdentifier for backwards compatibility Field 94H: second component now has get{name}AsBIC and set{name}(BIC) methods Field 56B: now inherits from OptionBPartyField (to have get/setPartyIdentifier) Field 26C: separated component 5 into 5 (Denomination) and 6 (Form) for compatibility with Swift. Kept get/setDenominationForm for backwards compatibility Field 26A: now has 2 components (Number 1 and Number 2) for compatibility with Swift. get/setNumber is kept for backwards compatibility Field 23: fixed getValue and parse to properly handle missing intermediate fields Field 14S: has 4 new compatibility methods: getRateSource/setRateSource for Source and Number components and getTimeAndLocation/setTimeAndLocation for Time and Location components Field 12: component is now of expected to have a numeric type Code cleanup for Fields and Date|BIC|Amount|Currency Container Added support for BigDecimal and Long component types (instead of just Number) in several fields Fixed display text generation for fields having a date with pattern MMDD (only the month was included in the text) OptionAPartyField: added set/getPartyIdentifier (for components 1 and 2) and renamed BIC to IdentifierCode. Affects fields 42A, 51A, 52A, 53A, 54A, 55A, 56A, 57A, 58A, 81A, 82A, 83A, 84A, 85A, 86A, 87A, 88A, 89A, 91A and 96A OptionDPartyField: added set/getPartyIdentifier (for components 1 and 2). Affects fields 42D, 50D, 51D, 52D, 53D, 54D, 55D, 56D, 57D, 58D, 81D, 82D, 83D, 84D, 85D, 86D, 87D, 88D, 89D, 91D and 96D OptionBPartyField: added set/getPartyIdentifier (for components 1 and 2). Affects fields 52B, 53B, 54B, 55B, 57B, 58B, 82B, 84B, 85B, 86B, 87B and 88B Prepared Option A, B and D classes to support the PartyIdentifier interface with methods getPartyIdentifier and setPartyIdentifier Enhanced Block2 creation by enriching Block Type to \"O\" or \"I\". (PW-746) Fixed MT reference extraction for 20C in categories other than 5, and with MUR as fallback option (CR-23) Added SwiftMessage#getMOR Updated dependency: Apache Commons Lang 3.8.1 -> 3.12.0 Updated dependency: Apache Commons Text 1.6 -> 1.9 Updated dependency: Gson 2.8.2 -> 2.8.8","title":"9.2.7 - October 2021"},{"location":"release-notes/changelog-core/#926-october-2021","text":"(GH-60) Enhanced parser for field 98C (PW-703) Enhanced SwiftParser in order to validate \"Input\" or \"Output\" Block 2 type Enhanced the MtId to automatically extract the variant from String identifiers such as \"fin.103.STP\" or \"202.COV\"","title":"9.2.6 - October 2021"},{"location":"release-notes/changelog-core/#925-september-2021","text":"(PW-664) Parser enhancement to be lenient on LF before block identifier","title":"9.2.5 - September 2021"},{"location":"release-notes/changelog-core/#924-august-2021","text":"MultiLineField: preserve starting component separator when getting lines with offset","title":"9.2.4 - August 2021"},{"location":"release-notes/changelog-core/#923-august-2021","text":"Added user assigned country codes (example \"XE\") as valid codes in the IsoUtils country validation Added field classes for SCORE messages: 11T, 12[S,R], 25G, 31[J,K,T], 34[D,K,L,M,S,T,U,X,V,W], 49[J,K,L] (to be used in the proprietary payload of the MT798 envelop) MT564: Minor scheme fix, 92a TAXR and WITL can be repeated in CASHMOVE (E2)","title":"9.2.3 - August 2021"},{"location":"release-notes/changelog-core/#922-july-2021","text":"(PW-627) fixed Narrative.builder() to compute \"//\" size in the lines wrapping (PW-581) the MultiLineField API now preserves any starting and trailing spaces in field lines MT565: fixed repetition of sequence B2 (multiple to single) MT548: Minor scheme fix, added letter option \"C\" in field \"98C:SCTS\" in sequence \"C1a1B1\"","title":"9.2.2 - July 2021"},{"location":"release-notes/changelog-core/#921-june-2021","text":"Added \"ignore block 3\" and \"ignore priority\" options to the SwiftMessageComparator Added field classes for SCORE messages: 12[H,K,L], 20E, 25F, 29[D,F], 31R, 78B (to be used in the proprietary payload of the MT798 envelop) Enhanced parser for LogicalTerminalAddress when the parameter has 9 characters (PW-534) allowed null value for the Tag constructor","title":"9.2.1 - June 2021"},{"location":"release-notes/changelog-core/#920-may-2021","text":"SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Fixed the getSequence API in MT classes when the sequence boundary field is repetitive, in some scenarios produced invalid results (PW-519) Field92H: Added \"Rate Status\" accessors (PW-519) Field92J: Replaced \"Narrative\" accessors by \"Rate Status\" accessors","title":"9.2.0 - May 2021"},{"location":"release-notes/changelog-core/#914-april-2021","text":"Fixed getConditionalQualifier in fields 69C, 69D and 92H Fixed field 41D isOptional(component) method (PW-510) Fixed parser of field 90L (PW-508) Fixed validator pattern in field 98K Added MultiLineField interface implementation to fields: 45C, 45L and 49Z Removed MultiLineField interface implementation to field 77H since its value is always a single line (PW-501) Added getNarrative(deli), getNameAndAddress(deli) and similar getters in Field classes to get a concatenation of the relevant components with a specific delimiter (PW-501) Fixed the getNarrative(), getNameAndAddress() and similar getters in Field classes to do a simple join of the relevant components, without CRLF and without components value trim (PW-505) Fixed SwiftFormatUtils#decimalsInAmount(BigDecimal) NPE prevention in AbstractMT.getFields() when the parsed FIN content is invalid Added UETRUtils to generate the GPI unique end-to-end transaction reference, mandatory for several payment messages Added customizable strategies to set the MtSwiftMessage metadata fields: reference, main amount, value date, etc... Added field classes for SCORE messages: 13E, 21S, 21T, 27A, 29P, 29S, 29U, 49Z (to be used in the proprietary payload of the MT798 envelop) (PW-451) Added backward compatible implementation in setComponent and SetNarrative API of narrative container fields: 29A, 37N, 70, 71B, 71D, 72Z, 72, 73A, 73, 74, 75, 76, 77A, 77B, 77D, 77 (PW-445) Added backward compatible fromJson for narrative container fields: 29A, 37N, 45B, 46B, 49M, 49N, 70, 71B, 71D, 72Z, 72, 73A, 73, 74, 75, 76, 77A, 77B, 77D, 77J, 77 Added Direction to the SwiftBlock2Field enumeration Added more message type cases to the SwiftMessageUtils valueDate Minor fixes in MT530 model: fields B/22F and C/90[A,B]","title":"9.1.4 - April 2021"},{"location":"release-notes/changelog-core/#913-december-2020","text":"Changed SwiftMessage#isGpi() to be true for: 103, 199, 299, 192, 196, 202COV or 205COV (mandatory outgoing GPI types) Removed the indexes from the AbstractSwiftMessage JPA mapping (can be created directly in the DB as needed) Added options in the MT message comparator to ignore the LT identifier or test flag when comparing header LT addresses Added asTestBic in BIC to create a test BIC by setting the second component of the location to zero Added API in the SwiftBlock2Output to set the MIR date and receiver date time fields from Calendar object","title":"9.1.3 - December 2020"},{"location":"release-notes/changelog-core/#912-october-2020","text":"Fixed set of MUR when an MtSwiftMessage is created from an acknowledge (service 21 message) Changed AbstractSwiftMessage JPA mapping to EAGER load the status trail and the properties Added a new MessageDirection enum as alternative to the legacy MessageIOType","title":"9.1.2 - October 2020"},{"location":"release-notes/changelog-core/#911-september-2020","text":"Fixed parser for fields 94L and 95L Added MurMessageComparator to match ACKs based on the MUR Changed the SwiftMessage#getMUR to retrieve field 108 from either block 3 or block 4 (system messages) Enhanced the AckMessageComparator to still match on differences in block 2 optional fields or block 4 EOL characters Minor refactor in MtSwiftMessage update from model (SwiftMessage) Added a trim to the content parsed from the RJE reader Fixed setPdm in MtSwiftMessage that was over writing the pde field Minor changes in the MtSwiftMessage to avoid log warnings when setting metadata from message model Added convenient field getters in the ServiceMessage21 (ACK/NAK) model class and made the getMtId() return \"gpa.021\"","title":"9.1.1 - September 2020"},{"location":"release-notes/changelog-core/#910-may-2020","text":"SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Enhanced components namings in field 98[DEGH] Added rich API to parse and build narrative fields: 29A, 37N, 45B, 46B, 49M, 49N, 70, 71B, 71D, 72Z, 72, 73A, 73, 74, 75, 76, 77A, 77B, 77D, 77J, 77 Mx related classes moved to the prowide-iso20022 project (open source since October 2020)","title":"9.1.0 - May 2020"},{"location":"release-notes/changelog-core/#802-april-2019","text":"Added IBAN validation for Seychelles Added field setters API in the SwiftBlock5 Added SwiftBlock5Field enumeration with commonly used block 5 trailer fields (CR #235) Added SafeXmlUtils to disallow XXE in all XML parsing code Fixed parser for fields 70[C,D,E,G], 94E, 95V when first line second component contains slashes Changed default root element for Mx from message to RequestPayload Fixed month day parsing in SwiftFormatUtils for leap years Added MxParser#containsLegacyHeader() to check weather the message uses the legacy SWIFT header or the ISO business header Added MtSwiftMessage constructor from AbstractMT Fixed parser to preserve trailing lines in field values, even if the lines are empty (empty trailing lines were trimmed before) (CR #203) Enhanced parser for party fields, explicit /D/ and /C/ is parsed as mark, otherwise any content following the / is parsed as account Fixed field 108 order and overwrite if exist logic in SwiftBlock3#generateMUR (CR #207) Added optional parameter in SwiftWriter and FINWriterVisitor to control whether field values should be trimmed","title":"8.0.2 - April 2019"},{"location":"release-notes/changelog-core/#801-october-2019","text":"Added SwiftMessageUtils#currencyAmount to retrieve the main currency and amount from a message (CR #192) Fixed ConversionService#getFIN(SwiftMessage) to avoid altering the message parameter when removing empty blocks Added an optional SwiftWriter#writeMessage with ignoreEmptyBlocks parameter SwiftMessage#setUserBlocks(List) made public Removed the trim to field values in the XML to enable consistent round trip conversion between FIN and XML Explicit UTF-8 encoding was added where necessary to ensure portability Added MultiLineField implementation to 45D, 49G, 49M and 49N","title":"8.0.1 - October 2019"},{"location":"release-notes/changelog-core/#800-may-2019","text":"JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Added common hierarchy for option J party fields","title":"8.0.0 - May 2019"},{"location":"release-notes/changelog-core/#7104-may-2019","text":"Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Added copy constructors to MT header blocks Added setDate(Calendar) to MIR object (Issue #25) Fixed padding in PPCWriter Added helper API SwiftTagListBlock#splitByTagName to get sub-blocks by field boundary Fixed IOB exception in SwiftBlock2Output#setMIR in lenient mode SwiftParser#tagStarts changed to protected to allow overwriting in custom parsers for non-compliant messages Moved getMessageType from MtSwiftMessage to parent class AbstractSwiftMessage Added getVariant and getMtId to MtSwiftMessage; added getMxId to MxSwiftMessage Added setMUR in SwiftMessage Added helper method in SwiftWriter to ensure break lines of any String has CRLF Added setSignature and getSignature to SwiftMessage and AbstractMT to set and retrieve MDG tag in S block (LAU computation available in Prowide Integrator) Added propertyValue to AbstractSwiftMessage to check if a property is set with a given value Changed IsoUtils implementation to use Currency.getAvailableCurrencies() in the initialization Deprecated AckSystemMessage in favor of ServiceMessage21 Fixed negative index bug in AbstractSwiftMessage#getPreviousStatusInfo when message has less than two statuses in the trail Fixed getLines API in Fields that in some cases was trimming the first line starting slash from the result Fixed eventual NPE produced in MxSwiftMessage#updateFromMessage() when creating MxSwiftMessage from XML document Fixed column length for \"variant\" in MxSwiftMessage persistence mapping Added a fields() method in SwiftTagListBlock to get all block Tag objects as Field objects Added API to field 50F and 59F to get structured content for the line numbers","title":"7.10.4 - May 2019"},{"location":"release-notes/changelog-core/#7103-october-2018","text":"License changed from LGPL to the more permissive Apache License 2.0 Fixed serialization of field 48 Completed SwiftMessageUtils#currencyAmount for missing MTs Fixed NPE in SwiftBlock4.removeEmptySequences with fields 15A as sequence boundary (Issue #15) MxParser.java typo analiseMessage -> analyseMessage Added getFields() to MT classes Added bean validation annotations for BIC, IBAN, ISO country and currency Enhanced the BIC internal model to allow accessor for all subfields Enhanced the BIC validation with enum to report the specific validation problem found Changed the default SwiftParser behavior to lenient, meaning by default it will not throw any IllegalArgumentException when headers size is invalid Fixed FIN writer to preserve trailing spaces in tag value Added JPA annotations to the SWIFT model intended for persistence (AbstractSwiftMessage and subclasses) Removed the old Hibernate XML mapping AbstractSwiftMessage.hbm.xml (in favor of generic JPA annotations in model) Added SwiftTagListBlock#removeSubBlocks to remove all instances of a given subblock (Issue #13) Fixed SwifttagListBlock#removeSubBlock Added JsonSerializable interface to all model classes implementing toJson() Added toJson and fromJson to MT and Field classes Added toJson and fromJson to the MtSwiftMessage and MxSwiftMessage model Added field 434 in SwiftBlock3Builder","title":"7.10.3 - October 2018"},{"location":"release-notes/changelog-core/#7102-may-2018","text":"Revamped the JSON API implementation using Gson, added missing fromJson methods","title":"7.10.2 - May 2018"},{"location":"release-notes/changelog-core/#7101-april-2018","text":"FIN writer: reverted the trim in tag values introduced in 7.8.9","title":"7.10.1 - April 2018"},{"location":"release-notes/changelog-core/#7100-april-2018","text":"SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Added API in SwiftMessage for the SWIFT gpi service: getters and setters for the service type identifier and UETR Added an automatically generated UETR when creating new MT instances for 103, 103 STP, 103 REMIT, 202, 202 COV, 205, or 205 COV Added API in SwiftMessage to set the variant (STP, REMIT, COV) New helper API for block 3 (SwiftBlock3Builder) to ensure only expected fields are added and in proper order","title":"7.10.0 - April 2018"},{"location":"release-notes/changelog-core/#797-april-2018","text":"Dependencies: added gson 2.8.2 Added full IBAN validation including control digits and custom account numbers per country Added SwiftCharset and SwiftCharsetUtils helper API to validate SWIFT related charsets. Added SwiftTagListBlock#getFieldByQualifiers(name, qualifier, conditionalQualifier) to gather generic fields based on qualifiers content Added addTag(index, tag) and setTag(index, tag) in SwiftTagListBlock to insert new field in specific positions Added Field#is(String ...) to test component 1 of fields against a list of possible values Added non-ISO country code XK (Kosovo) to IsoUtils Added API in IsoUtils to add custom codes for countries and currencies Added read-only properties in AbstractSwiftMessage for the message creation year, month and day of moth Added support for custom split char in RJE reader/writer Fixed missing repetitive 35B in MT549 Build migrated to Gradle","title":"7.9.7 - April 2018"},{"location":"release-notes/changelog-core/#796-december-2017","text":"Fixed conversion to XML with compressed parameter true in ConversionService","title":"7.9.6 - December 2017"},{"location":"release-notes/changelog-core/#795-december-2017","text":"Fixed getValueDisplay in field 50F to strip the starting slash in the account number Added getLabelForLineNumber(String subfieldNumber) in Field50F to return the labels for the structured line identifiers Enhanced getComponentLabel(final int number) in Field50F to return proper dynamic labels based on line number identifiers Added getCorrespondentBIC to SwiftMessage and AbstractSwiftMessage Expanded sender/receiver in MtSwiftMessage and MxSwiftMessage from BIC8 to BIC11 in order to keep branch information in those cached attributes Added checksumBody to AbstractSwiftMessage for proprietary checksum calculated on the body only, as a complement to the existing checksum on the whole message Fixed AbstractSwiftMessage#copyTo(msg) implementation to perform hard copy of list objects (similar to a copy constructor implementation) Expanded precision in getValueDisplay for all numeric fields to preserve the decimal digits present in the original value Implemented SwiftMessage#getUUID and added getUID(Calendar, Long) Implemented SwiftMessageUtils#calculateChecksum as MD5 hash on whole FIN message content and added new checksum for the text block only","title":"7.9.5 - December 2017"},{"location":"release-notes/changelog-core/#794-november-2017","text":"Internal code maintenance release","title":"7.9.4 - November 2017"},{"location":"release-notes/changelog-core/#793-october-2017","text":"JRE requirement increased to Java 1.6 Added API in BIC to return the distinguished name (DN) for a BIC Added equalsIgnoreCR in Tag to compare values regardless of carriage return character being present or not in new lines Fixed MxParser#parseBusinessApplicationHeaderV01 (it was setting the FinInstnId/Nm as BIC) Removed invalid component in field 86J Fixed order of components in fields 98J and 98K Completed the component labels for all fields Changed field 22C structure into individual components for the function Enhanced fields parse/serialization to preserve any whitespace in a component","title":"7.9.3 - October 2017"},{"location":"release-notes/changelog-core/#792-august-2017","text":"Fixed FINWriterVisitor to prevent printing 'null' tag values Deprecated custom resource properties for currency and country codes, in favor of Java nativa API in Currency and Locale Removed package-info.class from target jar to avoid class modifier issue in Java8 runtime Fixed serialization of field 50F to allow the first line without a starting forward slash","title":"7.9.2 - August 2017"},{"location":"release-notes/changelog-core/#791-june-2017","text":"(Issue #5) Enhanced performance in SwiftParser Removed sequence API for inner loops (non sequence) in MTs 306, 320, 340, 360, 361, 362, 410, 412, 420, 422, 450, 456","title":"7.9.1 - June 2017"},{"location":"release-notes/changelog-core/#790-may-2017","text":"SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX) (Issue #2) maven build issues (Issue #3) Field61 component 5 treated as amount (Issue #4) Field72 structure fixed to allow 6 components at most Field99A implements AmountContainer Field95L implements BICContainer","title":"7.9.0 - May 2017"},{"location":"release-notes/changelog-core/#789-may-2017","text":"Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Added convenient isType(int) to SwiftMessage Fixed amounts() in AmountContainer fields","title":"7.8.9 - May 2017"},{"location":"release-notes/changelog-core/#788-march-2017","text":"Added hashcode and equals to MxId Added MUR generation in block 3 Added a multi-purpose SwiftMessageComparator for MT, as an abstraction of the existing AckMessageComparator Added helper API to remove empty sequences in block 4 Added ACK/NAK identifier constants and API in AbstractSwiftMessage Added getDateAsCalendar in MIR/MOR Added MtCategory enum for MT message categories and convenient category API in SwiftMessage Added support for system and service messages in metadata gathered from SwiftMesasge in MtSwiftMessage Added isServiceMessage in SwiftMessage Added static factory method parse to SwiftMessage Added new fields in AbstractSwiftMessage to hold main currency and amount, automatically set for most MTs from fields 32a, 33a, 34a, 19a and 62a Added conversion to and from LT address in SwiftFormatUtils (CR #10) Added comprehensive implementation of MT and Field classes for system messages (category 0) Added custom name for internal loop sequences in MTs 110, 360, 361, 604, 605, 609, 824, 920, 935, 940, 942, 971 and 973 Added more options to retrieve information from the status trail in AbstractSwiftMessage Reduced visibility from public to protected for MTs inner sequence classes mutable fields; START, END, TAIL. Fixed analyze and strip API in MxParser to support nested Document elements Fixed MT500 removed invalid fields after GENL linkage sequence Fixed AckMessageComparator to cover all fields in block 2 input and output Fixed getSender and getReceiver for service messages in SwiftMessage Fixed MT600, removed invalid fields 26F, 34G, 31C in sequence A Fixed parse for DATE1 (MMDD) to handle properly leap years Fixed RJEWriter to avoid writing the split character '$' and the end of the file, afterwards the last message Expanded helper API in AckSystemMessage TagListBlock tags field made private instead of package protected Enabled mutability of LogicalTerminalAddress objects, allowing setting the branch from superclass BIC Enhanced parser for fields 11R, 11S and 37H (NPE prevention) Removed invalid generated code for internal loops (non-sequence) in MTs: 110, 201, 360, 361, 559, 604, 605, 609, 824, 920, 935, 940, 942, 971, 973 Enhanced from() and to() methods in BusinessHeader to catch more options","title":"7.8.8 - March 2017"},{"location":"release-notes/changelog-core/#787-december-2016","text":"Fixed getMessageType in MT103_STP, MT102_STP, MT103_REMIT, MT202COV and MT205COV to return the number without the validation flag (as expected per javadoc definition) MT518 fixed fieldset for Field 70 MT330 fixed qualifier in Field 22 MT513 and MT514 Field 11 moved outside previous fieldset MT541 to MT547 Field 90[A,B] changed to fieldset. MT564 fixed fieldset items in Field93[B,C] MT565 to MT567 Sequence D, fixed field 13 MT609 and MT798_763 fixed qualifiers in Field 29 When creating MT instances, the validation flag (STP, REMIT, COV) will be automatically created as block 3 field 119 when applies for the created MT Log warning when creating MTnnn objects from invalid message types, for example calling MT103.parse(fin) and passing FIN content for an MT 202 Ignore validation flag (STP, REMIT, COV) if it is not valid for the message type, when creating MT object from SwiftMessage (to avoid ClassNotFoundException) Enhanced semantic in AckMessageComparator when a blocks are null or empty (see javadoc for details on how blank blocks are handled in comparison)","title":"7.8.7 - December 2016"},{"location":"release-notes/changelog-core/#786-november-2016","text":"MxParser; IOB exception prevention in strip methods when XML has empty header or document Prevention for IOB exception in ensureEOLS when converting MT message from model into FIN text Expanded API in SwiftParser with static parse methods for each MT block Expanded API in SwiftWriter to serialize any MT block into its native SWIFT representation, also made visit API in SwiftMessage static","title":"7.8.6 - November 2016"},{"location":"release-notes/changelog-core/#785-october-2016","text":"Added getSubBlockByTagNames and getSubBlocksByTagNames in SwiftTagListBlock to retrieve subblocks based on comprehensive list or tag names Added API in BusinessHeader to create valid BAH from simple parameters Added API in BIC to get the branch and institution Added API to match message identifier by regex, for example fin.*STP Added API to strip header and document portion of Mx message in XML format Added analizeMessage in MxParser, lightweight API to retrieve structure information from an MX messages Added enumerations for message priority and delivery monitoring in MT block 2 Added json() to AbstractMT Added getComponentLabel(int) in Field classes Added updateFrom AbstractMT to MtSwiftMessage Added reference as class attribute in AbstractSwiftMessage (set by subclasses) Added FileFormat attribute to AbstractSwiftMessage for clear identification of content in implementing subclasses Added constructor of MxSwiftMessage from AbstracMX Added API to get BIC codes from DN in Mx messages Added MtId class, analogous to the existing MxId for MX messages SwiftParser parsing of block 4 published as static public method Added AbstractMessage as base class for specific MTnnn and MXmmm model hierarchy Added MessageStandardType with MT and MX values and ServiceIdType for header service id values Added nextSwiftMessage in RJE/PPC readers for system messages support Added valuesNumeric to MT enumeration MtType Added getValueDisplay with optional locale parameter to display formatted field and individual components values Added MTVariant enum and getVariant API in swift messages Added CONDITIONAL_QUALIFIER component number as static class field for all generic fields (fields implementing the GenericField interface) Added BusinessHeader serialization into xml and Element objects Added business header parse from Element object in MxParser Added RJEReader and RJEWriter to create MT message files in RJE format Added PPCWriter to create MT message files in DOS-PPC format (also enhanced API for the existing PPCFileReader) Added path() API in MxNode Added MtType, an enumeration of all available MTnnn implementations Added parse to Field classes to update field components from full value Added append lists of Tag or Field to TagListBlock Added support for attributes in MxNode Added generic setters for attributes in header blocks 1 and 2 using qualified names (#setField) Added write XML method for MX business header Added validName as static method in Field, to validate field names Added getField static API in Field to create new instances with reflection given the field name and value Added reference(msg) to SwiftMessageUtils to get the sender reference from messages that contain a reference field Added SwiftMessageRevision to the swift messages model, to hold and track changes in swift messages Fixed parser for field 98F Fixed field 61 parse allowing EC and ED as credit/debit mark subfield Fixed from() and to() methods in BusinessHeader to return the BIC code for both possible header types FIxed serialization of component 1 in field 50F Fixed parser and serialization in Field98F Fixed SwiftMessage.toJson single quote to double quote in timestamp field Fixed getLabel when used with the parameters combination of a valid mt and a null sequence Fixed getValue in Field61, Added proper implementation for isOptional(component) in Field61 Fixed components trim to null in parser for several fields when the component value is not present Fixed separators trim in getLine API Fixed setComponentN(Number) when component is not a SWIFT amount, Number is now serialized as an integer (without decimal separator) Fixed MT parser to allow additional lines in a field start with colon ':' Fixed field 32R second component changed from currency to string to allow codewords \u2019FOZ\u2019, \u2019GOZ\u2019, \u2019GRM\u2019, \u2019KLO\u2019, \u2018LIT\u2019, \u2019LOT\u2019, \u2018OTH\u2019, \u2018PND\u2019, \u2019TAL\u2019, \u2019TOL\u2019, \u2018TON\u2019, \u2018TOZ\u2019, \u2019UNT\u2019 Fixed field 33B first component changed from currency to string to allow codeword \u2019PCT\u2019 used in MT601 Fixed API inconsistencies in MtSwiftMessage when updating from SwiftMessage objects. Bugfix MT506 added mandatory field 28E Added missing getters for Sequence E1 in MT300 Changed MX messages detection in MxParser to lighter implementation using Stax Normalized Input/Output Outgoing/Incoming API in AbstractMT and SwiftMessage SwiftMessage.toJson changed timestamp format to the recommended ISO 8601 MxSwiftMessage meta-data (sender, receiver, reference, identifier) read and set from raw XML content Added support in XmlParser for the field version of Core proprietary XML format for MTs, the parser now reads both formats seamlessly Better header API in MxSwiftMessage to support both ISO and SWIFT business headers Elaborated identifier in MtSwiftMessage, using fin.type.variant instead of just the message type Added comprehensive sequence names into pw_swift_label property files Added translations of pw_swift_label property files to FR, DE and IT (complementing the existent EN, ES and RU files) Completed pw_swift_label property files for all field + mt + sequence combinations Complete application header parsing in MxParser Better application header detection in MxParser based on namespaces Added component labels for field 13K Fields 11R and 11S component 3 split into two independent components. In Field61, component 6 was splitted into two independent components to hold the \"transaction type\" and the \"identification code\" as stated in the standard definition for function Added SwiftParserConfiguration to encapsulate several parsing options, allowing fast parsing of AbstractMT by reading the text block in raw format","title":"7.8.5 - October 2016"},{"location":"release-notes/changelog-core/#770-october-2015","text":"valueDate in SwiftMessageUtils isType(int...) in SwiftMessage Enhanced the getSequence API in MT classes with support to nested sequences, allowing for ex: getSequenceE1(getSequenceEList().get(n)) getLine API for FieldNN classes based on semantic lines number identification Copy constructors for FieldNN classes, performing a deep copy of the components' list MxParser message detection New generic XML model and API, as backbone for MX messages. Headers Blocks: new generic getters in blocks 1 and 2 to retrieve attributes using full qualified names from enums; for example getField(SwiftBlock1Field.LogicalTerminal) Static labels for subfields in FieldNN classes to allow for example getComponent(Field93B.BALANCE) BIC: API to check for live and non-live bics MxParser: parseApplicationHeader and constructors from several sources Added missing labels' API to fields: 36E, 69A, 69C, 69D, 70C, 70D, 70G, 90F, 90J, 92D, 92L, 92M, 92N, 92R Added the ApplicationHeader attribute to AbstractMX Added API to search nodes or content by path or name in the MxNode tree returned by the MxParser Added json() and xml() methods to MT classes Added write to file and output streams to AbstractMT and AbstractMX Added consistent constructors from String, File or InputStream to MTnnn classes Added static parse methods to create MTnnn objects from String, File, InputStream or MtSwiftMessage Added consistent constructors from String, File or InputStream to AbstractSwiftMessage and subclasses MtSwiftMessage and MxSwiftMessage Added static parse methods to create MtSwiftMessage and MxSwiftMessage objects from String, File or InputStream Lib: added read from input streams NPE prevention in SwiftFormatUtils.getCurrency Fixed getSender and getReceiver for MTxxx to return accurate information regardless the message being of type input or output (also to be consistent with analogous methods in SwiftMessage) Added CR and LF to charset z and x at SwiftcharsetUtils Fixed validation of fields 70F, 77S and 77T that unnecessary restricted the allowed amount of lines (not it is unlimited because charset Z allows CRLF). Fixed OutOfBound exception at MxNode findFirst implementation when a node has multiple children Fixed getDescription for Field35B, now returning component 3 instead of 2 Better API consistency between MT and MX implementations, with common ways to parse and build. Changed sender and receiver attributes for MtSwiftMessage to hold BIC8 instead of full LT identifiers. Deprecated the use of model message inside MtSwiftMessage Simplified distribution zip with -sources and -javadoc jars","title":"7.7.0 - October 2015"},{"location":"release-notes/changelog-core/#760-october-2014","text":"New BIC API: isTestAndTraining(), getLogicalTerminalIdentifier(), bic8() and bic11() New model for LT addresses, and its related API in header classes New SwiftMessage API: AbstractMT toMT() New AbstractMT API: getSequence(name), getSequenceList(name) Added builder API: constructors and append methods to add content with chaining support Added missing getValue() implementations to field classes. Example: Field26C Added annotations to MTNNN classes to identify sequence split strategy involved (more traceable code) SRU 2014. Affected MTs: 300, 304, 305, 306, 340, 341, 360, 361, 380, 381, 502, 506, 508, 509, 513, 514, 515, 518, 527, 530, 536, 537, 538, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 558, 564, 565, 566, 567, 568, 569, 575, 600, 601, 942 Added description and release javadoc comments to MT classes Added MX Generic model support Added MX parse Added MT300.getSequenceE() Minor fix in MT300 sequences structure, B1 and B2 inside B, and named D's subsequence as D1 SwiftTagListBlock implements Iterable Bugfix SwitTagListBlock.countTagsStarsWith(string,string) was ignoring tagnames in count","title":"7.6.0 - October 2014"},{"location":"release-notes/changelog-core/#750-august-2014","text":"Added toJson in SwiftMessage and SwiftTagListBlock, SwiftBlock1 and 2 Added to SwiftTagListBlock getFieldByName(String, being) Added to SwiftTagListBlock getFieldByName(String, being, component2) Added to SwiftTagListBlock getFieldByNumber(int , being) Added START_TAG and END_TAG constant to Sequence inner classes Added Sequence.newInstance() method Added static method Field.emptyTag() Added to SwiftTagListBlock append(SwiftTagListBlock) Changed SwiftFormatUtils.getNumber(Number) to allow variable amount of decimal parts without the previous limit of two Added support for national clearing system codes in party identifier components: example 52A starting with //AT123 JSON serialization: fixed missing quotes escaping and newline in some occasions, getSequenceA() incorrectly returned null instead of empty sequence as stated in javadoc Refactored Field77A to include 20 independent components instead of just one (current implementation is similar to Field79) Deprecated isAnyOf(String ... names) and added isNameAnyOf(String ... names) semantics of method more clear with its name Changed the semantic of getAccount methods to remove starting slashes if any Some javadoc for BICRecord Added serialization timestamp to JSON generation In Field* void set changed to Class set so we can support the code style new Field().setThis().setThat().setThatToo() Added Field.asTag() Added option in XMLWriterVisitor to serialize field instead of tag","title":"7.5.0 - August 2014"},{"location":"release-notes/changelog-core/#740-march-2014","text":"In BIC added subtype attribute and getBranch method ReaderIterator to read a file from a classpath resource and split its content by the '$' symbol In SwiftMessage new API to check and get linkages sequences In AbstractSwiftMessage new constructor using MTSwiftMessage as parameter In MTSwiftMessage updateFromModel and updateFromFIN using internal attributes Several helper methods to parse field content using SwiftParseUtils Field classes implementation for fields belonging to System and Service Messages (i.e. 451) Resource bundle labels for System and Service Messages fields MOR class to represent the message output reference (inherited from the MIR) SwiftParseUtils: getTokenSecond and getTokenSecondLast with prefix getAll(SwiftMessage) in every FieldNN class getAll(SwiftTagListBlock) in every FieldNN class New constant in Field suitable for import static SwiftTagListBlock: constructors made public SwiftTagListBlock: added filterByNameOrdered(String ...) SwiftTagListBlock: added getFieldsByNumber(int) SwiftTagListBlock: added removeSubBlock(String) SwiftTagListBlock: deprecated int getTagCount(String) SwiftTagListBlock: added int countByName(String) SwiftTagListBlock: deprecated int getTagCount() SwiftTagListBlock: added int countAll() SwiftTagListBlock: added method boolean containsAllOf(String...) Improved toString in SwiftTagListBlock and Tag Javadoc improvements Fixed SwiftBlock1 constructor to allow LTs missing the optional A, B or C identifier (11 characters length); ex. FOOOAR22XXX Fixed getStatusInfo and getPreviousStatus in messages base class that was causing IOB exceptions Issue 39: missing trimToEmpty in getComponent2 in 50H MT207: fixed maximum repetitions of sequence B from 1 to unlimited","title":"7.4.0 - March 2014"},{"location":"release-notes/changelog-core/#730-january-2014","text":"removed log4j.properties New API: Field.isAnyOf(String...) Added many methods in SwiftTagListBlock in resemblance to String manipulation API SwiftTagListBlock added: getTagsByNumber(int), SwiftTagListBlock removeAfterFirst(String, boolean) Added Tag.startsWith Added Tag.contains Added PPCFileReader iterator to read and split pc connect files","title":"7.3.0 - January 2014"},{"location":"release-notes/changelog-core/#720-september-2013","text":"Added Field.letterOption Added SwiftTagListBlock.getSubBlockBeforeFirst Added SwiftTagListBlock.filterByName Fixed Field.appendInLines that was causing the getValue of several fields (ex 35B) to start with unexpected EOL Fixed NPE in XMLParser with null value in tags Fixed Avoid usage of double in amount resolver","title":"7.2.0 - September 2013"},{"location":"release-notes/changelog-core/#700-august-2013","text":"Enhanced messages model with base support for MX messages. New messages meta-data model to handle additional information: Status history, User notes, Properties list. Useful API to SwiftMessage to get: direction, PDE, PDM, UUID, MIR, MUR and getTypeInt Complete FieldNN implementation classes Complete MT helper classes, covering all message types Added model and API to handle Sequences at MT classes, covering all sequences based on 16R/16S boundaries. New API to handle sub blocks: SwiftTagListBlock.removeUntilFirst, SwiftTagListBlock.containsAnyOf Ensuring of SWIFT EOL at ConversionService.getFIN Fixed getValue of several fields to prevent printing of null Fixed getValue of several fields with missing slash separator on optional components Added missing field getters for MT classes with fieldsets: for example 93B at MT564. getValue for Field35B. Thanks to Raghu rathorr@users.sf.net getCalendar bug related to unused format parameter Changed Field26C parser and subfields structure to split the string before the VAR-SEQU into independent components Removed deprecated net.sourceforge classes Removed unimplemented method amounts() in AmountContainer","title":"7.0.0 - August 2013"},{"location":"release-notes/changelog-core/#640-march-2013","text":"Added visitor API on tag list block New interface to identify and use generic fields (notice DSS methods are not part of non-generic fields) Added API on MT classes to simplify messages creation Comprehensive getters and setter API for field classes using functional names Added PatternContainer interface and implemented in field Better CurrencyContainer API Added API to SwiftFormatUtils to get String components from Calendar using different SWIFT date/time formats Implemented API for CurrencyContainer for all Fields Added MT helper classes for MTs: 518, 549, 800, 801, 802, 824, 600, 601, 604, 605, 606, 607, 608, 609 Added Field implementations for 33G, 35U, 86B, 68A, 68B, 68C, 94C, 31F, 37a, 34J, 35H, 31X Added API to simplify messages creation; defaults for header blocks attributes, addField to Block4, setSender at Block1","title":"6.4.0 - March 2013"},{"location":"release-notes/changelog-core/#630-october-2012","text":"Added MT helper classes for MTs: 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 565 Fixed getAsCalendar for year component of field 77H Fixed parsing of field 50F Added field class for: 26C Support to identify which sequence a tag belongs to Added API to FieldNN classes to get the DSS field Added API to FieldNN classes to get the qualifier and conditional qualifier components Added API to FieldNN classes to determine if field is generic or non generic Field class made abstract FieldNN isOptional: method to check if a given component is optional for the field Field getLabel: support for label exceptions per mt and sequence SwiftParser changes to distinguish the presence of brackets when they are block boundaries or part of an invalid field value Improved parsing of Field35B, first and second components are set only if \"ISIN \" is present SR2012 update: deprecated fields 23C, 23F. Updated MT300, MT304, MT305 with field changes. Added serialization for: 20E, 29G, 31G, 36E, 50G, 50H, 69B, 69D, 69F, 77H, 90F, 90J, 90K, 92D, 92L, 92M, 92N, 94D, 94G, 95T, 98F Fixed serialization of field 59A","title":"6.3.0 - October 2012"},{"location":"release-notes/changelog-core/#620-june-2012","text":"Purged and some tunning of parser log Added getField* API con block4 Added Tag API: public boolean contains(String ... values) Added more API to get subblocks based on tag number boundaries regardless of letter options Fixed Tag.isNumber to consider the whole number and not just the prefix, isNumber(58) returns true to 58A but not to 5 Added Tag.getNumber() API Fixed build to include MTs and FieldNN source codes in the package Fixed parser for fields: 94D, 50H, 50G and 52G Added MT helper classes for MTs: 567, 900, 910, 920, 935, 941, 970, 971, 972, 973, 985, 986 Added API for getLabel at Field objects, to retrieve business oriented names from resource bundles","title":"6.2.0 - June 2012"},{"location":"release-notes/changelog-core/#610-march-2012","text":"Added BICContainer interface Added MT helper classes for MTs: 360, 361, 362, 364, 365, 381, n90, n92, n95, n96, n98, 420, 422, 430, 450, 455, 456, 701, 705, 711, 720, 721, 732, 734, 740, 742, 747, 750, 752, 754, 756, 768 Added getValue for Field13E Fixed getValue for Field31R (2nd component is optional)","title":"6.1.0 - March 2012"},{"location":"release-notes/changelog-core/#600-february-2012","text":"Merged patches from Walter Birch SwiftParser: fix for parse error with malformed tag 72 Implemented getValue for Fields: 19B, 31D, 31P, 31R, 39P, 40B, 41D, 92F, 93B, 98E and others with the same parser pattern Changed packages in Hibernate mappings from sourceforge to prowidesoftware Added SwiftMessageUtils class Added date container interface to Fields to better support higher level model expressions Added currency container interface to Fields to better support higher level model expressions SWIFT standard update (Nov 2011) Fixed field parser for 35B Changed SwiftParser log level Build: consistent release in jar, sources and javadocs jars, include dependent jars in lib directory API to create FieldNN objects from Tag objects Fixed field parser for 35B when first component is an ISIN number Added DATE1 support for fields parser (fixes Field61) SwiftMessage API to get sender and receiver addresses from message headers Added MT helper classes for MTs: 101, 104, 105, 107, 110, 111, 112, 200, 201, 204, 205, 205COV, 207, 256, 300, 305, 306, 307, 330, 340, 341, 350, 540, 541, 542, 543, 564, 566 MT helper classes 102_not_STP and 103_not_STP with inheritance from defaults MT103 and MT102 classes Added Field implementations for 36E, 69B, 69D, 69F, 90F, 90J, 93B, 93C, 94G, 95T, 95S, 98E, 98F, 98L, 67A, 77J, 92E, 98D, 95S, 50G, 50H, 52G, 31G, 77H TIME3 implementation to format utils Suppress warnings for unused imports in eclipse","title":"6.0.0 - February 2012"},{"location":"release-notes/changelog-core/#600-rc5-august-2011","text":"Fixed parser for Field20E Added Field implementations for 90K, 92D, 92L, 92M, 92N","title":"6.0.0-RC5 - August 2011"},{"location":"release-notes/changelog-core/#600-rc4-july-2011","text":"Added MT helper classes for MTs (SCORE): 798<743>, 798<745>, 798<760>, 798<761>, 798<762>, 798<763>, 798<764>, 798<766>, 798<767>, 798<769>, 798<779>, 798<788>, 798<789>, 798<790>, 798<791>, 798<793>, 798<794>, 798<799> Added MT helper classes for MTs: 191, 291, 391, 399, 491, 535, 591, 691, 699, 707, 760, 767, 769, 790, 791, 891, 991, 999 Added Field implementations for 13E, 20E, 22L, 23X, 24E, 27A, 29D, 29G, 29S, 31R, 39D, 39P, 49H, 49J, 50M, 72C, 77C, 77E, 78B","title":"6.0.0-RC4 - July 2011"},{"location":"release-notes/changelog-core/#600-rc3-april-2011","text":"Added MT helper classes for MTs: 304, 320, 321, 210, 599 Added Field implementations for 19B, 32H, 32R, 34E, 37G, 37M, 37R, 38J, 92F, 62A, 62B","title":"6.0.0-RC3 - April 2011"},{"location":"release-notes/changelog-core/#600-rc2-february-2011","text":"Added Field implementation for 15 (A,B,C,D,E,F,G,H,I,J,K,L,M,N) Added MT helper classes for MTs: 300, 400, 410, 412, 416, 499, 544, 545, 546, 547, 548, 700, 710, 730, 799 Added Field implementations for 31D, 31P, 40B, 41A, 41D, 45A, 45B, 46A, 46B, 47A, 47B field serialization from components values into SWIFT single string value Removed log4.properties from distribution jar MTs API: fixed field mutiplicity when a field becomes repetitive being present on multiple sequences or at repetitive sequences. Hibernate mappings: removed confusing/commented blocktype mappings at SwiftBlock.hbm.xml Hibernate mappings: package rename","title":"6.0.0-RC2 - February 2011"},{"location":"release-notes/changelog-core/#600-rc1-october-2010","text":"Migrated src code to java 1.5 (binary distribution is still 1.4 compatible by means of http://retroweaver.sourceforge.net/) Java 1.4 compatibility changes normalization of linefeeds to CRLF at Tag creation from XML parsing Removed deprecated API Added new package io with subpackages parser and writer; added new package utils. Renamed all packages to com.prowidesoftware (backward compatibility maintained with facades) Added implementation for MTs 102 not STP, 102 STP, 103 not STP, 103 STP, 195, 199, 202, 202COV, 203, 295, 299, 940, 942, 950 Added new SWIFT MT high level generated API, with classes for specific message types New source package for generated swift model Merged project \"prowide SWIFT Fields\" into \"WIFE\" Added comparison options to AckMessageComparator Removed old and incorrect charset validator class net.sourceforge.wife.swift.MessageValidator Fix in remove user block method, thanks to Herman's contribution and patience Parser API for (new SwiftParser()).parse(messageToParse); Replaced commons-lang-2.3 -> 2.4 Fixed message writer: system messages' block4 generated with inline tags SwiftMessage API to check if it's Straight Through Processing (STP), based on the content of the User Header SwiftMessage API to check if it's a cover payment (COV), based on the content of the User Header SwiftTagListBlock API to check if contains a specific Tag Removed unimplemented and confusing package net.sourceforge.wife.validation Deprecated old and unused validation-related classes Added AckMessageComparator which is useful of identify the ack of a given message. SwiftTagListBlock API to get a sub block given its name or its starting and ending Tag SwiftTagListBlock API to get tags by content, given its exact or partial value Helper methods from Block4 moved to SwiftTagListBlock SwiftTagListBlock is no longer abstract, so it can be used to create instances for subblocks Required JVM upgrade to 1.5 Initial update of upload-sf target for release to sourceforge","title":"6.0.0-RC1 - October 2010"},{"location":"release-notes/changelog-core/#520-february-2009","text":"Added missing hashcode and equals Javadocs improvements Revised and tested hibernate mappings Added getBlockType Added length to unparsed text persistence mappings Fixed persistence mapping for block2 inheritance Updated hibernate libs to version 3.2.6 Added isOutput isInput made concrete, not abstract Added abstract isInput() method to SwiftBlock2 for safer casting subblocks when input/output is unknown","title":"5.2.0 - February 2009"},{"location":"release-notes/changelog-core/#510-july-2007","text":"Migrated logging to java logging api Removed SwiftBlock's deprecated methods. Moved some common methods in SwiftBlock2Input/SwiftBlock2Output to parent class SwiftBlock2. Upgraded commons-lang to version 2.3 Improved persistence mapping. Move persistence (helper) package to wife-test project. Minor javadoc fixes. Fixed some warnings.","title":"5.1.0 - July 2007"},{"location":"release-notes/changelog-core/#500-june-2007","text":"Improved Hibernate mapping for simplified and more efficient data base schema. Added support for unparsed text to model, persistence mapping and conversion services (needed for some MT0xx for example). XML to SwiftMessage parsing methods moved from ConversionService to XMLParser in \"parser\" package. New package created for parser classes \"net.sourceforge.wife.swift.parser\". Made abstract intermediate classes of blocks object hierarchy. Added support for user custom blocks in model, persistence mapping and conversion services. Improved overall test cases coverage and source/resources structure. Fixed some warnings. Swift Parser enhancements; don't throw exception on unrecognized data, but preserve an internal list of errors. Added reference to current message in parser, so it can take decisions based on parsed data. Added constant for possible values for application id to SwiftBlock1. Updated dependency: hsqldb 1.8.0.4 -> hsqldb 1.8.0.7. Updated dependency: hibernate 3.1.3 -> hibernate 3.2.3.ga.","title":"5.0.0 - June 2007"},{"location":"release-notes/changelog-core/#400-april-2007","text":"Moving to junit 4 - some new tests are being written with junit4, this should make testing some features singificantly easier. Move size and isEmpty methods to subclasses. Improved deprecated exception messages and javadoc. Added useful getter for the MIR field in Block 2 output. Added support for optional fields in Block 2 input. Method specific to each block moved to each block class, when possible compatibility methods were left in old places, marked as deprecated to provide a smoother migration path. Removed deprecated API in SwiftBlock. Adapted parser to new model refactor. More javadoc in parser. Improved xml writer (more clean tabs and EOL). Refactored and fixed XML parsing for blocks 3 and 5. Fixed build.xml to include resources in generated jar files. Improved javadoc and validations in fin writer. Completed basic internal XML parsing. Added more tests for XML conversion. Implemented XML conversion parsing for all blocks (except 4). Updated passing test in conversion service.","title":"4.0.0 - April 2007"},{"location":"release-notes/changelog-core/#340-march-2007","text":"Added license header to source files. Minor fixes in build system. Enhanced IBAN validation routine. Added numerous tests for IBAN validation. Added JSValidationUnit backed by Rhino, to support easy extension of validations. Made all loggers private static transient final. Enhanced overview documentation. Javadoc updates. Code clean up. Added many tag specific validation units targeting MT103 validation. Removed ant junit fork since it broke in ant 1.7.","title":"3.4.0 - March 2007"},{"location":"release-notes/changelog-core/#330-january-2007","text":"Initiated MT103 validation rule. Validation framework core classes written. Utility classes for validation. Removed old and deprecated/replaces writer component. Dependencies clean up, ant downloads less libs now. Added Currency ISO Codes (needed for validations). VF: implemented TagExists and ConditionalTagPresence validation units. Started implementation of validation units. Initial implementation of BIC validation. Initial implementation of IBAN validation. Added ISO Countries for IBAN validation. Fixed issue in writer with block5 as mentioned in bug 1601122. Fixed issue 1595631.","title":"3.3.0 - January 2007"},{"location":"release-notes/changelog-core/#320-2006","text":"Parser logging information cleanup. Migrating to log4j 1.2.8 for better compatibility (issued with trace method on some servers). Fixed build to properly include current timestamp in dist target when property release.name is not set. Fixed bug in parser/writer integration which included double block number when using the writer with an object of a just parsed message(1595589). Updated code to fix issue mentioned in https://sourceforge.net/forum/message.php?msg_id=4001538.","title":"3.2.0 - 2006"},{"location":"release-notes/changelog-core/#311-2006","text":"Small fixes for java 1.4 compatibility.","title":"3.1.1 - 2006"},{"location":"release-notes/changelog-core/#310-2006","text":"Fixes to compile for java 1.4 by default. Fixed test for bug 1540294, typo in block number. Use system EOL in XML writer. Added compile timestamp to manifest in created jars.","title":"3.1.0 - 2006"},{"location":"release-notes/changelog-core/#300-2006","text":"Build: Added release.name property to manifest. Build: added selection of tests known to fail and those known to pass. Fixed persistence mapping. Improved build and added control to exclude tests that are know to fail. Model simplification: SwiftBlockN classes are being removed in favor of base class SwiftBlock removed list of blocks in message which was confusing when not all blocks present. SwiftBlock (base class) and subclasses are mapped and persisted ok, either the base class or the subclasses. Added many tests for Hibernate persistence of SwiftMessage hierarchy. Added XML Visitor to write a swift message to an XML representation. Added ConversionService class which encapsulates many services conveniently.","title":"3.0.0 - 2006"},{"location":"release-notes/changelog-core/#200-2006","text":"New parser component highly tested on production and unit tests. Writer component usable. while it has many limitations, it can be used as it is now. Work in progress swift message persistence mapping. Work in progress swift expression <-> regular expression conversion.","title":"2.0.0 - 2006"},{"location":"release-notes/changelog-guitools/","text":"Prowide GUI Tools - CHANGELOG 9.4.3 - January 2024 (PW-1725) Added support for UETR, in the auto-generation of form values 9.4.2 - November 2023 (PW-1686) In the auto-generation of form values, support both system default times and custom zone id (per user) (PW-1686) Deprecated property in MxConf to override AppHdr dateTime in favor of the new auto generation feature Changed the configuration property to show/hide auto-generated fields in favor of a readonly flag 9.4.1 - October 2023 New feature to enable auto generation of values for some specific paths (added in a config file) to be rendered in the message-entry form. New configuration option to hide or show this auto generated values as inputs in the message-entry form. Fix render UI date fields related with types YearMonth, Year, Month. 9.4.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase 9.3.0 - July 2023 Version aligned with Prowide Integrator 9.3.x for SRU2022 1.2.29 - July 2023 (PW-1446) reduce log verbosity in MX form builder when applying external code set 1.2.28 - January 2023 (PW-1140/PW-1142) Fix duplicated header in MX Form View when multiple header is enabled 1.2.27 - November 2022 (PW-1117) Fix combo pre-select when they contain a single option, the element is mandatory but the parent is optional (PW-1115) Fix comparison paths at verification removing predicates from the fields path 1.2.26 - November 2022 Fixed date picker in BAH headers 2 and 3 1.2.25 - November 2022 Added support for BusinessAppHdrV03 1.2.24 - November 2022 Dependencies and deprecated API updates for SRU2022 Added the customizable IBICDirectory in the form builder write detail method call, since the SdkConfiguration class is deprecated 1.2.23 - October 2022 (PW-1025) Enable relative paths for verification, all the children are considered as verifiable fields 1.2.22 - October 2022 (PW-1071) Fixed MX repairing form when the XML has a non-standard namespace, such as for the SIC4 schemas (PW-1071) Added TARGET_BIC to the elements detected as BIC codes for autocomplete (PW-1071) Fixed date time form elements handling when the XSD pattern is not as in ISO 20022 schemas (PW-1071) Enhancement to pre-select combos when they contain a single option and the element is mandatory (PW-1064) Fallback option to system classloader in resource loading (PW-1000) Fix defaultValue comparison, trimming values at RenderUtil to define selected value in combo 1.2.21 - July 2022 (PW-995) Downgrade jquery-ui from 1.13.0 to 1.12.1 to fix hang problem at html autocomplete inputs (PW-993) Fixed AppHdr creation date for BAH V1 that requires a date in UTC zone with explicit Z suffix 1.2.20 - June 2022 (PW-857) Update jquery from 3.5.0 to 3.5.1 to fix compatibility with bootstrap 1.2.19 - June 2022 (PW-857) Update jquery from 3.4.1 to 3.5.0 and jquery-ui from 1.12.1 to 1.13.0 to fix CVE (PW-495) Fixed unicode replacements to support SICText pattern (PW-495) Enhanced the Mx form builder to support custom schemas with namespace other than the ISO 20022, for example schemas for SIC4 Added support in the MtFormBuilder to create forms from external FIN schemas 1.2.18 - May 2022 (CR-138) New MX form builder configuration option to instruct the map from request to message, to use a custom ZoneId instead of the system default offset New MX form builder configuration option to instruct the map from request to message, to overwrite the MX header creation date time with the current zoned time 1.2.17 - May 2022 (PW-813) Internal enhancement to fix CVE 1.2.16 - May 2022 Internal refactor to use XmlBlock4 from the SDK instead of the legacy xml2mt API New configuration option to enable multiple ISO 2022 header version in the MX forms 1.2.15 - March 2022 (PW-863) Fixed CBPR time element creation in form (PW-860) Message repair does not maintain selected BIC when sender/receiver addresses are parameterized from list (PW-854) Added a parameter to the MX form builder to pass a custom header schema, such as the CBPR+ custom BAH v2 schema Unmarshall/marshal MX form data to apply adapters 1.2.14 - January 2022 (PW-854) fixed CBPR+ datetime pattern processing in the webjar JS when building the XML for the POST 1.2.13 - January 2022 (PW-852) Fixed bug when creating an MX form with the ISO 20022 external code set enabled 1.2.12 - January 2022 (PW-784) Added an option in the MT form builder to create and Output block 2 (along existing options for Input and any direction) (PW-828) Added UETR generator to UETR elements in MX (similar to field 121 in MT block 3) Added bicField class for fields with name starting with AnyBic or BICFI, to enable autocomplete 1.2.11 - December 2021 (PW-407-671) New lenient converter for MT to internal XML to enable repairing in GUI malformed messages (even with missing mandatory fields) (PW-530) Added a \"Content pattern\" title on mouse over on fields with the pattern of the element 1.2.10 - November 2021 (CR-23) Add formatter for Rate fields. (CR-23) Add decimals in Amount Fields. (CR-23) Fix Offset field format. (CR-23) Fix Datetime format at Tree View. 1.2.9 - September 2021 (PW-670) Added a parameter to explicitly indicate the message types for which to generate automatically the UETR 1.2.8 - August 2021 (PW-651) Added a parameter in the MT form builder to customize the indicator for any letter options in MT fields: for example 50a -> 50* (PW-576) fixed propagation of minOccurs from SEQUENCE to children fields 1.2.7 - July 2021 Add a new flag browserAutoComplete to switch on/off HTML Input/TextArea 'autocomplete' property. Fixed css set for bicField, currencyField and countryField in MX 1.2.6 - April 2021 Compatibility update for Prowide Integrator SDK 9.1.11+ 1.2.5 - March 2021 (PW-490) Added the autogenerate/autofill UETR when creating new MT202 and MT205 (PW-490) Added the \"generate new UETR\" button for all the MT messages Minor JS client validation fix of mandatory elements in dynamically added form fields 1.2.4 - March 2021 Fixed generation of sequence boundary field in message repairing Fixed form elements removal after validation action Added codeword to sequence names for better sequence type identification (ex: GENL, LINK, TRADDET) Added the qualifier/codeword in all combo selections along the text description 1.2.3 - March 2021 Fixed bug when repairing messages with a PDM trailer field 1.2.2 - February 2021 Normalized the generated form HTML to use double quotes Added HTML escape to input and textarea values when repairing messages Added org.apache.commons:commons-text:1.6 as dependency 1.2.1 - February 2021 Fixed bug in MT form processing on certain combinations of a nested sequence structure 1.2.0 - January 2021 Added a feature to create message verification forms; with a specific subset of fields as input and the rest as read only 1.1.4 - December 2020 Added support for BIC4 in license 1.1.3 - November 2020 Fixed configuration option to display blocks collapsed by default (example block 3 and 5) Added MtFormBuilder default constructor (with default english locale) 1.1.2 - November 2020 Fixed getElementsByTagName issue in main js 1.1.1 - November 2020 Simplified the MT form rendering, removing intermediate useless combo selectors and toggleable elements Fixed the server side form POST to XML builder for some special category 5 fieldset structures 1.1.0 - November 2020 Added API to build a form with presets from a key-value list (useful to create message from template data) Added MT form configuration per block to enable or disable printing the root element Added MT form configuration per block to show the root element collapsed or expanded Changed the amount formatter to always display the decimal part (even for zero) Refactored the MT form mapping to render the internal XML in the backend instead of client side Added parameters in the form builders to set fixed values for the message sender and receiver Added support for ISO 20022 variants: CBPR+, SEPA, SIC when creating MX forms Added support for Business Application Header version 2 1.0.9 - August 2020 (PW-361) Renamed the internal textarea escape element to avoid conflict with third party JS libraries 1.0.8 - August 2020 Thread safe patch in rendering to avoid: org.xml.sax.SAXException: FWK005 parse may not be called while parsing 1.0.7 - July 2020 Added the sequence alphanumeric identifier to sequence labels in MT Enhanced the tooltip/title documentation definition for elements, and added a configuration flag to switch it off Fixed NPE in MT repair form when the PDE trailer field is present with the tag name only and no value Hide field 15a in MT forms to avoid invalid field validation for this field that has empty value Hide by default the 16R and 16S boundary fields, and several block 1 fields in MT that user's should not fill Enhanced log for unexpected exceptions 1.0.6u1 - July 2020 Recompiled with latest core (8.0.2u1) to avoid NoSuchMethod exception in SwiftMessage 1.0.6 - March 2020 (PW-269) Added lenient support to repair messages with invalid component length and charset Prevent printing id=null when message is not null but id is null (in MX form builder) 1.0.5 - January 2020 Fixed XXE vulnerability processing form POST data Prevent printing id=null when message is not null but id is null Added a formatter to the MX mapper to have the created XML with indentation 1.0.4 - December 2019 (PW-226) Added support for the legacy SWIFT application header v10 as alternative for the ISO business header 1.0.3 - December 2019 (PW-193) Added support for character set extensions (such as Arabic) in the form configuration 1.0.2 - October 2019 Fixed license check in message detail function (PW-199) Updated jquery 1.12.2 -> 3.4.1 Updated jquery.validate 1.15.0 -> 1.19.0 Updated jquery.mask 1.14.0 -> 1.14.15 Updated jquery.inputmask 3.3.2-106 -> 3.3.7 1.0.1 - August 2019 Added lenient handling of EOLS (supporting either LF or CRLF) in the MT form builder when repairing messages 1.0.0 Added option to include the raw value in select option, active by default, for example \"Shared Charges (SHA)\" Webjars compliance for resources First release as standalone library, extracted from Prowide Enterprise Message Entry module","title":"Prowide GUI Tools"},{"location":"release-notes/changelog-guitools/#prowide-gui-tools-changelog","text":"","title":"Prowide GUI Tools - CHANGELOG"},{"location":"release-notes/changelog-guitools/#943-january-2024","text":"(PW-1725) Added support for UETR, in the auto-generation of form values","title":"9.4.3 - January 2024"},{"location":"release-notes/changelog-guitools/#942-november-2023","text":"(PW-1686) In the auto-generation of form values, support both system default times and custom zone id (per user) (PW-1686) Deprecated property in MxConf to override AppHdr dateTime in favor of the new auto generation feature Changed the configuration property to show/hide auto-generated fields in favor of a readonly flag","title":"9.4.2 - November 2023"},{"location":"release-notes/changelog-guitools/#941-october-2023","text":"New feature to enable auto generation of values for some specific paths (added in a config file) to be rendered in the message-entry form. New configuration option to hide or show this auto generated values as inputs in the message-entry form. Fix render UI date fields related with types YearMonth, Year, Month.","title":"9.4.1 - October 2023"},{"location":"release-notes/changelog-guitools/#940-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase","title":"9.4.0 - May 2023"},{"location":"release-notes/changelog-guitools/#930-july-2023","text":"Version aligned with Prowide Integrator 9.3.x for SRU2022","title":"9.3.0 - July 2023"},{"location":"release-notes/changelog-guitools/#1229-july-2023","text":"(PW-1446) reduce log verbosity in MX form builder when applying external code set","title":"1.2.29 - July 2023"},{"location":"release-notes/changelog-guitools/#1228-january-2023","text":"(PW-1140/PW-1142) Fix duplicated header in MX Form View when multiple header is enabled","title":"1.2.28 - January 2023"},{"location":"release-notes/changelog-guitools/#1227-november-2022","text":"(PW-1117) Fix combo pre-select when they contain a single option, the element is mandatory but the parent is optional (PW-1115) Fix comparison paths at verification removing predicates from the fields path","title":"1.2.27 - November 2022"},{"location":"release-notes/changelog-guitools/#1226-november-2022","text":"Fixed date picker in BAH headers 2 and 3","title":"1.2.26 - November 2022"},{"location":"release-notes/changelog-guitools/#1225-november-2022","text":"Added support for BusinessAppHdrV03","title":"1.2.25 - November 2022"},{"location":"release-notes/changelog-guitools/#1224-november-2022","text":"Dependencies and deprecated API updates for SRU2022 Added the customizable IBICDirectory in the form builder write detail method call, since the SdkConfiguration class is deprecated","title":"1.2.24 - November 2022"},{"location":"release-notes/changelog-guitools/#1223-october-2022","text":"(PW-1025) Enable relative paths for verification, all the children are considered as verifiable fields","title":"1.2.23 - October 2022"},{"location":"release-notes/changelog-guitools/#1222-october-2022","text":"(PW-1071) Fixed MX repairing form when the XML has a non-standard namespace, such as for the SIC4 schemas (PW-1071) Added TARGET_BIC to the elements detected as BIC codes for autocomplete (PW-1071) Fixed date time form elements handling when the XSD pattern is not as in ISO 20022 schemas (PW-1071) Enhancement to pre-select combos when they contain a single option and the element is mandatory (PW-1064) Fallback option to system classloader in resource loading (PW-1000) Fix defaultValue comparison, trimming values at RenderUtil to define selected value in combo","title":"1.2.22 - October 2022"},{"location":"release-notes/changelog-guitools/#1221-july-2022","text":"(PW-995) Downgrade jquery-ui from 1.13.0 to 1.12.1 to fix hang problem at html autocomplete inputs (PW-993) Fixed AppHdr creation date for BAH V1 that requires a date in UTC zone with explicit Z suffix","title":"1.2.21 - July 2022"},{"location":"release-notes/changelog-guitools/#1220-june-2022","text":"(PW-857) Update jquery from 3.5.0 to 3.5.1 to fix compatibility with bootstrap","title":"1.2.20 - June 2022"},{"location":"release-notes/changelog-guitools/#1219-june-2022","text":"(PW-857) Update jquery from 3.4.1 to 3.5.0 and jquery-ui from 1.12.1 to 1.13.0 to fix CVE (PW-495) Fixed unicode replacements to support SICText pattern (PW-495) Enhanced the Mx form builder to support custom schemas with namespace other than the ISO 20022, for example schemas for SIC4 Added support in the MtFormBuilder to create forms from external FIN schemas","title":"1.2.19 - June 2022"},{"location":"release-notes/changelog-guitools/#1218-may-2022","text":"(CR-138) New MX form builder configuration option to instruct the map from request to message, to use a custom ZoneId instead of the system default offset New MX form builder configuration option to instruct the map from request to message, to overwrite the MX header creation date time with the current zoned time","title":"1.2.18 - May 2022"},{"location":"release-notes/changelog-guitools/#1217-may-2022","text":"(PW-813) Internal enhancement to fix CVE","title":"1.2.17 - May 2022"},{"location":"release-notes/changelog-guitools/#1216-may-2022","text":"Internal refactor to use XmlBlock4 from the SDK instead of the legacy xml2mt API New configuration option to enable multiple ISO 2022 header version in the MX forms","title":"1.2.16 - May 2022"},{"location":"release-notes/changelog-guitools/#1215-march-2022","text":"(PW-863) Fixed CBPR time element creation in form (PW-860) Message repair does not maintain selected BIC when sender/receiver addresses are parameterized from list (PW-854) Added a parameter to the MX form builder to pass a custom header schema, such as the CBPR+ custom BAH v2 schema Unmarshall/marshal MX form data to apply adapters","title":"1.2.15 - March 2022"},{"location":"release-notes/changelog-guitools/#1214-january-2022","text":"(PW-854) fixed CBPR+ datetime pattern processing in the webjar JS when building the XML for the POST","title":"1.2.14 - January 2022"},{"location":"release-notes/changelog-guitools/#1213-january-2022","text":"(PW-852) Fixed bug when creating an MX form with the ISO 20022 external code set enabled","title":"1.2.13 - January 2022"},{"location":"release-notes/changelog-guitools/#1212-january-2022","text":"(PW-784) Added an option in the MT form builder to create and Output block 2 (along existing options for Input and any direction) (PW-828) Added UETR generator to UETR elements in MX (similar to field 121 in MT block 3) Added bicField class for fields with name starting with AnyBic or BICFI, to enable autocomplete","title":"1.2.12 - January 2022"},{"location":"release-notes/changelog-guitools/#1211-december-2021","text":"(PW-407-671) New lenient converter for MT to internal XML to enable repairing in GUI malformed messages (even with missing mandatory fields) (PW-530) Added a \"Content pattern\" title on mouse over on fields with the pattern of the element","title":"1.2.11 - December 2021"},{"location":"release-notes/changelog-guitools/#1210-november-2021","text":"(CR-23) Add formatter for Rate fields. (CR-23) Add decimals in Amount Fields. (CR-23) Fix Offset field format. (CR-23) Fix Datetime format at Tree View.","title":"1.2.10 - November 2021"},{"location":"release-notes/changelog-guitools/#129-september-2021","text":"(PW-670) Added a parameter to explicitly indicate the message types for which to generate automatically the UETR","title":"1.2.9 - September 2021"},{"location":"release-notes/changelog-guitools/#128-august-2021","text":"(PW-651) Added a parameter in the MT form builder to customize the indicator for any letter options in MT fields: for example 50a -> 50* (PW-576) fixed propagation of minOccurs from SEQUENCE to children fields","title":"1.2.8 - August 2021"},{"location":"release-notes/changelog-guitools/#127-july-2021","text":"Add a new flag browserAutoComplete to switch on/off HTML Input/TextArea 'autocomplete' property. Fixed css set for bicField, currencyField and countryField in MX","title":"1.2.7 - July 2021"},{"location":"release-notes/changelog-guitools/#126-april-2021","text":"Compatibility update for Prowide Integrator SDK 9.1.11+","title":"1.2.6 - April 2021"},{"location":"release-notes/changelog-guitools/#125-march-2021","text":"(PW-490) Added the autogenerate/autofill UETR when creating new MT202 and MT205 (PW-490) Added the \"generate new UETR\" button for all the MT messages Minor JS client validation fix of mandatory elements in dynamically added form fields","title":"1.2.5 - March 2021"},{"location":"release-notes/changelog-guitools/#124-march-2021","text":"Fixed generation of sequence boundary field in message repairing Fixed form elements removal after validation action Added codeword to sequence names for better sequence type identification (ex: GENL, LINK, TRADDET) Added the qualifier/codeword in all combo selections along the text description","title":"1.2.4 - March 2021"},{"location":"release-notes/changelog-guitools/#123-march-2021","text":"Fixed bug when repairing messages with a PDM trailer field","title":"1.2.3 - March 2021"},{"location":"release-notes/changelog-guitools/#122-february-2021","text":"Normalized the generated form HTML to use double quotes Added HTML escape to input and textarea values when repairing messages Added org.apache.commons:commons-text:1.6 as dependency","title":"1.2.2 - February 2021"},{"location":"release-notes/changelog-guitools/#121-february-2021","text":"Fixed bug in MT form processing on certain combinations of a nested sequence structure","title":"1.2.1 - February 2021"},{"location":"release-notes/changelog-guitools/#120-january-2021","text":"Added a feature to create message verification forms; with a specific subset of fields as input and the rest as read only","title":"1.2.0 - January 2021"},{"location":"release-notes/changelog-guitools/#114-december-2020","text":"Added support for BIC4 in license","title":"1.1.4 - December 2020"},{"location":"release-notes/changelog-guitools/#113-november-2020","text":"Fixed configuration option to display blocks collapsed by default (example block 3 and 5) Added MtFormBuilder default constructor (with default english locale)","title":"1.1.3 - November 2020"},{"location":"release-notes/changelog-guitools/#112-november-2020","text":"Fixed getElementsByTagName issue in main js","title":"1.1.2 - November 2020"},{"location":"release-notes/changelog-guitools/#111-november-2020","text":"Simplified the MT form rendering, removing intermediate useless combo selectors and toggleable elements Fixed the server side form POST to XML builder for some special category 5 fieldset structures","title":"1.1.1 - November 2020"},{"location":"release-notes/changelog-guitools/#110-november-2020","text":"Added API to build a form with presets from a key-value list (useful to create message from template data) Added MT form configuration per block to enable or disable printing the root element Added MT form configuration per block to show the root element collapsed or expanded Changed the amount formatter to always display the decimal part (even for zero) Refactored the MT form mapping to render the internal XML in the backend instead of client side Added parameters in the form builders to set fixed values for the message sender and receiver Added support for ISO 20022 variants: CBPR+, SEPA, SIC when creating MX forms Added support for Business Application Header version 2","title":"1.1.0 - November 2020"},{"location":"release-notes/changelog-guitools/#109-august-2020","text":"(PW-361) Renamed the internal textarea escape element to avoid conflict with third party JS libraries","title":"1.0.9 - August 2020"},{"location":"release-notes/changelog-guitools/#108-august-2020","text":"Thread safe patch in rendering to avoid: org.xml.sax.SAXException: FWK005 parse may not be called while parsing","title":"1.0.8 - August 2020"},{"location":"release-notes/changelog-guitools/#107-july-2020","text":"Added the sequence alphanumeric identifier to sequence labels in MT Enhanced the tooltip/title documentation definition for elements, and added a configuration flag to switch it off Fixed NPE in MT repair form when the PDE trailer field is present with the tag name only and no value Hide field 15a in MT forms to avoid invalid field validation for this field that has empty value Hide by default the 16R and 16S boundary fields, and several block 1 fields in MT that user's should not fill Enhanced log for unexpected exceptions","title":"1.0.7 - July 2020"},{"location":"release-notes/changelog-guitools/#106u1-july-2020","text":"Recompiled with latest core (8.0.2u1) to avoid NoSuchMethod exception in SwiftMessage","title":"1.0.6u1 - July 2020"},{"location":"release-notes/changelog-guitools/#106-march-2020","text":"(PW-269) Added lenient support to repair messages with invalid component length and charset Prevent printing id=null when message is not null but id is null (in MX form builder)","title":"1.0.6 - March 2020"},{"location":"release-notes/changelog-guitools/#105-january-2020","text":"Fixed XXE vulnerability processing form POST data Prevent printing id=null when message is not null but id is null Added a formatter to the MX mapper to have the created XML with indentation","title":"1.0.5 - January 2020"},{"location":"release-notes/changelog-guitools/#104-december-2019","text":"(PW-226) Added support for the legacy SWIFT application header v10 as alternative for the ISO business header","title":"1.0.4 - December 2019"},{"location":"release-notes/changelog-guitools/#103-december-2019","text":"(PW-193) Added support for character set extensions (such as Arabic) in the form configuration","title":"1.0.3 - December 2019"},{"location":"release-notes/changelog-guitools/#102-october-2019","text":"Fixed license check in message detail function (PW-199) Updated jquery 1.12.2 -> 3.4.1 Updated jquery.validate 1.15.0 -> 1.19.0 Updated jquery.mask 1.14.0 -> 1.14.15 Updated jquery.inputmask 3.3.2-106 -> 3.3.7","title":"1.0.2 - October 2019"},{"location":"release-notes/changelog-guitools/#101-august-2019","text":"Added lenient handling of EOLS (supporting either LF or CRLF) in the MT form builder when repairing messages","title":"1.0.1 - August 2019"},{"location":"release-notes/changelog-guitools/#100","text":"Added option to include the raw value in select option, active by default, for example \"Shared Charges (SHA)\" Webjars compliance for resources First release as standalone library, extracted from Prowide Enterprise Message Entry module","title":"1.0.0"},{"location":"release-notes/changelog-iso20022/","text":"Prowide ISO 20022 - CHANGELOG 9.4.5 - May 2024 (PW-1875) Changed the BusinessApplicationHeaderV01 marshaller to always use Zulu timezone with \"Z\" indicator 9.4.4 - January 2024 Enhanced the identifier extraction of the MxSwiftMessage to use the AppHdr when the Document namespace is missing Enhanced the generic AbstractMX#parse to detect the message type from the AppHdr when the Document namespace is missing Added default metadata extraction implementation for pacs and camt amounts and value dates Added default methods for sender, receiver, and identifier extraction to the MxSwiftMessage. Replaced the DistinguishedName parse logic with proprietary util class from the Prowide Core library 9.4.3 - August 2023 Enhanced metadata extraction for xsys messages getting sender/receiver BICs from the RequestHeader element Make the message metadata extraction lenient, by fixing the XML instruction of the payload when it contains invalid case 9.4.2 - July 2023 Added new utility class SupplementaryDataUtils to facilitate \"SplmtryData\" extraction from MX messages 9.4.1 - June 2023 (PW-1392) Fixed the default escape handler when serializing model objects into XML, that was duplicated quote characters in the output 9.4.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 9.3.6 - March 2023 (GH-74) Added a parameter in the MxWriteParams to define a custom indentation string to use when marshalling into XML 9.3.5 - January 2023 Added an optional way to pass a JaxbContext instance to the parse and write methods 9.3.4 - November 2022 (GH-63) Added message type versions in categories: acmt, admi, auth, caaa, camt, catm, fxtr, pacs, reda, seev, semt, sese, setr, supl and trck Added new business process and messages for: caad, cafc, cain, casp Removed obsolete trea (treasury) message types Added model and support for the BusinessApplicationHeaderV03 9.3.3 - October 2022 (PW-1082) Added support in the JaxbContextCache and its default implementation to create the context without the classes parameter 9.3.2 - August 2022 (PW-922) Added a parameter in the MxReadParams used by the AbstractMX#parse to control the log verbosity when parsing unrecognized messages 9.3.1 - August 2022 Added model for \"trck\" types 9.3.0 - May 2022 SWIFT Standard release update 2022 (live 21 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Updated gson dependency to 2.9.0 (GH-45) Fixed Json serialization in Java 17 9.2.6 - March 2022 (GH-36) Added customizable datetime, date and time adapter in the MxWriteConfiguration, MxReadConfiguration Changed the default date time serialization to local time with UTC offset format YYYY-MM-DDThh ss[.sss]+/-hh:mm Changed the default time serialization to local time with UTC offset format hh ss[.sss]+/-hh:mm Encapsulated the serialization options in a DTO, when calling xml or message methods in AbstractMX and AppHdr Validate.notNull -> Objects.requireNonNull 9.2.5 - January 2022 (GH-37) Updated dependency: gson:2.8.8 -> gson:2.8.9 9.2.4 - December 2021 Added com.prowidesoftware.iso20022 as automatic module name in the MANIFEST for JPMS support 9.2.3 - October 2021 Updated dependency: Apache Commons Lang 3.8.1 -> 3.12.0 Updated dependency: Apache Commons Text 1.6 -> 1.9 Updated dependency: Gson 2.8.2 -> 2.8.8 9.2.2 - October 2021 (PW-584) Enhanced the XML serialization to use localized line separators 9.2.1 - June 2021 NamespaceReader utility class made public with method to extract namespaces from XML, or to check if an element exists NamespaceAndElementFilter made public, used by the parser, handy to implement a validator (GH-26) Fixed AppHdr JSON conversion with explicit new namespace field as discriminator (GH-24) Added a new MxWriteConfiguration and EscapeHandler API to tweak the serialization into XML 9.2.0 - May 2021 SWIFT Standard release update 2021 (live 22 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.1.6 - April 2021 (GH-17|PW-506) Enhanced the XML format in the serializing, spaces and line breaks (GH-18) Fixed NPE in json serialization/deserialization of XMLGregorianCalendar fractional second Added customizable strategies to set the MxSwiftMessage metadata fields: reference, main amount, value date, etc... 9.1.5 - December 2020 (GH-8) (JR-428) Fixed parser to skip unbounded content such as the @XmlAnyElement(lax = true) elements used in many schemas for supplementary data 9.1.4 - November 2020 Fixed javadoc jar 9.1.3 - October 2020 Fixed pom file 9.1.2 - October 2020 Added AppHdrType enum and AppHdrFactory method to create headers with the enum as parameter Added targetNamespace method to the AbstractMX Internal SCM refactor for OS release Revamped the parser implementation with SAX to avoid custom namespace preprocessing Added AppHdrParser utility class Removed the CopyableTo implementation from the generated model Change the generic AbstractMX#parse to throw runtime exception when XML parameter is blank or null (same semantic as Mx classes parse method) 9.1.1 - September 2021 Removed blank lines in MX writer (marshalling) Fixed generic AbstractMX parse for system messages (xsys) 9.1.0 - May 2020 SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.0.1 - May 2021 Added a new extensible interface based model for the application headers: AppHdr Added support for the ISO Business Application Header version 2: head.001.001.02 9.0.0 - May 2020 ISO 20022 module extracted from Prowide Integrator to its own library, with its own version from now on","title":"Prowide ISO 20022"},{"location":"release-notes/changelog-iso20022/#prowide-iso-20022-changelog","text":"","title":"Prowide ISO 20022 - CHANGELOG"},{"location":"release-notes/changelog-iso20022/#945-may-2024","text":"(PW-1875) Changed the BusinessApplicationHeaderV01 marshaller to always use Zulu timezone with \"Z\" indicator","title":"9.4.5 - May 2024"},{"location":"release-notes/changelog-iso20022/#944-january-2024","text":"Enhanced the identifier extraction of the MxSwiftMessage to use the AppHdr when the Document namespace is missing Enhanced the generic AbstractMX#parse to detect the message type from the AppHdr when the Document namespace is missing Added default metadata extraction implementation for pacs and camt amounts and value dates Added default methods for sender, receiver, and identifier extraction to the MxSwiftMessage. Replaced the DistinguishedName parse logic with proprietary util class from the Prowide Core library","title":"9.4.4 - January 2024"},{"location":"release-notes/changelog-iso20022/#943-august-2023","text":"Enhanced metadata extraction for xsys messages getting sender/receiver BICs from the RequestHeader element Make the message metadata extraction lenient, by fixing the XML instruction of the payload when it contains invalid case","title":"9.4.3 - August 2023"},{"location":"release-notes/changelog-iso20022/#942-july-2023","text":"Added new utility class SupplementaryDataUtils to facilitate \"SplmtryData\" extraction from MX messages","title":"9.4.2 - July 2023"},{"location":"release-notes/changelog-iso20022/#941-june-2023","text":"(PW-1392) Fixed the default escape handler when serializing model objects into XML, that was duplicated quote characters in the output","title":"9.4.1 - June 2023"},{"location":"release-notes/changelog-iso20022/#940-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"9.4.0 - May 2023"},{"location":"release-notes/changelog-iso20022/#936-march-2023","text":"(GH-74) Added a parameter in the MxWriteParams to define a custom indentation string to use when marshalling into XML","title":"9.3.6 - March 2023"},{"location":"release-notes/changelog-iso20022/#935-january-2023","text":"Added an optional way to pass a JaxbContext instance to the parse and write methods","title":"9.3.5 - January 2023"},{"location":"release-notes/changelog-iso20022/#934-november-2022","text":"(GH-63) Added message type versions in categories: acmt, admi, auth, caaa, camt, catm, fxtr, pacs, reda, seev, semt, sese, setr, supl and trck Added new business process and messages for: caad, cafc, cain, casp Removed obsolete trea (treasury) message types Added model and support for the BusinessApplicationHeaderV03","title":"9.3.4 - November 2022"},{"location":"release-notes/changelog-iso20022/#933-october-2022","text":"(PW-1082) Added support in the JaxbContextCache and its default implementation to create the context without the classes parameter","title":"9.3.3 - October 2022"},{"location":"release-notes/changelog-iso20022/#932-august-2022","text":"(PW-922) Added a parameter in the MxReadParams used by the AbstractMX#parse to control the log verbosity when parsing unrecognized messages","title":"9.3.2 - August 2022"},{"location":"release-notes/changelog-iso20022/#931-august-2022","text":"Added model for \"trck\" types","title":"9.3.1 - August 2022"},{"location":"release-notes/changelog-iso20022/#930-may-2022","text":"SWIFT Standard release update 2022 (live 21 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Updated gson dependency to 2.9.0 (GH-45) Fixed Json serialization in Java 17","title":"9.3.0 - May 2022"},{"location":"release-notes/changelog-iso20022/#926-march-2022","text":"(GH-36) Added customizable datetime, date and time adapter in the MxWriteConfiguration, MxReadConfiguration Changed the default date time serialization to local time with UTC offset format YYYY-MM-DDThh ss[.sss]+/-hh:mm Changed the default time serialization to local time with UTC offset format hh ss[.sss]+/-hh:mm Encapsulated the serialization options in a DTO, when calling xml or message methods in AbstractMX and AppHdr Validate.notNull -> Objects.requireNonNull","title":"9.2.6 - March 2022"},{"location":"release-notes/changelog-iso20022/#925-january-2022","text":"(GH-37) Updated dependency: gson:2.8.8 -> gson:2.8.9","title":"9.2.5 - January 2022"},{"location":"release-notes/changelog-iso20022/#924-december-2021","text":"Added com.prowidesoftware.iso20022 as automatic module name in the MANIFEST for JPMS support","title":"9.2.4 - December 2021"},{"location":"release-notes/changelog-iso20022/#923-october-2021","text":"Updated dependency: Apache Commons Lang 3.8.1 -> 3.12.0 Updated dependency: Apache Commons Text 1.6 -> 1.9 Updated dependency: Gson 2.8.2 -> 2.8.8","title":"9.2.3 - October 2021"},{"location":"release-notes/changelog-iso20022/#922-october-2021","text":"(PW-584) Enhanced the XML serialization to use localized line separators","title":"9.2.2 - October 2021"},{"location":"release-notes/changelog-iso20022/#921-june-2021","text":"NamespaceReader utility class made public with method to extract namespaces from XML, or to check if an element exists NamespaceAndElementFilter made public, used by the parser, handy to implement a validator (GH-26) Fixed AppHdr JSON conversion with explicit new namespace field as discriminator (GH-24) Added a new MxWriteConfiguration and EscapeHandler API to tweak the serialization into XML","title":"9.2.1 - June 2021"},{"location":"release-notes/changelog-iso20022/#920-may-2021","text":"SWIFT Standard release update 2021 (live 22 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.2.0 - May 2021"},{"location":"release-notes/changelog-iso20022/#916-april-2021","text":"(GH-17|PW-506) Enhanced the XML format in the serializing, spaces and line breaks (GH-18) Fixed NPE in json serialization/deserialization of XMLGregorianCalendar fractional second Added customizable strategies to set the MxSwiftMessage metadata fields: reference, main amount, value date, etc...","title":"9.1.6 - April 2021"},{"location":"release-notes/changelog-iso20022/#915-december-2020","text":"(GH-8) (JR-428) Fixed parser to skip unbounded content such as the @XmlAnyElement(lax = true) elements used in many schemas for supplementary data","title":"9.1.5 - December 2020"},{"location":"release-notes/changelog-iso20022/#914-november-2020","text":"Fixed javadoc jar","title":"9.1.4 - November 2020"},{"location":"release-notes/changelog-iso20022/#913-october-2020","text":"Fixed pom file","title":"9.1.3 - October 2020"},{"location":"release-notes/changelog-iso20022/#912-october-2020","text":"Added AppHdrType enum and AppHdrFactory method to create headers with the enum as parameter Added targetNamespace method to the AbstractMX Internal SCM refactor for OS release Revamped the parser implementation with SAX to avoid custom namespace preprocessing Added AppHdrParser utility class Removed the CopyableTo implementation from the generated model Change the generic AbstractMX#parse to throw runtime exception when XML parameter is blank or null (same semantic as Mx classes parse method)","title":"9.1.2 - October 2020"},{"location":"release-notes/changelog-iso20022/#911-september-2021","text":"Removed blank lines in MX writer (marshalling) Fixed generic AbstractMX parse for system messages (xsys)","title":"9.1.1 - September 2021"},{"location":"release-notes/changelog-iso20022/#910-may-2020","text":"SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.1.0 - May 2020"},{"location":"release-notes/changelog-iso20022/#901-may-2021","text":"Added a new extensible interface based model for the application headers: AppHdr Added support for the ISO Business Application Header version 2: head.001.001.02","title":"9.0.1 - May 2021"},{"location":"release-notes/changelog-iso20022/#900-may-2020","text":"ISO 20022 module extracted from Prowide Integrator to its own library, with its own version from now on","title":"9.0.0 - May 2020"},{"location":"release-notes/changelog-myformat/","text":"Prowide Integrator MyFormat - CHANGELOG 9.4.6 - SNAPSHOT Added a convenient write method with default write mode in the MessageWriter interface 9.4.5 - December 2023 Added schema paths validation for source and target selectors in the conversion from or to MX 9.4.4 - October 2023 (PW-1604) Added concat function to MatrixReader in order to allow retrieving multiples source value during foreach iterations 9.4.3 - October 2023 (PW-1642) Changed the mapping validator to enable literal() in the source selector, this makes sense when combined with a defaultString(value) transformation 9.4.2 - September 2023 (PW-1118) Changed MtReader in order to include null value items in readMany results when valueSelector is used 9.4.1 - June 2023 Enhancements to fully support propagation of foreach indexes into the target selectors, including Line, such asf A[2]/B[{n}]/B1[3]/23A[{m}]/Line[{o}] 9.4.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 9.3.14 - May 2023 (PW-1370) Fixed the MxReader so that it can properly extract content from /AppHdr and /Document paths in conversions from MX (PW-1232) Changed the CSV writer to be more lenient; enabling empty rows, auto extend by default when using addRows, and single separator in the whole CSV Internal implementation enhancement 9.3.13 - April 2023 Refactored the MappingTable spreadsheet loader to use the new MappingTableExcelLoader Refactored the MappingValidator in order to optimize the Rules Parsing, Validation and Process steps 9.3.12 - March 2023 Fixed transformation toTimeZone when both source and target zone identifiers are used as parameters 9.3.11 - March 2023 Internal implementation enhancement in the SETUP commands API 9.3.10 - February 2023 (PW-1174) Added SETUP function to indicate the appHdrType for MX messages in the externalized configuration (spreadsheet or DB) Added support for Zone Ids such as \"America/Argentina\" to the offset parameters in the transformation functions 9.3.9 - February 2023 Added transformation now() to get the current datetime in local timezone, formatted as yyyy-MM-dd'T'HH ss.SSSZ (ISO 8601) Added transformation now(utcOffset)to get the current datetime in the specified time-zone, formatted as yyyy-MM-dd'T'HH ss.SSSZ (ISO 8601) Added transformation uetr() to generates a new random UETR (unique end to end reference) used in both MT and ISO 20022 messages Added transformation toTimeZone(dateTimeFormat, targetOffset) to transform a given datetime in local time and convert it to the target UTC timezone Added transformation toTimeZone(dateTimeFormat, sourceOffset, targetOffset) to transform an input datetime from a specific UTC timezone to another MtPath enhancement to enable using component names (labels) in the selector expressions instead of component numbers 9.3.8 - January 2023 Enhanced selector validation, checking that value selectors (secondary selector in expression) do not contain variables Added support for JSON as source and target formats for the conversion 9.3.7 - December 2022 (PW-1118) minor fixes and added \"@main\" to MtReader to work with main message (when processing an attachment) Minor internal code enhancements Fixed error text formatting in transformations validation 9.3.6 - December 2022 (PW-1105) Added support in the CSV writer setup to pass \"\\t\" as parameter to require the tab character as separator Added a constraint for the CsvFieldsDef to match the pattern ([A-Za-z0-9_]*) and thus avoid mapping selector parsing issues 9.3.5 - November 2022 Updated Apache Commons Text dependency to 1.10 to fix reported CVE Added SETUP functions to indicate the source and target formats in the externalized configuration (spreadsheet or DB) Added SETUP functions to indicate the target MT type or target MX type in the externalized configuration (spreadsheet or DB) Added SETUP function to set up the mapping name in the externalized configuration (spreadsheet or DB) Added support in the MtWriter to generate automatically the field 15 in the sequences separated by 15a 9.3.4 - October 2022 Added API in the MxWriter to configure the specific AppHdr version to use when creating MX messages as output Set the default AppHdr version when creating MX messages to ISO Business Application Header v2 Added ifElse power function to facilitate conditional mappings 9.3.3 - October 2022 (PW-1064) Fallback option to system classloader in resource loading 9.3.2 - September 2022 Added transformation functions logicalTerminalAddress, logicalTerminalAddressSend and logicalTerminalAddressReceive Added transformation function sum 9.3.1 - August 2022 (PW-1010) Added an automatic sanitization when converting into MT, to fix start of line characters and some missing components 9.3.0 - May 2022 SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.2.6 - May 2022 (PW-813) Internal enhancement to fix CVE Deprecation API review 9.2.5 - April 2022 Minor fix in the database loader, to set the table name with the configuration name parameter Fixed mapping table validation when there are SETUP commands in the mappings Minor internal code enhancements Prowide Integrator SDK and Prowide Core updates 9.2.4 - January 2022 Prowide Integrator SDK and Prowide Core updates 9.2.3 - December 2021 Added com.prowidesoftware.integrator.myformat as automatic module name in the MANIFEST for JPMS support 9.2.2 - June 2021 Added support to read and write block 5 fields with selectors such as \"b5/CHK\" 9.2.1 - June 2021 (PW-527) Additional change in the XML and MX reader to trim indentation and trailing spaces from elements while preserving line feeds (PW-527) Changed the XML and MX reader to preserve whitespaces from elements content (PW-527) Added transformation functions wrapLinesPreserve and wrapLinesPreservePrepend 9.2.0 - May 2021 SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.1.8 - April 2021 (PW-502) Added MappingTableDatabaseLoader for more flexible data base access and querying when load the mappings 9.1.7 - March 2021 (PW-480) Fixed mapping into block 2 using whole block value as input data 9.1.6 - February 2021 Added validation of the new SETUP commands: separator, smartQuotes, smartEscapes, addFieldNames and columnNames 9.1.5 - January 2021 Fixed CSV writer with APPEND mode Added SETUP commands to the externalized mapping into CSV: separator, smartQuotes, smartEscapes, addFieldNames and columnNames 9.1.4 - January 2021 Fixed semantic of the MtReader to return null content if the MT selector targets a missing field component Fixed transformation \"rightPad\" Fixed transformation \"formatDecimal\" when input number contains decimal separator and no decimal digits (valid case in MT amounts) Fixed transformation \"fixed\" to avoud setting the default value if the input content is null (not found in source) Fixed transformations \"append\", \"prepend\", \"replaceIfEquals\" and \"wrap\" to avoid generating value if input is null Fixed transformations \"indexOf\", \"indexOfIgnoreCase\", \"lastIndexOf\" and \"lastIndexOfIgnoreCase\" when found substring is at index 0 Enhanced number parse exception handling in transformations using or expecting integers and decimal numbers 9.1.3 - December 2020 License check review 9.1.2 - November 2020 (CR-27) Added support for forced double quotes for CSVWriter (CR-27) Added support for disable smart escaping (ex: comma inside double quotes are not escaped) for CSVWriter (CR-27) Added support to generate header column with field names for CSVWriter (CR-29) Added support in the MtWriter to create internal loop (sequences without 16R and 16S boundary) present for example in MT940 (CR-28) Added support in the MtWriter to create block 1 and block 2 from whole value strings (not targeting individual fields) (CR-28) Added support in the MtReader to retrieve the whole block 1 or block 2 value with selectors \"b1\" and \"b2\" Minor fix in formatDecimal transformation when default locale has comma for decimal separator 9.1.1 - September 2020 (PW-334) Added backward compatibility support for custom(\"MyCustomTransformer\") in the mapping transformations 9.1.0 - May 2020 SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.0.1 - May 2020 Internal implementation changes to the use the new AppHdr model in the SDK 9.0.0 - May 2020 MyFormat module extracted to its own jar in the distribution, with its own version from now on 8.0.7 - May 2020 Added a CsvReader constructor parsing a whole csv where the first row is used as field definition for the mappings Fixed index in CsvFieldsDef constructor to be zero-based instead of one-based 8.0.6 - February 2020 (PW-237) Added ifMatches and IfNotMatches power functions to facilitate conditional mappings 8.0.3 - September 2019 (PW-179) Added support for custom transformations in externalized mapping tables Added support for header rows skip configuration in CsvReader 8.0.2 - August 2019 Added support in the CsvFileReader for the header offset parameter, rows are now skipped directly by the Iterator 8.0.1 - July 2019 Fixed XML and MX writer to avoid creating empty elements if the source content is null Fixed bug in MX/XML writer when creating more than 100 target elements in a rule with variables Added support for foreach when converting from MT 8.0.0 - May 2019 JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 7.10.9 - May 2019 Enhanced selectors for CSV with support for repetition, variables and filters. Added support for FIXED-LENGTH files as source and target message format. Added API to load the mappings from a database, providing a data source or a context name for JNDI lookup Added automatic sequence creation in conversions to MT, for example /E/E1/95Q will create E and E1 boundary fields Fixed block 3 fields order when target is MT and the writer has a pre-filled block 3 Added CONCAT function in source selector to combine the result of a list of selectors in a single rule Added wrapLinesPrepend transformation to split content in to lines, with both fixed length and a prefix Added support for FOREACH in the mappings to process a list of source elements in a single rule Added support for parameterized predicates in the selector to map repetitions from source to target message Added the token LITERAL as alternative to indicate a source content is a plain literal instead of a selector Enhanced reporting in the mapping rules validation, detail message when the selectors are invalid 7.10.8 - March 2019 Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Fixed obfuscation to keep directories in jar Added transformation: abbreviate, unwrap, wrapLines, remove and replace functions based on regex Added support for custom transformation functions When using the CsvFileReader, the iteration counter variable can be used in both target and source selectors Fixed handling of row header offset in CsvFileReader Fixed CSV selector for empty column values (consecutive split characters without values) 7.10.7 - January 2019 Added a constructor with AbstractMT in the MtWriter to initialize the writer with a pre-filled message Added MessageReaderIterator to do n to 1 translations from multiple rows in CSV to single consolidated output Added constructors to create MxWriter from existing AbstractMX message and from MxType identifier 7.10.0 - April 2018 SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 7.9.7 - January 2018 Changes in the distribution package: Command line tools in the bic directory changed from jar files to wrapper scripts Dependencies directory renamed to lib Removed the BUILD id timestamp from the jar files Added constructor from stream in XlsReader 7.9.4 - November 2017 JRE requirement backported to Java 1.6 7.9 - May 2017 SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX) 7.8.9 - May 2017 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 7.8.6 - November 2016 JRE requirement increased to Java 1.7 (only for Integrator SDK and modules, Core still works on 1.5) 7.8.5 - October 2016 Added out-of-the-box translation from MT300 into MxFxtr014 Added transformation to perform content replacement based on map of tuples Added transformation to create fixed values Added transformations for BIC related operations (bic8, bic11, branch, country, etc...) 7.8.3 - Jul 2016 Generic XML API moved to SDK","title":"Prowide Integrator MyFormat"},{"location":"release-notes/changelog-myformat/#prowide-integrator-myformat-changelog","text":"","title":"Prowide Integrator MyFormat - CHANGELOG"},{"location":"release-notes/changelog-myformat/#946-snapshot","text":"Added a convenient write method with default write mode in the MessageWriter interface","title":"9.4.6 - SNAPSHOT"},{"location":"release-notes/changelog-myformat/#945-december-2023","text":"Added schema paths validation for source and target selectors in the conversion from or to MX","title":"9.4.5 - December 2023"},{"location":"release-notes/changelog-myformat/#944-october-2023","text":"(PW-1604) Added concat function to MatrixReader in order to allow retrieving multiples source value during foreach iterations","title":"9.4.4 - October 2023"},{"location":"release-notes/changelog-myformat/#943-october-2023","text":"(PW-1642) Changed the mapping validator to enable literal() in the source selector, this makes sense when combined with a defaultString(value) transformation","title":"9.4.3 - October 2023"},{"location":"release-notes/changelog-myformat/#942-september-2023","text":"(PW-1118) Changed MtReader in order to include null value items in readMany results when valueSelector is used","title":"9.4.2 - September 2023"},{"location":"release-notes/changelog-myformat/#941-june-2023","text":"Enhancements to fully support propagation of foreach indexes into the target selectors, including Line, such asf A[2]/B[{n}]/B1[3]/23A[{m}]/Line[{o}]","title":"9.4.1 - June 2023"},{"location":"release-notes/changelog-myformat/#940-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"9.4.0 - May 2023"},{"location":"release-notes/changelog-myformat/#9314-may-2023","text":"(PW-1370) Fixed the MxReader so that it can properly extract content from /AppHdr and /Document paths in conversions from MX (PW-1232) Changed the CSV writer to be more lenient; enabling empty rows, auto extend by default when using addRows, and single separator in the whole CSV Internal implementation enhancement","title":"9.3.14 - May 2023"},{"location":"release-notes/changelog-myformat/#9313-april-2023","text":"Refactored the MappingTable spreadsheet loader to use the new MappingTableExcelLoader Refactored the MappingValidator in order to optimize the Rules Parsing, Validation and Process steps","title":"9.3.13 - April 2023"},{"location":"release-notes/changelog-myformat/#9312-march-2023","text":"Fixed transformation toTimeZone when both source and target zone identifiers are used as parameters","title":"9.3.12 - March 2023"},{"location":"release-notes/changelog-myformat/#9311-march-2023","text":"Internal implementation enhancement in the SETUP commands API","title":"9.3.11 - March 2023"},{"location":"release-notes/changelog-myformat/#9310-february-2023","text":"(PW-1174) Added SETUP function to indicate the appHdrType for MX messages in the externalized configuration (spreadsheet or DB) Added support for Zone Ids such as \"America/Argentina\" to the offset parameters in the transformation functions","title":"9.3.10 - February 2023"},{"location":"release-notes/changelog-myformat/#939-february-2023","text":"Added transformation now() to get the current datetime in local timezone, formatted as yyyy-MM-dd'T'HH ss.SSSZ (ISO 8601) Added transformation now(utcOffset)to get the current datetime in the specified time-zone, formatted as yyyy-MM-dd'T'HH ss.SSSZ (ISO 8601) Added transformation uetr() to generates a new random UETR (unique end to end reference) used in both MT and ISO 20022 messages Added transformation toTimeZone(dateTimeFormat, targetOffset) to transform a given datetime in local time and convert it to the target UTC timezone Added transformation toTimeZone(dateTimeFormat, sourceOffset, targetOffset) to transform an input datetime from a specific UTC timezone to another MtPath enhancement to enable using component names (labels) in the selector expressions instead of component numbers","title":"9.3.9 - February 2023"},{"location":"release-notes/changelog-myformat/#938-january-2023","text":"Enhanced selector validation, checking that value selectors (secondary selector in expression) do not contain variables Added support for JSON as source and target formats for the conversion","title":"9.3.8 - January 2023"},{"location":"release-notes/changelog-myformat/#937-december-2022","text":"(PW-1118) minor fixes and added \"@main\" to MtReader to work with main message (when processing an attachment) Minor internal code enhancements Fixed error text formatting in transformations validation","title":"9.3.7 - December 2022"},{"location":"release-notes/changelog-myformat/#936-december-2022","text":"(PW-1105) Added support in the CSV writer setup to pass \"\\t\" as parameter to require the tab character as separator Added a constraint for the CsvFieldsDef to match the pattern ([A-Za-z0-9_]*) and thus avoid mapping selector parsing issues","title":"9.3.6 - December 2022"},{"location":"release-notes/changelog-myformat/#935-november-2022","text":"Updated Apache Commons Text dependency to 1.10 to fix reported CVE Added SETUP functions to indicate the source and target formats in the externalized configuration (spreadsheet or DB) Added SETUP functions to indicate the target MT type or target MX type in the externalized configuration (spreadsheet or DB) Added SETUP function to set up the mapping name in the externalized configuration (spreadsheet or DB) Added support in the MtWriter to generate automatically the field 15 in the sequences separated by 15a","title":"9.3.5 - November 2022"},{"location":"release-notes/changelog-myformat/#934-october-2022","text":"Added API in the MxWriter to configure the specific AppHdr version to use when creating MX messages as output Set the default AppHdr version when creating MX messages to ISO Business Application Header v2 Added ifElse power function to facilitate conditional mappings","title":"9.3.4 - October 2022"},{"location":"release-notes/changelog-myformat/#933-october-2022","text":"(PW-1064) Fallback option to system classloader in resource loading","title":"9.3.3 - October 2022"},{"location":"release-notes/changelog-myformat/#932-september-2022","text":"Added transformation functions logicalTerminalAddress, logicalTerminalAddressSend and logicalTerminalAddressReceive Added transformation function sum","title":"9.3.2 - September 2022"},{"location":"release-notes/changelog-myformat/#931-august-2022","text":"(PW-1010) Added an automatic sanitization when converting into MT, to fix start of line characters and some missing components","title":"9.3.1 - August 2022"},{"location":"release-notes/changelog-myformat/#930-may-2022","text":"SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.3.0 - May 2022"},{"location":"release-notes/changelog-myformat/#926-may-2022","text":"(PW-813) Internal enhancement to fix CVE Deprecation API review","title":"9.2.6 - May 2022"},{"location":"release-notes/changelog-myformat/#925-april-2022","text":"Minor fix in the database loader, to set the table name with the configuration name parameter Fixed mapping table validation when there are SETUP commands in the mappings Minor internal code enhancements Prowide Integrator SDK and Prowide Core updates","title":"9.2.5 - April 2022"},{"location":"release-notes/changelog-myformat/#924-january-2022","text":"Prowide Integrator SDK and Prowide Core updates","title":"9.2.4 - January 2022"},{"location":"release-notes/changelog-myformat/#923-december-2021","text":"Added com.prowidesoftware.integrator.myformat as automatic module name in the MANIFEST for JPMS support","title":"9.2.3 - December 2021"},{"location":"release-notes/changelog-myformat/#922-june-2021","text":"Added support to read and write block 5 fields with selectors such as \"b5/CHK\"","title":"9.2.2 - June 2021"},{"location":"release-notes/changelog-myformat/#921-june-2021","text":"(PW-527) Additional change in the XML and MX reader to trim indentation and trailing spaces from elements while preserving line feeds (PW-527) Changed the XML and MX reader to preserve whitespaces from elements content (PW-527) Added transformation functions wrapLinesPreserve and wrapLinesPreservePrepend","title":"9.2.1 - June 2021"},{"location":"release-notes/changelog-myformat/#920-may-2021","text":"SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.2.0 - May 2021"},{"location":"release-notes/changelog-myformat/#918-april-2021","text":"(PW-502) Added MappingTableDatabaseLoader for more flexible data base access and querying when load the mappings","title":"9.1.8 - April 2021"},{"location":"release-notes/changelog-myformat/#917-march-2021","text":"(PW-480) Fixed mapping into block 2 using whole block value as input data","title":"9.1.7 - March 2021"},{"location":"release-notes/changelog-myformat/#916-february-2021","text":"Added validation of the new SETUP commands: separator, smartQuotes, smartEscapes, addFieldNames and columnNames","title":"9.1.6 - February 2021"},{"location":"release-notes/changelog-myformat/#915-january-2021","text":"Fixed CSV writer with APPEND mode Added SETUP commands to the externalized mapping into CSV: separator, smartQuotes, smartEscapes, addFieldNames and columnNames","title":"9.1.5 - January 2021"},{"location":"release-notes/changelog-myformat/#914-january-2021","text":"Fixed semantic of the MtReader to return null content if the MT selector targets a missing field component Fixed transformation \"rightPad\" Fixed transformation \"formatDecimal\" when input number contains decimal separator and no decimal digits (valid case in MT amounts) Fixed transformation \"fixed\" to avoud setting the default value if the input content is null (not found in source) Fixed transformations \"append\", \"prepend\", \"replaceIfEquals\" and \"wrap\" to avoid generating value if input is null Fixed transformations \"indexOf\", \"indexOfIgnoreCase\", \"lastIndexOf\" and \"lastIndexOfIgnoreCase\" when found substring is at index 0 Enhanced number parse exception handling in transformations using or expecting integers and decimal numbers","title":"9.1.4 - January 2021"},{"location":"release-notes/changelog-myformat/#913-december-2020","text":"License check review","title":"9.1.3 - December 2020"},{"location":"release-notes/changelog-myformat/#912-november-2020","text":"(CR-27) Added support for forced double quotes for CSVWriter (CR-27) Added support for disable smart escaping (ex: comma inside double quotes are not escaped) for CSVWriter (CR-27) Added support to generate header column with field names for CSVWriter (CR-29) Added support in the MtWriter to create internal loop (sequences without 16R and 16S boundary) present for example in MT940 (CR-28) Added support in the MtWriter to create block 1 and block 2 from whole value strings (not targeting individual fields) (CR-28) Added support in the MtReader to retrieve the whole block 1 or block 2 value with selectors \"b1\" and \"b2\" Minor fix in formatDecimal transformation when default locale has comma for decimal separator","title":"9.1.2 - November 2020"},{"location":"release-notes/changelog-myformat/#911-september-2020","text":"(PW-334) Added backward compatibility support for custom(\"MyCustomTransformer\") in the mapping transformations","title":"9.1.1 - September 2020"},{"location":"release-notes/changelog-myformat/#910-may-2020","text":"SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.1.0 - May 2020"},{"location":"release-notes/changelog-myformat/#901-may-2020","text":"Internal implementation changes to the use the new AppHdr model in the SDK","title":"9.0.1 - May 2020"},{"location":"release-notes/changelog-myformat/#900-may-2020","text":"MyFormat module extracted to its own jar in the distribution, with its own version from now on","title":"9.0.0 - May 2020"},{"location":"release-notes/changelog-myformat/#807-may-2020","text":"Added a CsvReader constructor parsing a whole csv where the first row is used as field definition for the mappings Fixed index in CsvFieldsDef constructor to be zero-based instead of one-based","title":"8.0.7 - May 2020"},{"location":"release-notes/changelog-myformat/#806-february-2020","text":"(PW-237) Added ifMatches and IfNotMatches power functions to facilitate conditional mappings","title":"8.0.6 - February 2020"},{"location":"release-notes/changelog-myformat/#803-september-2019","text":"(PW-179) Added support for custom transformations in externalized mapping tables Added support for header rows skip configuration in CsvReader","title":"8.0.3 - September 2019"},{"location":"release-notes/changelog-myformat/#802-august-2019","text":"Added support in the CsvFileReader for the header offset parameter, rows are now skipped directly by the Iterator","title":"8.0.2 - August 2019"},{"location":"release-notes/changelog-myformat/#801-july-2019","text":"Fixed XML and MX writer to avoid creating empty elements if the source content is null Fixed bug in MX/XML writer when creating more than 100 target elements in a rule with variables Added support for foreach when converting from MT","title":"8.0.1 - July 2019"},{"location":"release-notes/changelog-myformat/#800-may-2019","text":"JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"8.0.0 - May 2019"},{"location":"release-notes/changelog-myformat/#7109-may-2019","text":"Enhanced selectors for CSV with support for repetition, variables and filters. Added support for FIXED-LENGTH files as source and target message format. Added API to load the mappings from a database, providing a data source or a context name for JNDI lookup Added automatic sequence creation in conversions to MT, for example /E/E1/95Q will create E and E1 boundary fields Fixed block 3 fields order when target is MT and the writer has a pre-filled block 3 Added CONCAT function in source selector to combine the result of a list of selectors in a single rule Added wrapLinesPrepend transformation to split content in to lines, with both fixed length and a prefix Added support for FOREACH in the mappings to process a list of source elements in a single rule Added support for parameterized predicates in the selector to map repetitions from source to target message Added the token LITERAL as alternative to indicate a source content is a plain literal instead of a selector Enhanced reporting in the mapping rules validation, detail message when the selectors are invalid","title":"7.10.9 - May 2019"},{"location":"release-notes/changelog-myformat/#7108-march-2019","text":"Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Fixed obfuscation to keep directories in jar Added transformation: abbreviate, unwrap, wrapLines, remove and replace functions based on regex Added support for custom transformation functions When using the CsvFileReader, the iteration counter variable can be used in both target and source selectors Fixed handling of row header offset in CsvFileReader Fixed CSV selector for empty column values (consecutive split characters without values)","title":"7.10.8 - March 2019"},{"location":"release-notes/changelog-myformat/#7107-january-2019","text":"Added a constructor with AbstractMT in the MtWriter to initialize the writer with a pre-filled message Added MessageReaderIterator to do n to 1 translations from multiple rows in CSV to single consolidated output Added constructors to create MxWriter from existing AbstractMX message and from MxType identifier","title":"7.10.7 - January 2019"},{"location":"release-notes/changelog-myformat/#7100-april-2018","text":"SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"7.10.0 - April 2018"},{"location":"release-notes/changelog-myformat/#797-january-2018","text":"Changes in the distribution package: Command line tools in the bic directory changed from jar files to wrapper scripts Dependencies directory renamed to lib Removed the BUILD id timestamp from the jar files Added constructor from stream in XlsReader","title":"7.9.7 - January 2018"},{"location":"release-notes/changelog-myformat/#794-november-2017","text":"JRE requirement backported to Java 1.6","title":"7.9.4 - November 2017"},{"location":"release-notes/changelog-myformat/#79-may-2017","text":"SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX)","title":"7.9 - May 2017"},{"location":"release-notes/changelog-myformat/#789-may-2017","text":"Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"7.8.9 - May 2017"},{"location":"release-notes/changelog-myformat/#786-november-2016","text":"JRE requirement increased to Java 1.7 (only for Integrator SDK and modules, Core still works on 1.5)","title":"7.8.6 - November 2016"},{"location":"release-notes/changelog-myformat/#785-october-2016","text":"Added out-of-the-box translation from MT300 into MxFxtr014 Added transformation to perform content replacement based on map of tuples Added transformation to create fixed values Added transformations for BIC related operations (bic8, bic11, branch, country, etc...)","title":"7.8.5 - October 2016"},{"location":"release-notes/changelog-myformat/#783-jul-2016","text":"Generic XML API moved to SDK","title":"7.8.3 - Jul 2016"},{"location":"release-notes/changelog-score/","text":"Prowide Integrator SCORE - CHANGELOG Model extension for SCORE messages (SWIFT for corporates) 9.4.7 - January 2024 (PW-1751) Fixed schemes for MT 798<760> B2C 9.4.6 - November 2023 Added new custom semantic rules to the MT798<700> message structure scheme Fixed SRU2023 qualification for MT 798 sub-message types 700, 707, 708, 759, 761, 765, 767, 769, 785, 786, 787 9.4.5 - November 2023 (PW-994) Fixed schemes for MT 798<760> B2C 9.4.4 - November 2023 (PW-1058) Fixed schemes for MT 798<767> 9.4.3 - November 2023 (PW-1675) Fixed schemes for MT 798<760/765/767/775> 9.4.2 - September 2023 (PW-1575) MT SCORE 798<700/701/707/708>: Fixed B2C schemes, replace field 21A with 21P (PW-1572) Fixes in structure for qualifiers validation in MT 798<710> 9.4.1 - August 2023 PW-1461: Remove field 31R from SCORE since it was moved back to Prowide Core 9.4.0 - July 2023 Version aligned with Prowide Integrator 9.4.x for SRU2023 1.4.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 1.3.10 - May 2023 (PW-1373) Additional fixes in structure for qualifiers validation in MT 798<720> 1.3.9 - May 2023 (PW-1373) Fixed structure for qualifiers validation in MT 798<720> 1.3.8 - May 2023 (PW-1367) Added MT SCORE 798 sub-message types: 722_LC_C2B, 726_LC_C2B, 735_LC_C2B, 770_LC_C2B, 772_LC_C2B (PW-1373) MT SCORE 798<720>: Fixed codewords and rules for fields 40B and 41a 1.3.7 - March 2023 (PW-1231) MT SCORE 798<758>: Added missing fields after field 33a 1.3.6 - February 2023 (PW-1206) Added message model for the MT SCORE subtypes 707/708/710/711/720/721/732/734/750 (PW-1198) Added validation for MT SCORE subtype 767 - Sequence B optional for 22A ISCA or ICCA 1.3.5 - February 2023 Model for SCORE fields moved from the Prowide Core library to this Prowide Integrator SCORE library (PW-1168) Added message model for the MT SCORE subtypes 723/733/737/751/758/776/780/782 1.3.4 - January 2023 (PW-1150) Added message model for the MT SCORE subtypes 731/736/748/753/755/757/771/773 1.3.3 - November 2022 Updated Apache Commons Text dependency to 1.10 to fix reported CVE 1.3.2 - September 2022 (PW-1058) Fix SCORE 798<767> and 798<775> B2C - field 21 is optional Added the current SRU to the version number for consistent SRU based BOM and dependency with other Integrator artifacts 1.3.1 - August 2022 (PW-1015) Added schemes for submessage types 700, 701 and 774 PW-994: Removed NONREF qualifier to the B/20 field in scheme 1.3.0 - May 2022 SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 1.2.3 - March 2022 (PW-882) SCORE 798_760 scheme change to have sequence B optional (mandatory presence checked by semantic rule as necessary) 1.2.2 - January 2022 Prowide Integrator SDK and Prowide Core updates 1.2.1 - December 2021 Added com.prowidesoftware.integrator.score as automatic module name in the MANIFEST for JPMS support 1.2.0 - August 2021 Comprehensive implementation of message types 1.0.0 - February 2021 Initial version including support for Guarantee/Standby LC: request for amendment, notification of amendment, response","title":"Prowide Integrator SCORE"},{"location":"release-notes/changelog-score/#prowide-integrator-score-changelog","text":"Model extension for SCORE messages (SWIFT for corporates)","title":"Prowide Integrator SCORE - CHANGELOG"},{"location":"release-notes/changelog-score/#947-january-2024","text":"(PW-1751) Fixed schemes for MT 798<760> B2C","title":"9.4.7 - January 2024"},{"location":"release-notes/changelog-score/#946-november-2023","text":"Added new custom semantic rules to the MT798<700> message structure scheme Fixed SRU2023 qualification for MT 798 sub-message types 700, 707, 708, 759, 761, 765, 767, 769, 785, 786, 787","title":"9.4.6 - November 2023"},{"location":"release-notes/changelog-score/#945-november-2023","text":"(PW-994) Fixed schemes for MT 798<760> B2C","title":"9.4.5 - November 2023"},{"location":"release-notes/changelog-score/#944-november-2023","text":"(PW-1058) Fixed schemes for MT 798<767>","title":"9.4.4 - November 2023"},{"location":"release-notes/changelog-score/#943-november-2023","text":"(PW-1675) Fixed schemes for MT 798<760/765/767/775>","title":"9.4.3 - November 2023"},{"location":"release-notes/changelog-score/#942-september-2023","text":"(PW-1575) MT SCORE 798<700/701/707/708>: Fixed B2C schemes, replace field 21A with 21P (PW-1572) Fixes in structure for qualifiers validation in MT 798<710>","title":"9.4.2 - September 2023"},{"location":"release-notes/changelog-score/#941-august-2023","text":"PW-1461: Remove field 31R from SCORE since it was moved back to Prowide Core","title":"9.4.1 - August 2023"},{"location":"release-notes/changelog-score/#940-july-2023","text":"Version aligned with Prowide Integrator 9.4.x for SRU2023","title":"9.4.0 - July 2023"},{"location":"release-notes/changelog-score/#140-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"1.4.0 - May 2023"},{"location":"release-notes/changelog-score/#1310-may-2023","text":"(PW-1373) Additional fixes in structure for qualifiers validation in MT 798<720>","title":"1.3.10 - May 2023"},{"location":"release-notes/changelog-score/#139-may-2023","text":"(PW-1373) Fixed structure for qualifiers validation in MT 798<720>","title":"1.3.9 - May 2023"},{"location":"release-notes/changelog-score/#138-may-2023","text":"(PW-1367) Added MT SCORE 798 sub-message types: 722_LC_C2B, 726_LC_C2B, 735_LC_C2B, 770_LC_C2B, 772_LC_C2B (PW-1373) MT SCORE 798<720>: Fixed codewords and rules for fields 40B and 41a","title":"1.3.8 - May 2023"},{"location":"release-notes/changelog-score/#137-march-2023","text":"(PW-1231) MT SCORE 798<758>: Added missing fields after field 33a","title":"1.3.7 - March 2023"},{"location":"release-notes/changelog-score/#136-february-2023","text":"(PW-1206) Added message model for the MT SCORE subtypes 707/708/710/711/720/721/732/734/750 (PW-1198) Added validation for MT SCORE subtype 767 - Sequence B optional for 22A ISCA or ICCA","title":"1.3.6 - February 2023"},{"location":"release-notes/changelog-score/#135-february-2023","text":"Model for SCORE fields moved from the Prowide Core library to this Prowide Integrator SCORE library (PW-1168) Added message model for the MT SCORE subtypes 723/733/737/751/758/776/780/782","title":"1.3.5 - February 2023"},{"location":"release-notes/changelog-score/#134-january-2023","text":"(PW-1150) Added message model for the MT SCORE subtypes 731/736/748/753/755/757/771/773","title":"1.3.4 - January 2023"},{"location":"release-notes/changelog-score/#133-november-2022","text":"Updated Apache Commons Text dependency to 1.10 to fix reported CVE","title":"1.3.3 - November 2022"},{"location":"release-notes/changelog-score/#132-september-2022","text":"(PW-1058) Fix SCORE 798<767> and 798<775> B2C - field 21 is optional Added the current SRU to the version number for consistent SRU based BOM and dependency with other Integrator artifacts","title":"1.3.2 - September 2022"},{"location":"release-notes/changelog-score/#131-august-2022","text":"(PW-1015) Added schemes for submessage types 700, 701 and 774 PW-994: Removed NONREF qualifier to the B/20 field in scheme","title":"1.3.1 - August 2022"},{"location":"release-notes/changelog-score/#130-may-2022","text":"SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"1.3.0 - May 2022"},{"location":"release-notes/changelog-score/#123-march-2022","text":"(PW-882) SCORE 798_760 scheme change to have sequence B optional (mandatory presence checked by semantic rule as necessary)","title":"1.2.3 - March 2022"},{"location":"release-notes/changelog-score/#122-january-2022","text":"Prowide Integrator SDK and Prowide Core updates","title":"1.2.2 - January 2022"},{"location":"release-notes/changelog-score/#121-december-2021","text":"Added com.prowidesoftware.integrator.score as automatic module name in the MANIFEST for JPMS support","title":"1.2.1 - December 2021"},{"location":"release-notes/changelog-score/#120-august-2021","text":"Comprehensive implementation of message types","title":"1.2.0 - August 2021"},{"location":"release-notes/changelog-score/#100-february-2021","text":"Initial version including support for Guarantee/Standby LC: request for amendment, notification of amendment, response","title":"1.0.0 - February 2021"},{"location":"release-notes/changelog-sdk/","text":"Prowide Integrator SDK - CHANGELOG 9.4.26 - SNAPSHOT MT SchemeXmlWriter: make description and release optional 9.4.25 - May 2024 (PW-1868) Added a DataPDUWriterFactory to create specific versions of the writer instance based on the Revision element in the XML (PW-1870) Added new method to MxPrintoutVisitor in order to allow printing the MX path for a given element 9.4.24 - April 2024 (PW-1844) Enhanced the DataPDUWriter to propagate the original Document namespace when not strictly ISO-20022 (for example SIC) 9.4.23 - April 2024 (PW-1836) Fixed scheme for MT 537, enabling repetitions of sequence C2a 9.4.22 - April 2024 (PW-1816) Added XmlNode support for default namespaces 9.4.21 - March 2024 (PW-1810) Added changes to allow removing AppHdr and Document namespaces prefixes when creating a DataPDU XML 9.4.20 - March 2024 (PW-1755) Fix Block4Xml for field 37K to handle the special \"PCT\" (percentage) in the currency field (used in MT305) (PW-1697) Fix Block4Xml for fields 29O and 37K, affecting MT306 structure validation Added method findAllContainingValue in XmlNode class 9.4.19 - February 2024 Updated the SchemeMatcherQualifier report logic to provide Code word errors information 9.4.18 - January 2024 (PW-1743) Remove usage of deprecated SafeXMLUtils methods 9.4.17 - January 2024 (PW-1739) Fixed field 23 expanded printout in order to match specification for MT102/MT103/MT305/MT601 Added method findFirstByValue in XmlNode class 9.4.16 - January 2024 (PW-1734) Fixed schemes for MT503/504/506/507/510,517/538/541/567/575. Converted optional subsequences to mandatory 9.4.15 - December 2023 (PW-1732) Fixed scheme for MT543: sequence E3 Amounts is mandatory 9.4.14 - December 2023 (PW-1718) Fixed fields 50F and 59F expanded printout missing components Added Xsd Path Generator in order to generate all valid paths from a XSD element Added XsdPath validation classes: AppHdrPathValidator, MxPathValidator, and XsdPathValidator interface. 9.4.13 - December 2023 (PW-1718) Fixed the TXT expanded printout for fields 50 and 59 that was missing some components 9.4.12 - November 2023 (PW-1697) Fixed scheme for MT306 9.4.11 - November 2023 (PW-1688) Updated the pw_mt_info properties with labels and descriptions from the SRU2023 changes (PW-1675) Updated Scheme 765 adding new semantic check for field 31R 9.4.10 - October 2023 (PW-1639) Added options in the LAU signing and verification processing parameters to support latest version of SWIFT Alliance Lite 9.4.9 - October 2023 (PW-1667) Updated Scheme 671 schema to fix field 95 9.4.8 - October 2023 (PW-1664) Updated MT543 schema to fix field 36[B,D] PAIR/TURN position within LINK subsequence 9.4.7 - October 2023 Added JSON file format support in the AbstractSwiftMessageFactory to automatically detect the JSON structure and parse it into an MT or MX message Added missing versions to the AbstractDataPDU generic parse 9.4.6 - September 2023 (PW-1612) Fixed Block4Xml serialization of field 72 in MT102_STP and MT103_STP tht was producing a non XSD compatible structure (PW-1605) Fixed the SwiftMessageFactory#toggleDirection to use 24-hour time format in the Block2 Output 9.4.5 - September 2023 (PW-1594) Fixed invalid qualifier in MT543 scheme; qualifier MFKT -> MRKT in sequence B1 9.4.4 - September 2023 (PW-1578) Updated schemes 710, 720 to fix a bug introduced in 9.4.1 (PW-1449) Added support for version 2.0.14 of the SAA DataPDU wrapper (PW-1118) Added support in MtPath extract content from Block3 given an existing MtPathResult as parameter 9.4.3 - July 2023 (PW-1423) Added a RitsMessageIdentifierGenerator helper class to generate RITS MX message identifiers 9.4.2 - June 2023 (PW-1369) Added a property to the TxtPrintoutVisitor to opt out printing the label for the components within a field (PW-1369) Added an includeComponentLabel boolean to the MTInfo#fieldValue method to opt out printing the label for the components within a field (PW-1369) Added an onField method to the PrintoutVisitor interface to customize how field components are split and printed Changed the MtPathExpression to support variables in predicates, such as A[2]/B[{n}]/B1[3]/23A[{m}]/Line[{o}] 9.4.1 - June 2023 Fixed MT schemes fo MT537 Fixed MT schemes fo MT710 and MT720 9.4.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 9.3.23 - April 2023 (PW-1350) Added 2 MxWriteParams vars to XmlV2Configuration in order to allow custom setting of AppHdr and Document namespaces prefixes when creating a DataPDU XML 9.3.22 - April 2023 (PW-1348) Added a IBICDirectory setter to the MTInfo to customize the directory used when doing expanded printout of BIC codes 9.3.21 - March 2023 (PW-1239) Further enhanced the PrintoutWriter to resolve the labels of the MT798 proprietary fields, for any recognized sub-message type Changed the MTInfo.fieldValue to use the same implementation as the PrintoutWriter, which is more complete and produces a better result 9.3.20 - March 2023 (PW-1239) Enhanced the PrintoutWriter to resolve the labels of the MT798_700 proprietary fields 9.3.19 - March 2023 (PW-1195) Revert charset to system default value instead of fixed UTF-8 in: XmlNode, DataPDU, MxPrintoutWriter and LAU 9.3.18 - March 2023 Fixed MtPath log verbosity when querying fields with wildcard letter option, such as 93a Re-enabled the BIC query tool command line to check the integrator data jar file contains the imported data 9.3.17 - February 2023 Minor javadoc fixes 9.3.16 - February 2023 (PW-1168) Added message model for the MT SCORE subtypes 723/733/737/751/758/776/780/782/731/736/748/753/755/757/771/773 9.3.15 - February 2023 Prowide Core dependency update 9.3.14 - January 2023 (PW-1149) Added UETR to the MT expanded printout, and fixed indentation when printing multiline fields in TXT format 9.3.13 - December 2022 Removed the deprecated \"eval\" JS expressions from the MT schemes, in favor of the new \"qualifierValidation\" structure 9.3.12 - November 2022 (GH-63) Added message type versions in categories: acmt, admi, auth, caaa, camt, catm, fxtr, pacs, reda, seev, semt, sese, setr, supl and trck Added new business process and messages for: caad, cafc, cain, casp 9.3.11 - November 2022 (PW-1109) Fixed BLock4Xml for narrative container fields having a codeword without any narrative text Added DataPDU model for versions 2.0.1, 2.0.2, 2.0.3, 2.0.4, 2.0.5, 2.0.6, 2.0.8, 2.0.9 and 2.0.10 Deprecated the SdkConfiguration in favor of localized configuration API in each module/feature Fixed the embedded BIC directory connection handling, with automatic reopening after a closed connection 9.3.10 - November 2022 Updated Apache Commons Text dependency to 1.10 to fix reported CVE (PW-1101) Fixed field 35C unmarshalling in XmlBlock4 (PW-1086) Fixed field 36D unmarshalling in XmlBlock4 (PW-1085) Moved the custom BIC directory implementation setter from the SDK singleton configuration to the PrintoutWriter constructor 9.3.9 - October 2022 (PW-1082) Added support for cached JaxbContext in the DataPDU parsing to achieve better performance 9.3.8 - October 2022 Added a StringSchemaProvider that can be used to provide a schema from a String when using the Mx API 9.3.7 - September 2022 (PW-1058) Fix SCORE 798<767> and 798<775> B2C - field 21 is optional (PW-1048) Added options in the SwiftMessageFactory to create an ACK from an MX message 9.3.6 - September 2022 (GH-119) MT566: Fixed repetitions of sequence USECU/FIA that is not repetitive Minor fix in MT internal schemes, added some missing \"rules\" reference attributes 9.3.5 - August 2022 MT schemes refactor to decommission the need for the Rhino dependency when validating MT message structure 9.3.4 - August 2022 (PW-1010) Added helper API MtSanitizer to fix MT content charset, start of line characters and certain missing components (PW-1015) Added field validation for fields 47E, 49D and 49F (required in SCORE MT798_774) (PW-922) MxPrintout: Added support for xsys message types SchemeXmlWriter/Reader fixed and refactored 9.3.3 - August 2022 (PW-922) Added a fallback option to the MX printout writer to handle unknown message types 9.3.2 - July 2022 (PW-977) Fixed MT scheme 203 with inner loops instead of formal sequences (PW-969) fixes to xml converters for fields 12E, 12K and 12R (PW-895) Fixed Block4Xml to properly name anonymous sequences (LoopN) (PW-894) Fixed MT scheme 203 with inner loops instead of formal sequences (PW-873) Added a new MxPrintoutWriter to generate a human-friendly view of MX messages in plain text (PW-873) Added the MxLabelInfo helper class to retrieve business labels for MX message elements Split MxType into enumeration per category to deal with compiler class size limitations Added internal loops API to MTs: 110, 201, 203, 210, 410, 412, 420, 422, 450, 456, 604, 605, 801, 920, 973 Added support for Loop selectors in MtPath, example: Loop1/58A/1 MtType: added a method to retrieve the MtId equivalent MtType: enhanced the enum to implement the SchemaProvider interface, and thus return XSD schemas for MTs Added PathSchemaProvider helper class to read the schemas from a file path Added missing schemas for new versions of MX messages 9.3.1 - May 2022 Fixed packaging 9.3.0 - May 2022 SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Updated gson dependency to 2.9.0 9.2.21 - May 2022 (PW-923) Updated org.apache.santuario:xmlsec dependency to 2.3.1 (only used in LAU signing) to fix CVE-2022-23437 (PW-813) Internal enhancement to fix CVE Deprecation API review 9.2.20 - May 2022 Fixed security vulnerabilities for XML to MT Block4 parser 9.2.19 - April 2022 Fixed MT LAU sign/verify when an ACK + Msg is received 9.2.18 - April 2022 Internal schema compress to reduce jar size (PW-877) Added XmlBlock4; XML to MT Block4 conversion, with an XML structure compatible with the XSD for FIN by SWIFT Fixes to Block4ToXml (PW-810) Fix un LAU signing and verifying algorithm 9.2.17 - March 2022 (PW-877) Fixed exception in Block4Xml when not using Apache xalan 9.2.16 - March 2022 (PW-871) Fixed Block4ToXml for field 46B Added @attach feature to the MtPath, specially suited to retrieve content from the original message attached to an ACK/NAK 9.2.15 - March 2022 Added implementation for version 2.0.11 and 2.0.13 of the SAA DataPDU wrapper Added support for multiple versions of the SAA DataPDU wrapper 9.2.14 - February 2022 (PW-829) In the MT text expanded printout, line feeds are now system dependant 9.2.13 - January 2022 (PW-833) Fixed mandatory field 77E in MTn98 scheme 9.2.12 - January 2022 (PW-819-820) Fixed scheme for SCORE message MT798_760 NPE prevention in SwiftMessageFactory#toggleDirection 9.2.11 - January 2022 MT530: Fixed repetition of sequence C ADDINFO Updated dependency: gson:2.8.8 -> gson:2.8.9 9.2.10 - December 2021 Added Block4Xml; a new converter from MT Block4 into the XML structure compatible with the XSD for FIN by SWIFT Added com.prowidesoftware.integrator.sdk as automatic module name in the MANIFEST for JPMS support (PW-785) Added the original sent message content in the expanded printout of service 21 messages (ACK/NAK) 9.2.9 - November 2021 Fixed MT509 scheme: letter options in B/98a 9.2.8 - October 2021 (PW-750) Fixed MT527 scheme, invalid 94L qualifiers (CR-23) Added MOR to the expanded printout of for inbound MT messages (PW-749) Updated dependency: org.apache.santuario:xmlsec -> 2.2.3 to fix vulnerability (only used in XML v2 features) Updated dependency: Apache Commons Lang 3.8.1 -> 3.12.0 Updated dependency: Apache Commons Text 1.6 -> 1.9 Updated dependency: Gson 2.8.2 -> 2.8.8 9.2.7 - October 2021 (PW-723) Fixed LT identifier (X or default) in SwiftMessageFactory#toggleDirection (PW-719) fixed 77H qualifiers in MT 300, 304, 305 and 306 9.2.6 - October 20221 Added a SchemeXmlWriter class to serialize the MT structure structure definitions into plain XML 9.2.5 - September 2021 Added support for block 5 in the MtPath selector expressions such as b5/MRF 9.2.4 - August 2021 (PW-654) Fixed bic importer parameter path 9.2.3 - August 2021 (PW-599) MT564: Minor scheme fix, 92a TAXR and WITL can be repeated in CASHMOVE (E2) 9.2.2 - July 2021 MT548: Minor scheme fix, added letter option \"C\" in field \"98C:SCTS\" in sequence \"C1a1B1\" (PW-625) XMLv2 DataPDU: mapped Block3/103 into CopyService, and Block3/111 into ServiceLevelAgreement with default to \"001\" (PW-590) Fixed MtPath evaluator when selecting an inner sequence with no unique boundary separator, such as B1 (FIA) in MT564 9.2.1 - June 2021 Changed the generic XmlParser to preserve whitespace by default (added a new method to use the previous implementation) Minor special case fix in MtPath when the source result targets the same field/qualifier as the target expression Added sameQualifier(Field) in the MtPathExpression adn asList() in MtPathResult MT537 scheme fixed fieldset definition for 95PQR ACOW CACO in D1a1B1 MT548 scheme fixed fieldset definition for 22F TRTR, SETR in C1a1B1 Minor fixes in scheme for MT575 9.2.0 - May 2021 SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.1.11 - April 2021 (PW-460) Divided the internal schemas package into packages by category to allow trimming the jar by use (PW-500) Fixed schemes for MT565, qualifier check for field 90[F,J]:OFFR in CAINST sequence 9.1.10 - March 2021 (PW-499) Fixed schemes for MT513, MT564 and MT566: invalid qualifier in field 69D 9.1.9 - March 2021 (PW-494) Fixed schemes for MT565 (sequence B can be repeated up to 1) and MT568 (sequence B is optional, not mandatory) 9.1.8 - March 2021 (PW-493) Fixed scheme for MT671, missing :22H::PRCD//PREF in Other Details sequence 9.1.7 - March 2021 Added expanded printout support for service 21 messages (ACK and NAK) Enhanced the MTInfo implementation to be lenient on the detected message type 9.1.6 - February 2021 (PW-455) Added lenient parsing of MT headers in conversion to XML v2 9.1.5 - January 2021 Added selector b2/Direction in MtPath returning Input or Output Added valueForPath in the MtPathResult to get precise values related to the queried path 9.1.4 - December 2020 Added GpiUtils to determine if the UETR field in block 3 is mandatory for an MT Added explicit file format to model when creating messages with the AbstractSwiftMessageFactory 9.1.3 - November 2020 (PW-414) Fixed DataPDU parsing of LocalOutputTime into block2 receiver date and time fields Added API in Scheme to check if an MT Scheme contains sequences or internal loops (CR-28) Enhanced MtPath to support full-block selector expressions \"b1\" and \"b2\", returning the complete block value as a single result Added targetNamespace() method to the SchemaProvider interface and to the MxType enumeration Fixed MT537 scheme: field 19A in sequence D1a1B1 Transaction Details (PW-387) In the DataPDU parser for MT messages, the Body element is autodetected expecting either a complete MT content or only the block 4 (PW-387) DataPDUWriter: Added generation of the Message/InterfaceInfo 9.1.2 - September 2020 (PW-358) Added LAU signing and verification for FileAct (XML v2 companion files detached from actual payload) (PW-343) Added canonicalization to signed XMLv2 messages (PW-357) PrintoutWriter: Added a setter to overwrite the default BICDirectory 9.1.1 - August 2020 (PW-343) Added API in the XML v2 and LAU classes to compute and verify the binary prefix in XML v2 messages (PW-344) Fixed the XML v2 parser of MT headers when message is Output (inbound) and Body contains only block 4 (PW-316) Added LAU signature creation and verification for the XML v2 message wrapper (PW-327) Added support in the XML v2 API to parse DataPDU TransmissionReport into ACK/NACK messages (PW-324) Fixed the XML v2 parser to capture gpi fields (111 and 121) from the FINUserHeader element when present (PW-324) Updated the XML v2 DataPDU wrapper model to version SAA 2.0.7 (PW-195) Added handy methods in the BICDirectory to query by institution and country Internal refactor of generated MT Scheme classes to avoid MethodTooLargeException in runtime (PW-322) Fixed the XML v2 parser for MT Output messages with DataPDU Body containing only the block 4 9.1.0 - May 2020 SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.0.1 - May 2020 (PW-301) Minor fix in SwiftMessageFactory.toggle that was not setting sender input time in outbound to inbound conversion 9.0.0 - May 2020 Prowide Integrator fatjar split into single jars for the SDK and modules, each with its own versioning from now on 8.0.9 - May 2020 Fixed scheme for 564, typo in MET2 and MET3 qualifiers 8.0.8 - April 2020 Expanded the ISO 20022 model to include all the historic message versions, not only the latest Added a specific model library including the set of restricted ISO 20022 for CBPR+ (Cross-border Payments and Reporting Plus) release 1.2 Enhanced the PrintoutWriter to support invalid message types and invalid fields NPE prevention in BICDirectory create connection 8.0.7 - March 2020 Added a specific model library including the set of restricted ISO 20022 for SIC (Swiss RTGS) v4.6 release Added support for keywords \"sender\" and \"receiver\" in MtPath expressions to retrieve header addresses regardless of the message direction 8.0.6 - February 2020 Added parser and model classes for seev.045, seev.046, seev.047, seev.048, seev.049 8.0.5 - January 2019 (PW-235) Added SafeXmlUtils to disallow XXE in all XML parsing and validation code Added abstract message() serialization method to AbstractMessage (implemented by the AbstractMT and AbstractMX subclasses) Fixed NPE in MtPath evaluation with null blocks as parameter Added support for \"child\" axis in MtPath expressions to query direct children of sequences instead of the default \"all descendants\" behaviour BusinessHeader added factory methods to create the ISO business header or the legacy SWIFT header given a few simple parameters 8.0.4 - December 2019 Prevention of NPE in expanded printout when sender or receiver BIC are null Changed default MX serialization root element \"message\" to \"RequestPayload\" when both Document and AppHdr are present Changed default MX serialization in AbstractMX#message() to include the AppHdr when present and not just the Document Added a jaxb context cache to boost performance when parsing MX messages, this can be enabled with SdkConfiguration#setCachedJaxbContext 8.0.3 - September 2019 (PW-189) Added back message model for pain.008.001.02, pain.001.001.05 and pain.002.001.05 (PW-186) Added fallback option to load IBAN property file from different classloader Added a specific model library including all SEPA messages of the EPC 2019 v1.0 release Added the SchemaProvider interface, implemented by the MxType enum, to get the default ISO schemas for each message type 8.0.2 - August 2019 Explicit UTF-8 encoding was added where necessary to ensure portability Added fallback option to load license from different classloader 8.0.1 - July 2019 Fixed BIC Directory imported (truncation error for BIC PLus files) Fixed SwiftMessageFactory#ACK that was appending the original message to the ACK twice 8.0.0 - May 2019 JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 7.10.9 - May 2019 Fixed classpath in bin/*.bat scripts Added support for field repetitions in MtPath expressions, such as /A/22F[3] to select the third 22F in sequence A Fixed stack overflow exception in XmlParser#parse(Stream) Fixed SwiftMessageFactory#ACK the MUR field goes to block 4 instead of block 3 7.10.8 - March 2019 Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Fixed obfuscation to keep directories in jar Added API to sign and validate LAU signatures in MT messages Added valueDate and tradeDate to the AbstractSwiftMessage model 7.10.7 - January 2019 Fixed constructor for String or MxSwiftMessage in the MX model classes (subclasses of AbstractMX) Added support for legacy pain.002.001.03 Fixed semantic rules for MT 360 and 361 Moved MtSchemeValidator from internal package to com.prowidesoftware.swift.scheme as part of the public API 7.10.6 - November 2018 (PW-120) Added an SDK configuration option to indicate if the institution is a GPI member Added tag index information to the MtPath results when the expression targets a field or a component within a field Added a builder pattern implementation to the MtPathResult Fixed MX parser for Java 8+ to enable parsing recognized MX messages with non-standard (swift or iso) xmlns Fixed writer and parser for XML v2 (block 4 only mode): removed trailing line break in last tag Fixed writer for XML v2 (whole message mode): removed empty blocks before base64 encoding 7.10.5 - October 2018 Added checkFormat in AbstractSwiftMessageFactory to validate a raw SWIFT content against an expected format Added XmlV2Configuration to customize the behaviour of the XML v2 parser and writer API Fixed DataPDUWriter creation from AbstractMX that was not propagating the MX header 7.10.3 - July 2018 Removed deprecated Hibernate XML mappings for MT schemes (Scheme.hbm.xml, SchemeElement.hbm.xml, SchemeFieldDefaultValue.hbm.xml) 7.10.2 - July 2018 JPA annotations moved from accessors to fields Fixed com.sun.xml reference in MX marshalling Added toJson and fromJson to MX classes (AbstractMX and subclasses) 7.10.0 - April 2018 SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) BIC directory: added support to seamlessly import BIC Plus or BIC Directory 2018 txt files from swiftrefdata.com 7.9.7u1 - February 2018 (PW-54) New API in SwiftMessageFactory to toggle the message direction 7.9.7 - January 2018 Changes in the distribution package: Command line tools in the bic directory changed from jar files to wrapper scripts Dependencies directory renamed to lib Removed the BUILD id timestamp from the jar files Updated dependency: org.apache.derby:derby:10.10.1.1 -> org.apache.derby:derby:10.12.+ Updated dependency: com.google.code.gson:gson 1.7.1 -> com.google.code.gson:gson:2.8.2 7.9.6 - December 2017 Added isEmpty API in MtPathResult XmlNode: added support for parent steps (..) in find API 7.9.5 - December 2017 PrintoutVisitor: added onBICExpansion event to customize how BIC codes are expanded with information from the catalog PrintoutVisitor: added ACCOUNT as FieldType to customize how to render account numbers Added \"ignore whitespaces and case\" to value comparator Changed checksum fields in persistence mapping from length 30 to 32 to support uncoded MD5 hashes size Added checksumBody to persistence mapping Deprecated message relation DUPLICATE in favour of DUPLICATE OF and DUPLICATED BY 7.9.4 - November 2017 JRE requirement backported to Java 1.6 BIC directory: added all fields from the FI specification to both the importer tool and the query API Fixed MANIFEST classpath for bicimporter.jar tool 7.9.3 - October 2017 Added MtPathType in MtPathResult and MtPathExpression MtPath: enhanced support in nested queries, check javadoc for MtPath#evaluate(String path, MtPathResult source) Added attributes in MtPathResult to hold the original message and path used for the query Fixed MtPath when querying for fields within other source field block and with an expression not targeting a component New helper API to trim segments in XPath New out-of-the-box XML expanded printout for MTs (XmlPrintoutVisitor) Added comprehensive support for MX system messages (xsys category) Added API in MtPath API to query content within a specific given block Fixed city heading import in BIC directory 7.9.2 - August 2017 Added API in generic XmlNode implementation: hasAttributes(), isEmpty() and removeEmptyElements() Added schemes and model for MX cbrf category Added missing updates for MX supl XPath added API to strip predicates and to collapse parent segments XmlNode more API for siblings, enhanced path() to include predicates when element is repeated Removed commons-beanutils and dom4j dependencies Updated pom.xml for Integrator 7.9.1 - June 2017 Added customizable expanded printout for MT messages, to display MT messages in human-friendly TXT and HTML 7.9 - May 2017 SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX) 7.8.9 - May 2017 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 7.8.8 - March 2017 Added helper class BICDirectoryUtils to expand BIC codes New MXInfo feature to retrieve MX messages names and description in english 7.8.7 - December 2016 New generic ValueComparator to compare field and components values with special equality condition based on exceptions Internal code clean ups (removing SRU2015 stuff) 7.8.6 - November 2016 JRE requirement increased to Java 1.7 (only for Integrator SDK and modules, Core still works on 1.5) New internal MT-XML converter New internal XSD package for MT Internal code clean ups (removing deprecated SRU2014 stuff) Updated all internal XSD schemas for MX to the latest enriched version 7.8.4 - Oct 2016 Enhanced AbstractMX parse to support namespaces with single quotes Expanded BIC directory and bicimporter to include institution name, city and country as table columns Added updateFrom AbstractMX to MxSwiftMessage Fixed MxSwiftMessage mapping to store BusinessProcess enum as simple string New AbstractSwiftMessageFactory to create messages from different source formats and objects Enhanced Mx parsing to support a wider range of XMLs, reading AppHdr and Document as partial chunks and ignoring the rest Mx reader migrated from SAX to StAX for better performance Support for SAA message wrapper (DataPDU) used in XML v2 formats for both MT and MX 7.8.3 - Jul 2016 Generic XML API migrated from MyFormat to SDK Removed invalid Mx classes generated from FIN schemas 7.8.2 - Jul 2016 Fixed schemes: definition of field 12A in FIA subsequences of MTs 54x Semantic 283 bugfix (used in MTs 307,503,504,505,506,536,537,548,578,586) 2016 June Added API Scheme.getSequenceByField Added API SchemeManager schemes loading from MT message objects Added API SchemeManager to get default scheme name for MT messages 2015 November Added API to control prefix, and XML declaration when serializing Mx headers and documents Added wrapper API, with SNL wrapper as initial implementation Added MxParserIntegrator containing generic Mx parsing (common API to parse all Mx) Fixed entity escape in serialization to XML (for example: & instead of & in the generated XML) Fixed serialization of field 11R, 11S and 32R 2015 August Fields 11R and 11S component 3 split into two independent components. 2014 December MX: Fixed attribute handling in xml event writer MX: Better XML error handling Added adhoc sequence code to MT609 SwiftTagListBlock: more consistent append api, deprecated replaced methods SwiftParser: Added a lenient version to allow partial parsing of blocks 1 and blocks 2 when the total value size is invalid 2014 June Release package includes now both checkouts of core examples and integrator examples from github Examples moved out to github repository 2014 April Added Field.is(String,String) 2014 March Added missing SwiftCharset_it.properties Added exists() to BICDirectory Added IntegratorConfiguration class Optional BIC Directory query and app to import into internal database Added a BIC directory importing command line application Added model and API for BIC Directory information 2013 September SRU 2013 update","title":"Prowide Integrator SDK"},{"location":"release-notes/changelog-sdk/#prowide-integrator-sdk-changelog","text":"","title":"Prowide Integrator SDK - CHANGELOG"},{"location":"release-notes/changelog-sdk/#9426-snapshot","text":"MT SchemeXmlWriter: make description and release optional","title":"9.4.26 - SNAPSHOT"},{"location":"release-notes/changelog-sdk/#9425-may-2024","text":"(PW-1868) Added a DataPDUWriterFactory to create specific versions of the writer instance based on the Revision element in the XML (PW-1870) Added new method to MxPrintoutVisitor in order to allow printing the MX path for a given element","title":"9.4.25 - May 2024"},{"location":"release-notes/changelog-sdk/#9424-april-2024","text":"(PW-1844) Enhanced the DataPDUWriter to propagate the original Document namespace when not strictly ISO-20022 (for example SIC)","title":"9.4.24 - April 2024"},{"location":"release-notes/changelog-sdk/#9423-april-2024","text":"(PW-1836) Fixed scheme for MT 537, enabling repetitions of sequence C2a","title":"9.4.23 - April 2024"},{"location":"release-notes/changelog-sdk/#9422-april-2024","text":"(PW-1816) Added XmlNode support for default namespaces","title":"9.4.22 - April 2024"},{"location":"release-notes/changelog-sdk/#9421-march-2024","text":"(PW-1810) Added changes to allow removing AppHdr and Document namespaces prefixes when creating a DataPDU XML","title":"9.4.21 - March 2024"},{"location":"release-notes/changelog-sdk/#9420-march-2024","text":"(PW-1755) Fix Block4Xml for field 37K to handle the special \"PCT\" (percentage) in the currency field (used in MT305) (PW-1697) Fix Block4Xml for fields 29O and 37K, affecting MT306 structure validation Added method findAllContainingValue in XmlNode class","title":"9.4.20 - March 2024"},{"location":"release-notes/changelog-sdk/#9419-february-2024","text":"Updated the SchemeMatcherQualifier report logic to provide Code word errors information","title":"9.4.19 - February 2024"},{"location":"release-notes/changelog-sdk/#9418-january-2024","text":"(PW-1743) Remove usage of deprecated SafeXMLUtils methods","title":"9.4.18 - January 2024"},{"location":"release-notes/changelog-sdk/#9417-january-2024","text":"(PW-1739) Fixed field 23 expanded printout in order to match specification for MT102/MT103/MT305/MT601 Added method findFirstByValue in XmlNode class","title":"9.4.17 - January 2024"},{"location":"release-notes/changelog-sdk/#9416-january-2024","text":"(PW-1734) Fixed schemes for MT503/504/506/507/510,517/538/541/567/575. Converted optional subsequences to mandatory","title":"9.4.16 - January 2024"},{"location":"release-notes/changelog-sdk/#9415-december-2023","text":"(PW-1732) Fixed scheme for MT543: sequence E3 Amounts is mandatory","title":"9.4.15 - December 2023"},{"location":"release-notes/changelog-sdk/#9414-december-2023","text":"(PW-1718) Fixed fields 50F and 59F expanded printout missing components Added Xsd Path Generator in order to generate all valid paths from a XSD element Added XsdPath validation classes: AppHdrPathValidator, MxPathValidator, and XsdPathValidator interface.","title":"9.4.14 - December 2023"},{"location":"release-notes/changelog-sdk/#9413-december-2023","text":"(PW-1718) Fixed the TXT expanded printout for fields 50 and 59 that was missing some components","title":"9.4.13 - December 2023"},{"location":"release-notes/changelog-sdk/#9412-november-2023","text":"(PW-1697) Fixed scheme for MT306","title":"9.4.12 - November 2023"},{"location":"release-notes/changelog-sdk/#9411-november-2023","text":"(PW-1688) Updated the pw_mt_info properties with labels and descriptions from the SRU2023 changes (PW-1675) Updated Scheme 765 adding new semantic check for field 31R","title":"9.4.11 - November 2023"},{"location":"release-notes/changelog-sdk/#9410-october-2023","text":"(PW-1639) Added options in the LAU signing and verification processing parameters to support latest version of SWIFT Alliance Lite","title":"9.4.10 - October 2023"},{"location":"release-notes/changelog-sdk/#949-october-2023","text":"(PW-1667) Updated Scheme 671 schema to fix field 95","title":"9.4.9 - October 2023"},{"location":"release-notes/changelog-sdk/#948-october-2023","text":"(PW-1664) Updated MT543 schema to fix field 36[B,D] PAIR/TURN position within LINK subsequence","title":"9.4.8 - October 2023"},{"location":"release-notes/changelog-sdk/#947-october-2023","text":"Added JSON file format support in the AbstractSwiftMessageFactory to automatically detect the JSON structure and parse it into an MT or MX message Added missing versions to the AbstractDataPDU generic parse","title":"9.4.7 - October 2023"},{"location":"release-notes/changelog-sdk/#946-september-2023","text":"(PW-1612) Fixed Block4Xml serialization of field 72 in MT102_STP and MT103_STP tht was producing a non XSD compatible structure (PW-1605) Fixed the SwiftMessageFactory#toggleDirection to use 24-hour time format in the Block2 Output","title":"9.4.6 - September 2023"},{"location":"release-notes/changelog-sdk/#945-september-2023","text":"(PW-1594) Fixed invalid qualifier in MT543 scheme; qualifier MFKT -> MRKT in sequence B1","title":"9.4.5 - September 2023"},{"location":"release-notes/changelog-sdk/#944-september-2023","text":"(PW-1578) Updated schemes 710, 720 to fix a bug introduced in 9.4.1 (PW-1449) Added support for version 2.0.14 of the SAA DataPDU wrapper (PW-1118) Added support in MtPath extract content from Block3 given an existing MtPathResult as parameter","title":"9.4.4 - September 2023"},{"location":"release-notes/changelog-sdk/#943-july-2023","text":"(PW-1423) Added a RitsMessageIdentifierGenerator helper class to generate RITS MX message identifiers","title":"9.4.3 - July 2023"},{"location":"release-notes/changelog-sdk/#942-june-2023","text":"(PW-1369) Added a property to the TxtPrintoutVisitor to opt out printing the label for the components within a field (PW-1369) Added an includeComponentLabel boolean to the MTInfo#fieldValue method to opt out printing the label for the components within a field (PW-1369) Added an onField method to the PrintoutVisitor interface to customize how field components are split and printed Changed the MtPathExpression to support variables in predicates, such as A[2]/B[{n}]/B1[3]/23A[{m}]/Line[{o}]","title":"9.4.2 - June 2023"},{"location":"release-notes/changelog-sdk/#941-june-2023","text":"Fixed MT schemes fo MT537 Fixed MT schemes fo MT710 and MT720","title":"9.4.1 - June 2023"},{"location":"release-notes/changelog-sdk/#940-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"9.4.0 - May 2023"},{"location":"release-notes/changelog-sdk/#9323-april-2023","text":"(PW-1350) Added 2 MxWriteParams vars to XmlV2Configuration in order to allow custom setting of AppHdr and Document namespaces prefixes when creating a DataPDU XML","title":"9.3.23 - April 2023"},{"location":"release-notes/changelog-sdk/#9322-april-2023","text":"(PW-1348) Added a IBICDirectory setter to the MTInfo to customize the directory used when doing expanded printout of BIC codes","title":"9.3.22 - April 2023"},{"location":"release-notes/changelog-sdk/#9321-march-2023","text":"(PW-1239) Further enhanced the PrintoutWriter to resolve the labels of the MT798 proprietary fields, for any recognized sub-message type Changed the MTInfo.fieldValue to use the same implementation as the PrintoutWriter, which is more complete and produces a better result","title":"9.3.21 - March 2023"},{"location":"release-notes/changelog-sdk/#9320-march-2023","text":"(PW-1239) Enhanced the PrintoutWriter to resolve the labels of the MT798_700 proprietary fields","title":"9.3.20 - March 2023"},{"location":"release-notes/changelog-sdk/#9319-march-2023","text":"(PW-1195) Revert charset to system default value instead of fixed UTF-8 in: XmlNode, DataPDU, MxPrintoutWriter and LAU","title":"9.3.19 - March 2023"},{"location":"release-notes/changelog-sdk/#9318-march-2023","text":"Fixed MtPath log verbosity when querying fields with wildcard letter option, such as 93a Re-enabled the BIC query tool command line to check the integrator data jar file contains the imported data","title":"9.3.18 - March 2023"},{"location":"release-notes/changelog-sdk/#9317-february-2023","text":"Minor javadoc fixes","title":"9.3.17 - February 2023"},{"location":"release-notes/changelog-sdk/#9316-february-2023","text":"(PW-1168) Added message model for the MT SCORE subtypes 723/733/737/751/758/776/780/782/731/736/748/753/755/757/771/773","title":"9.3.16 - February 2023"},{"location":"release-notes/changelog-sdk/#9315-february-2023","text":"Prowide Core dependency update","title":"9.3.15 - February 2023"},{"location":"release-notes/changelog-sdk/#9314-january-2023","text":"(PW-1149) Added UETR to the MT expanded printout, and fixed indentation when printing multiline fields in TXT format","title":"9.3.14 - January 2023"},{"location":"release-notes/changelog-sdk/#9313-december-2022","text":"Removed the deprecated \"eval\" JS expressions from the MT schemes, in favor of the new \"qualifierValidation\" structure","title":"9.3.13 - December 2022"},{"location":"release-notes/changelog-sdk/#9312-november-2022","text":"(GH-63) Added message type versions in categories: acmt, admi, auth, caaa, camt, catm, fxtr, pacs, reda, seev, semt, sese, setr, supl and trck Added new business process and messages for: caad, cafc, cain, casp","title":"9.3.12 - November 2022"},{"location":"release-notes/changelog-sdk/#9311-november-2022","text":"(PW-1109) Fixed BLock4Xml for narrative container fields having a codeword without any narrative text Added DataPDU model for versions 2.0.1, 2.0.2, 2.0.3, 2.0.4, 2.0.5, 2.0.6, 2.0.8, 2.0.9 and 2.0.10 Deprecated the SdkConfiguration in favor of localized configuration API in each module/feature Fixed the embedded BIC directory connection handling, with automatic reopening after a closed connection","title":"9.3.11 - November 2022"},{"location":"release-notes/changelog-sdk/#9310-november-2022","text":"Updated Apache Commons Text dependency to 1.10 to fix reported CVE (PW-1101) Fixed field 35C unmarshalling in XmlBlock4 (PW-1086) Fixed field 36D unmarshalling in XmlBlock4 (PW-1085) Moved the custom BIC directory implementation setter from the SDK singleton configuration to the PrintoutWriter constructor","title":"9.3.10 - November 2022"},{"location":"release-notes/changelog-sdk/#939-october-2022","text":"(PW-1082) Added support for cached JaxbContext in the DataPDU parsing to achieve better performance","title":"9.3.9 - October 2022"},{"location":"release-notes/changelog-sdk/#938-october-2022","text":"Added a StringSchemaProvider that can be used to provide a schema from a String when using the Mx API","title":"9.3.8 - October 2022"},{"location":"release-notes/changelog-sdk/#937-september-2022","text":"(PW-1058) Fix SCORE 798<767> and 798<775> B2C - field 21 is optional (PW-1048) Added options in the SwiftMessageFactory to create an ACK from an MX message","title":"9.3.7 - September 2022"},{"location":"release-notes/changelog-sdk/#936-september-2022","text":"(GH-119) MT566: Fixed repetitions of sequence USECU/FIA that is not repetitive Minor fix in MT internal schemes, added some missing \"rules\" reference attributes","title":"9.3.6 - September 2022"},{"location":"release-notes/changelog-sdk/#935-august-2022","text":"MT schemes refactor to decommission the need for the Rhino dependency when validating MT message structure","title":"9.3.5 - August 2022"},{"location":"release-notes/changelog-sdk/#934-august-2022","text":"(PW-1010) Added helper API MtSanitizer to fix MT content charset, start of line characters and certain missing components (PW-1015) Added field validation for fields 47E, 49D and 49F (required in SCORE MT798_774) (PW-922) MxPrintout: Added support for xsys message types SchemeXmlWriter/Reader fixed and refactored","title":"9.3.4 - August 2022"},{"location":"release-notes/changelog-sdk/#933-august-2022","text":"(PW-922) Added a fallback option to the MX printout writer to handle unknown message types","title":"9.3.3 - August 2022"},{"location":"release-notes/changelog-sdk/#932-july-2022","text":"(PW-977) Fixed MT scheme 203 with inner loops instead of formal sequences (PW-969) fixes to xml converters for fields 12E, 12K and 12R (PW-895) Fixed Block4Xml to properly name anonymous sequences (LoopN) (PW-894) Fixed MT scheme 203 with inner loops instead of formal sequences (PW-873) Added a new MxPrintoutWriter to generate a human-friendly view of MX messages in plain text (PW-873) Added the MxLabelInfo helper class to retrieve business labels for MX message elements Split MxType into enumeration per category to deal with compiler class size limitations Added internal loops API to MTs: 110, 201, 203, 210, 410, 412, 420, 422, 450, 456, 604, 605, 801, 920, 973 Added support for Loop selectors in MtPath, example: Loop1/58A/1 MtType: added a method to retrieve the MtId equivalent MtType: enhanced the enum to implement the SchemaProvider interface, and thus return XSD schemas for MTs Added PathSchemaProvider helper class to read the schemas from a file path Added missing schemas for new versions of MX messages","title":"9.3.2 - July 2022"},{"location":"release-notes/changelog-sdk/#931-may-2022","text":"Fixed packaging","title":"9.3.1 - May 2022"},{"location":"release-notes/changelog-sdk/#930-may-2022","text":"SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Updated gson dependency to 2.9.0","title":"9.3.0 - May 2022"},{"location":"release-notes/changelog-sdk/#9221-may-2022","text":"(PW-923) Updated org.apache.santuario:xmlsec dependency to 2.3.1 (only used in LAU signing) to fix CVE-2022-23437 (PW-813) Internal enhancement to fix CVE Deprecation API review","title":"9.2.21 - May 2022"},{"location":"release-notes/changelog-sdk/#9220-may-2022","text":"Fixed security vulnerabilities for XML to MT Block4 parser","title":"9.2.20 - May 2022"},{"location":"release-notes/changelog-sdk/#9219-april-2022","text":"Fixed MT LAU sign/verify when an ACK + Msg is received","title":"9.2.19 - April 2022"},{"location":"release-notes/changelog-sdk/#9218-april-2022","text":"Internal schema compress to reduce jar size (PW-877) Added XmlBlock4; XML to MT Block4 conversion, with an XML structure compatible with the XSD for FIN by SWIFT Fixes to Block4ToXml (PW-810) Fix un LAU signing and verifying algorithm","title":"9.2.18 - April 2022"},{"location":"release-notes/changelog-sdk/#9217-march-2022","text":"(PW-877) Fixed exception in Block4Xml when not using Apache xalan","title":"9.2.17 - March 2022"},{"location":"release-notes/changelog-sdk/#9216-march-2022","text":"(PW-871) Fixed Block4ToXml for field 46B Added @attach feature to the MtPath, specially suited to retrieve content from the original message attached to an ACK/NAK","title":"9.2.16 - March 2022"},{"location":"release-notes/changelog-sdk/#9215-march-2022","text":"Added implementation for version 2.0.11 and 2.0.13 of the SAA DataPDU wrapper Added support for multiple versions of the SAA DataPDU wrapper","title":"9.2.15 - March 2022"},{"location":"release-notes/changelog-sdk/#9214-february-2022","text":"(PW-829) In the MT text expanded printout, line feeds are now system dependant","title":"9.2.14 - February 2022"},{"location":"release-notes/changelog-sdk/#9213-january-2022","text":"(PW-833) Fixed mandatory field 77E in MTn98 scheme","title":"9.2.13 - January 2022"},{"location":"release-notes/changelog-sdk/#9212-january-2022","text":"(PW-819-820) Fixed scheme for SCORE message MT798_760 NPE prevention in SwiftMessageFactory#toggleDirection","title":"9.2.12 - January 2022"},{"location":"release-notes/changelog-sdk/#9211-january-2022","text":"MT530: Fixed repetition of sequence C ADDINFO Updated dependency: gson:2.8.8 -> gson:2.8.9","title":"9.2.11 - January 2022"},{"location":"release-notes/changelog-sdk/#9210-december-2021","text":"Added Block4Xml; a new converter from MT Block4 into the XML structure compatible with the XSD for FIN by SWIFT Added com.prowidesoftware.integrator.sdk as automatic module name in the MANIFEST for JPMS support (PW-785) Added the original sent message content in the expanded printout of service 21 messages (ACK/NAK)","title":"9.2.10 - December 2021"},{"location":"release-notes/changelog-sdk/#929-november-2021","text":"Fixed MT509 scheme: letter options in B/98a","title":"9.2.9 - November 2021"},{"location":"release-notes/changelog-sdk/#928-october-2021","text":"(PW-750) Fixed MT527 scheme, invalid 94L qualifiers (CR-23) Added MOR to the expanded printout of for inbound MT messages (PW-749) Updated dependency: org.apache.santuario:xmlsec -> 2.2.3 to fix vulnerability (only used in XML v2 features) Updated dependency: Apache Commons Lang 3.8.1 -> 3.12.0 Updated dependency: Apache Commons Text 1.6 -> 1.9 Updated dependency: Gson 2.8.2 -> 2.8.8","title":"9.2.8 - October 2021"},{"location":"release-notes/changelog-sdk/#927-october-2021","text":"(PW-723) Fixed LT identifier (X or default) in SwiftMessageFactory#toggleDirection (PW-719) fixed 77H qualifiers in MT 300, 304, 305 and 306","title":"9.2.7 - October 2021"},{"location":"release-notes/changelog-sdk/#926-october-20221","text":"Added a SchemeXmlWriter class to serialize the MT structure structure definitions into plain XML","title":"9.2.6 - October 20221"},{"location":"release-notes/changelog-sdk/#925-september-2021","text":"Added support for block 5 in the MtPath selector expressions such as b5/MRF","title":"9.2.5 - September 2021"},{"location":"release-notes/changelog-sdk/#924-august-2021","text":"(PW-654) Fixed bic importer parameter path","title":"9.2.4 - August 2021"},{"location":"release-notes/changelog-sdk/#923-august-2021","text":"(PW-599) MT564: Minor scheme fix, 92a TAXR and WITL can be repeated in CASHMOVE (E2)","title":"9.2.3 - August 2021"},{"location":"release-notes/changelog-sdk/#922-july-2021","text":"MT548: Minor scheme fix, added letter option \"C\" in field \"98C:SCTS\" in sequence \"C1a1B1\" (PW-625) XMLv2 DataPDU: mapped Block3/103 into CopyService, and Block3/111 into ServiceLevelAgreement with default to \"001\" (PW-590) Fixed MtPath evaluator when selecting an inner sequence with no unique boundary separator, such as B1 (FIA) in MT564","title":"9.2.2 - July 2021"},{"location":"release-notes/changelog-sdk/#921-june-2021","text":"Changed the generic XmlParser to preserve whitespace by default (added a new method to use the previous implementation) Minor special case fix in MtPath when the source result targets the same field/qualifier as the target expression Added sameQualifier(Field) in the MtPathExpression adn asList() in MtPathResult MT537 scheme fixed fieldset definition for 95PQR ACOW CACO in D1a1B1 MT548 scheme fixed fieldset definition for 22F TRTR, SETR in C1a1B1 Minor fixes in scheme for MT575","title":"9.2.1 - June 2021"},{"location":"release-notes/changelog-sdk/#920-may-2021","text":"SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.2.0 - May 2021"},{"location":"release-notes/changelog-sdk/#9111-april-2021","text":"(PW-460) Divided the internal schemas package into packages by category to allow trimming the jar by use (PW-500) Fixed schemes for MT565, qualifier check for field 90[F,J]:OFFR in CAINST sequence","title":"9.1.11 - April 2021"},{"location":"release-notes/changelog-sdk/#9110-march-2021","text":"(PW-499) Fixed schemes for MT513, MT564 and MT566: invalid qualifier in field 69D","title":"9.1.10 - March 2021"},{"location":"release-notes/changelog-sdk/#919-march-2021","text":"(PW-494) Fixed schemes for MT565 (sequence B can be repeated up to 1) and MT568 (sequence B is optional, not mandatory)","title":"9.1.9 - March 2021"},{"location":"release-notes/changelog-sdk/#918-march-2021","text":"(PW-493) Fixed scheme for MT671, missing :22H::PRCD//PREF in Other Details sequence","title":"9.1.8 - March 2021"},{"location":"release-notes/changelog-sdk/#917-march-2021","text":"Added expanded printout support for service 21 messages (ACK and NAK) Enhanced the MTInfo implementation to be lenient on the detected message type","title":"9.1.7 - March 2021"},{"location":"release-notes/changelog-sdk/#916-february-2021","text":"(PW-455) Added lenient parsing of MT headers in conversion to XML v2","title":"9.1.6 - February 2021"},{"location":"release-notes/changelog-sdk/#915-january-2021","text":"Added selector b2/Direction in MtPath returning Input or Output Added valueForPath in the MtPathResult to get precise values related to the queried path","title":"9.1.5 - January 2021"},{"location":"release-notes/changelog-sdk/#914-december-2020","text":"Added GpiUtils to determine if the UETR field in block 3 is mandatory for an MT Added explicit file format to model when creating messages with the AbstractSwiftMessageFactory","title":"9.1.4 - December 2020"},{"location":"release-notes/changelog-sdk/#913-november-2020","text":"(PW-414) Fixed DataPDU parsing of LocalOutputTime into block2 receiver date and time fields Added API in Scheme to check if an MT Scheme contains sequences or internal loops (CR-28) Enhanced MtPath to support full-block selector expressions \"b1\" and \"b2\", returning the complete block value as a single result Added targetNamespace() method to the SchemaProvider interface and to the MxType enumeration Fixed MT537 scheme: field 19A in sequence D1a1B1 Transaction Details (PW-387) In the DataPDU parser for MT messages, the Body element is autodetected expecting either a complete MT content or only the block 4 (PW-387) DataPDUWriter: Added generation of the Message/InterfaceInfo","title":"9.1.3 - November 2020"},{"location":"release-notes/changelog-sdk/#912-september-2020","text":"(PW-358) Added LAU signing and verification for FileAct (XML v2 companion files detached from actual payload) (PW-343) Added canonicalization to signed XMLv2 messages (PW-357) PrintoutWriter: Added a setter to overwrite the default BICDirectory","title":"9.1.2 - September 2020"},{"location":"release-notes/changelog-sdk/#911-august-2020","text":"(PW-343) Added API in the XML v2 and LAU classes to compute and verify the binary prefix in XML v2 messages (PW-344) Fixed the XML v2 parser of MT headers when message is Output (inbound) and Body contains only block 4 (PW-316) Added LAU signature creation and verification for the XML v2 message wrapper (PW-327) Added support in the XML v2 API to parse DataPDU TransmissionReport into ACK/NACK messages (PW-324) Fixed the XML v2 parser to capture gpi fields (111 and 121) from the FINUserHeader element when present (PW-324) Updated the XML v2 DataPDU wrapper model to version SAA 2.0.7 (PW-195) Added handy methods in the BICDirectory to query by institution and country Internal refactor of generated MT Scheme classes to avoid MethodTooLargeException in runtime (PW-322) Fixed the XML v2 parser for MT Output messages with DataPDU Body containing only the block 4","title":"9.1.1 - August 2020"},{"location":"release-notes/changelog-sdk/#910-may-2020","text":"SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.1.0 - May 2020"},{"location":"release-notes/changelog-sdk/#901-may-2020","text":"(PW-301) Minor fix in SwiftMessageFactory.toggle that was not setting sender input time in outbound to inbound conversion","title":"9.0.1 - May 2020"},{"location":"release-notes/changelog-sdk/#900-may-2020","text":"Prowide Integrator fatjar split into single jars for the SDK and modules, each with its own versioning from now on","title":"9.0.0 - May 2020"},{"location":"release-notes/changelog-sdk/#809-may-2020","text":"Fixed scheme for 564, typo in MET2 and MET3 qualifiers","title":"8.0.9 - May 2020"},{"location":"release-notes/changelog-sdk/#808-april-2020","text":"Expanded the ISO 20022 model to include all the historic message versions, not only the latest Added a specific model library including the set of restricted ISO 20022 for CBPR+ (Cross-border Payments and Reporting Plus) release 1.2 Enhanced the PrintoutWriter to support invalid message types and invalid fields NPE prevention in BICDirectory create connection","title":"8.0.8 - April 2020"},{"location":"release-notes/changelog-sdk/#807-march-2020","text":"Added a specific model library including the set of restricted ISO 20022 for SIC (Swiss RTGS) v4.6 release Added support for keywords \"sender\" and \"receiver\" in MtPath expressions to retrieve header addresses regardless of the message direction","title":"8.0.7 - March 2020"},{"location":"release-notes/changelog-sdk/#806-february-2020","text":"Added parser and model classes for seev.045, seev.046, seev.047, seev.048, seev.049","title":"8.0.6 - February 2020"},{"location":"release-notes/changelog-sdk/#805-january-2019","text":"(PW-235) Added SafeXmlUtils to disallow XXE in all XML parsing and validation code Added abstract message() serialization method to AbstractMessage (implemented by the AbstractMT and AbstractMX subclasses) Fixed NPE in MtPath evaluation with null blocks as parameter Added support for \"child\" axis in MtPath expressions to query direct children of sequences instead of the default \"all descendants\" behaviour BusinessHeader added factory methods to create the ISO business header or the legacy SWIFT header given a few simple parameters","title":"8.0.5 - January 2019"},{"location":"release-notes/changelog-sdk/#804-december-2019","text":"Prevention of NPE in expanded printout when sender or receiver BIC are null Changed default MX serialization root element \"message\" to \"RequestPayload\" when both Document and AppHdr are present Changed default MX serialization in AbstractMX#message() to include the AppHdr when present and not just the Document Added a jaxb context cache to boost performance when parsing MX messages, this can be enabled with SdkConfiguration#setCachedJaxbContext","title":"8.0.4 - December 2019"},{"location":"release-notes/changelog-sdk/#803-september-2019","text":"(PW-189) Added back message model for pain.008.001.02, pain.001.001.05 and pain.002.001.05 (PW-186) Added fallback option to load IBAN property file from different classloader Added a specific model library including all SEPA messages of the EPC 2019 v1.0 release Added the SchemaProvider interface, implemented by the MxType enum, to get the default ISO schemas for each message type","title":"8.0.3 - September 2019"},{"location":"release-notes/changelog-sdk/#802-august-2019","text":"Explicit UTF-8 encoding was added where necessary to ensure portability Added fallback option to load license from different classloader","title":"8.0.2 - August 2019"},{"location":"release-notes/changelog-sdk/#801-july-2019","text":"Fixed BIC Directory imported (truncation error for BIC PLus files) Fixed SwiftMessageFactory#ACK that was appending the original message to the ACK twice","title":"8.0.1 - July 2019"},{"location":"release-notes/changelog-sdk/#800-may-2019","text":"JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"8.0.0 - May 2019"},{"location":"release-notes/changelog-sdk/#7109-may-2019","text":"Fixed classpath in bin/*.bat scripts Added support for field repetitions in MtPath expressions, such as /A/22F[3] to select the third 22F in sequence A Fixed stack overflow exception in XmlParser#parse(Stream) Fixed SwiftMessageFactory#ACK the MUR field goes to block 4 instead of block 3","title":"7.10.9 - May 2019"},{"location":"release-notes/changelog-sdk/#7108-march-2019","text":"Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Fixed obfuscation to keep directories in jar Added API to sign and validate LAU signatures in MT messages Added valueDate and tradeDate to the AbstractSwiftMessage model","title":"7.10.8 - March 2019"},{"location":"release-notes/changelog-sdk/#7107-january-2019","text":"Fixed constructor for String or MxSwiftMessage in the MX model classes (subclasses of AbstractMX) Added support for legacy pain.002.001.03 Fixed semantic rules for MT 360 and 361 Moved MtSchemeValidator from internal package to com.prowidesoftware.swift.scheme as part of the public API","title":"7.10.7 - January 2019"},{"location":"release-notes/changelog-sdk/#7106-november-2018","text":"(PW-120) Added an SDK configuration option to indicate if the institution is a GPI member Added tag index information to the MtPath results when the expression targets a field or a component within a field Added a builder pattern implementation to the MtPathResult Fixed MX parser for Java 8+ to enable parsing recognized MX messages with non-standard (swift or iso) xmlns Fixed writer and parser for XML v2 (block 4 only mode): removed trailing line break in last tag Fixed writer for XML v2 (whole message mode): removed empty blocks before base64 encoding","title":"7.10.6 - November 2018"},{"location":"release-notes/changelog-sdk/#7105-october-2018","text":"Added checkFormat in AbstractSwiftMessageFactory to validate a raw SWIFT content against an expected format Added XmlV2Configuration to customize the behaviour of the XML v2 parser and writer API Fixed DataPDUWriter creation from AbstractMX that was not propagating the MX header","title":"7.10.5 - October 2018"},{"location":"release-notes/changelog-sdk/#7103-july-2018","text":"Removed deprecated Hibernate XML mappings for MT schemes (Scheme.hbm.xml, SchemeElement.hbm.xml, SchemeFieldDefaultValue.hbm.xml)","title":"7.10.3 - July 2018"},{"location":"release-notes/changelog-sdk/#7102-july-2018","text":"JPA annotations moved from accessors to fields Fixed com.sun.xml reference in MX marshalling Added toJson and fromJson to MX classes (AbstractMX and subclasses)","title":"7.10.2 - July 2018"},{"location":"release-notes/changelog-sdk/#7100-april-2018","text":"SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) BIC directory: added support to seamlessly import BIC Plus or BIC Directory 2018 txt files from swiftrefdata.com","title":"7.10.0 - April 2018"},{"location":"release-notes/changelog-sdk/#797u1-february-2018","text":"(PW-54) New API in SwiftMessageFactory to toggle the message direction","title":"7.9.7u1 - February 2018"},{"location":"release-notes/changelog-sdk/#797-january-2018","text":"Changes in the distribution package: Command line tools in the bic directory changed from jar files to wrapper scripts Dependencies directory renamed to lib Removed the BUILD id timestamp from the jar files Updated dependency: org.apache.derby:derby:10.10.1.1 -> org.apache.derby:derby:10.12.+ Updated dependency: com.google.code.gson:gson 1.7.1 -> com.google.code.gson:gson:2.8.2","title":"7.9.7 - January 2018"},{"location":"release-notes/changelog-sdk/#796-december-2017","text":"Added isEmpty API in MtPathResult XmlNode: added support for parent steps (..) in find API","title":"7.9.6 - December 2017"},{"location":"release-notes/changelog-sdk/#795-december-2017","text":"PrintoutVisitor: added onBICExpansion event to customize how BIC codes are expanded with information from the catalog PrintoutVisitor: added ACCOUNT as FieldType to customize how to render account numbers Added \"ignore whitespaces and case\" to value comparator Changed checksum fields in persistence mapping from length 30 to 32 to support uncoded MD5 hashes size Added checksumBody to persistence mapping Deprecated message relation DUPLICATE in favour of DUPLICATE OF and DUPLICATED BY","title":"7.9.5 - December 2017"},{"location":"release-notes/changelog-sdk/#794-november-2017","text":"JRE requirement backported to Java 1.6 BIC directory: added all fields from the FI specification to both the importer tool and the query API Fixed MANIFEST classpath for bicimporter.jar tool","title":"7.9.4 - November 2017"},{"location":"release-notes/changelog-sdk/#793-october-2017","text":"Added MtPathType in MtPathResult and MtPathExpression MtPath: enhanced support in nested queries, check javadoc for MtPath#evaluate(String path, MtPathResult source) Added attributes in MtPathResult to hold the original message and path used for the query Fixed MtPath when querying for fields within other source field block and with an expression not targeting a component New helper API to trim segments in XPath New out-of-the-box XML expanded printout for MTs (XmlPrintoutVisitor) Added comprehensive support for MX system messages (xsys category) Added API in MtPath API to query content within a specific given block Fixed city heading import in BIC directory","title":"7.9.3 - October 2017"},{"location":"release-notes/changelog-sdk/#792-august-2017","text":"Added API in generic XmlNode implementation: hasAttributes(), isEmpty() and removeEmptyElements() Added schemes and model for MX cbrf category Added missing updates for MX supl XPath added API to strip predicates and to collapse parent segments XmlNode more API for siblings, enhanced path() to include predicates when element is repeated Removed commons-beanutils and dom4j dependencies Updated pom.xml for Integrator","title":"7.9.2 - August 2017"},{"location":"release-notes/changelog-sdk/#791-june-2017","text":"Added customizable expanded printout for MT messages, to display MT messages in human-friendly TXT and HTML","title":"7.9.1 - June 2017"},{"location":"release-notes/changelog-sdk/#79-may-2017","text":"SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX)","title":"7.9 - May 2017"},{"location":"release-notes/changelog-sdk/#789-may-2017","text":"Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"7.8.9 - May 2017"},{"location":"release-notes/changelog-sdk/#788-march-2017","text":"Added helper class BICDirectoryUtils to expand BIC codes New MXInfo feature to retrieve MX messages names and description in english","title":"7.8.8 - March 2017"},{"location":"release-notes/changelog-sdk/#787-december-2016","text":"New generic ValueComparator to compare field and components values with special equality condition based on exceptions Internal code clean ups (removing SRU2015 stuff)","title":"7.8.7 - December 2016"},{"location":"release-notes/changelog-sdk/#786-november-2016","text":"JRE requirement increased to Java 1.7 (only for Integrator SDK and modules, Core still works on 1.5) New internal MT-XML converter New internal XSD package for MT Internal code clean ups (removing deprecated SRU2014 stuff) Updated all internal XSD schemas for MX to the latest enriched version","title":"7.8.6 - November 2016"},{"location":"release-notes/changelog-sdk/#784-oct-2016","text":"Enhanced AbstractMX parse to support namespaces with single quotes Expanded BIC directory and bicimporter to include institution name, city and country as table columns Added updateFrom AbstractMX to MxSwiftMessage Fixed MxSwiftMessage mapping to store BusinessProcess enum as simple string New AbstractSwiftMessageFactory to create messages from different source formats and objects Enhanced Mx parsing to support a wider range of XMLs, reading AppHdr and Document as partial chunks and ignoring the rest Mx reader migrated from SAX to StAX for better performance Support for SAA message wrapper (DataPDU) used in XML v2 formats for both MT and MX","title":"7.8.4 - Oct 2016"},{"location":"release-notes/changelog-sdk/#783-jul-2016","text":"Generic XML API migrated from MyFormat to SDK Removed invalid Mx classes generated from FIN schemas","title":"7.8.3 - Jul 2016"},{"location":"release-notes/changelog-sdk/#782-jul-2016","text":"Fixed schemes: definition of field 12A in FIA subsequences of MTs 54x Semantic 283 bugfix (used in MTs 307,503,504,505,506,536,537,548,578,586)","title":"7.8.2 - Jul 2016"},{"location":"release-notes/changelog-sdk/#2016-june","text":"Added API Scheme.getSequenceByField Added API SchemeManager schemes loading from MT message objects Added API SchemeManager to get default scheme name for MT messages","title":"2016 June"},{"location":"release-notes/changelog-sdk/#2015-november","text":"Added API to control prefix, and XML declaration when serializing Mx headers and documents Added wrapper API, with SNL wrapper as initial implementation Added MxParserIntegrator containing generic Mx parsing (common API to parse all Mx) Fixed entity escape in serialization to XML (for example: & instead of & in the generated XML) Fixed serialization of field 11R, 11S and 32R","title":"2015 November"},{"location":"release-notes/changelog-sdk/#2015-august","text":"Fields 11R and 11S component 3 split into two independent components.","title":"2015 August"},{"location":"release-notes/changelog-sdk/#2014-december","text":"MX: Fixed attribute handling in xml event writer MX: Better XML error handling Added adhoc sequence code to MT609 SwiftTagListBlock: more consistent append api, deprecated replaced methods SwiftParser: Added a lenient version to allow partial parsing of blocks 1 and blocks 2 when the total value size is invalid","title":"2014 December"},{"location":"release-notes/changelog-sdk/#2014-june","text":"Release package includes now both checkouts of core examples and integrator examples from github Examples moved out to github repository","title":"2014 June"},{"location":"release-notes/changelog-sdk/#2014-april","text":"Added Field.is(String,String)","title":"2014 April"},{"location":"release-notes/changelog-sdk/#2014-march","text":"Added missing SwiftCharset_it.properties Added exists() to BICDirectory Added IntegratorConfiguration class Optional BIC Directory query and app to import into internal database Added a BIC directory importing command line application Added model and API for BIC Directory information","title":"2014 March"},{"location":"release-notes/changelog-sdk/#2013-september","text":"SRU 2013 update","title":"2013 September"},{"location":"release-notes/changelog-sepa/","text":"Prowide Integrator SEPA - CHANGELOG Model extension for SEPA messages 9.4.0 - July 2023 Version aligned with Prowide Integrator 9.4.x for SRU2023 1.1.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 1.0.8 - December 2022 Switched to semantic versioning 2019v1.0u7 - November 2022 Updated Apache Commons Text dependency to 1.10 to fix reported CVE 2019v1.0u6 - September 2022 Added the current SRU to the version number for consistent SRU based BOM and dependency with other Integrator artifacts 2019v1.0u5 - April 2022 Internal schema compress to reduce jar size 2019v1.0u4 - January 2022 Prowide Integrator SDK and Prowide Core updates 2019v1.0u3 - December 2021 Added com.prowidesoftware.integrator.sepa as automatic module name in the MANIFEST for JPMS support 2019v1.0u2 - October 2020 Removed the CopyableTo implementation from the generated model Added a method to return the MxId and the targetNamespace in the SepaMessageType enumeration 2019v1.0u1 - June 2020 Minor change to removed some unused classes from the SEPA generated dictionary model 2019v1.0 First implementation for the Nov 2019 release","title":"Prowide Integrator SEPA"},{"location":"release-notes/changelog-sepa/#prowide-integrator-sepa-changelog","text":"Model extension for SEPA messages","title":"Prowide Integrator SEPA - CHANGELOG"},{"location":"release-notes/changelog-sepa/#940-july-2023","text":"Version aligned with Prowide Integrator 9.4.x for SRU2023","title":"9.4.0 - July 2023"},{"location":"release-notes/changelog-sepa/#110-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"1.1.0 - May 2023"},{"location":"release-notes/changelog-sepa/#108-december-2022","text":"Switched to semantic versioning","title":"1.0.8 - December 2022"},{"location":"release-notes/changelog-sepa/#2019v10u7-november-2022","text":"Updated Apache Commons Text dependency to 1.10 to fix reported CVE","title":"2019v1.0u7 - November 2022"},{"location":"release-notes/changelog-sepa/#2019v10u6-september-2022","text":"Added the current SRU to the version number for consistent SRU based BOM and dependency with other Integrator artifacts","title":"2019v1.0u6 - September 2022"},{"location":"release-notes/changelog-sepa/#2019v10u5-april-2022","text":"Internal schema compress to reduce jar size","title":"2019v1.0u5 - April 2022"},{"location":"release-notes/changelog-sepa/#2019v10u4-january-2022","text":"Prowide Integrator SDK and Prowide Core updates","title":"2019v1.0u4 - January 2022"},{"location":"release-notes/changelog-sepa/#2019v10u3-december-2021","text":"Added com.prowidesoftware.integrator.sepa as automatic module name in the MANIFEST for JPMS support","title":"2019v1.0u3 - December 2021"},{"location":"release-notes/changelog-sepa/#2019v10u2-october-2020","text":"Removed the CopyableTo implementation from the generated model Added a method to return the MxId and the targetNamespace in the SepaMessageType enumeration","title":"2019v1.0u2 - October 2020"},{"location":"release-notes/changelog-sepa/#2019v10u1-june-2020","text":"Minor change to removed some unused classes from the SEPA generated dictionary model","title":"2019v1.0u1 - June 2020"},{"location":"release-notes/changelog-sepa/#2019v10","text":"First implementation for the Nov 2019 release","title":"2019v1.0"},{"location":"release-notes/changelog-sic/","text":"Prowide Integrator SIC - CHANGELOG Model extension for SIC (Swiss RGTS) messages 9.4.1 - October 2023 Added model for SIC release 4.10 Moved release 4.9 to specific package Deprecated default model.mx.sic package in favor of package per specific SIC releases 9.4.0 - July 2023 Version aligned with Prowide Integrator 9.4.x for SRU2023 4.10.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 4.9.5 - April 2023 Added a SicMessageFactory to autodetect and parse and XML message into the correct Mx SIC model class 4.9.4 - February 2023 Minor javadoc fixes 4.9.3 - February 2023 Prowide dependencies update 4.9.2 - December 2022 Switched to semantic versioning 4.9u1 - November 2022 Updated Apache Commons Text dependency to 1.10 to fix reported CVE 4.9 - November 2022 Model migrated to SIC release 4.9 versions 4.6u6 - September 2022 Added the current SRU to the version number for consistent SRU based BOM and dependency with other Integrator artifacts 4.6u5 - April 2022 Internal schema compress to reduce jar size 4.6u4 - January 2022 Prowide Integrator SDK and Prowide Core updates 4.6u3 - December 2021 Added com.prowidesoftware.integrator.sic as automatic module name in the MANIFEST for JPMS support 4.6u2 - October 2020 Removed the CopyableTo implementation from the generated model Added a method to return the MxId and the targetNamespace in the SicMessageType enumeration 4.6u1 - June 2020 Fixed generated model for the Mx classes to use the restricted SIC elements 4.6 First implementation for the Nov 2019 release","title":"Prowide Integrator SIC"},{"location":"release-notes/changelog-sic/#prowide-integrator-sic-changelog","text":"Model extension for SIC (Swiss RGTS) messages","title":"Prowide Integrator SIC - CHANGELOG"},{"location":"release-notes/changelog-sic/#941-october-2023","text":"Added model for SIC release 4.10 Moved release 4.9 to specific package Deprecated default model.mx.sic package in favor of package per specific SIC releases","title":"9.4.1 - October 2023"},{"location":"release-notes/changelog-sic/#940-july-2023","text":"Version aligned with Prowide Integrator 9.4.x for SRU2023","title":"9.4.0 - July 2023"},{"location":"release-notes/changelog-sic/#4100-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"4.10.0 - May 2023"},{"location":"release-notes/changelog-sic/#495-april-2023","text":"Added a SicMessageFactory to autodetect and parse and XML message into the correct Mx SIC model class","title":"4.9.5 - April 2023"},{"location":"release-notes/changelog-sic/#494-february-2023","text":"Minor javadoc fixes","title":"4.9.4 - February 2023"},{"location":"release-notes/changelog-sic/#493-february-2023","text":"Prowide dependencies update","title":"4.9.3 - February 2023"},{"location":"release-notes/changelog-sic/#492-december-2022","text":"Switched to semantic versioning","title":"4.9.2 - December 2022"},{"location":"release-notes/changelog-sic/#49u1-november-2022","text":"Updated Apache Commons Text dependency to 1.10 to fix reported CVE","title":"4.9u1 - November 2022"},{"location":"release-notes/changelog-sic/#49-november-2022","text":"Model migrated to SIC release 4.9 versions","title":"4.9 - November 2022"},{"location":"release-notes/changelog-sic/#46u6-september-2022","text":"Added the current SRU to the version number for consistent SRU based BOM and dependency with other Integrator artifacts","title":"4.6u6 - September 2022"},{"location":"release-notes/changelog-sic/#46u5-april-2022","text":"Internal schema compress to reduce jar size","title":"4.6u5 - April 2022"},{"location":"release-notes/changelog-sic/#46u4-january-2022","text":"Prowide Integrator SDK and Prowide Core updates","title":"4.6u4 - January 2022"},{"location":"release-notes/changelog-sic/#46u3-december-2021","text":"Added com.prowidesoftware.integrator.sic as automatic module name in the MANIFEST for JPMS support","title":"4.6u3 - December 2021"},{"location":"release-notes/changelog-sic/#46u2-october-2020","text":"Removed the CopyableTo implementation from the generated model Added a method to return the MxId and the targetNamespace in the SicMessageType enumeration","title":"4.6u2 - October 2020"},{"location":"release-notes/changelog-sic/#46u1-june-2020","text":"Fixed generated model for the Mx classes to use the restricted SIC elements","title":"4.6u1 - June 2020"},{"location":"release-notes/changelog-sic/#46","text":"First implementation for the Nov 2019 release","title":"4.6"},{"location":"release-notes/changelog-translations/","text":"Prowide Integrator Translations - CHANGELOG 9.4.40 - SNAPSHOT pacs.010.001.03 -> MT204: fixed mappings for fields 58A and 58D 9.4.39 - May 2024 CBPR+ MT102/103 -> pacs.008.001.08 and MT200/201/202/205 -> pacs.009.001.08: enhanced and fixed mappings from field 72 codewords CATPURP, SVCLVL and LOCINS 9.4.38 - May 2024 (PW-1878) CBPR+ MT900 and MT910 to camt: set Entry/EntryReference to NOTPROVIDED since field 25 is already mapped to the Notification/Account (PW-1865) Added new flag to TranslatorConfiguration class, in order to force the number formatting to have exactly two decimal places 9.4.37 - May 2024 (PW-1872) CBPR+ MT 950 -> camt.053.001.08: fixed mappings from 60M to Balance\\Type\\Code = OPBD and 62M to Balance\\Type\\Code = CLBD (PW-1863) CBPR+ MT 940 -> camt.053.001.08: fixed mappings from 60M to Balance\\Type\\Code = OPBD and 62M to Balance\\Type\\Code = CLBD (PW-1862) MT to MX: Revamped implementation of Narrative translation functions (PW-1847) Added new ISO translators: MT 564/568 <-> seev.031.002.13 Fixed mapping of Block5/PDE flag into the AppHdr/PossibleDuplicate when PDE exists and is empty CBPR+ MT 102/103 -> pacs.008.001.08: fixed mappings for fields 70 and 72 into InstructionForNextAgent and RemittanceInformation\\Unstructured CBPR+ MT 102/103 -> pacs.008.001.08: removed mapping for codeword PURP in field 72 and fixed use of codeword CATPURP into CategoryPurpose\\Code CBPR+ MT 202.COV/205.COV -> pacs.009.001.08.COV: fixed mappings for fields 70 and 72 into InstructionForNextAgent and RemittanceInformation\\Unstructured CBPR+ MT 202 -> pacs.009.001.08/pacs.009.001.08.ADV: fixed mappings for codeword PURP in field 72 into Purpose\\Code and Purpose\\Proprietary Enhanced the market type factories returned by the TranslatorFactoryProvider to honour the translation mappings configuration 9.4.36 - April 2024 (PW-1857) CBPR+ MT 900/910 -> camt.054.001.08: fixed mappings according to CBPR+ mapping rules (PW-1856) MT 200/202/203/205 -> pacs.009: fixed mappings for 72 Narrative extra codewords to InstructionForNextAgent (PW-1855) CBPR+ MT 202 -> pacs.004.001.09: added extra XT99 narrative to ReturnReasonInformation\\AdditionalInformation (PW-1854) CBPR+ MT 202 -> pacs.004.001.09: added mapping for OriginalInstructionIdentification (PW-1850) CBPR+ MT 202 -> pacs.004.001.09: fixed mapping for ServiceLevel\\Code when there's no Block3\\111 (PW-1852) CBPR+ MT 202 -> pacs.004.001.09: added mapping for ReturnIdentification (PW-1851) CBPR+ MT 202 -> pacs.004.001.09: fixed mapping for CreditorAgent when there's no 57a field (PW-1849) CBPR+ MT 202.COV/205.COV -> pacs.009: preserve line numbers in field 50F mapping as part of value in the MX elements (PW-1848) CBPR+ MT 103 -> pacs.004.001.09: fixed mappings to 'NOTPROVIDED' as instructed by the CBPR+ mapping rules (PW-1848) CBPR+ MT 103 -> pacs.004.001.09: added extra XT99 narrative to ReturnReasonInformation\\AdditionalInformation (PW-1848) Fixed mapping of Block5/PDE flag into the AppHdr/PossibleDuplicate (PW-1848) CBPR+ MT 103 -> pacs.004.001.09: fixed mappings to 'NOTPROVIDED' as instructed by the CBPR+ mapping rules MT 103 -> pacs.008: fixed typo in codeword CATPURP 9.4.35 - April 2024 (PW-1835) CBPR+ camt.054.001.08 -> MT 910/910 : fixed mappings for tag 21 (PW-1832) CBPR translators: fixed mapping to comply with CBPR_Agent_Name_Postal_Address_FormalRule rule MX to MT: Revamped implementation of MxToMtFinancialInstitutionNameAndAddress for translation into fields 52D, 53D, 54D, 55D, 56D & 57D MX to MT: Revamped implementation of MxToMtMTFATFNameAndAddress and MxToMtMTFATFNameAndAddress2 for translation into field 50F and 50K MX to MT: fixed coverage in MxToMt functions Added new ISO translator: seev.008.001.08 -> MT 568 Added new ISO translator: MT 536 -> semt.017.001.12 Added new ISO translator: MT 537 -> semt.018.001.13 Added new ISO translators: sese.028.001.09/10 -> MT 578 9.4.34 - April 2024 (PW-1827) Added new ISO translators: camt.053.001.10/11 <-> MT 940/950 (PW-1814) Removed criteria selection in translations MT196/MT296 -> camt.029.001.11 (PW-1759) TranslationFactory: fixed getTranslator for ACK/NACK messages with a specific MX version Added new ISO translator: seev.001.001.10 -> MT 564 Added new ISO translator: seev.002.001.09 -> MT 564 Added new ISO translator: seev.003.001.09 -> MT 564 Added new ISO translator: seev.004.001.09 -> MT 565 Added new ISO translator: seev.005.001.09 -> MT 565 Added new ISO translator: seev.006.001.09 -> MT 567 Added new ISO translator: seev.007.001.09 -> MT 567 MT to MX: Revamped mapping for fields 50F and 59F into structured postal address node when line 3 (country) is present 9.4.33 - March 2024 (PW-1814) MT 196/296 -> camt.029: fixed mapping from narrative 77A when codeword /UETR/ is used in multiple lines (PW-1635) camt.056 -> MT 192/292: fixed default value for tag 20 when node Underlying\\TransactionInformation\\Case\\Identification is missing T2 Translators: added NONREF as fixed value for GroupHeader\\MessageIdentification node T2 Translators: map field 20 to BusinessMessageIdentifier in header 9.4.32 - March 2024 (PW-1759) TranslatorFactory: Added translator ACK/NAK (service 21 message) -> admi.007.001.01 9.4.31 - March 2024 (PW-1804) sese.025 -> MT 540/541/542/543: fixed mapping for multiple 22F STCO indicators (PW-1635) camt.029 -> MT 196/296: fixed default value for tag 20 when node CancellationStatusIdentification is missing Added new ISO translators: sese.020.001.07 -> MT 540/541/542/543 Added new ISO translators: semt.020.001.07 <-> MT 578 Added new ISO translators: semt.002.001.11 <-> MT 535 Added new ISO translator: semt.017.001.12 -> MT 536 Added new ISO translator: semt.018.001.13 -> MT 537 Enhanced truncation report: added MX source path even when partial element content is truncated 9.4.30 - March 2024 (PW-1800) MT 540/541/542/543 -> sese.023: fixed 36B Quantity of Financial Instrument precondition 9.4.29 - March 2024 (PW-1756) MT 102/103 -> pacs.008: added mapping for field 72 codeword /PURP/ into Purpose/Proprietary Added new ISO translators: sese.024.001.11/12 <-> MT 548 Added new ISO translators: pacs.009.001.10 <-> MT 200 (PW-1787) Added new ISO translators: sese.026.001.10 <-> MT 544/545/546/547 (PW-1790) MT950 -> camt.053: fixed BookingDate and EntryDetails mappings (PW-1790) MT942 -> camt.052: fixed BookingDate mapping 9.4.28 - February 2024 (PW-1759) TranslationFactoryConfiguration - deprecated setEvaluatePreconditions (replaced with withEvaluatePreconditions) 9.4.27 - February 2024 (PW-1764) Added new ISO translators: sese.023.001.11 -> MT 540/541/542/543 (PW-1764) Added new ISO translators: sese.025.001.11 -> MT 544/545/546/547 (PW-1764) ISO sese.023.001. / sese.025.001. <-> MT 54*: added mappings for SecuritiesSubBalanceType <-> 22F SSBT (PW-1762) MT 103 -> pacs.004.001.09 (CBPR+/LYNX/T2): fixed mapping for /CHGS/ codeword into ChargesInformation (PW-1759) Added new translator: ACK/NAK (service 21 message) -> admi.007.001.01 (PW-1756) MT 202 -> pacs.009: added mapping for field 72 codeword /PURP/ into Purpose/Proprietary 9.4.26 - January 2024 Added new translator: MT 097 <-> xsys.001.001.01 Added new CBPR+ translator: MT 104 <- pacs.003.001.08 Added new CBPR+ translator: MT 107 -> pacs.003.001.08 Added new ISO translators: MT 104 <- pacs.003.001.08/09/10 Added new ISO translators: MT 107 <-> pacs.003.001.08/09/10 (PW-1754) ISO seev.036.001.14 -> MT 566: fixed mappings in section 16R:CASHMOVE 9.4.25 - January 2024 (PW-1748/1733) CHATS for pacs message the receiver BIC in the AppHdr is fixed to HKICHKHHXXX (PW-1747) SWIFT GO MT199 <-> trck.001.001.02/trck.002.001.01: Fixed mappings Enhanced the TranslatorFactory with new parameters to specify the prefered MT/MX target type and version (replacing preferLatestVersions flag) Added new ISO translators: MT 103.REMIT -> pacs.008.* Added new CBPR+ translator: MT 104 -> pacs.003.001.08 Added new ISO translators: MT 104 -> pacs.003.001.08/09/10 MT192/292 -> camt.058/056: fixed mapping and added default NOTPROVIDED in CancelationReason/AdditionalInformation Truncated report: added path to source and target truncated fields 9.4.24 - January 2024 MT196/296 -> camt.029: removed UETR existence precondition Added new ISO translators: MT 110 <-> camt.107.001.01 Added new ISO translators: MT 111 <-> camt.108.001.01 Added new ISO translators: MT 112 <-> camt.109.001.01 sese.20/23/33/36.* -> MT541: added precondition to check SettlementAmount or OtherAmounts existence seev.32/34/41.* -> MT567: added default A16S:LINK mandatory section 9.4.23 - January 2024 Added new translator: MT 192 -> camt.058.001.08 Added new CBPR+ translator: MT 292 -> camt.058.001.08 Added new CBPR+ translator: MT 192 -> camt.055.001.08 Added new CBPR+ translator: MT 110 -> camt.107.001.01 Added new CBPR+ translator: MT 111 -> camt.108.001.01 Added new CBPR+ translator: MT 112 -> camt.109.001.01 9.4.22 - December 2023 (PW-1732) sese.020 / sese.023 / sese.033 / sese.036 -> MT 543: added precondition to validate SettlementAmount existence in sese messages ISO MT103 -> pacs.008.*: added mapping for block3/103 to ClearingSystem\\Code Added new translators: MT 540 / MT 541 / MT 542 / MT 543 -> sese.020.001.07 / sese.023.001.11 Added new translators: MT 544 / MT 545 / MT 546 / MT 547 -> sese.025.001.11 9.4.21 - December 2023 (PW-1674) CHATS MT103 / MT202 -> pacs.008 / pacs.009: fixed mapping for field 72 /SPRO/ instruction to InstructionForNextAgent\\InstructionInformation CHATS/LYNX/RITS/SCRIPS/T2 pacs.008.001.* <-> MT 103: added mapping for field 26T to CreditTransferTransactionInformation\\Purpose\\Proprietary T2 MT103 -> pacs.008.001.*: convert 8 digit BIC to 11 digit BIC for FinancialInstrumentIdentification/BICFI 9.4.20 - December 2023 (PW-1674) CHATS/LYNX/RITS/SCRIPS/T2 translation factories: return ISO translators in the getTranslator(AbstractMX mx) method (PW-1674) CBPR/SIC/SWIFTGO translation factories: return ISO translators in the getTranslator(AbstractMX mx) method if no specific translator is found (PW-1674) CHATS MT 202/202.COV -> pacs.009.001.08: added mapping for field 72 /CATPURP/ codeword into PaymentTypeInformation\\CategoryPurpose\\Proprietary 9.4.19 - November 2023 (PW-1674) CHATS MT 202/202.COV -> pacs.009.001.08: added mapping for field 72 /SPRO/ instruction to InstructionForNextAgent\\InstructionInformation (PW-1397) CHATS MT 103 -> pacs.008.001.08: added mapping for field 72 /SPRO/ instruction to InstructionForNextAgent\\InstructionInformation 9.4.18 - November 2023 (PW-1698) MT950 -> camt.053: added mapping block3\\108 to GroupHeader\\MessageIdentification (PW-1674) ISO pacs.004/pacs.008/pacs.009 -> MT102/MT103/MT200/MT202/MT205: added mapping GroupHeader\\SettlementInformation\\ClearingSystem\\Code To Block3\\103 (PW-1674) CHATS MT202.COV -> pacs.009.001.08: removed fixed LocalInstrument\\Proprietary mapping 9.4.17 - November 2023 (PW-1691) CBPR+ Translation: fixed business service value for MT 104 -> pain.008.001.08 (PW-1394) Added translation CBPR+ pacs.003.001.08 -> MT107 Updated the SIC translations and translator factory, to use the SIC 4.10 model and message versions 9.4.16 - November 2023 Reverted RITS translations to set the AppHdr creation datetime to the current local time with UTC offset (not necessarily UTC 0) (PW-1684) MT548 -> sese.024: deprecated preconditions 9.4.15 - November 2023 (PW-1683) MT548 -> sese.024/sese.027: don't use field 23G as criteria to define MX target (PW-1674) CHATS Translations: Added MT 192/292 -> camt.056.001.08 (PW-1674) CHATS Translations: Added MT 202 COV -> pacs.009.001.08.COV (PW-1670) seev.031.001.13 -> MT 564: fixed additional mapping for dates without 98C field Added specific translations for SWIFT GO: MT103 <-> pacs.008.001.08 Added specific translations for SWIFT GO: MT199 <-> trck.001.001.02/trck.002.001.01 Added translation MT292 -> camt.058.001.08 9.4.14 - October 2023 (PW-1670) seev.031.001.13 -> MT 564: fixed mapping for dates without 98C field 9.4.13 - October 2023 (PW-1657) pacs.008.001.08/09/10 -> MT 102/103: added additional mapping for PaymentTypeInformation\\ServiceLevel\\Code to Block3\\111 (PW-1581) Enhanced mapping into field 72 to trim the instruction narratives avoiding pure blanks such as \"/REC/ \" (PW-1394) Added translation CBPR+ camt.055.001.08 -> MT192 (PW-1394) Added translation CBPR+ pain.008.001.08 -> MT104 MT564 -> seev.031.002.06 translation: mapping fixes sese.027.001.05 -> MT548 translation: mapping fixes Added missing entries in the CBPR+ translator factory for the recently added translations 9.4.12 - October 2023 (PW-1644) MT 900/910 -> camt.054.001.06/07/08/09: added additional mapping for 21 to TransactionDetails\\References\\EndToEndIdentification 9.4.11 - September 2023 (PW-1596) MT 540/541/542/543 <-> sese.023.001.09: added a special mapping for 22F::STCO/COEX/PARQ and 22F::STCO/COEX/PARC to/from SttlmParams\\PrtlSttlmInd (PW-1397) CHATS Translations: fixed PaymentTypeInformation/CategoryPurpose/Proprietary code IFT 9.4.10 - September 2023 (PW-1477) MT 540/541/542/543 -> sese.023.001.09: added a special mapping for 22F::STCO BPSS into SttlmParams\\SttlmTxCond\\Prtry using BSSP as identification and T2S as issuer 9.4.9 - September 2023 (PW-1442) MT <-> MX translations: fixed TimeZone handling in date time conversions that might lead to invalid date changes during translation depending on the local offset 9.4.8 - September 2023 (PW-1304) LYNX Translation Factory: pacs.009.001.08 returns MT205 translation by default (PW-1304) RITS/SCRIPS/CHATS/T2 Translation Factories: return generic Mx to Mt ISO translators 9.4.7 - August 2023 (PW-1562/PW-1565) MT 530 <-> sese.030.001.008 : Fixed mapping for 22F::PRTL into ReqDtls\\PrtlSttlmInd (PW-1563/PW-1564) MT 548 -> sese.031.001.08 : Fixed mapping, do not map section ReqDtls in MX (Ref\\AcctOwnrTxId, Ref\\MktInfrstrctrTxId and HldInd) (PW-1557) Added translation CBPR+ MT104 -> pain.008.001.08 (PW-1210) Added specific translations for T2 (T2 RTGS) for MT103, MT202 and MT205 to MX (PW-1210) Added specific translations for Lynx (Canada RTGS) for MT103, MT202 and MT205 to MX RITS Translations: fixed creation time in header (Zulu time) MT to MX: replaced the dummy creation date 9999-12-31 in all translations but the CBPR+ ones with the current date 9.4.6 - August 2023 (PW-1474) CBPR MT 900 / MT 910 -> camt.054.001.08 : Added mapping for field 25 into Entry\\EntryReference (PW-1471) MT 548 -> sese.031.001.08 : Fixed mapping for :25D::TPRC//MODC -> ProcessingStatus/Completed (PW-1469) MT 540 / MT 541 / MT 542 / MT 543 <-> sese.023.001.09 : Fixed mapping for 94a <-> SafekeepingPlace (PW-1469) MT 544 / MT 545 / MT 546 / MT 547 <-> sese.025.001.09 : Fixed mapping for 94a <-> SafekeepingPlace (PW-1469) MT 548 <-> sese.024.001.10 : Fixed mapping for 94a <-> SafekeepingPlace (PW-1469) MT 578 <-> sese.028.001.08 : Fixed mapping for 94a <-> SafekeepingPlace (PW-1465) RITS translators: Generate automatic UETR if it doesn't exist in the MT source (Block3/121) (PW-1459) sese.023 <-> MT 540 / MT 541 / MT 542 / MT 543 : Fixed mapping for HoldIndicator <-> 23G (PW-1459) sese.024 <-> MT 548 : Fixed mapping for HoldIndicator <-> 23G (PW-1455) sese.030 -> MT 530 : Fixed mapping for HoldIndicator into :22F::SETT (PW-1454) MxToMt72FullField fix, accept proprietary codewords with alphanumeric characters (PW-1440) MT 548 -> sese.024.001.10 : Added NOTPROVIDED to ProcessingStatus\\CancellationRequested\\AdditionalReasonInformation when :25D::IPRC equals to CPRC and :70D::REAS don't exist 9.4.5 - July 2023 (PW-1423) RITS: Added automatic message identifier generation for the MX header and group header pacs.004 -> MT 103 : Revamped mappings for tag 70 pacs.008 -> MT 102 / 103 : Revamped mappings for tag 70 pacs.009 -> MT 202 COV / 205 COV : Revamped mappings for tag 70 pacs.008 -> MT 102 / 103 : Revamped mappings for tags 50 and 59 Name and Address component pacs.009 -> MT 202 COV / 205 COV : Revamped mappings for tags 50 and 59 Name and Address component 9.4.4 - July 2023 (PW-1438) Added translation seev.044.001.12 -> MT564 (PW-1437) Added translation seev.039.001.12 -> MT564 (PW-1436) Added translation seev.037.001.14 -> MT566 (PW-1435) Added translation seev.036.001.14 -> MT566 (PW-1434) Added translation seev.035.001.14 -> MT564 (PW-1433) Added translation seev.031.001.13 -> MT564 (PW-1433) Added translation seev.031.001.13 -> MT568 Added specific translations for SCRIPS (MEPS+, Singapore RGTS) for MT103 and MT202 to MX Added specific translations for SCRIPS (MEPS+, Singapore RTGS) for MT103 and MT202 to MX (PW-1397) Added specific translations for CHATS (Hong Kong RTGS) for MT103 and MT202 to MX (PW-1399) MT -> MX: amounts are converted into the MX decimal number with minimal decimal places according to the currency (PW-1397) Added specific translations for CHATS (Hong Kong RGTS) for MT103 and MT202 to MX 9.4.3 - July 2023 (PW-1427) Added translations MT564 <-> seev.031.001.11 (PW-1427) Added translations MT568 <-> seev.031.001.11 (PW-1425) Added translation sese.029.001.04 -> MT578 (PW-1425) Added translation semt.020.001.05 -> MT578 (PW-1417) MT104 -> pain.008.001.08 : added mapping for 53A into RemittanceInformation/Structured/AdditionalRemittanceInformation 9.4.2 - June 2023 (PW-1424) Added translations MT530 <-> sese.030.001.08 (PW-1424) Added translations MT548 <-> sese.031.001.08 (PW-1399) FormatDecimal MT -> MX : added 2 fixed decimal places in all translations (PW-1421) CBPR+ MT910 -> camt.054.001.08 : fixed CreditDebitIndicator from DBIT to CRDT (PW-1412) Added translation sese.028.001.08 -> MT578 9.4.1 - June 2023 (PW-1407) MT548 -> sese.024/032/034 / semt.014 and MT537 -> semt.018 : added pending reason code mapping (PATD to OTHR) (PW-1407) MT548 -> sese.024/034 : added rejected reason code mapping (NARR to OTHR) (PW-1406) CBPR+ MT to MX translations -> trim starting slashes while mapping account numbers into Identification/Other/Identification to be compliant with CBPR+ restricted charset (PW-1394) Added CBPR+ translation camt.058.001.08 -> MT292 (PW-1394) Added CBPR+ translation camt.107.001.01 -> MT110 (PW-1394) Added CBPR+ translation camt.108.001.01 -> MT111 (PW-1394) Added CBPR+ translation camt.109.001.01 -> MT112 MTn92, MTn96 and MT200 to MX: Fixed translation of field 11[R,S] into date time element in MX, adding a dummy time component 9.4.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 9.3.42 - June 2023 (PW-1395) Added translation MT578 -> sese.028.001.08 (PW-1391) pacs.008.001 -> MT102/103: Revamped implementation of MxToMtRemittanceInformation for translation into field 70 (PW-1390) CBPR+ pacs.009.001.08 -> MT200/202/205: Revamped implementation of MxToMtPartyNameAndStructuredAddress and MxToMtPartyNameAndUnstructuredAddress for translation into fields 52D/56D/57D/58D (PW-1388) CBPR+ pacs.008.001.08 -> MT103: minor fix in function MxToMtAddressLineIsStructured (PW-1385) CBPR+ pacs.008.001.08 -> MT103: minor fix in function MxToMtNameAndAddress (7/NIDN information) (PW-1384) CBPR+ pacs.008.001.08 -> MT103: fixed mapping for PaymentTypeInformation/CategoryPurpose/Code into tag 23E (PW-1382) sese.023.001.09 -> MT540/MT541/MT542/MT543: new mapping from OtherBusinessParties/Investor/Nationality to field 95C (PW-1182) Added CBPR+ translation MT201 -> pacs.008.001.08 (PW-1182) Added CBPR+ translation MT203 -> pacs.008.001.08 (PW-1182) Added CBPR+ translations MT102 / MT102.STP <-> pacs.009.001.08 / pacs.009.001.08.STP pacs.008/pacs.004/pain.001 -> MT101/102/103: truncate with evidence last line in field 70 mapping CBPR+ camt.052/camt.053: fixes in fields 20/28C/34F/61 mapping pacs.002 <-> MT199 / MT299: Revamped implementation of MxToMt72Or79REJT for translation into field 79 9.3.41 - May 2023 (PW-1371) pacs.004/pacs.008 -> MT102/MT103: conditional mapping to field 71G only if the amount is different from 0 (PW-1360/PW-1363) CBPR+ pacs.004 -> MT103: Revamped implementation of MxToMtRETN(MT1) for translation into field 72 (PW-1359) CBPR+ pacs.008.001.08.STP -> MT103.STP: use only the last PreviousAgent occurrence for mapping into field 72 pacs.004 -> MT103: implementation of MxToMtRETN(MT1) for translation into field 72 pacs.004 -> MT202/MT205: implementation of MxToMtRETN(MT2) for translation into field 72 9.3.40 - May 2023 Added specific translations for RITS (Australian RTGS) for MT103 and MT202 to MX Added a TranslatorFactoryProvider to allow the creation of a TranslatorFactory for a specific market or clearing type Added accessors for the TranslatorConfiguration in the Translator interface Deprecated the 'translate' call with configuration parameter in favor of modifying the translator instance configuration 9.3.39 - April 2023 (PW-1353/1354) CBPR+ pacs.004/pacs.008/pacs.009 to MT: fixed tags 50/59 letter option logic and added MxToMtAddressLineIsStructured function implementation (PW-1349) Enhanced mapping into field 72 by adding MxToMt72FullField function implementation (PW-1349) Fixed the implementation of the InstructionForNextAgent function (PW-1347) Added translation seev.044.001.11 -> MT564 (PW-1345) Added translation seev.037.001.13 -> MT566 (PW-1344) Added translation seev.036.001.13 -> MT566 (PW-1343) Added translation seev.035.001.13 -> MT564 (PW-1342) Added translations seev.031.001.12 -> MT564 / MT568 9.3.38 - April 2023 (PW-1340) CBPR+ MT210 -> camt.057: strip leading slash (/) while mapping tag 25 into Notification/Account/Identification/Other/Identification (PW-1336) pacs.004.001 -> MT103 / MT202 / MT205: fixed mapping of tag 72, added XT99 code to unmappable reason codes 9.3.37 - April 2023 (PW-1335) MT to MX: fixed MxToMt72FullField for translation into field 72, multiple lines mapping in InstructionForNextAgent node (PW-1334) camt.053 -> MT940 / MT950: fixed preconditions and mapping for 60F/M - 61 (PW-1330) pacs.008 -> MT103: fixed mapping of tag 77B, admit simultaneous /ORDERRES/ and /BENEFRES/ codes (PW-1310/1314/1328/1329) MX to MT: mapping for Name and Address fields 50/52/53/54/56/57/58/59, Revamped implementation of MxToMtNameAndAddress functions (PW-1310/1314/1328/1329) CBPR+ pacs.004/pacs.008/pacs.009 translators, using new MxToMtNameAndAddress functions (PW-1276) MX to MT: MxToMt72FullField for translation into field 72, add ACC code to InstructionForCreditorAgent Added and option in the translator configuration to define the specific version for the AppHdr to generate 9.3.36 - April 2023 (PW-1208) ISO pacs.008 / pacs.004 -> MT103: deprecated preconditions (InstructingAgent and InstructedAgent) 9.3.35 - April 2023 (PW-1325) sese.024 -> MT548: fixed translation of tag 24B:REJT, mapping of code OTHR to NARR 9.3.34 - April 2023 (PW-1319) pacs to MT103: removed mapping of extra content /LOCINS/CRED in field 72 (PW-1317) pacs.008.001 -> MT103: fixed mapping of tag 77B, included CountryOfResidence for Debtor and Creditor (PW-1316) MT to MX: fixed mapping of tag 59F PartyIdentifier (PW-1315) MT to MX: MxToMt72FullField for translation into field 72, excluded Proprietary fields in LOCINS indicator (PW-1312) pacs.004.001 -> MT103 / MT202 / MT205: fixed mapping of tag 72, correct parsing of ReasonCode and AdditionalInformation (PW-1311) CBPR+ pacs.008.001 -> MT103: fixed mapping of tag 59, extra row in Name and Address section (PW-1309) CBPR+ pacs.008.001 -> MT103: fixed mapping of tag 59F, extra row in Name and Address section (PW-1308) CBPR+ pacs.008.001 -> MT103: fixed mapping of tag 23E SDVA and INTC (PW-1301) CBPR+ pacs.008.001 -> MT103: added mapping of tag 23E for HOLD, CHQB, PHOB and TELB codes in CreditTransferTransactionInformation\\InstructionForCreditorAgent (PW-1299) pacs.008.001 -> MT103 / MT102: fixed mapping of tag 70, added /URI/ indicator to RemittanceInformation\\Unstructured mapping (PW-1298) pacs.004.001 -> MT103 / MT202 / MT205: fixed mapping of tag 72, added /XT99/ to reason code (PW-1297) MT to MX: fixed mapping of tag 52D, truncate line 2 when FinancialInstitutionIdentification\\Name is longer than max length (PW-1276) pacs.008.001 -> MT103 / MT102: fixed mapping of tag 70, RemittanceInformation\\Unstructured with /RFB/ indicator 9.3.33 - March 2023 (PW-1296) CBPR+ MT202/205 -> pacs.009 and MT103 -> pacs.008: removed the precondition rejecting 53B in present along 54a CBPR+ MT202/205 -> pacs.009 and MT204 -> pacs.010: fixed mapping of 58D into Name & Address to be compliant with CBPR+ UG rule MT to MX: Removed unnecessary precondition checking the format of /CLSTIME/ in field 72 9.3.32 - March 2023 (PW-1288/1289/1290/1291/1293/1295) pacs.004.001.09/10 -> MT103: minor fixes in mapping for Creditor/Agent to field 59 and Debtor/Agent to field 50 (PW-1285) pacs.008.001 -> MT103: fixed mapping InstructionForCreditorAgent\\Code CHQB to field 23E (PW-1284/1294) minor fixes in MxToMt72FullField and MxToMt72FullField2 for translation into field 72 (PW-1283) pacs.004.001.09/10 -> MT103 / MT202 / MT205: fixed mapping for field 72 added extra TEXT line (PW-1282) pacs.004.001.09/10 -> MT103: added mapping for Creditor/Agent to field 59 and Debtor/Agent to field 50 (PW-1280) pacs.008 -> MT103: fixed mapping of tag 70, remove /RFB/ prefix when EndToEndIdentification is NOTPROVIDED (PW-1280) MX_To_MTAgent: removed Schema/Code prefix when it's different from CUID (PW-1280) MX_To_MTFATFNameAndAddress: replaced last / separator in CountryCode/TownName/PostCode for CountryCode/TownName,PostCode (PW-1278) pacs.009.001 -> MT202.COV: Implementation of MxToMt72FullField and MxToMt72FullField2 for translation into field 72 (PW-1276) CBPR+ pacs.008 -> MT103: Revamped implementation of MxToMt72FullField for translation into field 72 (PW-1275) Added translation semt.002.001.10 -> MT535 (PW-1267) MT103 -> pacs.008: Changed field 23E mapping to avoid InstructionForNextAgent/Code for compatibility with HVPS (PW-1209) MT204 -> pacs.010.001.03: deprecated mandatory Block3/121 precondition and autogenerate new UETR if Block3/121 is missing 9.3.31 - March 2023 (PW-1270) MT535 -> semt.002.002.03 / semt.003.002.03: fixed mapping of tag 94a in Sequence B1 to BalanceForAccount/SafekeepingPlace (PW-1265) ISO pacs.004.001.09/10 -> MT103 / MT202 / MT205: fixed reason code mapping for field 72 (PW-1265) ISO pacs.004.001.09/10 -> MT103 / MT202 / MT205: fixed selector criteria, defaulting to MT202 (PW-1265) ISO pacs.004.001.09/10 -> MT103: fixed mapping field 72, field 50F and field 57D (PW-1208) ISO pacs.009 -> MT202: deprecated preconditions (InstructingAgent and InstructedAgent) 9.3.30 - March 2023 (PW-1271) MT192/MT292 -> camt.056.001.08/10: fixed mappings of fields 20 and 21 into the Underlying message information (PW-1266) Fixed length in field 72 wrapped lines (PW-1265) CBPR+ pacs.004.001.09 -> MT103 / MT202 / MT205: fixed reason code mapping for field 72 (PW-1262) CBPR+ pacs.004 -> MT103 / MT202 / MT205: fixed selector criteria, defaulting to MT202 (PW-1240) pacs.009 -> MT202/MT205: proper generation of the // (continuation of narrative) prefixes in field 72 9.3.29 - March 2023 (PW-1240) pacs.009.001.* -> MT202 / MT205: fixed mapping of RemittanceInformation/Unstructured in MxToMt72FullField2 for translation into field 72 9.3.28 - March 2023 (PW-1258) CBPR+ pacs.004.001.09 -> MT103: fixed mapping field 72, field 50F and field 57D (PW-1257) camt.053.001.02/07/08 -> MT940: fixed mapping of multiple AdditionalEntryInformation to field 86 (PW-1182) Fixed translations MT940 <-> camt.060.001.05 for both generic ISO and CBPR+ versions (PW-1182) Added translations MT940 <-> camt.060.001.06 9.3.27 - March 2023 (PW-1253) camt.056.001.08/10 -> MT192 / MT292: fixed mapping of OriginalGroupInformation\\OriginalCreationDateTime to 11S (PW-1252) camt.053.001.* -> MT950: fixed mapping of Statement\\LegalSequenceNumber and Statement\\ElectronicSequenceNumber to field 28C (PW-1249) pacs.008.001.* -> MT102 / MT103: fixed mapping of RemittanceInformation/Unstructured with ROC prefix to field 70 (PW-1247) MT202 / MT205 to pacs.009: Fixed mapping of TELEBEN code into InstructionForCreditorAgent/Code (PW-1245) CBPR+ pacs.009.001.08.COV -> MT202.COV: removed unnecessary RFB prefix in field 70, fixed field 72 line split (PW-1240) MT103 -> pacs.008.001.*: removed unnecessary defaults 'false' for BatchBooking (PW-1238) MT202 / MT205 -> pacs.009.001.*: fixed 53A mapping to SettlementInformation/SettlementAccount (PW-1237) MT103 / MT103.STP -> pacs.008.001.*: fixed 53A mapping to /FIN53/ in InstructionForNextAgent (PW-1235) CBPR+ pacs.009.001.* -> MT202 / MT205: Revamped implementation of MxToMt72FullField2 for translation into field 72 (PW-1233, PW-1246) CBPR+ pacs/camt -> MT: ignore FinancialInstitutionIdentification\\PostalAddress\\AddressLine containing \"NOTPROVIDED\" (PW-1230) CBPR+ pacs.008.001.08 -> MT103: added mapping for field 26T (PW-1229) Preserve whitespaces in XML element values when parsing the source MX for translation into MT (PW-1229) CBPR+ pacs.008/pacs.009 -> MT103/MT202: fixed mapping of multiple occurrences of InstructionForNextAgent/InstructionInformation to field 72 (PW-1229) camt.053.001.* -> MT940: fixed mapping of EntryDetails/AdditionalEntryInformation to field 86 (PW-1229) TranslationConfiguration: added new attribute preserveWhitespaces to prevent the translator from trimming the node contents in the MX to MT translations 9.3.26 - March 2023 (PW-1251) CBPR+ MT to pacs.009: Fixed mapping of field 72 into repetitive InstructionForNextAgent with proper truncation 9.3.25 - March 2023 (PW-1228) CBPR+ translation: fixed duplicated Member Identification in field 57D when translating from a ClearingSystemMemberIdentification element (PW-1225) CBPR+ pacs.004/pacs.009/pacs.009.COV/pacs.009.ADV -> MT202/MT202COV: removed unnecessary defaults 'NOTPROVIDED' for fields 52D-56D-57D (PW-1219) camt.054.001.06/07/08/09 -> MT900/MT910: fixed AddtlTxInf split into field 72 lines 9.3.24 - March 2023 (PW-1224) Fixed RemittanceInformation\\Unstructured -> tag 70 (code RFB deleted) in CBPR+ translation pacs.008.001.08 -> MT103 (PW-1220) Fixed tag 53B incorrect prefix (INGA = C/INDA = D) in CBPR+ translation pacs.008.001.08 -> MT103 (PW-1217) Fixed InstructionForNextAgent\\InstructionInformation -> tag 72 (multiple occurrences) in CBPR+ translation pacs.008.001.08 -> MT103 (PW-1216) Fixed InstgAgt mapping to 72/INS/ in translation CBPR+ pacs.009.001.08 -> MT202 (PW-1210) Added translations MT102 <-> pacs.008.001.09 (PW-1210) Added translations MT103 / MT103.STP <-> pacs.008.001.09 (PW-1210) Added translations MT103 <-> pacs.004.001.10 (PW-1210) Added translations MT202 <-> pacs.004.001.10 (PW-1210) Added translations MT205 <-> pacs.004.001.10 (PW-1210) Added translations MT200 <-> pacs.009.001.09 (PW-1210) Added translations MT202 / MT202.COV <-> pacs.009.001.09 (PW-1210) Added translations MT205 / MT205.COV <-> pacs.009.001.09 (PW-1196) Fixed field 61/Supplementary Details mapping in the MT940 -> camt.053.001.07/08/09 translators (PW-1182) MT920 to camt.060.001.05: fixed intermediate field 34F repetition mapping (PW-1182) Added translations MT196/296 <-> camt.029.001.11 (PW-1182) Added translations pacs.009.001.08 -> MT205.COV 9.3.23 - February 2023 (PW-1205) Removed criteria selection in translations MT196/MT296 -> camt.029.001.09 (PW-1204) Fixed 22F:STCO repetitive tag in translations sese.024. /sese.034. -> MT548 - semt.017.002.01 -> MT536 - semt.018.002.01 -> MT537 9.3.22 - February 2023 (PW-1196) Enhancements in the MT940 <-> camt.053.001.* translators to enable back-and-forth conversion without data loss (PW-1196) Translator Factory: prefer MT940 over MT950 when both options are available as target MT (PW-1194) Fixed field 50A mapping in pacs.008.001.* to MT translators, it was the wildcard letter option 'a' instead of 'A' (PW-1089) Fixed Field 72 translation in MT103 -> pacs.008.001.* (PW-1089) Internal enhancement of narrative fields content extraction (MTs n99, 103, 200, 202 and 205 to MX) 9.3.21 - February 2023 (PW-1183) Fixed criteria filter in translations pacs.008.001.08/10 -> MT102 9.3.20 - February 2023 (PW-1182) Added translations MT102 <-> pacs.008.001.08 (PW-1182) Added translations MT900 <-> camt.054.001.09 (PW-1182) Added translations MT192/292) <-> camt.056.001.10 (PW-1182) Added translations MT941 <-> camt.052.001.09 (PW-1182) Added translation camt.060.001.06 -> MT920 (PW-1089) pacs.008 to MT103: enhanced field 72 mapping to support and propagate also custom codes (PW-1173) mapped the MX header priority into the target MT also when the direction of the MT is inbound (SwiftBlock2Output) Reviewed preconditions for pacs, semt to meet MT semantic checks restrictions Reviewed MT103 translation preconditions to make sure field 54A used with //RT indicator is followed by data for the member id 9.3.19 - January 2023 (PW-1157) Added translation seev.035.001.11 to MT564 9.3.18 - January 2023 (PW-1148) Added translation MT548 to sese.027.001.05 (PW-1146) Added translations sese.020.001.06 to MT540/MT541/MT542/MT543 (PW-1137) Added translations MT199/MT299 RJCT to pacs.002.001.10 (generic ISO 20022 and CBPR+ versions) 9.3.17 - December 2022 (PW-1138) camt.057.001.06 to MT210: Notification/Item/Account fix (PW-1137) CBPR+ translation issue for pacs.002 (PW-1136) Added translation seev.039.001.10/11 to MT564 (PW-1135) Added translation seev.037.001.11 to MT566 (PW-1134) Added translation seev.036.001.11 to MT566 (PW-1133) Added translation seev.035.001.10 to MT564 (PW-1132) Added translation seev.031.001.10 to MT564 (PW-1131) Added translation seev.031.001.10 to MT568 (PW-1129) CBPR pacs.008.001.08 to MT103: minor fix fin field 72 /REC/ mapping MT300 to fxtr.014.001.03: implementation enhancements 9.3.16 - December 2022 (PW-1125) pacs.009.001 to MT202 precondition SR23 fix 9.3.15 - December 2022 (PW-1123) MT202/MT205 to pacs.009.001: added mapping of account in field 53A into instruction for next agent with /FIN53/ prefix Internal implementation enhancements in MT564/MT568 to seev.031 and MT564 to seev.039 9.3.14 - November 2022 (PW-1112) sese.023.001.09 to MT540, MT541, MT542 and MT543 enhancements 9.3.13 - November 2022 (PW-1111) Added translation sese.023.001.09 to MT541 and MT543 Added translation sese.024.001.09 to MT548 9.3.12 - November 2022 Updated Apache Commons Text dependency to 1.10 to fix reported CVE (PW-1103) MT210 <-> camt.057.001.06: Enhanced mapping of fields 50, 52 and 56 (PW-1100) MT196/296 to camt.029: optional 11R/11S criteria check and added 11S translation (PW-1089) MT103 to pacs.008: Enhanced mapping of fields 70 and 72 into InstructionForNextAgent and RemittanceInformation (PW-1044) MT103 to pacs.008 - added narrative 72 /LOCINS/ /CATPURP/ and Batch Booking node Added translation MT200 to camt.050.001.05 9.3.11 - November 2022 Migrated SIC translations to release 4.9 9.3.10 - October 2022 Added translation camt.050.001.05 to MT200 (PW-1088) MT101 to pain.001 and MT103 to pacs.008: field 23E mapping enhancements 9.3.9 - October 2022 (PW-1077) MT548 to sese.024.001.10 mapping enhancements (PW-1063) MT544/545/546/547 to sese.025.001.09: Fixed partial settlement indicator mapping (PART, NPAR) (PW-1063) MT542 to sese.023.001.09: Fixed partial settlement indicator mapping (PART, NPAR) (PW-1057) MT to pacs.008 and pacs.009 - translate field 72 - added /BNF/ and /REC/ prefix in MX output 9.3.8 - October 2022 (PW-1075) MT548 to sese.024.001.10: MatchingStatus fixes with default if field 70D is not present (PW-1072) pacs to MT103 (and 202): Fixed logic for field 33B mapping to avoid D49 error in semantic check (PW-1057) MT103 to pacs.008: Remittance Unstructured mapped from Field 72 /BNF/ with fallback to mapping from field 70 if /BNF/ is not present (PW-1064) Fallback option to system classloader in resource loading Enhancements in MT party identifier into to MX clearing system identification mappings Added missing new versions for SRU2022 to the translator factory 9.3.7 - September 2022 (PW-1066) Added translations MT545 MT546 MT547 to sese.025.001.09 (PW-1065) Added translation sese.023.001.09 to MT542 (PW-1063) Added translation MT544 to sese.025.001.09 (PW-1062) pacs.008/pacs.009 to MT translates enhancements in field 20 for consistency between CBPR+ and generic ISO 20022 mappings (PW-1061) Revamp of the translation factory in order to enhance defaults and disambiguation (PW-1060) Fixed cast exception in MX to MT translations using explicit Output direction for the target message (PW-1059) MT to MX: Fixes an enhancements in translation of fields 50F and 59F (MTs; 101, 102, 103, 104, 202, 205, 210) (PW-1057) MT to pacs.008/pacs.009 enhanced mapping of REC code in field 72 (PW-955) pain.001 to MT101: copy raw unstructured remittance information to field 70 Added enum classes MtToMxTranslation and MxToMtTranslation will the supported translations 9.3.6 - September 2022 (PW-1043) CBPR+: Minor enhancements in the 192/292 to camt.056 translations (PW-1006) Changed the translation factory, to fall-back into 29 for MT target when both 19 and 29* are feasible Added generic ISO: MT103 to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT196 to camt.029.001.09 (based on CBPR+ translation) Added generic ISO: MT200 to pacs.009.001.08 (based on CBPR+ translation) Added generic ISO: MT202 to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT202 to pacs.004.001.09 (based on CBPR+ translation) Added generic ISO: MT202COV to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT204 to pacs.010.001.03 (based on CBPR+ translation) Added generic ISO: MT205 to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT205 to pacs.004.001.09 (based on CBPR+ translation) Added generic ISO: MT205 to pacs.009.001.08 (based on CBPR+ translation) Added generic ISO: MT205COV to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT205COV to pacs.009.001.08 (based on CBPR+ translation) Added generic ISO: MT296 to camt.029.001.09 (based on CBPR+ translation) Added generic ISO: camt.029.001.09 to MT196 (based on CBPR+ translation) Added generic ISO: camt.029.001.09 to MT296 (based on CBPR+ translation) Added generic ISO: camt.056.001.08 to MT292 (based on CBPR+ translation) Added generic ISO: camt.057.001.06 to MT210 (based on CBPR+ translation) Added generic ISO: camt.060.001.05 to MT920 (based on CBPR+ translation) Added generic ISO: pacs.002.001.10 to MT199 (based on CBPR+ translation) Added generic ISO: pacs.002.001.10 to MT299 (based on CBPR+ translation) Added generic ISO: pacs.004.001.09 to MT202 (based on CBPR+ translation) Added generic ISO: pacs.004.001.09 to MT205 (based on CBPR+ translation) Added generic ISO: pacs.009.001.08 to MT200 (based on CBPR+ translation) Added generic ISO: pacs.009.001.08 to MT205 (based on CBPR+ translation) Added generic ISO: pacs.010.001.03 to MT204 (based on CBPR+ translation) Removed unnecesary unescape in internal extractPattern function 9.3.5 - September 2022 (PW-1031) Added translation MT548 to sese.024.001.10 (PW-1006) MX to MT: Added a translation coverage report to see what source elements have been read during the translation semt.020.002.01 to MT578 mapping fix for REDE/RECE => REAG semantic check compiance in the generated MT 9.3.4 - August 2022 (PW-1012) sese.027.001.05 to MT548 mapping fixes 9.3.3 - August 2022 (PW-955) pain.001 to MT101: added truncation to the text after /RFB in field 70 Added internal loops API to MTs: 110, 201, 203, 210, 410, 412, 420, 422, 450, 456, 604, 605, 801, 920, 973 9.3.2 - July 2022 (PW-958) Enhanced the truncation report to differentiate between truncation regular fields and reference fields (PW-949) MX to MT: enhanced mapping of name & address fields, with truncation with evidence and having the country, when present, always at the last line (PW-948) MX -> MT202, MT204, MT205: enhanced mapping of field 58D (PW-948) MX -> MT202, MT204, MT205: enhanced mapping of field 58D (PW-948) pacs.009.01.10 -> MT202: enhanced mapping of field 58D (PW-943) Added translation: pacs.002.001.10 positive -> MT199/MT299 (PW-943) pacs.002.001.10 positive to MT199/MT299 (PW-935) Added MT-MX translation for latest versions of seev.031, seev.032, seev.033, seev.034, seev.038, seev.039, seev.040, seev.041, seev.042 (PW-932) Added translation: pacs.008.001.08 (ISO and CBPR+) -> MT103.REMIT (PW-932) Added a translation configuration parameter to disable the generation of the PDE flag (PW-932) Added translation: camt.056.001.08 -> MT192 (PW-924) Added translation: camt.052.001.09 <-> MT942 (PW-924) Added translation: camt.053.001.09 <-> MT940 (PW-924) Added translation: camt.053.001.09 <-> MT950 (PW-924) Added translation: camt.054.001.09 <-> MT910 setr.004.001.04 -> MT502: mapped the Holdings Redemption Rate into 36B::ORDR/UNIT to be compliant with semantic 258 check MT102 -> pacs.008.001.10: fixed mapping to be compliant with MX cross element checks Implementation enhancements 9.3.1 - May 2022 (PW-832) Added translation sese.023.001.09 -> MT540 MX to MT: Added truncation with evidence in party identification name fields 9.3.0 - May 2022 SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.2.35 - May 2022 (PW-918) Added translation MT192/MT292 -> camt.056.001.08 (PW-908) Added translation: MT102 -> pacs.008.001.10 (PW-813) Internal enhancement to fix CVE Added getTruncatedContent() to the Translator interface Deprecation API review 9.2.34 - May 2022 (PW-915) Added translation: pacs.009.001.10 <-> MT202 (PW-915) Added translation: pacs.008.001.10 <-> MT103 (PW-908) Added translation: pacs.008.001.10 -> MT102 Mx to MT: Added a post process to sanitize with default values missing components in party fields options D, K and H 9.2.33 - May 2022 (PW-905) MX pain.001 to MT101: Added default values for charges and creditor and removed related preconditions 9.2.32 - May 2022 (PW-899) sese.027.001.05 -> MT548 added the mapping of TxDtls into SETTRAN Added CBPR+ translation: MT950 <-> camt.053.001.08 Added CBPR+ translation: MT941 <-> camt.052.001.08 Added CBPR+ translation: camt.060.001.05 -> MT920 Added CBPR+ translation: pacs.009.001.08 -> MT200 Added CBPR+ translation: MT941 <-> camt.052.001.08 9.2.31 - April 2022 Added CBPR+ translation: MT200 -> pacs.009.001.08 Added CBPR+ translation: MT942 -> camt.052.001.08 Added CBPR+ translation: MT940 -> camt.053.001.08 Added CBPR+ translation: MT204 <-> pacs.010.001.03 Added CBPR+ translation: MT103, MT202, MT205 -> pacs.004.001.09 Added CBPR+ translation: MT900 -> camt.054.001.08 Added CBPR+ translation: MT910 -> camt.054.001.08 Added CBPR+ translation: MT210 -> camt.057.001.06 Added CBPR+ translation: MT101 <-> pain.001.001.09 MT101 to pain.001: fixed mapping of fields 50F and 59F, with preference for structured postal address instead of unstructured address lines CBPR+ MT192 and MT292 to camt.056: Added mapping of mandatory CreationDateTime MT103 STP to CBPR+ pacs.008.001.08.STP: Fixed mapping of mandatory creditor account CBPR+ MT to MX: changed the mapping of GroupHeader/CreationDateTime to have a fixed dummy date instead of the current time (PW-887) MT to MX: fixed the concatenation of narrative, to use space separator or not, depending on the MT value being split by length or words (PW-887) MX to MT: added a postprocess of the created message to sanitize fields with lines starting with '-' or ':' using '.' as replacement 9.2.30 - April 2022 seev.036 and seev.037 to MT566: Fixed mapping of CADETL dates seev.036 to MT566: Fixed mapping of SECMOVE dates, CASHMOVE and 19B::WITF -> 19B::FTCA seev.035 to MT564: FIxed mapping of CADETL Added CBPR+ translation: camt.057.001.06 -> MT210 MX to MT: Fixed mapping of field 50F party identifier using code, country and identifier (no account number) 9.2.29 - April 2022 Added translations: MT196/MT296 -> CBPR+ camt.029.001.09 Added translations xsys.011.001.01 and xsys.001.001.02 -> ACK/NAK (service 21 message) Fixed MIR generation in translations from xsys.012 and xsys.003 to MT019 9.2.28 - March 2022 Added CBPR+ translation camt.029.001.09 to MT196/296 (PW-747) Added translation: MT104 -> pain.008.001.08 9.2.27 - March 2022 (PW-872) Fixed mapping of field 95Q with multiple lines of name & address Added translations: MT566 <-> seev.036.002.12 and seev.036.001.12 Added translations: MT566 <-> seev.037.002.12 and seev.037.001.12 Added translations: MT564 <-> seev.035.002.12 and seev.035.001.12 Added translations: MT564 <-> seev.044.002.10 and seev.044.001.10 9.2.26 - March 2022 Added CBPR+ translation MT103 REJT to pacs.002.001.10 Added CBPR+ translation MT202 REJT and MT202 COV REJT to pacs.002.001.10 Added CBPR+ translation MT205 REJT and MT205 COV REJT to pacs.002.001.10 (PW-865) MT540/541/542/543 to sese.023.001.09: fixed mapping of place of trade 94B Added API to the translation factories to indicate a specific message type/version output 9.2.25 - March 2022 (PW-747) Added CBPR+ translations camt.056 <-> MT192/MT292 9.2.24 - March 2022 Enhanced support for local date time offset in the mappings MX to MT: mapping review for fields 98a, with preference of 98E over 98C when possible From prowide-iso2022 update: changed the default date time serialization to local time with UTC offset 9.2.23 - March 2022 (PW-859) MT54x to sese.020 fixed mapping of fields 20C:SEME, 20C:PCTI and 20C:MITI 9.2.22 - February 2022 Added CBPR+ translation camt.052 to MT942 camt.052 to MT941/MT942 migrated to common translations hierarchy camt.052/053 to MT: Fixed mapping of pagination into 28C CBPR+ fixed translation of 72:/INS to previous instructing agent, added dummy postal address to be compliant with UG 9.2.21 - February 2022 Added translation versions MT566 to seev.036.001.12 and seev.037.001.12 Added CBPR+ translation camt.053 to MT940 Added CBPR+ translation camt.054 to MT900/MT910 Added CBPR+ translation pacs.002 negative to MT199/MT299 REJT CBPR+ MT202 to pacs.009 ADV: fixed mapping of settlement information from fields 53a and 54a in the MT CBPR+ MT103 and MT202 mapping: fixed mapping for default creditor and debtor agents camt.053 to MT940/MT950 migrated to common translations hierarchy 9.2.20 - January 2022 (PW-831) camt.052 and camt.053 to 9xx: Fixed direction toggle by configuration 9.2.19 - January 2022 Added CBPR+ translation pacs.004.001.09 to MT103 RETN Added CBPR+ translation pacs.004.001.09 to MT202 RETN Added CBPR+ translation pacs.004.001.09 to MT205 RETN Added CBPR+ translation pacs.009.001.08.ADV to MT202 Added CBPR+ translation pacs.009.001.08 to MT205 Added CBPR+ translation pacs.009.001.08.COV to MT205COV Added translation version pacs.004.001.09 to MT103 RETN (PW-747) Added translations version for pain.001.001.09 <--> MT101 (PW-831) MT9xx to camt.05x: Versions 6, 7 and 8 migrated to common translations hierarchy MT101 to pain.001.001.08: migrated to common translations hierarchy Migrated CBPR+ translations to release 2.1 9.2.18 - January 2022 (PW-798) Added translations from MT540, MT541, MT542 and MT543 to sese.020.001.06 (PW-798) Added translations from sese.027.001.05 to MT548 Added specific translation implementation classes for CBPR+ (pacs.009 --> MT202) Added a CbprTranslatorFactory to autodetect source CBPR+ messages and provide its corresponding translation implementation MT to seev: Fixed incorrect version at AppHdr/MsgDefIdr in some MT to seev translations MX to MT: Added a translation configuration option to enabled or disabled the conversion of non-SWIFT characters into '.' 9.2.17 - January 2022 Added specific translation implementation classes for CBPR+ (pacs.009 <-- MT202/MT205) MT103 and MT202 to MX: removed redundant mapping for Interbank Settlement Date to meet cross-element rule constraint MT202 to pacs.009: Added criteria selection, field 72 must not indicate message is a rejection or return MT202 to pacs.009: Versions 6, 7 and 8 migrated to common translations hierarchy MT202 to pacs.009: enhanced mapping of SttlmInf in GrpHdr according to the CBPR+ METAFCT002/METAFCT003 9.2.17 - December 2021 Added specific translation implementation classes for CBPR+ (pacs.008 <-> MT103) Added com.prowidesoftware.integrator.translations as automatic module name in the MANIFEST for JPMS support MT103 to pacs.008.001.08: minor mapping enhancements (UETR, field 13C) MT to MX: Changed default ISO date time to local time with offset (for CBPR+ compatibility) MT to MX: Changed default label for missing content from UNKNOWN to NOTPROVIDED (for CBPR+ compatibility) 9.2.16 - December 2021 (PW-781) Added translation sese.025.001.09 to MT545 and MT547 (PW-779) Added translation MT541 and MT543 to sese.023.001.09 MT103 to pacs.008: added criteria check to avoid translating RETURN messages into pacs.008 (pacs.004 should be used instead) MT to MX: BusinessApplicationHeaderV02 is now generated by default instead of BusinessApplicationHeaderV01 Added back and forth mapping between the MT priority and PDE flag and the MX AppHdr 9.2.15 - November 2021 MT103 to pacs.008: enhanced mapping of SttlmInf in GrpHdr according to the CBPR+ METAFCT001 9.2.14 - November 2021 (PW-769): Added mapping for expected trade and settlement dates (from B/98a into NewDetails dates) MT103 to pacs.008: removed redundant IntrBkSttlmDt from GrpHdr (already mapped in CdtTrfTxInf) to be compliant with cross-element rule 9.2.13 - November 2021 (PW-762) Added translation MT542 to sese.023.001.09 9.2.12 - November 2021 (PW-754) camt.054 to MT900 and MT910: fixed mapping of 13D, 32A value date, 52D, 72 and added mapping for 50F option 9.2.11 - October 2021 (PW-643) setr.010.001.04 to MT502: RSET is set from CshSttlmDt (with fallback to ReqdFutrTradDt) 9.2.10 - October 2021 (PW-643) setr.004.001.04 to MT502: RSET is set from CshSttlmDt (with fallback to ReqdFutrTradDt) 9.2.9 - October 2021 (PW-643) MT509 to setr.016.001.04: changed mapping of OrdrDtlsRpt to IndvOrdrDtlsRpt to align with the SMPG spec (PW-663) Added translation MT210 to camt.057.001.06 (PW-663) Added translation MT103 RETURN to pacs.004.001.09 9.2.8 - October 2021 (PW-709) MT54x and 578 to sese: fixed generation of empty Settlement Transaction Condition (PW-709) MT540 to sese.023.001.09: fixed mapping of Partial Settlement Indicator (PW-708) pacs.008 and pacs.004 to MT: Fixed mapping of third reimbursement agent account (PW-643) setr.004.001.04 and setr.010.001.04 to MT502: RSET is set from CshSttlmDt (with fallback to ReqdFutrTradDt) 9.2.7 - September 2021 (JR-613) pacs.009 to MT202: Avoid redundant codewords in field 72 lines 9.2.6 - September 2021 (PW-662) pacs.009.001.08 to MT202[COV]: added mapping for PaymentIdentification/UETR into Block3/121 with fallback to autogenerated UETR (PW-643) MT515 to setr.012 and setr.006: added mapping for 95a::ALTE and removed related precondition check 9.2.5 - August 2021 (PW-643) MT515 into setr.012: enhanced mapping of InvstmtAcctDtls/AcctId to avoid precondition on INVE/BUYR parties (PW-643) MT515 into setr.006.001.04 and setr.012.001.04: fixed mapping of 35B when ISIN is not present (CUSIP, SEDOL, etc...) (PW-643) setr into MT502: TILI indicator defaults to GTCA (good until canceled) License check fix when source MX does not contain AppHdr 9.2.4 - August 2021 (PW-626) sese.024.001 and sese.025.001 to MT: mapped AppHdr/CreDt into 98C:PREP (PW-623) MT566 to seev036: removed unnecessary precondition check and enhanced mapping of the ADDB indicator, amount and rates (PW-613) pacs.009 to MT202 and MT202COV: Enhanced mapping of field 72 Added API to set default amount, unit and currency; when it is mandatory in a target element/field and not present in the source message 9.2.3 - August 2021 (PW-642) sese.025.001.09 to MT: fixed PlcOfTrad into 94B:EXCH mapping, fixed FctvSttlmDt into 98C:ESET mapping (PW-643) setr.004.001.04 and setr.010.001.04 to MT502: multiple mapping enhancements (PW-643) setr.004, setr.006, setr.010, setr.012, setr.015: enhanced mapping into 35B without ISIN, including corresponding prefixes (PW-569) pacs.008 and pacs.009 to MT: enhanced heuristic to attempt mapping into 50F and 59F instead of 50K and 59 pacs.008 and pacs.009 to MT: minor bugfix translating into field 50F when StrtNm and BldgNb concatenation exceeds the line limit in field 50F (PW-605) MT to MX: avoid split of DSS into Issr and SchmeNm elements if the Issr alone in the MX has enough length for the DSS value (PW-591-598, 600-604, 607-612, 614, 616, 618) Mapping fixes in MT564 to seev.031.001.10 9.2.2 - July 2021 (PW-626) sese.024.001.10 to MT548: several mapping fixes (PW-572) pacs.008 to MT103: avoid the /REC/ in field 72 if the InstrForNxtAgt already contains and instruction code (PW-569) pacs.009 to MT202COV: added mapping of structured beneficiary data into field 59F option (PW-567) pacs.008.001.08 to MT103: added mapping for PaymentIdentification/UETR into Block3/121 with fallback to autogenerated UETR Added translation sese.025.001.09 to MT546 (PW-569) pacs.008 to MT103: added mapping of structured beneficiary data into field 59F option (PW-568) pacs.008 to MT103: fixed mapping of CtgyPurp/Cd with \"INTC\" or \"CORT\" into 23E (PW-617) MT502, MT504, MT515, MT564 and MT566 to MX: fixed mapping of 98E with offset into ISO date time (PW-580-582-585-586-588-589-590) Mapping fixes in MT564 to seev.031.001.10 (PW-581) MT to MX: Preserve starting and trailing spaces when narrative field content is mapped into multiple lines of a single XML element (PW-568) pacs.008 to MT103: mapped special use case of CtgyPurp/Prtry with \"INTC CORT\" into respective 23E instances with \"INTC\" and \"CORT\" (PW-567) pacs.008 to MT103: avoid propagation of useless EndToEndId with \"NOTPROVIDED\" to field 70:/ROC/NOTPROVIDED MT856 translations: fixed mapping for sequence B6b Added translation setr.004.001.04 to MT502 Added translation setr.010.001.04 to MT502 (PW-579) MT564 to seev.031 added mapping for 70E::OFFO into Offerr elements (PW-577) MT564 to seev.031.001.10 added mapping for 25D with DSS into processing status sese and semt to MT: fixed mapping for SETPRTY 97A::SAFE when type and name was present besides the account identifier MX to MT: general fix in field 20C mapping that could occasionally generate more than 16 characters Added translation MT540 to sese.023.001.09 Added translation sese.024.001.10 to MT548 Added translation sese.025.001.09 to MT544 9.2.1 - June 2021 Added translation MT509 to setr.016.001.04 Added translation MT515 to setr.006.001.04 Added translation MT515 to setr.012.001.04 Added translation seev.035.001.03 to MT564 Added translation seev.039.001.03 to MT564 Added translation seev.044.001.03 to MT564 setr.017 to MT509: OrdrRef reverted change, mapped back to TRRF instead of RELA MX to MT: preserve line breaks in MT fields when translated from MX narrative content Added translation seev.038.001.03 to MT568 (PW-551) seev.031 to MT564: fixed 90K PRPP and 90L OFFR field mapping into cash movement details (PW-550) MT564 to seev.035, MT565 to seev.033, MT566 to seev.036: fixed mapping of field 90J currency component (PW-549) seev.031.001.10 to MT564: fixed mapping of MACI MICI and MMCI into the corporate action option details (PW-548) seev.031 to MT564: fixed mapping of 90F, 90J and 90L OFFR into the securities movement details (PW-547) seev.031 to MT564: added mapping for 90s option L into the maximum and minimum price details with 'PRCT' as default code (PW-546) seev.031 to MT564: fixed mapping of price details in SctiesMvmntDtls (PW-545) seev.031.001.03 to MT564: fixed mapping of certification breakdown flags (PW-544) MT564 to seev.031: fixed mapping of indicator flags in CADETL and CAOPTN (PW-543) seev.031.001.03 to MT564: fixed ISIN mapping (PW-542) MT564 to seev.031.001.10: fixed mapping of repetitive 70E content (PW-541) MT564 to seev.031.001.10: added missing mapping for 92D:WAPA into WarrantParity (PW-537) MT to MX: fixed mapping of face amount, that in some cases was propagated as 1.0 instead of the actual value (PW-535) MT564 to seev.031.001.10: mapping fixes in the cash movement details (PW-533) Added translation from seev.031.001.09 to MT564 MX pacs.008 and pacs.004 to MT103: fixed calculation of total charges in field 71G when the ChrgsInf is repeated in the MX Mapping fixes in setr.006.001.04, setr.012.001.04 and setr.015.001.04 to MT515 Mapping fix in MT103 to pacs.008 when multiple sender charges are present (PW-521) MT564 to seev.031.001.10: reviewed mapping of rate and amount details setr016 and setr.017 to MT509: OrdrRef is mapped into RELA instead of TRRF 9.2.0 - May 2021 SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.1.12 - April 2021 (PW-518) More flexible check of licensed BIC codes extracted from the translated MT headers xsys.012 to MT019: minor fix in target message fields order 9.1.11 - February 2021 (CR-34) Added seev.031.001.001.03 to MT564 and MT568 translations (CR-34) Added MT564 and MT568 to seev.031.001.10 translations Fixed seev.031 to 564/568 invalid codewords MIEX and MILT in translation into field 36B Fixed generation of 20C:SEME when BAH is not present, in translations from seev.031/033/034/037/038/044 Fixed generation of LINK in translations from: seev.031/032/033/034/035/036/037, semt.016, sese.023/026/033/037 9.1.10 - January 2021 (PW-438) Further enhancements in the setr.016 to MT509 when status is suspended 9.1.9 - January 2021 (PW-438) Fixed setr.016 to MT509 when status is suspended with proprietary reason code 9.1.8 - December 2020 Added translation from camt.053.001.02 to MT940 Added a one to many special translation for camt.053.001.02 to list of MT940 License check review 9.1.7 - November 2020 (PW-368) setr.015.001, setr.006.001 and setr.012.001 to MT515: Fixed mapping of transfer agent into 95Q from RltdPtyDtls with code TRAG (PW-368) setr.015 to MT515: added mapping for :22H::CAOP from Income Preference in the MX (PW-368) setr.015 to MT515: changed the mapping of InvstmtAcctDtls/AcctId into 95Q SELL/BUYR instead of 97A:SAFE setr.015.001 MT515: enhanced mapping for 35B when identification is not an ISIN setr.015.001 to MT515: removed no longer necessary precondition checks 30, 31 and 34 setr.006.001 to MT515: removed no longer necessary precondition checks 25 Fixed option to set sender/receiver from configuration in MX to MT940, MT941, MT942, MT900 and MT910 translations 9.1.6 - November 2020 (PW-368) setr.012.001 to MT515: removed no longer necessary precondition checks 6 (PW-368) setr.015.001 to MT515: removed no longer necessary precondition checks 5 (PW-368) setr.006.001 to MT515: removed no longer necessary precondition checks 5, 19 and 36 (PW-368) setr.006.001 and setr.012.001 to to 515: Mapped amount with codeword SWIT into amount with OTHR in the MT since SWIT is not accepted (PW-368) setr.006.001 and setr.012.001 to MT515: enhanced mapping for 35B when identification is not an ISIN (PW-368) setr.006.001 and setr.012.001 to MT515: fixed mapping for 95P when source message party information contains a BIC code semt, sese and setr into MT: fixed mapping into fields 19A and 90B when source message has too many decimal digits setr into MT: fixed mapping into field 95R from when source uses a proprietary identification 9.1.5 - November 2020 (PW-368) setr.016.001 to MT509: enhanced mapping for /Extension content (PW-368) setr.017.001 to MT509: enhanced mapping for /Extension content (PW-368) setr.017.001 to MT509: references and status mapping review (PW-368) setr.006.001 to MT515: more lenient precondition, and enhanced amounts mapping (PW-368) setr.012.001 to MT515: more lenient precondition, and enhanced amounts mapping (PW-368) setr.015.001 to MT515: more lenient precondition, and enhanced amounts mapping (PW-368) setr.016.001 to MT509: added mapping for the Extension into the Reason narrative 70D (PW-395) Added translation for MT567 to seev.041.001.10 corporate action cancellation status 9.1.4 - October 2020 (PW-368) Enhanced the setr.016.001 to MT509 translation to support all code and reason structures in the source MX (PW-374) Added a one to many special translation for pacs.001 to list of MT101 (PW-374) Added sender, receiver and direction to the optional TranslatorConfiguration (PW-368) Added global preventive check in MX to MT translations to avoid propagating tab characters into MT fields (PW-368) setr to MT515: added fallback mappings for mandatory fields 98a:SETT and 95:SELL or 95:BUYR in MT515 (PW-377) pacs.001 to MT101 added a fallback mapping from CdtTrfTxInf/PmtId/EndToEndId into field 21 when CdtTrfTxInf/PmtId/InstrId is not present (PW-377) pacs.001 to MT101 added a fallback mapping to create the optional field 23E with value OTHR if no other 23E field is created MT to MX: General fix for 35B ISIN mapping into MX identification of security elements 9.1.3 - August 2020 (PW-368) MX to MT: enhanced mapping of references (field 20 or 20C:SEME) with fallback to reference from AppHdr and truncation if necessary setr.016 to MT509: fixed mapping of mandatory field 24B 9.1.2 - August 2020 (PW-320) Replaced legacy default translations DSS name 'STRS' by 'COEX' (Coexistence global DSS from ISO 20022) Added version 8 translation between pacs.009 and MT202 Added version 8 translation between pacs.008 and MT103 Added version 8 translation between camt.053 and MT940 Added version 8 translation between camt.053 and MT950 Added version 8 translation between camt.054 and MT900 Added version 8 translation between camt.054 and MT910 In pacs.009 to 202 fixed precondition check for the CdtTrfTxInf[1]/PrvsInstgAgt Minor Fix in MX to MT time with offset mapping, offset was not propagated properly in some use cases Minor fix in logical criteria exception messages Added pacs.004.001.02 to MT 103 RETURN translation (for both ISO and SIC versions) Added pacs.002.001.03 to ACK/NAK translation (for both ISO and SIC versions) MX to MT: Added a parameter in the TranslatorConfiguration to optionally set a ClearingSystemMemberIdToBic function implementation SIC: MT to MX, trimmed spaces from reference to be compliant with SIC restriction SIC: MT103 to pacs.008 instructed agent mapped from 56A when present in the MT SIC: MT202 to pacs.009 instructed agent mapped from 57A when present in the MT 9.1.1 - Jun 2020 MT103 to pacs.008 fixed mapping of fields 70 and 72 MT101 to pacs.008 fixed mapping of fields 70 and 72 MT202 to pacs.009 fixed mapping of fields 70 and 72 MT202 to pacs.009 fixed precondition checking the format of the CLSTIME MT to MX: general enhancements in mapping of field 50F when line numbers are repeated MT502 to to setr.004 and setr.010: enhanced mapping for fields 70E and 70C MT564 to seev.031 enhanced mapping for field 94G MT565 to seev.033 enhanced mapping for fields 70E and 95G MT568 to seev.031 enhanced mapping for field 70E 9.1.0 - May 2020 SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.0.1 - May 2020 Internal implementation changes to the use the new AppHdr model in the SDK 9.0.0 - May 2020 Translations module extracted to its own jar in the distribution, with its own version from now on (PW-286) Fixed ISO datetime conversions into MT variants 8.0.8 - April 2020 Fixed logical message criteria for camt.054 into 900 or 910 depending on the entry debit/credit indicator Fixed translator factory finder for pacs.008.001.06 to 103 and seev to 566 Change in preconditions from camt.053 to MT to make them more flexible 8.0.7 - March 2020 Added specific translations for SIC (SWISS RTGS): between 202 and pacs.009 Added specific translations for SIC (SWISS RTGS): between 103 and pacs.008 In MX to MT: fixed extra slash when mapping clearing system codes or account numbers into party fields pacs.008 to 103 and pacs.009 to 202: field 20 now is mapped from CdtTrfTxInf/PmtId/TxId instead of GrpHdr/MsgId 103 to pacs.008: when present, the block 3 MUR is mapped into GrpHdr/MsgId instead of the reference field 20 8.0.6 - February 2020 Added translation from setr.006.001.04 redemption order confirmation to MT515 Added translation from setr.012.001.04 subscription order confirmation to MT515 Added translation from setr.016.001.04 order instruction status report to MT509 Added translation from setr.015.001.04 switch order confirmation into MT515 redemption and subscription leg messages Added translation between setr.017.001.04 order cancellation status report and MT509 (back and forth) Added a truncation report in translator classes and a '+' as last character of truncated data in the target message In MT to MX; header data is propagated to the AppHdr, including sender, receiver, reference, message type, and also PDE flag if present in the MT trailer In MX to MT; if the source MX contains an ISO header with the possible duplicate flag set to true, the created MT will have a PDE trailer flag MT103 to pacs.008 added mapping from 32A date into the group header settlement date Added a remove spaces transformation when mapping IBAN numbers from MT to MX 8.0.5 - January 2019 MT202 and MT202COV to MX, added mapping for sender correspondent field 53B location into group header instructing agent postal address (PW-225) MT202 and MT202COV to MX, removed the precondition requiring a mandatory party identifier in the sender correspondent field 53B 8.0.4 - December 2019 MT103 to MX, added mapping for sender correspondent field 53B location into group header instructing agent postal address (PW-225) MT103 to MX, removed the precondition requiring a mandatory party identifier in the sender correspondent field 53B (PW-225) MT103 to MX, removed the precondition requiring the same currency In semt to MT translations when Document/*/Id/Id is not found in MX the 20C:SEME is generated from AppHdr/BizMsgIdr Enhanced mapping of field 35B description of security when the ISIN is not present 8.0.3 - September 2019 Fixed mapping for field 36E in translations from MX to MT Added version 6, 7, 8 and 9 for translations between MT566 and seev.036 and seev.037 8.0.2 - August 2019 Added version 6, 7, 8 and 9 for translations between MT566 and seev.036 and seev.037 Fixed mapping for field 36E in translations from MX to MT Fixed bin/translator CLI app that stopped reading input on the first line break 8.0.1 - July 2019 Added a TranslatorFactory to enable automatic translator selection based on the source message Added a CLI to run automatic translation of files in the command line 8.0.0 - May 2019 JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 7.10.8 - March 2019 Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Fixed obfuscation to keep directories in jar Fixed mapping of Field70 to EndToEndId 7.10.7 - January 2019 Added alternative translate call in translation implementation classes to run the process without precondition checks Added translations between pacs.001.001.08 and MT101 Fixed translations for fields 50F and 77B Fixed precondition check for MX pain.001.001.03 to MT101 translation Fixed translation MX pain.001.001.03 to MT101 when multiple PmtInf and CdtTrfTxInf combinations are present 7.10.0 - April 2018 SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Added 103 and 103 STP to pacs.008.001.07 Added 202 and 202 COV to pacs.009.001.07 Added 900 to camt.054.001.07 Added 910 to camt.054.001.07 Added 940 to camt.053.001.07 Added 941 to camt.052.001.07 Added 942 to camt.052.001.07 Added 950 to camt.053.001.07 Added pacs.008.001.07 to 103 Added pacs.009.001.07 to 202 and 202 COV Added camt.052.001.07 to 941 and 942 Added camt.053.001.07 to 940 and 950 Added camt.054.001.07 to 900 and 910 7.9.8 - April 2018 MT to MX: fixed decimal separator in amount format to avoid locale dependant issues 7.9.7 - January 2018 Changes in the distribution package |-> Command line tools in the bic directory changed from jar files to wrapper scripts |-> Dependencies directory renamed to lib |-> Removed the BUILD id timestamp from the jar files * MT to MX: sender and receiver address from header blocks mapped according to message direction 7.9.6 - December 2017 Added camt.054.001.06 to MT900 and MT910 Added camt.053.001.06 to MT940 and MT950 Added camt.052.001.06 to MT941 and MT942 Added pacs.009.001.06 to MT202 and MT202 COV Added pacs.008.001.06 to MT103 Added xsys.003.001.01 to MT019 Added xsys.012.001.01 to MT019 Added MT300 to fxtr.014.001.03 Performance enhancement: comprehensive use of relative paths to optimize content selection. Performance enhancement: mappings migrated from docname to xml to avoid paths conversion in engine. MX to MT: Fixed generation of fields with letter option D (such as 52D) when only name & address was present as content Added plugable PathAdapter to customize MX paths used in translations 7.9.5 - December 2017 Performance enhancement: static methods for internal processing, reduced path conversion Individual precondition checks made private in favor of the global preconditionsChecks API 7.9.4 - November 2017 JRE requirement backported to Java 1.6 Added xsys.002.001.01 to MT012 7.9.3 - October 2017 Fixed MT548 to MX: fixed mappings for ProcessingStatus Fixed MT586 to MX: mappings with invalid amounts sequence B5c changed to B5b MT564 and 566 to MX: fixed mapping for currency component in field 92J Added MT568 to seev.031.002.06 Added MT564 to seev.031.002.06 and seev.039.002.06 Added MT019 to xsys.003.001.01 and xsys.012.001.01 Added MT012 to xsys.002.001.01 Added MT202 and MT202 COV to pacs.009.001.06 Added MT103 and MT103 STP to pacs.008.001.06 MT to MX: fixed mapping header for sender and receiver addresses in output (incoming) messages MT to MX: replaced fixed data in message creation date time with current ISO time stamp MT940 to camt.053 and MT941/MT942 to camt.052: fixed translation for field 86 repetitions into additional entries information MT101 to pain.001: fixed translation for field 23E repetitions MT900 and MT910 to camt.054: fixed translation for field 72 repetitions Added MT941 and MT942 to camt.052.001.06 Added MT940 and MT950 to camt.053.001.06 Added MT900 and MT910 to camt.054.001.06 7.9.2 - August 2017 semt.020.02.01 to MTs 508, 545, 547, 578: changed default amount XXX99999999999999 to locale currency and 0 sese.020.002.01 and semt.013.002.01 to MT524 fixed generation of LINK sequences seev, semt, sese, setr to MT5xx: fixed generation of field 36B with quantity of financial instrument semt.020.002.01 to MT578: changed translation to generate the alleged instruction indicator (:22H::PAYM) in sequence B with codeword FREE instead of APMT to be compliant with MT semantic 283 pain.001.001.03 to MT101: fixed mapping for multiline field 77B and fixed MX paths when checking the available payment information instances setr.006.002.01 and setr.012.002.01 to MT515: fixed mapping for multiline field 70C semt and sese to MTs 544, 545, 546, 547 and 548: added link sequence with RELA to be compliant with MT semantic rules 73 semt.020.002.01 to MTs 535, 536, 537, 538 and 586: changed translations to set Activity Flag (field :17B:ACTI) to 'N' to be compliant with MT semantic rules 256, 266 and 267 semt.020.002.01 to MT508 and sese.020.002.01 to 524: changed translations to be compliant with MT semantic rule 281 MX to MT: fixed collapsing data in output MT, due to bug in handling repeat predicates from MX path MX to MT: fixed generic bug when creating fieldset with multiple letter options MX to MT: general mappings fixes for MX categories seev, semt, sese and setr Generic fix for proper handling of repetitive fields/elements in target message MX to MT: fixed bug when creating fieldset with multiple letter options MX to MT: fixed mappings translations for seev, semt, sese and setr 7.9 - May 2017 SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX) Removed false positive warning for invalid namespace in header when the header was actually empty 7.8.9 - May 2017 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 7.8.3 - Jul 2016 If GrpHdr is present when converting from MX to MT, header BICs are set from it Internal migration from MxNode to XmlNode from SDK","title":"Prowide Integrator Translations"},{"location":"release-notes/changelog-translations/#prowide-integrator-translations-changelog","text":"","title":"Prowide Integrator Translations - CHANGELOG"},{"location":"release-notes/changelog-translations/#9440-snapshot","text":"pacs.010.001.03 -> MT204: fixed mappings for fields 58A and 58D","title":"9.4.40 - SNAPSHOT"},{"location":"release-notes/changelog-translations/#9439-may-2024","text":"CBPR+ MT102/103 -> pacs.008.001.08 and MT200/201/202/205 -> pacs.009.001.08: enhanced and fixed mappings from field 72 codewords CATPURP, SVCLVL and LOCINS","title":"9.4.39 - May 2024"},{"location":"release-notes/changelog-translations/#9438-may-2024","text":"(PW-1878) CBPR+ MT900 and MT910 to camt: set Entry/EntryReference to NOTPROVIDED since field 25 is already mapped to the Notification/Account (PW-1865) Added new flag to TranslatorConfiguration class, in order to force the number formatting to have exactly two decimal places","title":"9.4.38 - May 2024"},{"location":"release-notes/changelog-translations/#9437-may-2024","text":"(PW-1872) CBPR+ MT 950 -> camt.053.001.08: fixed mappings from 60M to Balance\\Type\\Code = OPBD and 62M to Balance\\Type\\Code = CLBD (PW-1863) CBPR+ MT 940 -> camt.053.001.08: fixed mappings from 60M to Balance\\Type\\Code = OPBD and 62M to Balance\\Type\\Code = CLBD (PW-1862) MT to MX: Revamped implementation of Narrative translation functions (PW-1847) Added new ISO translators: MT 564/568 <-> seev.031.002.13 Fixed mapping of Block5/PDE flag into the AppHdr/PossibleDuplicate when PDE exists and is empty CBPR+ MT 102/103 -> pacs.008.001.08: fixed mappings for fields 70 and 72 into InstructionForNextAgent and RemittanceInformation\\Unstructured CBPR+ MT 102/103 -> pacs.008.001.08: removed mapping for codeword PURP in field 72 and fixed use of codeword CATPURP into CategoryPurpose\\Code CBPR+ MT 202.COV/205.COV -> pacs.009.001.08.COV: fixed mappings for fields 70 and 72 into InstructionForNextAgent and RemittanceInformation\\Unstructured CBPR+ MT 202 -> pacs.009.001.08/pacs.009.001.08.ADV: fixed mappings for codeword PURP in field 72 into Purpose\\Code and Purpose\\Proprietary Enhanced the market type factories returned by the TranslatorFactoryProvider to honour the translation mappings configuration","title":"9.4.37 - May 2024"},{"location":"release-notes/changelog-translations/#9436-april-2024","text":"(PW-1857) CBPR+ MT 900/910 -> camt.054.001.08: fixed mappings according to CBPR+ mapping rules (PW-1856) MT 200/202/203/205 -> pacs.009: fixed mappings for 72 Narrative extra codewords to InstructionForNextAgent (PW-1855) CBPR+ MT 202 -> pacs.004.001.09: added extra XT99 narrative to ReturnReasonInformation\\AdditionalInformation (PW-1854) CBPR+ MT 202 -> pacs.004.001.09: added mapping for OriginalInstructionIdentification (PW-1850) CBPR+ MT 202 -> pacs.004.001.09: fixed mapping for ServiceLevel\\Code when there's no Block3\\111 (PW-1852) CBPR+ MT 202 -> pacs.004.001.09: added mapping for ReturnIdentification (PW-1851) CBPR+ MT 202 -> pacs.004.001.09: fixed mapping for CreditorAgent when there's no 57a field (PW-1849) CBPR+ MT 202.COV/205.COV -> pacs.009: preserve line numbers in field 50F mapping as part of value in the MX elements (PW-1848) CBPR+ MT 103 -> pacs.004.001.09: fixed mappings to 'NOTPROVIDED' as instructed by the CBPR+ mapping rules (PW-1848) CBPR+ MT 103 -> pacs.004.001.09: added extra XT99 narrative to ReturnReasonInformation\\AdditionalInformation (PW-1848) Fixed mapping of Block5/PDE flag into the AppHdr/PossibleDuplicate (PW-1848) CBPR+ MT 103 -> pacs.004.001.09: fixed mappings to 'NOTPROVIDED' as instructed by the CBPR+ mapping rules MT 103 -> pacs.008: fixed typo in codeword CATPURP","title":"9.4.36 - April 2024"},{"location":"release-notes/changelog-translations/#9435-april-2024","text":"(PW-1835) CBPR+ camt.054.001.08 -> MT 910/910 : fixed mappings for tag 21 (PW-1832) CBPR translators: fixed mapping to comply with CBPR_Agent_Name_Postal_Address_FormalRule rule MX to MT: Revamped implementation of MxToMtFinancialInstitutionNameAndAddress for translation into fields 52D, 53D, 54D, 55D, 56D & 57D MX to MT: Revamped implementation of MxToMtMTFATFNameAndAddress and MxToMtMTFATFNameAndAddress2 for translation into field 50F and 50K MX to MT: fixed coverage in MxToMt functions Added new ISO translator: seev.008.001.08 -> MT 568 Added new ISO translator: MT 536 -> semt.017.001.12 Added new ISO translator: MT 537 -> semt.018.001.13 Added new ISO translators: sese.028.001.09/10 -> MT 578","title":"9.4.35 - April 2024"},{"location":"release-notes/changelog-translations/#9434-april-2024","text":"(PW-1827) Added new ISO translators: camt.053.001.10/11 <-> MT 940/950 (PW-1814) Removed criteria selection in translations MT196/MT296 -> camt.029.001.11 (PW-1759) TranslationFactory: fixed getTranslator for ACK/NACK messages with a specific MX version Added new ISO translator: seev.001.001.10 -> MT 564 Added new ISO translator: seev.002.001.09 -> MT 564 Added new ISO translator: seev.003.001.09 -> MT 564 Added new ISO translator: seev.004.001.09 -> MT 565 Added new ISO translator: seev.005.001.09 -> MT 565 Added new ISO translator: seev.006.001.09 -> MT 567 Added new ISO translator: seev.007.001.09 -> MT 567 MT to MX: Revamped mapping for fields 50F and 59F into structured postal address node when line 3 (country) is present","title":"9.4.34 - April 2024"},{"location":"release-notes/changelog-translations/#9433-march-2024","text":"(PW-1814) MT 196/296 -> camt.029: fixed mapping from narrative 77A when codeword /UETR/ is used in multiple lines (PW-1635) camt.056 -> MT 192/292: fixed default value for tag 20 when node Underlying\\TransactionInformation\\Case\\Identification is missing T2 Translators: added NONREF as fixed value for GroupHeader\\MessageIdentification node T2 Translators: map field 20 to BusinessMessageIdentifier in header","title":"9.4.33 - March 2024"},{"location":"release-notes/changelog-translations/#9432-march-2024","text":"(PW-1759) TranslatorFactory: Added translator ACK/NAK (service 21 message) -> admi.007.001.01","title":"9.4.32 - March 2024"},{"location":"release-notes/changelog-translations/#9431-march-2024","text":"(PW-1804) sese.025 -> MT 540/541/542/543: fixed mapping for multiple 22F STCO indicators (PW-1635) camt.029 -> MT 196/296: fixed default value for tag 20 when node CancellationStatusIdentification is missing Added new ISO translators: sese.020.001.07 -> MT 540/541/542/543 Added new ISO translators: semt.020.001.07 <-> MT 578 Added new ISO translators: semt.002.001.11 <-> MT 535 Added new ISO translator: semt.017.001.12 -> MT 536 Added new ISO translator: semt.018.001.13 -> MT 537 Enhanced truncation report: added MX source path even when partial element content is truncated","title":"9.4.31 - March 2024"},{"location":"release-notes/changelog-translations/#9430-march-2024","text":"(PW-1800) MT 540/541/542/543 -> sese.023: fixed 36B Quantity of Financial Instrument precondition","title":"9.4.30 - March 2024"},{"location":"release-notes/changelog-translations/#9429-march-2024","text":"(PW-1756) MT 102/103 -> pacs.008: added mapping for field 72 codeword /PURP/ into Purpose/Proprietary Added new ISO translators: sese.024.001.11/12 <-> MT 548 Added new ISO translators: pacs.009.001.10 <-> MT 200 (PW-1787) Added new ISO translators: sese.026.001.10 <-> MT 544/545/546/547 (PW-1790) MT950 -> camt.053: fixed BookingDate and EntryDetails mappings (PW-1790) MT942 -> camt.052: fixed BookingDate mapping","title":"9.4.29 - March 2024"},{"location":"release-notes/changelog-translations/#9428-february-2024","text":"(PW-1759) TranslationFactoryConfiguration - deprecated setEvaluatePreconditions (replaced with withEvaluatePreconditions)","title":"9.4.28 - February 2024"},{"location":"release-notes/changelog-translations/#9427-february-2024","text":"(PW-1764) Added new ISO translators: sese.023.001.11 -> MT 540/541/542/543 (PW-1764) Added new ISO translators: sese.025.001.11 -> MT 544/545/546/547 (PW-1764) ISO sese.023.001. / sese.025.001. <-> MT 54*: added mappings for SecuritiesSubBalanceType <-> 22F SSBT (PW-1762) MT 103 -> pacs.004.001.09 (CBPR+/LYNX/T2): fixed mapping for /CHGS/ codeword into ChargesInformation (PW-1759) Added new translator: ACK/NAK (service 21 message) -> admi.007.001.01 (PW-1756) MT 202 -> pacs.009: added mapping for field 72 codeword /PURP/ into Purpose/Proprietary","title":"9.4.27 - February 2024"},{"location":"release-notes/changelog-translations/#9426-january-2024","text":"Added new translator: MT 097 <-> xsys.001.001.01 Added new CBPR+ translator: MT 104 <- pacs.003.001.08 Added new CBPR+ translator: MT 107 -> pacs.003.001.08 Added new ISO translators: MT 104 <- pacs.003.001.08/09/10 Added new ISO translators: MT 107 <-> pacs.003.001.08/09/10 (PW-1754) ISO seev.036.001.14 -> MT 566: fixed mappings in section 16R:CASHMOVE","title":"9.4.26 - January 2024"},{"location":"release-notes/changelog-translations/#9425-january-2024","text":"(PW-1748/1733) CHATS for pacs message the receiver BIC in the AppHdr is fixed to HKICHKHHXXX (PW-1747) SWIFT GO MT199 <-> trck.001.001.02/trck.002.001.01: Fixed mappings Enhanced the TranslatorFactory with new parameters to specify the prefered MT/MX target type and version (replacing preferLatestVersions flag) Added new ISO translators: MT 103.REMIT -> pacs.008.* Added new CBPR+ translator: MT 104 -> pacs.003.001.08 Added new ISO translators: MT 104 -> pacs.003.001.08/09/10 MT192/292 -> camt.058/056: fixed mapping and added default NOTPROVIDED in CancelationReason/AdditionalInformation Truncated report: added path to source and target truncated fields","title":"9.4.25 - January 2024"},{"location":"release-notes/changelog-translations/#9424-january-2024","text":"MT196/296 -> camt.029: removed UETR existence precondition Added new ISO translators: MT 110 <-> camt.107.001.01 Added new ISO translators: MT 111 <-> camt.108.001.01 Added new ISO translators: MT 112 <-> camt.109.001.01 sese.20/23/33/36.* -> MT541: added precondition to check SettlementAmount or OtherAmounts existence seev.32/34/41.* -> MT567: added default A16S:LINK mandatory section","title":"9.4.24 - January 2024"},{"location":"release-notes/changelog-translations/#9423-january-2024","text":"Added new translator: MT 192 -> camt.058.001.08 Added new CBPR+ translator: MT 292 -> camt.058.001.08 Added new CBPR+ translator: MT 192 -> camt.055.001.08 Added new CBPR+ translator: MT 110 -> camt.107.001.01 Added new CBPR+ translator: MT 111 -> camt.108.001.01 Added new CBPR+ translator: MT 112 -> camt.109.001.01","title":"9.4.23 - January 2024"},{"location":"release-notes/changelog-translations/#9422-december-2023","text":"(PW-1732) sese.020 / sese.023 / sese.033 / sese.036 -> MT 543: added precondition to validate SettlementAmount existence in sese messages ISO MT103 -> pacs.008.*: added mapping for block3/103 to ClearingSystem\\Code Added new translators: MT 540 / MT 541 / MT 542 / MT 543 -> sese.020.001.07 / sese.023.001.11 Added new translators: MT 544 / MT 545 / MT 546 / MT 547 -> sese.025.001.11","title":"9.4.22 - December 2023"},{"location":"release-notes/changelog-translations/#9421-december-2023","text":"(PW-1674) CHATS MT103 / MT202 -> pacs.008 / pacs.009: fixed mapping for field 72 /SPRO/ instruction to InstructionForNextAgent\\InstructionInformation CHATS/LYNX/RITS/SCRIPS/T2 pacs.008.001.* <-> MT 103: added mapping for field 26T to CreditTransferTransactionInformation\\Purpose\\Proprietary T2 MT103 -> pacs.008.001.*: convert 8 digit BIC to 11 digit BIC for FinancialInstrumentIdentification/BICFI","title":"9.4.21 - December 2023"},{"location":"release-notes/changelog-translations/#9420-december-2023","text":"(PW-1674) CHATS/LYNX/RITS/SCRIPS/T2 translation factories: return ISO translators in the getTranslator(AbstractMX mx) method (PW-1674) CBPR/SIC/SWIFTGO translation factories: return ISO translators in the getTranslator(AbstractMX mx) method if no specific translator is found (PW-1674) CHATS MT 202/202.COV -> pacs.009.001.08: added mapping for field 72 /CATPURP/ codeword into PaymentTypeInformation\\CategoryPurpose\\Proprietary","title":"9.4.20 - December 2023"},{"location":"release-notes/changelog-translations/#9419-november-2023","text":"(PW-1674) CHATS MT 202/202.COV -> pacs.009.001.08: added mapping for field 72 /SPRO/ instruction to InstructionForNextAgent\\InstructionInformation (PW-1397) CHATS MT 103 -> pacs.008.001.08: added mapping for field 72 /SPRO/ instruction to InstructionForNextAgent\\InstructionInformation","title":"9.4.19 - November 2023"},{"location":"release-notes/changelog-translations/#9418-november-2023","text":"(PW-1698) MT950 -> camt.053: added mapping block3\\108 to GroupHeader\\MessageIdentification (PW-1674) ISO pacs.004/pacs.008/pacs.009 -> MT102/MT103/MT200/MT202/MT205: added mapping GroupHeader\\SettlementInformation\\ClearingSystem\\Code To Block3\\103 (PW-1674) CHATS MT202.COV -> pacs.009.001.08: removed fixed LocalInstrument\\Proprietary mapping","title":"9.4.18 - November 2023"},{"location":"release-notes/changelog-translations/#9417-november-2023","text":"(PW-1691) CBPR+ Translation: fixed business service value for MT 104 -> pain.008.001.08 (PW-1394) Added translation CBPR+ pacs.003.001.08 -> MT107 Updated the SIC translations and translator factory, to use the SIC 4.10 model and message versions","title":"9.4.17 - November 2023"},{"location":"release-notes/changelog-translations/#9416-november-2023","text":"Reverted RITS translations to set the AppHdr creation datetime to the current local time with UTC offset (not necessarily UTC 0) (PW-1684) MT548 -> sese.024: deprecated preconditions","title":"9.4.16 - November 2023"},{"location":"release-notes/changelog-translations/#9415-november-2023","text":"(PW-1683) MT548 -> sese.024/sese.027: don't use field 23G as criteria to define MX target (PW-1674) CHATS Translations: Added MT 192/292 -> camt.056.001.08 (PW-1674) CHATS Translations: Added MT 202 COV -> pacs.009.001.08.COV (PW-1670) seev.031.001.13 -> MT 564: fixed additional mapping for dates without 98C field Added specific translations for SWIFT GO: MT103 <-> pacs.008.001.08 Added specific translations for SWIFT GO: MT199 <-> trck.001.001.02/trck.002.001.01 Added translation MT292 -> camt.058.001.08","title":"9.4.15 - November 2023"},{"location":"release-notes/changelog-translations/#9414-october-2023","text":"(PW-1670) seev.031.001.13 -> MT 564: fixed mapping for dates without 98C field","title":"9.4.14 - October 2023"},{"location":"release-notes/changelog-translations/#9413-october-2023","text":"(PW-1657) pacs.008.001.08/09/10 -> MT 102/103: added additional mapping for PaymentTypeInformation\\ServiceLevel\\Code to Block3\\111 (PW-1581) Enhanced mapping into field 72 to trim the instruction narratives avoiding pure blanks such as \"/REC/ \" (PW-1394) Added translation CBPR+ camt.055.001.08 -> MT192 (PW-1394) Added translation CBPR+ pain.008.001.08 -> MT104 MT564 -> seev.031.002.06 translation: mapping fixes sese.027.001.05 -> MT548 translation: mapping fixes Added missing entries in the CBPR+ translator factory for the recently added translations","title":"9.4.13 - October 2023"},{"location":"release-notes/changelog-translations/#9412-october-2023","text":"(PW-1644) MT 900/910 -> camt.054.001.06/07/08/09: added additional mapping for 21 to TransactionDetails\\References\\EndToEndIdentification","title":"9.4.12 - October 2023"},{"location":"release-notes/changelog-translations/#9411-september-2023","text":"(PW-1596) MT 540/541/542/543 <-> sese.023.001.09: added a special mapping for 22F::STCO/COEX/PARQ and 22F::STCO/COEX/PARC to/from SttlmParams\\PrtlSttlmInd (PW-1397) CHATS Translations: fixed PaymentTypeInformation/CategoryPurpose/Proprietary code IFT","title":"9.4.11 - September 2023"},{"location":"release-notes/changelog-translations/#9410-september-2023","text":"(PW-1477) MT 540/541/542/543 -> sese.023.001.09: added a special mapping for 22F::STCO BPSS into SttlmParams\\SttlmTxCond\\Prtry using BSSP as identification and T2S as issuer","title":"9.4.10 - September 2023"},{"location":"release-notes/changelog-translations/#949-september-2023","text":"(PW-1442) MT <-> MX translations: fixed TimeZone handling in date time conversions that might lead to invalid date changes during translation depending on the local offset","title":"9.4.9 - September 2023"},{"location":"release-notes/changelog-translations/#948-september-2023","text":"(PW-1304) LYNX Translation Factory: pacs.009.001.08 returns MT205 translation by default (PW-1304) RITS/SCRIPS/CHATS/T2 Translation Factories: return generic Mx to Mt ISO translators","title":"9.4.8 - September 2023"},{"location":"release-notes/changelog-translations/#947-august-2023","text":"(PW-1562/PW-1565) MT 530 <-> sese.030.001.008 : Fixed mapping for 22F::PRTL into ReqDtls\\PrtlSttlmInd (PW-1563/PW-1564) MT 548 -> sese.031.001.08 : Fixed mapping, do not map section ReqDtls in MX (Ref\\AcctOwnrTxId, Ref\\MktInfrstrctrTxId and HldInd) (PW-1557) Added translation CBPR+ MT104 -> pain.008.001.08 (PW-1210) Added specific translations for T2 (T2 RTGS) for MT103, MT202 and MT205 to MX (PW-1210) Added specific translations for Lynx (Canada RTGS) for MT103, MT202 and MT205 to MX RITS Translations: fixed creation time in header (Zulu time) MT to MX: replaced the dummy creation date 9999-12-31 in all translations but the CBPR+ ones with the current date","title":"9.4.7 - August 2023"},{"location":"release-notes/changelog-translations/#946-august-2023","text":"(PW-1474) CBPR MT 900 / MT 910 -> camt.054.001.08 : Added mapping for field 25 into Entry\\EntryReference (PW-1471) MT 548 -> sese.031.001.08 : Fixed mapping for :25D::TPRC//MODC -> ProcessingStatus/Completed (PW-1469) MT 540 / MT 541 / MT 542 / MT 543 <-> sese.023.001.09 : Fixed mapping for 94a <-> SafekeepingPlace (PW-1469) MT 544 / MT 545 / MT 546 / MT 547 <-> sese.025.001.09 : Fixed mapping for 94a <-> SafekeepingPlace (PW-1469) MT 548 <-> sese.024.001.10 : Fixed mapping for 94a <-> SafekeepingPlace (PW-1469) MT 578 <-> sese.028.001.08 : Fixed mapping for 94a <-> SafekeepingPlace (PW-1465) RITS translators: Generate automatic UETR if it doesn't exist in the MT source (Block3/121) (PW-1459) sese.023 <-> MT 540 / MT 541 / MT 542 / MT 543 : Fixed mapping for HoldIndicator <-> 23G (PW-1459) sese.024 <-> MT 548 : Fixed mapping for HoldIndicator <-> 23G (PW-1455) sese.030 -> MT 530 : Fixed mapping for HoldIndicator into :22F::SETT (PW-1454) MxToMt72FullField fix, accept proprietary codewords with alphanumeric characters (PW-1440) MT 548 -> sese.024.001.10 : Added NOTPROVIDED to ProcessingStatus\\CancellationRequested\\AdditionalReasonInformation when :25D::IPRC equals to CPRC and :70D::REAS don't exist","title":"9.4.6 - August 2023"},{"location":"release-notes/changelog-translations/#945-july-2023","text":"(PW-1423) RITS: Added automatic message identifier generation for the MX header and group header pacs.004 -> MT 103 : Revamped mappings for tag 70 pacs.008 -> MT 102 / 103 : Revamped mappings for tag 70 pacs.009 -> MT 202 COV / 205 COV : Revamped mappings for tag 70 pacs.008 -> MT 102 / 103 : Revamped mappings for tags 50 and 59 Name and Address component pacs.009 -> MT 202 COV / 205 COV : Revamped mappings for tags 50 and 59 Name and Address component","title":"9.4.5 - July 2023"},{"location":"release-notes/changelog-translations/#944-july-2023","text":"(PW-1438) Added translation seev.044.001.12 -> MT564 (PW-1437) Added translation seev.039.001.12 -> MT564 (PW-1436) Added translation seev.037.001.14 -> MT566 (PW-1435) Added translation seev.036.001.14 -> MT566 (PW-1434) Added translation seev.035.001.14 -> MT564 (PW-1433) Added translation seev.031.001.13 -> MT564 (PW-1433) Added translation seev.031.001.13 -> MT568 Added specific translations for SCRIPS (MEPS+, Singapore RGTS) for MT103 and MT202 to MX Added specific translations for SCRIPS (MEPS+, Singapore RTGS) for MT103 and MT202 to MX (PW-1397) Added specific translations for CHATS (Hong Kong RTGS) for MT103 and MT202 to MX (PW-1399) MT -> MX: amounts are converted into the MX decimal number with minimal decimal places according to the currency (PW-1397) Added specific translations for CHATS (Hong Kong RGTS) for MT103 and MT202 to MX","title":"9.4.4 - July 2023"},{"location":"release-notes/changelog-translations/#943-july-2023","text":"(PW-1427) Added translations MT564 <-> seev.031.001.11 (PW-1427) Added translations MT568 <-> seev.031.001.11 (PW-1425) Added translation sese.029.001.04 -> MT578 (PW-1425) Added translation semt.020.001.05 -> MT578 (PW-1417) MT104 -> pain.008.001.08 : added mapping for 53A into RemittanceInformation/Structured/AdditionalRemittanceInformation","title":"9.4.3 - July 2023"},{"location":"release-notes/changelog-translations/#942-june-2023","text":"(PW-1424) Added translations MT530 <-> sese.030.001.08 (PW-1424) Added translations MT548 <-> sese.031.001.08 (PW-1399) FormatDecimal MT -> MX : added 2 fixed decimal places in all translations (PW-1421) CBPR+ MT910 -> camt.054.001.08 : fixed CreditDebitIndicator from DBIT to CRDT (PW-1412) Added translation sese.028.001.08 -> MT578","title":"9.4.2 - June 2023"},{"location":"release-notes/changelog-translations/#941-june-2023","text":"(PW-1407) MT548 -> sese.024/032/034 / semt.014 and MT537 -> semt.018 : added pending reason code mapping (PATD to OTHR) (PW-1407) MT548 -> sese.024/034 : added rejected reason code mapping (NARR to OTHR) (PW-1406) CBPR+ MT to MX translations -> trim starting slashes while mapping account numbers into Identification/Other/Identification to be compliant with CBPR+ restricted charset (PW-1394) Added CBPR+ translation camt.058.001.08 -> MT292 (PW-1394) Added CBPR+ translation camt.107.001.01 -> MT110 (PW-1394) Added CBPR+ translation camt.108.001.01 -> MT111 (PW-1394) Added CBPR+ translation camt.109.001.01 -> MT112 MTn92, MTn96 and MT200 to MX: Fixed translation of field 11[R,S] into date time element in MX, adding a dummy time component","title":"9.4.1 - June 2023"},{"location":"release-notes/changelog-translations/#940-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"9.4.0 - May 2023"},{"location":"release-notes/changelog-translations/#9342-june-2023","text":"(PW-1395) Added translation MT578 -> sese.028.001.08 (PW-1391) pacs.008.001 -> MT102/103: Revamped implementation of MxToMtRemittanceInformation for translation into field 70 (PW-1390) CBPR+ pacs.009.001.08 -> MT200/202/205: Revamped implementation of MxToMtPartyNameAndStructuredAddress and MxToMtPartyNameAndUnstructuredAddress for translation into fields 52D/56D/57D/58D (PW-1388) CBPR+ pacs.008.001.08 -> MT103: minor fix in function MxToMtAddressLineIsStructured (PW-1385) CBPR+ pacs.008.001.08 -> MT103: minor fix in function MxToMtNameAndAddress (7/NIDN information) (PW-1384) CBPR+ pacs.008.001.08 -> MT103: fixed mapping for PaymentTypeInformation/CategoryPurpose/Code into tag 23E (PW-1382) sese.023.001.09 -> MT540/MT541/MT542/MT543: new mapping from OtherBusinessParties/Investor/Nationality to field 95C (PW-1182) Added CBPR+ translation MT201 -> pacs.008.001.08 (PW-1182) Added CBPR+ translation MT203 -> pacs.008.001.08 (PW-1182) Added CBPR+ translations MT102 / MT102.STP <-> pacs.009.001.08 / pacs.009.001.08.STP pacs.008/pacs.004/pain.001 -> MT101/102/103: truncate with evidence last line in field 70 mapping CBPR+ camt.052/camt.053: fixes in fields 20/28C/34F/61 mapping pacs.002 <-> MT199 / MT299: Revamped implementation of MxToMt72Or79REJT for translation into field 79","title":"9.3.42 - June 2023"},{"location":"release-notes/changelog-translations/#9341-may-2023","text":"(PW-1371) pacs.004/pacs.008 -> MT102/MT103: conditional mapping to field 71G only if the amount is different from 0 (PW-1360/PW-1363) CBPR+ pacs.004 -> MT103: Revamped implementation of MxToMtRETN(MT1) for translation into field 72 (PW-1359) CBPR+ pacs.008.001.08.STP -> MT103.STP: use only the last PreviousAgent occurrence for mapping into field 72 pacs.004 -> MT103: implementation of MxToMtRETN(MT1) for translation into field 72 pacs.004 -> MT202/MT205: implementation of MxToMtRETN(MT2) for translation into field 72","title":"9.3.41 - May 2023"},{"location":"release-notes/changelog-translations/#9340-may-2023","text":"Added specific translations for RITS (Australian RTGS) for MT103 and MT202 to MX Added a TranslatorFactoryProvider to allow the creation of a TranslatorFactory for a specific market or clearing type Added accessors for the TranslatorConfiguration in the Translator interface Deprecated the 'translate' call with configuration parameter in favor of modifying the translator instance configuration","title":"9.3.40 - May 2023"},{"location":"release-notes/changelog-translations/#9339-april-2023","text":"(PW-1353/1354) CBPR+ pacs.004/pacs.008/pacs.009 to MT: fixed tags 50/59 letter option logic and added MxToMtAddressLineIsStructured function implementation (PW-1349) Enhanced mapping into field 72 by adding MxToMt72FullField function implementation (PW-1349) Fixed the implementation of the InstructionForNextAgent function (PW-1347) Added translation seev.044.001.11 -> MT564 (PW-1345) Added translation seev.037.001.13 -> MT566 (PW-1344) Added translation seev.036.001.13 -> MT566 (PW-1343) Added translation seev.035.001.13 -> MT564 (PW-1342) Added translations seev.031.001.12 -> MT564 / MT568","title":"9.3.39 - April 2023"},{"location":"release-notes/changelog-translations/#9338-april-2023","text":"(PW-1340) CBPR+ MT210 -> camt.057: strip leading slash (/) while mapping tag 25 into Notification/Account/Identification/Other/Identification (PW-1336) pacs.004.001 -> MT103 / MT202 / MT205: fixed mapping of tag 72, added XT99 code to unmappable reason codes","title":"9.3.38 - April 2023"},{"location":"release-notes/changelog-translations/#9337-april-2023","text":"(PW-1335) MT to MX: fixed MxToMt72FullField for translation into field 72, multiple lines mapping in InstructionForNextAgent node (PW-1334) camt.053 -> MT940 / MT950: fixed preconditions and mapping for 60F/M - 61 (PW-1330) pacs.008 -> MT103: fixed mapping of tag 77B, admit simultaneous /ORDERRES/ and /BENEFRES/ codes (PW-1310/1314/1328/1329) MX to MT: mapping for Name and Address fields 50/52/53/54/56/57/58/59, Revamped implementation of MxToMtNameAndAddress functions (PW-1310/1314/1328/1329) CBPR+ pacs.004/pacs.008/pacs.009 translators, using new MxToMtNameAndAddress functions (PW-1276) MX to MT: MxToMt72FullField for translation into field 72, add ACC code to InstructionForCreditorAgent Added and option in the translator configuration to define the specific version for the AppHdr to generate","title":"9.3.37 - April 2023"},{"location":"release-notes/changelog-translations/#9336-april-2023","text":"(PW-1208) ISO pacs.008 / pacs.004 -> MT103: deprecated preconditions (InstructingAgent and InstructedAgent)","title":"9.3.36 - April 2023"},{"location":"release-notes/changelog-translations/#9335-april-2023","text":"(PW-1325) sese.024 -> MT548: fixed translation of tag 24B:REJT, mapping of code OTHR to NARR","title":"9.3.35 - April 2023"},{"location":"release-notes/changelog-translations/#9334-april-2023","text":"(PW-1319) pacs to MT103: removed mapping of extra content /LOCINS/CRED in field 72 (PW-1317) pacs.008.001 -> MT103: fixed mapping of tag 77B, included CountryOfResidence for Debtor and Creditor (PW-1316) MT to MX: fixed mapping of tag 59F PartyIdentifier (PW-1315) MT to MX: MxToMt72FullField for translation into field 72, excluded Proprietary fields in LOCINS indicator (PW-1312) pacs.004.001 -> MT103 / MT202 / MT205: fixed mapping of tag 72, correct parsing of ReasonCode and AdditionalInformation (PW-1311) CBPR+ pacs.008.001 -> MT103: fixed mapping of tag 59, extra row in Name and Address section (PW-1309) CBPR+ pacs.008.001 -> MT103: fixed mapping of tag 59F, extra row in Name and Address section (PW-1308) CBPR+ pacs.008.001 -> MT103: fixed mapping of tag 23E SDVA and INTC (PW-1301) CBPR+ pacs.008.001 -> MT103: added mapping of tag 23E for HOLD, CHQB, PHOB and TELB codes in CreditTransferTransactionInformation\\InstructionForCreditorAgent (PW-1299) pacs.008.001 -> MT103 / MT102: fixed mapping of tag 70, added /URI/ indicator to RemittanceInformation\\Unstructured mapping (PW-1298) pacs.004.001 -> MT103 / MT202 / MT205: fixed mapping of tag 72, added /XT99/ to reason code (PW-1297) MT to MX: fixed mapping of tag 52D, truncate line 2 when FinancialInstitutionIdentification\\Name is longer than max length (PW-1276) pacs.008.001 -> MT103 / MT102: fixed mapping of tag 70, RemittanceInformation\\Unstructured with /RFB/ indicator","title":"9.3.34 - April 2023"},{"location":"release-notes/changelog-translations/#9333-march-2023","text":"(PW-1296) CBPR+ MT202/205 -> pacs.009 and MT103 -> pacs.008: removed the precondition rejecting 53B in present along 54a CBPR+ MT202/205 -> pacs.009 and MT204 -> pacs.010: fixed mapping of 58D into Name & Address to be compliant with CBPR+ UG rule MT to MX: Removed unnecessary precondition checking the format of /CLSTIME/ in field 72","title":"9.3.33 - March 2023"},{"location":"release-notes/changelog-translations/#9332-march-2023","text":"(PW-1288/1289/1290/1291/1293/1295) pacs.004.001.09/10 -> MT103: minor fixes in mapping for Creditor/Agent to field 59 and Debtor/Agent to field 50 (PW-1285) pacs.008.001 -> MT103: fixed mapping InstructionForCreditorAgent\\Code CHQB to field 23E (PW-1284/1294) minor fixes in MxToMt72FullField and MxToMt72FullField2 for translation into field 72 (PW-1283) pacs.004.001.09/10 -> MT103 / MT202 / MT205: fixed mapping for field 72 added extra TEXT line (PW-1282) pacs.004.001.09/10 -> MT103: added mapping for Creditor/Agent to field 59 and Debtor/Agent to field 50 (PW-1280) pacs.008 -> MT103: fixed mapping of tag 70, remove /RFB/ prefix when EndToEndIdentification is NOTPROVIDED (PW-1280) MX_To_MTAgent: removed Schema/Code prefix when it's different from CUID (PW-1280) MX_To_MTFATFNameAndAddress: replaced last / separator in CountryCode/TownName/PostCode for CountryCode/TownName,PostCode (PW-1278) pacs.009.001 -> MT202.COV: Implementation of MxToMt72FullField and MxToMt72FullField2 for translation into field 72 (PW-1276) CBPR+ pacs.008 -> MT103: Revamped implementation of MxToMt72FullField for translation into field 72 (PW-1275) Added translation semt.002.001.10 -> MT535 (PW-1267) MT103 -> pacs.008: Changed field 23E mapping to avoid InstructionForNextAgent/Code for compatibility with HVPS (PW-1209) MT204 -> pacs.010.001.03: deprecated mandatory Block3/121 precondition and autogenerate new UETR if Block3/121 is missing","title":"9.3.32 - March 2023"},{"location":"release-notes/changelog-translations/#9331-march-2023","text":"(PW-1270) MT535 -> semt.002.002.03 / semt.003.002.03: fixed mapping of tag 94a in Sequence B1 to BalanceForAccount/SafekeepingPlace (PW-1265) ISO pacs.004.001.09/10 -> MT103 / MT202 / MT205: fixed reason code mapping for field 72 (PW-1265) ISO pacs.004.001.09/10 -> MT103 / MT202 / MT205: fixed selector criteria, defaulting to MT202 (PW-1265) ISO pacs.004.001.09/10 -> MT103: fixed mapping field 72, field 50F and field 57D (PW-1208) ISO pacs.009 -> MT202: deprecated preconditions (InstructingAgent and InstructedAgent)","title":"9.3.31 - March 2023"},{"location":"release-notes/changelog-translations/#9330-march-2023","text":"(PW-1271) MT192/MT292 -> camt.056.001.08/10: fixed mappings of fields 20 and 21 into the Underlying message information (PW-1266) Fixed length in field 72 wrapped lines (PW-1265) CBPR+ pacs.004.001.09 -> MT103 / MT202 / MT205: fixed reason code mapping for field 72 (PW-1262) CBPR+ pacs.004 -> MT103 / MT202 / MT205: fixed selector criteria, defaulting to MT202 (PW-1240) pacs.009 -> MT202/MT205: proper generation of the // (continuation of narrative) prefixes in field 72","title":"9.3.30 - March 2023"},{"location":"release-notes/changelog-translations/#9329-march-2023","text":"(PW-1240) pacs.009.001.* -> MT202 / MT205: fixed mapping of RemittanceInformation/Unstructured in MxToMt72FullField2 for translation into field 72","title":"9.3.29 - March 2023"},{"location":"release-notes/changelog-translations/#9328-march-2023","text":"(PW-1258) CBPR+ pacs.004.001.09 -> MT103: fixed mapping field 72, field 50F and field 57D (PW-1257) camt.053.001.02/07/08 -> MT940: fixed mapping of multiple AdditionalEntryInformation to field 86 (PW-1182) Fixed translations MT940 <-> camt.060.001.05 for both generic ISO and CBPR+ versions (PW-1182) Added translations MT940 <-> camt.060.001.06","title":"9.3.28 - March 2023"},{"location":"release-notes/changelog-translations/#9327-march-2023","text":"(PW-1253) camt.056.001.08/10 -> MT192 / MT292: fixed mapping of OriginalGroupInformation\\OriginalCreationDateTime to 11S (PW-1252) camt.053.001.* -> MT950: fixed mapping of Statement\\LegalSequenceNumber and Statement\\ElectronicSequenceNumber to field 28C (PW-1249) pacs.008.001.* -> MT102 / MT103: fixed mapping of RemittanceInformation/Unstructured with ROC prefix to field 70 (PW-1247) MT202 / MT205 to pacs.009: Fixed mapping of TELEBEN code into InstructionForCreditorAgent/Code (PW-1245) CBPR+ pacs.009.001.08.COV -> MT202.COV: removed unnecessary RFB prefix in field 70, fixed field 72 line split (PW-1240) MT103 -> pacs.008.001.*: removed unnecessary defaults 'false' for BatchBooking (PW-1238) MT202 / MT205 -> pacs.009.001.*: fixed 53A mapping to SettlementInformation/SettlementAccount (PW-1237) MT103 / MT103.STP -> pacs.008.001.*: fixed 53A mapping to /FIN53/ in InstructionForNextAgent (PW-1235) CBPR+ pacs.009.001.* -> MT202 / MT205: Revamped implementation of MxToMt72FullField2 for translation into field 72 (PW-1233, PW-1246) CBPR+ pacs/camt -> MT: ignore FinancialInstitutionIdentification\\PostalAddress\\AddressLine containing \"NOTPROVIDED\" (PW-1230) CBPR+ pacs.008.001.08 -> MT103: added mapping for field 26T (PW-1229) Preserve whitespaces in XML element values when parsing the source MX for translation into MT (PW-1229) CBPR+ pacs.008/pacs.009 -> MT103/MT202: fixed mapping of multiple occurrences of InstructionForNextAgent/InstructionInformation to field 72 (PW-1229) camt.053.001.* -> MT940: fixed mapping of EntryDetails/AdditionalEntryInformation to field 86 (PW-1229) TranslationConfiguration: added new attribute preserveWhitespaces to prevent the translator from trimming the node contents in the MX to MT translations","title":"9.3.27 - March 2023"},{"location":"release-notes/changelog-translations/#9326-march-2023","text":"(PW-1251) CBPR+ MT to pacs.009: Fixed mapping of field 72 into repetitive InstructionForNextAgent with proper truncation","title":"9.3.26 - March 2023"},{"location":"release-notes/changelog-translations/#9325-march-2023","text":"(PW-1228) CBPR+ translation: fixed duplicated Member Identification in field 57D when translating from a ClearingSystemMemberIdentification element (PW-1225) CBPR+ pacs.004/pacs.009/pacs.009.COV/pacs.009.ADV -> MT202/MT202COV: removed unnecessary defaults 'NOTPROVIDED' for fields 52D-56D-57D (PW-1219) camt.054.001.06/07/08/09 -> MT900/MT910: fixed AddtlTxInf split into field 72 lines","title":"9.3.25 - March 2023"},{"location":"release-notes/changelog-translations/#9324-march-2023","text":"(PW-1224) Fixed RemittanceInformation\\Unstructured -> tag 70 (code RFB deleted) in CBPR+ translation pacs.008.001.08 -> MT103 (PW-1220) Fixed tag 53B incorrect prefix (INGA = C/INDA = D) in CBPR+ translation pacs.008.001.08 -> MT103 (PW-1217) Fixed InstructionForNextAgent\\InstructionInformation -> tag 72 (multiple occurrences) in CBPR+ translation pacs.008.001.08 -> MT103 (PW-1216) Fixed InstgAgt mapping to 72/INS/ in translation CBPR+ pacs.009.001.08 -> MT202 (PW-1210) Added translations MT102 <-> pacs.008.001.09 (PW-1210) Added translations MT103 / MT103.STP <-> pacs.008.001.09 (PW-1210) Added translations MT103 <-> pacs.004.001.10 (PW-1210) Added translations MT202 <-> pacs.004.001.10 (PW-1210) Added translations MT205 <-> pacs.004.001.10 (PW-1210) Added translations MT200 <-> pacs.009.001.09 (PW-1210) Added translations MT202 / MT202.COV <-> pacs.009.001.09 (PW-1210) Added translations MT205 / MT205.COV <-> pacs.009.001.09 (PW-1196) Fixed field 61/Supplementary Details mapping in the MT940 -> camt.053.001.07/08/09 translators (PW-1182) MT920 to camt.060.001.05: fixed intermediate field 34F repetition mapping (PW-1182) Added translations MT196/296 <-> camt.029.001.11 (PW-1182) Added translations pacs.009.001.08 -> MT205.COV","title":"9.3.24 - March 2023"},{"location":"release-notes/changelog-translations/#9323-february-2023","text":"(PW-1205) Removed criteria selection in translations MT196/MT296 -> camt.029.001.09 (PW-1204) Fixed 22F:STCO repetitive tag in translations sese.024. /sese.034. -> MT548 - semt.017.002.01 -> MT536 - semt.018.002.01 -> MT537","title":"9.3.23 - February 2023"},{"location":"release-notes/changelog-translations/#9322-february-2023","text":"(PW-1196) Enhancements in the MT940 <-> camt.053.001.* translators to enable back-and-forth conversion without data loss (PW-1196) Translator Factory: prefer MT940 over MT950 when both options are available as target MT (PW-1194) Fixed field 50A mapping in pacs.008.001.* to MT translators, it was the wildcard letter option 'a' instead of 'A' (PW-1089) Fixed Field 72 translation in MT103 -> pacs.008.001.* (PW-1089) Internal enhancement of narrative fields content extraction (MTs n99, 103, 200, 202 and 205 to MX)","title":"9.3.22 - February 2023"},{"location":"release-notes/changelog-translations/#9321-february-2023","text":"(PW-1183) Fixed criteria filter in translations pacs.008.001.08/10 -> MT102","title":"9.3.21 - February 2023"},{"location":"release-notes/changelog-translations/#9320-february-2023","text":"(PW-1182) Added translations MT102 <-> pacs.008.001.08 (PW-1182) Added translations MT900 <-> camt.054.001.09 (PW-1182) Added translations MT192/292) <-> camt.056.001.10 (PW-1182) Added translations MT941 <-> camt.052.001.09 (PW-1182) Added translation camt.060.001.06 -> MT920 (PW-1089) pacs.008 to MT103: enhanced field 72 mapping to support and propagate also custom codes (PW-1173) mapped the MX header priority into the target MT also when the direction of the MT is inbound (SwiftBlock2Output) Reviewed preconditions for pacs, semt to meet MT semantic checks restrictions Reviewed MT103 translation preconditions to make sure field 54A used with //RT indicator is followed by data for the member id","title":"9.3.20 - February 2023"},{"location":"release-notes/changelog-translations/#9319-january-2023","text":"(PW-1157) Added translation seev.035.001.11 to MT564","title":"9.3.19 - January 2023"},{"location":"release-notes/changelog-translations/#9318-january-2023","text":"(PW-1148) Added translation MT548 to sese.027.001.05 (PW-1146) Added translations sese.020.001.06 to MT540/MT541/MT542/MT543 (PW-1137) Added translations MT199/MT299 RJCT to pacs.002.001.10 (generic ISO 20022 and CBPR+ versions)","title":"9.3.18 - January 2023"},{"location":"release-notes/changelog-translations/#9317-december-2022","text":"(PW-1138) camt.057.001.06 to MT210: Notification/Item/Account fix (PW-1137) CBPR+ translation issue for pacs.002 (PW-1136) Added translation seev.039.001.10/11 to MT564 (PW-1135) Added translation seev.037.001.11 to MT566 (PW-1134) Added translation seev.036.001.11 to MT566 (PW-1133) Added translation seev.035.001.10 to MT564 (PW-1132) Added translation seev.031.001.10 to MT564 (PW-1131) Added translation seev.031.001.10 to MT568 (PW-1129) CBPR pacs.008.001.08 to MT103: minor fix fin field 72 /REC/ mapping MT300 to fxtr.014.001.03: implementation enhancements","title":"9.3.17 - December 2022"},{"location":"release-notes/changelog-translations/#9316-december-2022","text":"(PW-1125) pacs.009.001 to MT202 precondition SR23 fix","title":"9.3.16 - December 2022"},{"location":"release-notes/changelog-translations/#9315-december-2022","text":"(PW-1123) MT202/MT205 to pacs.009.001: added mapping of account in field 53A into instruction for next agent with /FIN53/ prefix Internal implementation enhancements in MT564/MT568 to seev.031 and MT564 to seev.039","title":"9.3.15 - December 2022"},{"location":"release-notes/changelog-translations/#9314-november-2022","text":"(PW-1112) sese.023.001.09 to MT540, MT541, MT542 and MT543 enhancements","title":"9.3.14 - November 2022"},{"location":"release-notes/changelog-translations/#9313-november-2022","text":"(PW-1111) Added translation sese.023.001.09 to MT541 and MT543 Added translation sese.024.001.09 to MT548","title":"9.3.13 - November 2022"},{"location":"release-notes/changelog-translations/#9312-november-2022","text":"Updated Apache Commons Text dependency to 1.10 to fix reported CVE (PW-1103) MT210 <-> camt.057.001.06: Enhanced mapping of fields 50, 52 and 56 (PW-1100) MT196/296 to camt.029: optional 11R/11S criteria check and added 11S translation (PW-1089) MT103 to pacs.008: Enhanced mapping of fields 70 and 72 into InstructionForNextAgent and RemittanceInformation (PW-1044) MT103 to pacs.008 - added narrative 72 /LOCINS/ /CATPURP/ and Batch Booking node Added translation MT200 to camt.050.001.05","title":"9.3.12 - November 2022"},{"location":"release-notes/changelog-translations/#9311-november-2022","text":"Migrated SIC translations to release 4.9","title":"9.3.11 - November 2022"},{"location":"release-notes/changelog-translations/#9310-october-2022","text":"Added translation camt.050.001.05 to MT200 (PW-1088) MT101 to pain.001 and MT103 to pacs.008: field 23E mapping enhancements","title":"9.3.10 - October 2022"},{"location":"release-notes/changelog-translations/#939-october-2022","text":"(PW-1077) MT548 to sese.024.001.10 mapping enhancements (PW-1063) MT544/545/546/547 to sese.025.001.09: Fixed partial settlement indicator mapping (PART, NPAR) (PW-1063) MT542 to sese.023.001.09: Fixed partial settlement indicator mapping (PART, NPAR) (PW-1057) MT to pacs.008 and pacs.009 - translate field 72 - added /BNF/ and /REC/ prefix in MX output","title":"9.3.9 - October 2022"},{"location":"release-notes/changelog-translations/#938-october-2022","text":"(PW-1075) MT548 to sese.024.001.10: MatchingStatus fixes with default if field 70D is not present (PW-1072) pacs to MT103 (and 202): Fixed logic for field 33B mapping to avoid D49 error in semantic check (PW-1057) MT103 to pacs.008: Remittance Unstructured mapped from Field 72 /BNF/ with fallback to mapping from field 70 if /BNF/ is not present (PW-1064) Fallback option to system classloader in resource loading Enhancements in MT party identifier into to MX clearing system identification mappings Added missing new versions for SRU2022 to the translator factory","title":"9.3.8 - October 2022"},{"location":"release-notes/changelog-translations/#937-september-2022","text":"(PW-1066) Added translations MT545 MT546 MT547 to sese.025.001.09 (PW-1065) Added translation sese.023.001.09 to MT542 (PW-1063) Added translation MT544 to sese.025.001.09 (PW-1062) pacs.008/pacs.009 to MT translates enhancements in field 20 for consistency between CBPR+ and generic ISO 20022 mappings (PW-1061) Revamp of the translation factory in order to enhance defaults and disambiguation (PW-1060) Fixed cast exception in MX to MT translations using explicit Output direction for the target message (PW-1059) MT to MX: Fixes an enhancements in translation of fields 50F and 59F (MTs; 101, 102, 103, 104, 202, 205, 210) (PW-1057) MT to pacs.008/pacs.009 enhanced mapping of REC code in field 72 (PW-955) pain.001 to MT101: copy raw unstructured remittance information to field 70 Added enum classes MtToMxTranslation and MxToMtTranslation will the supported translations","title":"9.3.7 - September 2022"},{"location":"release-notes/changelog-translations/#936-september-2022","text":"(PW-1043) CBPR+: Minor enhancements in the 192/292 to camt.056 translations (PW-1006) Changed the translation factory, to fall-back into 29 for MT target when both 19 and 29* are feasible Added generic ISO: MT103 to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT196 to camt.029.001.09 (based on CBPR+ translation) Added generic ISO: MT200 to pacs.009.001.08 (based on CBPR+ translation) Added generic ISO: MT202 to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT202 to pacs.004.001.09 (based on CBPR+ translation) Added generic ISO: MT202COV to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT204 to pacs.010.001.03 (based on CBPR+ translation) Added generic ISO: MT205 to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT205 to pacs.004.001.09 (based on CBPR+ translation) Added generic ISO: MT205 to pacs.009.001.08 (based on CBPR+ translation) Added generic ISO: MT205COV to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT205COV to pacs.009.001.08 (based on CBPR+ translation) Added generic ISO: MT296 to camt.029.001.09 (based on CBPR+ translation) Added generic ISO: camt.029.001.09 to MT196 (based on CBPR+ translation) Added generic ISO: camt.029.001.09 to MT296 (based on CBPR+ translation) Added generic ISO: camt.056.001.08 to MT292 (based on CBPR+ translation) Added generic ISO: camt.057.001.06 to MT210 (based on CBPR+ translation) Added generic ISO: camt.060.001.05 to MT920 (based on CBPR+ translation) Added generic ISO: pacs.002.001.10 to MT199 (based on CBPR+ translation) Added generic ISO: pacs.002.001.10 to MT299 (based on CBPR+ translation) Added generic ISO: pacs.004.001.09 to MT202 (based on CBPR+ translation) Added generic ISO: pacs.004.001.09 to MT205 (based on CBPR+ translation) Added generic ISO: pacs.009.001.08 to MT200 (based on CBPR+ translation) Added generic ISO: pacs.009.001.08 to MT205 (based on CBPR+ translation) Added generic ISO: pacs.010.001.03 to MT204 (based on CBPR+ translation) Removed unnecesary unescape in internal extractPattern function","title":"9.3.6 - September 2022"},{"location":"release-notes/changelog-translations/#935-september-2022","text":"(PW-1031) Added translation MT548 to sese.024.001.10 (PW-1006) MX to MT: Added a translation coverage report to see what source elements have been read during the translation semt.020.002.01 to MT578 mapping fix for REDE/RECE => REAG semantic check compiance in the generated MT","title":"9.3.5 - September 2022"},{"location":"release-notes/changelog-translations/#934-august-2022","text":"(PW-1012) sese.027.001.05 to MT548 mapping fixes","title":"9.3.4 - August 2022"},{"location":"release-notes/changelog-translations/#933-august-2022","text":"(PW-955) pain.001 to MT101: added truncation to the text after /RFB in field 70 Added internal loops API to MTs: 110, 201, 203, 210, 410, 412, 420, 422, 450, 456, 604, 605, 801, 920, 973","title":"9.3.3 - August 2022"},{"location":"release-notes/changelog-translations/#932-july-2022","text":"(PW-958) Enhanced the truncation report to differentiate between truncation regular fields and reference fields (PW-949) MX to MT: enhanced mapping of name & address fields, with truncation with evidence and having the country, when present, always at the last line (PW-948) MX -> MT202, MT204, MT205: enhanced mapping of field 58D (PW-948) MX -> MT202, MT204, MT205: enhanced mapping of field 58D (PW-948) pacs.009.01.10 -> MT202: enhanced mapping of field 58D (PW-943) Added translation: pacs.002.001.10 positive -> MT199/MT299 (PW-943) pacs.002.001.10 positive to MT199/MT299 (PW-935) Added MT-MX translation for latest versions of seev.031, seev.032, seev.033, seev.034, seev.038, seev.039, seev.040, seev.041, seev.042 (PW-932) Added translation: pacs.008.001.08 (ISO and CBPR+) -> MT103.REMIT (PW-932) Added a translation configuration parameter to disable the generation of the PDE flag (PW-932) Added translation: camt.056.001.08 -> MT192 (PW-924) Added translation: camt.052.001.09 <-> MT942 (PW-924) Added translation: camt.053.001.09 <-> MT940 (PW-924) Added translation: camt.053.001.09 <-> MT950 (PW-924) Added translation: camt.054.001.09 <-> MT910 setr.004.001.04 -> MT502: mapped the Holdings Redemption Rate into 36B::ORDR/UNIT to be compliant with semantic 258 check MT102 -> pacs.008.001.10: fixed mapping to be compliant with MX cross element checks Implementation enhancements","title":"9.3.2 - July 2022"},{"location":"release-notes/changelog-translations/#931-may-2022","text":"(PW-832) Added translation sese.023.001.09 -> MT540 MX to MT: Added truncation with evidence in party identification name fields","title":"9.3.1 - May 2022"},{"location":"release-notes/changelog-translations/#930-may-2022","text":"SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.3.0 - May 2022"},{"location":"release-notes/changelog-translations/#9235-may-2022","text":"(PW-918) Added translation MT192/MT292 -> camt.056.001.08 (PW-908) Added translation: MT102 -> pacs.008.001.10 (PW-813) Internal enhancement to fix CVE Added getTruncatedContent() to the Translator interface Deprecation API review","title":"9.2.35 - May 2022"},{"location":"release-notes/changelog-translations/#9234-may-2022","text":"(PW-915) Added translation: pacs.009.001.10 <-> MT202 (PW-915) Added translation: pacs.008.001.10 <-> MT103 (PW-908) Added translation: pacs.008.001.10 -> MT102 Mx to MT: Added a post process to sanitize with default values missing components in party fields options D, K and H","title":"9.2.34 - May 2022"},{"location":"release-notes/changelog-translations/#9233-may-2022","text":"(PW-905) MX pain.001 to MT101: Added default values for charges and creditor and removed related preconditions","title":"9.2.33 - May 2022"},{"location":"release-notes/changelog-translations/#9232-may-2022","text":"(PW-899) sese.027.001.05 -> MT548 added the mapping of TxDtls into SETTRAN Added CBPR+ translation: MT950 <-> camt.053.001.08 Added CBPR+ translation: MT941 <-> camt.052.001.08 Added CBPR+ translation: camt.060.001.05 -> MT920 Added CBPR+ translation: pacs.009.001.08 -> MT200 Added CBPR+ translation: MT941 <-> camt.052.001.08","title":"9.2.32 - May 2022"},{"location":"release-notes/changelog-translations/#9231-april-2022","text":"Added CBPR+ translation: MT200 -> pacs.009.001.08 Added CBPR+ translation: MT942 -> camt.052.001.08 Added CBPR+ translation: MT940 -> camt.053.001.08 Added CBPR+ translation: MT204 <-> pacs.010.001.03 Added CBPR+ translation: MT103, MT202, MT205 -> pacs.004.001.09 Added CBPR+ translation: MT900 -> camt.054.001.08 Added CBPR+ translation: MT910 -> camt.054.001.08 Added CBPR+ translation: MT210 -> camt.057.001.06 Added CBPR+ translation: MT101 <-> pain.001.001.09 MT101 to pain.001: fixed mapping of fields 50F and 59F, with preference for structured postal address instead of unstructured address lines CBPR+ MT192 and MT292 to camt.056: Added mapping of mandatory CreationDateTime MT103 STP to CBPR+ pacs.008.001.08.STP: Fixed mapping of mandatory creditor account CBPR+ MT to MX: changed the mapping of GroupHeader/CreationDateTime to have a fixed dummy date instead of the current time (PW-887) MT to MX: fixed the concatenation of narrative, to use space separator or not, depending on the MT value being split by length or words (PW-887) MX to MT: added a postprocess of the created message to sanitize fields with lines starting with '-' or ':' using '.' as replacement","title":"9.2.31 - April 2022"},{"location":"release-notes/changelog-translations/#9230-april-2022","text":"seev.036 and seev.037 to MT566: Fixed mapping of CADETL dates seev.036 to MT566: Fixed mapping of SECMOVE dates, CASHMOVE and 19B::WITF -> 19B::FTCA seev.035 to MT564: FIxed mapping of CADETL Added CBPR+ translation: camt.057.001.06 -> MT210 MX to MT: Fixed mapping of field 50F party identifier using code, country and identifier (no account number)","title":"9.2.30 - April 2022"},{"location":"release-notes/changelog-translations/#9229-april-2022","text":"Added translations: MT196/MT296 -> CBPR+ camt.029.001.09 Added translations xsys.011.001.01 and xsys.001.001.02 -> ACK/NAK (service 21 message) Fixed MIR generation in translations from xsys.012 and xsys.003 to MT019","title":"9.2.29 - April 2022"},{"location":"release-notes/changelog-translations/#9228-march-2022","text":"Added CBPR+ translation camt.029.001.09 to MT196/296 (PW-747) Added translation: MT104 -> pain.008.001.08","title":"9.2.28 - March 2022"},{"location":"release-notes/changelog-translations/#9227-march-2022","text":"(PW-872) Fixed mapping of field 95Q with multiple lines of name & address Added translations: MT566 <-> seev.036.002.12 and seev.036.001.12 Added translations: MT566 <-> seev.037.002.12 and seev.037.001.12 Added translations: MT564 <-> seev.035.002.12 and seev.035.001.12 Added translations: MT564 <-> seev.044.002.10 and seev.044.001.10","title":"9.2.27 - March 2022"},{"location":"release-notes/changelog-translations/#9226-march-2022","text":"Added CBPR+ translation MT103 REJT to pacs.002.001.10 Added CBPR+ translation MT202 REJT and MT202 COV REJT to pacs.002.001.10 Added CBPR+ translation MT205 REJT and MT205 COV REJT to pacs.002.001.10 (PW-865) MT540/541/542/543 to sese.023.001.09: fixed mapping of place of trade 94B Added API to the translation factories to indicate a specific message type/version output","title":"9.2.26 - March 2022"},{"location":"release-notes/changelog-translations/#9225-march-2022","text":"(PW-747) Added CBPR+ translations camt.056 <-> MT192/MT292","title":"9.2.25 - March 2022"},{"location":"release-notes/changelog-translations/#9224-march-2022","text":"Enhanced support for local date time offset in the mappings MX to MT: mapping review for fields 98a, with preference of 98E over 98C when possible From prowide-iso2022 update: changed the default date time serialization to local time with UTC offset","title":"9.2.24 - March 2022"},{"location":"release-notes/changelog-translations/#9223-march-2022","text":"(PW-859) MT54x to sese.020 fixed mapping of fields 20C:SEME, 20C:PCTI and 20C:MITI","title":"9.2.23 - March 2022"},{"location":"release-notes/changelog-translations/#9222-february-2022","text":"Added CBPR+ translation camt.052 to MT942 camt.052 to MT941/MT942 migrated to common translations hierarchy camt.052/053 to MT: Fixed mapping of pagination into 28C CBPR+ fixed translation of 72:/INS to previous instructing agent, added dummy postal address to be compliant with UG","title":"9.2.22 - February 2022"},{"location":"release-notes/changelog-translations/#9221-february-2022","text":"Added translation versions MT566 to seev.036.001.12 and seev.037.001.12 Added CBPR+ translation camt.053 to MT940 Added CBPR+ translation camt.054 to MT900/MT910 Added CBPR+ translation pacs.002 negative to MT199/MT299 REJT CBPR+ MT202 to pacs.009 ADV: fixed mapping of settlement information from fields 53a and 54a in the MT CBPR+ MT103 and MT202 mapping: fixed mapping for default creditor and debtor agents camt.053 to MT940/MT950 migrated to common translations hierarchy","title":"9.2.21 - February 2022"},{"location":"release-notes/changelog-translations/#9220-january-2022","text":"(PW-831) camt.052 and camt.053 to 9xx: Fixed direction toggle by configuration","title":"9.2.20 - January 2022"},{"location":"release-notes/changelog-translations/#9219-january-2022","text":"Added CBPR+ translation pacs.004.001.09 to MT103 RETN Added CBPR+ translation pacs.004.001.09 to MT202 RETN Added CBPR+ translation pacs.004.001.09 to MT205 RETN Added CBPR+ translation pacs.009.001.08.ADV to MT202 Added CBPR+ translation pacs.009.001.08 to MT205 Added CBPR+ translation pacs.009.001.08.COV to MT205COV Added translation version pacs.004.001.09 to MT103 RETN (PW-747) Added translations version for pain.001.001.09 <--> MT101 (PW-831) MT9xx to camt.05x: Versions 6, 7 and 8 migrated to common translations hierarchy MT101 to pain.001.001.08: migrated to common translations hierarchy Migrated CBPR+ translations to release 2.1","title":"9.2.19 - January 2022"},{"location":"release-notes/changelog-translations/#9218-january-2022","text":"(PW-798) Added translations from MT540, MT541, MT542 and MT543 to sese.020.001.06 (PW-798) Added translations from sese.027.001.05 to MT548 Added specific translation implementation classes for CBPR+ (pacs.009 --> MT202) Added a CbprTranslatorFactory to autodetect source CBPR+ messages and provide its corresponding translation implementation MT to seev: Fixed incorrect version at AppHdr/MsgDefIdr in some MT to seev translations MX to MT: Added a translation configuration option to enabled or disabled the conversion of non-SWIFT characters into '.'","title":"9.2.18 - January 2022"},{"location":"release-notes/changelog-translations/#9217-january-2022","text":"Added specific translation implementation classes for CBPR+ (pacs.009 <-- MT202/MT205) MT103 and MT202 to MX: removed redundant mapping for Interbank Settlement Date to meet cross-element rule constraint MT202 to pacs.009: Added criteria selection, field 72 must not indicate message is a rejection or return MT202 to pacs.009: Versions 6, 7 and 8 migrated to common translations hierarchy MT202 to pacs.009: enhanced mapping of SttlmInf in GrpHdr according to the CBPR+ METAFCT002/METAFCT003","title":"9.2.17 - January 2022"},{"location":"release-notes/changelog-translations/#9217-december-2021","text":"Added specific translation implementation classes for CBPR+ (pacs.008 <-> MT103) Added com.prowidesoftware.integrator.translations as automatic module name in the MANIFEST for JPMS support MT103 to pacs.008.001.08: minor mapping enhancements (UETR, field 13C) MT to MX: Changed default ISO date time to local time with offset (for CBPR+ compatibility) MT to MX: Changed default label for missing content from UNKNOWN to NOTPROVIDED (for CBPR+ compatibility)","title":"9.2.17 - December 2021"},{"location":"release-notes/changelog-translations/#9216-december-2021","text":"(PW-781) Added translation sese.025.001.09 to MT545 and MT547 (PW-779) Added translation MT541 and MT543 to sese.023.001.09 MT103 to pacs.008: added criteria check to avoid translating RETURN messages into pacs.008 (pacs.004 should be used instead) MT to MX: BusinessApplicationHeaderV02 is now generated by default instead of BusinessApplicationHeaderV01 Added back and forth mapping between the MT priority and PDE flag and the MX AppHdr","title":"9.2.16 - December 2021"},{"location":"release-notes/changelog-translations/#9215-november-2021","text":"MT103 to pacs.008: enhanced mapping of SttlmInf in GrpHdr according to the CBPR+ METAFCT001","title":"9.2.15 - November 2021"},{"location":"release-notes/changelog-translations/#9214-november-2021","text":"(PW-769): Added mapping for expected trade and settlement dates (from B/98a into NewDetails dates) MT103 to pacs.008: removed redundant IntrBkSttlmDt from GrpHdr (already mapped in CdtTrfTxInf) to be compliant with cross-element rule","title":"9.2.14 - November 2021"},{"location":"release-notes/changelog-translations/#9213-november-2021","text":"(PW-762) Added translation MT542 to sese.023.001.09","title":"9.2.13 - November 2021"},{"location":"release-notes/changelog-translations/#9212-november-2021","text":"(PW-754) camt.054 to MT900 and MT910: fixed mapping of 13D, 32A value date, 52D, 72 and added mapping for 50F option","title":"9.2.12 - November 2021"},{"location":"release-notes/changelog-translations/#9211-october-2021","text":"(PW-643) setr.010.001.04 to MT502: RSET is set from CshSttlmDt (with fallback to ReqdFutrTradDt)","title":"9.2.11 - October 2021"},{"location":"release-notes/changelog-translations/#9210-october-2021","text":"(PW-643) setr.004.001.04 to MT502: RSET is set from CshSttlmDt (with fallback to ReqdFutrTradDt)","title":"9.2.10 - October 2021"},{"location":"release-notes/changelog-translations/#929-october-2021","text":"(PW-643) MT509 to setr.016.001.04: changed mapping of OrdrDtlsRpt to IndvOrdrDtlsRpt to align with the SMPG spec (PW-663) Added translation MT210 to camt.057.001.06 (PW-663) Added translation MT103 RETURN to pacs.004.001.09","title":"9.2.9 - October 2021"},{"location":"release-notes/changelog-translations/#928-october-2021","text":"(PW-709) MT54x and 578 to sese: fixed generation of empty Settlement Transaction Condition (PW-709) MT540 to sese.023.001.09: fixed mapping of Partial Settlement Indicator (PW-708) pacs.008 and pacs.004 to MT: Fixed mapping of third reimbursement agent account (PW-643) setr.004.001.04 and setr.010.001.04 to MT502: RSET is set from CshSttlmDt (with fallback to ReqdFutrTradDt)","title":"9.2.8 - October 2021"},{"location":"release-notes/changelog-translations/#927-september-2021","text":"(JR-613) pacs.009 to MT202: Avoid redundant codewords in field 72 lines","title":"9.2.7 - September 2021"},{"location":"release-notes/changelog-translations/#926-september-2021","text":"(PW-662) pacs.009.001.08 to MT202[COV]: added mapping for PaymentIdentification/UETR into Block3/121 with fallback to autogenerated UETR (PW-643) MT515 to setr.012 and setr.006: added mapping for 95a::ALTE and removed related precondition check","title":"9.2.6 - September 2021"},{"location":"release-notes/changelog-translations/#925-august-2021","text":"(PW-643) MT515 into setr.012: enhanced mapping of InvstmtAcctDtls/AcctId to avoid precondition on INVE/BUYR parties (PW-643) MT515 into setr.006.001.04 and setr.012.001.04: fixed mapping of 35B when ISIN is not present (CUSIP, SEDOL, etc...) (PW-643) setr into MT502: TILI indicator defaults to GTCA (good until canceled) License check fix when source MX does not contain AppHdr","title":"9.2.5 - August 2021"},{"location":"release-notes/changelog-translations/#924-august-2021","text":"(PW-626) sese.024.001 and sese.025.001 to MT: mapped AppHdr/CreDt into 98C:PREP (PW-623) MT566 to seev036: removed unnecessary precondition check and enhanced mapping of the ADDB indicator, amount and rates (PW-613) pacs.009 to MT202 and MT202COV: Enhanced mapping of field 72 Added API to set default amount, unit and currency; when it is mandatory in a target element/field and not present in the source message","title":"9.2.4 - August 2021"},{"location":"release-notes/changelog-translations/#923-august-2021","text":"(PW-642) sese.025.001.09 to MT: fixed PlcOfTrad into 94B:EXCH mapping, fixed FctvSttlmDt into 98C:ESET mapping (PW-643) setr.004.001.04 and setr.010.001.04 to MT502: multiple mapping enhancements (PW-643) setr.004, setr.006, setr.010, setr.012, setr.015: enhanced mapping into 35B without ISIN, including corresponding prefixes (PW-569) pacs.008 and pacs.009 to MT: enhanced heuristic to attempt mapping into 50F and 59F instead of 50K and 59 pacs.008 and pacs.009 to MT: minor bugfix translating into field 50F when StrtNm and BldgNb concatenation exceeds the line limit in field 50F (PW-605) MT to MX: avoid split of DSS into Issr and SchmeNm elements if the Issr alone in the MX has enough length for the DSS value (PW-591-598, 600-604, 607-612, 614, 616, 618) Mapping fixes in MT564 to seev.031.001.10","title":"9.2.3 - August 2021"},{"location":"release-notes/changelog-translations/#922-july-2021","text":"(PW-626) sese.024.001.10 to MT548: several mapping fixes (PW-572) pacs.008 to MT103: avoid the /REC/ in field 72 if the InstrForNxtAgt already contains and instruction code (PW-569) pacs.009 to MT202COV: added mapping of structured beneficiary data into field 59F option (PW-567) pacs.008.001.08 to MT103: added mapping for PaymentIdentification/UETR into Block3/121 with fallback to autogenerated UETR Added translation sese.025.001.09 to MT546 (PW-569) pacs.008 to MT103: added mapping of structured beneficiary data into field 59F option (PW-568) pacs.008 to MT103: fixed mapping of CtgyPurp/Cd with \"INTC\" or \"CORT\" into 23E (PW-617) MT502, MT504, MT515, MT564 and MT566 to MX: fixed mapping of 98E with offset into ISO date time (PW-580-582-585-586-588-589-590) Mapping fixes in MT564 to seev.031.001.10 (PW-581) MT to MX: Preserve starting and trailing spaces when narrative field content is mapped into multiple lines of a single XML element (PW-568) pacs.008 to MT103: mapped special use case of CtgyPurp/Prtry with \"INTC CORT\" into respective 23E instances with \"INTC\" and \"CORT\" (PW-567) pacs.008 to MT103: avoid propagation of useless EndToEndId with \"NOTPROVIDED\" to field 70:/ROC/NOTPROVIDED MT856 translations: fixed mapping for sequence B6b Added translation setr.004.001.04 to MT502 Added translation setr.010.001.04 to MT502 (PW-579) MT564 to seev.031 added mapping for 70E::OFFO into Offerr elements (PW-577) MT564 to seev.031.001.10 added mapping for 25D with DSS into processing status sese and semt to MT: fixed mapping for SETPRTY 97A::SAFE when type and name was present besides the account identifier MX to MT: general fix in field 20C mapping that could occasionally generate more than 16 characters Added translation MT540 to sese.023.001.09 Added translation sese.024.001.10 to MT548 Added translation sese.025.001.09 to MT544","title":"9.2.2 - July 2021"},{"location":"release-notes/changelog-translations/#921-june-2021","text":"Added translation MT509 to setr.016.001.04 Added translation MT515 to setr.006.001.04 Added translation MT515 to setr.012.001.04 Added translation seev.035.001.03 to MT564 Added translation seev.039.001.03 to MT564 Added translation seev.044.001.03 to MT564 setr.017 to MT509: OrdrRef reverted change, mapped back to TRRF instead of RELA MX to MT: preserve line breaks in MT fields when translated from MX narrative content Added translation seev.038.001.03 to MT568 (PW-551) seev.031 to MT564: fixed 90K PRPP and 90L OFFR field mapping into cash movement details (PW-550) MT564 to seev.035, MT565 to seev.033, MT566 to seev.036: fixed mapping of field 90J currency component (PW-549) seev.031.001.10 to MT564: fixed mapping of MACI MICI and MMCI into the corporate action option details (PW-548) seev.031 to MT564: fixed mapping of 90F, 90J and 90L OFFR into the securities movement details (PW-547) seev.031 to MT564: added mapping for 90s option L into the maximum and minimum price details with 'PRCT' as default code (PW-546) seev.031 to MT564: fixed mapping of price details in SctiesMvmntDtls (PW-545) seev.031.001.03 to MT564: fixed mapping of certification breakdown flags (PW-544) MT564 to seev.031: fixed mapping of indicator flags in CADETL and CAOPTN (PW-543) seev.031.001.03 to MT564: fixed ISIN mapping (PW-542) MT564 to seev.031.001.10: fixed mapping of repetitive 70E content (PW-541) MT564 to seev.031.001.10: added missing mapping for 92D:WAPA into WarrantParity (PW-537) MT to MX: fixed mapping of face amount, that in some cases was propagated as 1.0 instead of the actual value (PW-535) MT564 to seev.031.001.10: mapping fixes in the cash movement details (PW-533) Added translation from seev.031.001.09 to MT564 MX pacs.008 and pacs.004 to MT103: fixed calculation of total charges in field 71G when the ChrgsInf is repeated in the MX Mapping fixes in setr.006.001.04, setr.012.001.04 and setr.015.001.04 to MT515 Mapping fix in MT103 to pacs.008 when multiple sender charges are present (PW-521) MT564 to seev.031.001.10: reviewed mapping of rate and amount details setr016 and setr.017 to MT509: OrdrRef is mapped into RELA instead of TRRF","title":"9.2.1 - June 2021"},{"location":"release-notes/changelog-translations/#920-may-2021","text":"SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.2.0 - May 2021"},{"location":"release-notes/changelog-translations/#9112-april-2021","text":"(PW-518) More flexible check of licensed BIC codes extracted from the translated MT headers xsys.012 to MT019: minor fix in target message fields order","title":"9.1.12 - April 2021"},{"location":"release-notes/changelog-translations/#9111-february-2021","text":"(CR-34) Added seev.031.001.001.03 to MT564 and MT568 translations (CR-34) Added MT564 and MT568 to seev.031.001.10 translations Fixed seev.031 to 564/568 invalid codewords MIEX and MILT in translation into field 36B Fixed generation of 20C:SEME when BAH is not present, in translations from seev.031/033/034/037/038/044 Fixed generation of LINK in translations from: seev.031/032/033/034/035/036/037, semt.016, sese.023/026/033/037","title":"9.1.11 - February 2021"},{"location":"release-notes/changelog-translations/#9110-january-2021","text":"(PW-438) Further enhancements in the setr.016 to MT509 when status is suspended","title":"9.1.10 - January 2021"},{"location":"release-notes/changelog-translations/#919-january-2021","text":"(PW-438) Fixed setr.016 to MT509 when status is suspended with proprietary reason code","title":"9.1.9 - January 2021"},{"location":"release-notes/changelog-translations/#918-december-2020","text":"Added translation from camt.053.001.02 to MT940 Added a one to many special translation for camt.053.001.02 to list of MT940 License check review","title":"9.1.8 - December 2020"},{"location":"release-notes/changelog-translations/#917-november-2020","text":"(PW-368) setr.015.001, setr.006.001 and setr.012.001 to MT515: Fixed mapping of transfer agent into 95Q from RltdPtyDtls with code TRAG (PW-368) setr.015 to MT515: added mapping for :22H::CAOP from Income Preference in the MX (PW-368) setr.015 to MT515: changed the mapping of InvstmtAcctDtls/AcctId into 95Q SELL/BUYR instead of 97A:SAFE setr.015.001 MT515: enhanced mapping for 35B when identification is not an ISIN setr.015.001 to MT515: removed no longer necessary precondition checks 30, 31 and 34 setr.006.001 to MT515: removed no longer necessary precondition checks 25 Fixed option to set sender/receiver from configuration in MX to MT940, MT941, MT942, MT900 and MT910 translations","title":"9.1.7 - November 2020"},{"location":"release-notes/changelog-translations/#916-november-2020","text":"(PW-368) setr.012.001 to MT515: removed no longer necessary precondition checks 6 (PW-368) setr.015.001 to MT515: removed no longer necessary precondition checks 5 (PW-368) setr.006.001 to MT515: removed no longer necessary precondition checks 5, 19 and 36 (PW-368) setr.006.001 and setr.012.001 to to 515: Mapped amount with codeword SWIT into amount with OTHR in the MT since SWIT is not accepted (PW-368) setr.006.001 and setr.012.001 to MT515: enhanced mapping for 35B when identification is not an ISIN (PW-368) setr.006.001 and setr.012.001 to MT515: fixed mapping for 95P when source message party information contains a BIC code semt, sese and setr into MT: fixed mapping into fields 19A and 90B when source message has too many decimal digits setr into MT: fixed mapping into field 95R from when source uses a proprietary identification","title":"9.1.6 - November 2020"},{"location":"release-notes/changelog-translations/#915-november-2020","text":"(PW-368) setr.016.001 to MT509: enhanced mapping for /Extension content (PW-368) setr.017.001 to MT509: enhanced mapping for /Extension content (PW-368) setr.017.001 to MT509: references and status mapping review (PW-368) setr.006.001 to MT515: more lenient precondition, and enhanced amounts mapping (PW-368) setr.012.001 to MT515: more lenient precondition, and enhanced amounts mapping (PW-368) setr.015.001 to MT515: more lenient precondition, and enhanced amounts mapping (PW-368) setr.016.001 to MT509: added mapping for the Extension into the Reason narrative 70D (PW-395) Added translation for MT567 to seev.041.001.10 corporate action cancellation status","title":"9.1.5 - November 2020"},{"location":"release-notes/changelog-translations/#914-october-2020","text":"(PW-368) Enhanced the setr.016.001 to MT509 translation to support all code and reason structures in the source MX (PW-374) Added a one to many special translation for pacs.001 to list of MT101 (PW-374) Added sender, receiver and direction to the optional TranslatorConfiguration (PW-368) Added global preventive check in MX to MT translations to avoid propagating tab characters into MT fields (PW-368) setr to MT515: added fallback mappings for mandatory fields 98a:SETT and 95:SELL or 95:BUYR in MT515 (PW-377) pacs.001 to MT101 added a fallback mapping from CdtTrfTxInf/PmtId/EndToEndId into field 21 when CdtTrfTxInf/PmtId/InstrId is not present (PW-377) pacs.001 to MT101 added a fallback mapping to create the optional field 23E with value OTHR if no other 23E field is created MT to MX: General fix for 35B ISIN mapping into MX identification of security elements","title":"9.1.4 - October 2020"},{"location":"release-notes/changelog-translations/#913-august-2020","text":"(PW-368) MX to MT: enhanced mapping of references (field 20 or 20C:SEME) with fallback to reference from AppHdr and truncation if necessary setr.016 to MT509: fixed mapping of mandatory field 24B","title":"9.1.3 - August 2020"},{"location":"release-notes/changelog-translations/#912-august-2020","text":"(PW-320) Replaced legacy default translations DSS name 'STRS' by 'COEX' (Coexistence global DSS from ISO 20022) Added version 8 translation between pacs.009 and MT202 Added version 8 translation between pacs.008 and MT103 Added version 8 translation between camt.053 and MT940 Added version 8 translation between camt.053 and MT950 Added version 8 translation between camt.054 and MT900 Added version 8 translation between camt.054 and MT910 In pacs.009 to 202 fixed precondition check for the CdtTrfTxInf[1]/PrvsInstgAgt Minor Fix in MX to MT time with offset mapping, offset was not propagated properly in some use cases Minor fix in logical criteria exception messages Added pacs.004.001.02 to MT 103 RETURN translation (for both ISO and SIC versions) Added pacs.002.001.03 to ACK/NAK translation (for both ISO and SIC versions) MX to MT: Added a parameter in the TranslatorConfiguration to optionally set a ClearingSystemMemberIdToBic function implementation SIC: MT to MX, trimmed spaces from reference to be compliant with SIC restriction SIC: MT103 to pacs.008 instructed agent mapped from 56A when present in the MT SIC: MT202 to pacs.009 instructed agent mapped from 57A when present in the MT","title":"9.1.2 - August 2020"},{"location":"release-notes/changelog-translations/#911-jun-2020","text":"MT103 to pacs.008 fixed mapping of fields 70 and 72 MT101 to pacs.008 fixed mapping of fields 70 and 72 MT202 to pacs.009 fixed mapping of fields 70 and 72 MT202 to pacs.009 fixed precondition checking the format of the CLSTIME MT to MX: general enhancements in mapping of field 50F when line numbers are repeated MT502 to to setr.004 and setr.010: enhanced mapping for fields 70E and 70C MT564 to seev.031 enhanced mapping for field 94G MT565 to seev.033 enhanced mapping for fields 70E and 95G MT568 to seev.031 enhanced mapping for field 70E","title":"9.1.1 - Jun 2020"},{"location":"release-notes/changelog-translations/#910-may-2020","text":"SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.1.0 - May 2020"},{"location":"release-notes/changelog-translations/#901-may-2020","text":"Internal implementation changes to the use the new AppHdr model in the SDK","title":"9.0.1 - May 2020"},{"location":"release-notes/changelog-translations/#900-may-2020","text":"Translations module extracted to its own jar in the distribution, with its own version from now on (PW-286) Fixed ISO datetime conversions into MT variants","title":"9.0.0 - May 2020"},{"location":"release-notes/changelog-translations/#808-april-2020","text":"Fixed logical message criteria for camt.054 into 900 or 910 depending on the entry debit/credit indicator Fixed translator factory finder for pacs.008.001.06 to 103 and seev to 566 Change in preconditions from camt.053 to MT to make them more flexible","title":"8.0.8 - April 2020"},{"location":"release-notes/changelog-translations/#807-march-2020","text":"Added specific translations for SIC (SWISS RTGS): between 202 and pacs.009 Added specific translations for SIC (SWISS RTGS): between 103 and pacs.008 In MX to MT: fixed extra slash when mapping clearing system codes or account numbers into party fields pacs.008 to 103 and pacs.009 to 202: field 20 now is mapped from CdtTrfTxInf/PmtId/TxId instead of GrpHdr/MsgId 103 to pacs.008: when present, the block 3 MUR is mapped into GrpHdr/MsgId instead of the reference field 20","title":"8.0.7 - March 2020"},{"location":"release-notes/changelog-translations/#806-february-2020","text":"Added translation from setr.006.001.04 redemption order confirmation to MT515 Added translation from setr.012.001.04 subscription order confirmation to MT515 Added translation from setr.016.001.04 order instruction status report to MT509 Added translation from setr.015.001.04 switch order confirmation into MT515 redemption and subscription leg messages Added translation between setr.017.001.04 order cancellation status report and MT509 (back and forth) Added a truncation report in translator classes and a '+' as last character of truncated data in the target message In MT to MX; header data is propagated to the AppHdr, including sender, receiver, reference, message type, and also PDE flag if present in the MT trailer In MX to MT; if the source MX contains an ISO header with the possible duplicate flag set to true, the created MT will have a PDE trailer flag MT103 to pacs.008 added mapping from 32A date into the group header settlement date Added a remove spaces transformation when mapping IBAN numbers from MT to MX","title":"8.0.6 - February 2020"},{"location":"release-notes/changelog-translations/#805-january-2019","text":"MT202 and MT202COV to MX, added mapping for sender correspondent field 53B location into group header instructing agent postal address (PW-225) MT202 and MT202COV to MX, removed the precondition requiring a mandatory party identifier in the sender correspondent field 53B","title":"8.0.5 - January 2019"},{"location":"release-notes/changelog-translations/#804-december-2019","text":"MT103 to MX, added mapping for sender correspondent field 53B location into group header instructing agent postal address (PW-225) MT103 to MX, removed the precondition requiring a mandatory party identifier in the sender correspondent field 53B (PW-225) MT103 to MX, removed the precondition requiring the same currency In semt to MT translations when Document/*/Id/Id is not found in MX the 20C:SEME is generated from AppHdr/BizMsgIdr Enhanced mapping of field 35B description of security when the ISIN is not present","title":"8.0.4 - December 2019"},{"location":"release-notes/changelog-translations/#803-september-2019","text":"Fixed mapping for field 36E in translations from MX to MT Added version 6, 7, 8 and 9 for translations between MT566 and seev.036 and seev.037","title":"8.0.3 - September 2019"},{"location":"release-notes/changelog-translations/#802-august-2019","text":"Added version 6, 7, 8 and 9 for translations between MT566 and seev.036 and seev.037 Fixed mapping for field 36E in translations from MX to MT Fixed bin/translator CLI app that stopped reading input on the first line break","title":"8.0.2 - August 2019"},{"location":"release-notes/changelog-translations/#801-july-2019","text":"Added a TranslatorFactory to enable automatic translator selection based on the source message Added a CLI to run automatic translation of files in the command line","title":"8.0.1 - July 2019"},{"location":"release-notes/changelog-translations/#800-may-2019","text":"JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"8.0.0 - May 2019"},{"location":"release-notes/changelog-translations/#7108-march-2019","text":"Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Fixed obfuscation to keep directories in jar Fixed mapping of Field70 to EndToEndId","title":"7.10.8 - March 2019"},{"location":"release-notes/changelog-translations/#7107-january-2019","text":"Added alternative translate call in translation implementation classes to run the process without precondition checks Added translations between pacs.001.001.08 and MT101 Fixed translations for fields 50F and 77B Fixed precondition check for MX pain.001.001.03 to MT101 translation Fixed translation MX pain.001.001.03 to MT101 when multiple PmtInf and CdtTrfTxInf combinations are present","title":"7.10.7 - January 2019"},{"location":"release-notes/changelog-translations/#7100-april-2018","text":"SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Added 103 and 103 STP to pacs.008.001.07 Added 202 and 202 COV to pacs.009.001.07 Added 900 to camt.054.001.07 Added 910 to camt.054.001.07 Added 940 to camt.053.001.07 Added 941 to camt.052.001.07 Added 942 to camt.052.001.07 Added 950 to camt.053.001.07 Added pacs.008.001.07 to 103 Added pacs.009.001.07 to 202 and 202 COV Added camt.052.001.07 to 941 and 942 Added camt.053.001.07 to 940 and 950 Added camt.054.001.07 to 900 and 910","title":"7.10.0 - April 2018"},{"location":"release-notes/changelog-translations/#798-april-2018","text":"MT to MX: fixed decimal separator in amount format to avoid locale dependant issues","title":"7.9.8 - April 2018"},{"location":"release-notes/changelog-translations/#797-january-2018","text":"Changes in the distribution package |-> Command line tools in the bic directory changed from jar files to wrapper scripts |-> Dependencies directory renamed to lib |-> Removed the BUILD id timestamp from the jar files * MT to MX: sender and receiver address from header blocks mapped according to message direction","title":"7.9.7 - January 2018"},{"location":"release-notes/changelog-translations/#796-december-2017","text":"Added camt.054.001.06 to MT900 and MT910 Added camt.053.001.06 to MT940 and MT950 Added camt.052.001.06 to MT941 and MT942 Added pacs.009.001.06 to MT202 and MT202 COV Added pacs.008.001.06 to MT103 Added xsys.003.001.01 to MT019 Added xsys.012.001.01 to MT019 Added MT300 to fxtr.014.001.03 Performance enhancement: comprehensive use of relative paths to optimize content selection. Performance enhancement: mappings migrated from docname to xml to avoid paths conversion in engine. MX to MT: Fixed generation of fields with letter option D (such as 52D) when only name & address was present as content Added plugable PathAdapter to customize MX paths used in translations","title":"7.9.6 - December 2017"},{"location":"release-notes/changelog-translations/#795-december-2017","text":"Performance enhancement: static methods for internal processing, reduced path conversion Individual precondition checks made private in favor of the global preconditionsChecks API","title":"7.9.5 - December 2017"},{"location":"release-notes/changelog-translations/#794-november-2017","text":"JRE requirement backported to Java 1.6 Added xsys.002.001.01 to MT012","title":"7.9.4 - November 2017"},{"location":"release-notes/changelog-translations/#793-october-2017","text":"Fixed MT548 to MX: fixed mappings for ProcessingStatus Fixed MT586 to MX: mappings with invalid amounts sequence B5c changed to B5b MT564 and 566 to MX: fixed mapping for currency component in field 92J Added MT568 to seev.031.002.06 Added MT564 to seev.031.002.06 and seev.039.002.06 Added MT019 to xsys.003.001.01 and xsys.012.001.01 Added MT012 to xsys.002.001.01 Added MT202 and MT202 COV to pacs.009.001.06 Added MT103 and MT103 STP to pacs.008.001.06 MT to MX: fixed mapping header for sender and receiver addresses in output (incoming) messages MT to MX: replaced fixed data in message creation date time with current ISO time stamp MT940 to camt.053 and MT941/MT942 to camt.052: fixed translation for field 86 repetitions into additional entries information MT101 to pain.001: fixed translation for field 23E repetitions MT900 and MT910 to camt.054: fixed translation for field 72 repetitions Added MT941 and MT942 to camt.052.001.06 Added MT940 and MT950 to camt.053.001.06 Added MT900 and MT910 to camt.054.001.06","title":"7.9.3 - October 2017"},{"location":"release-notes/changelog-translations/#792-august-2017","text":"semt.020.02.01 to MTs 508, 545, 547, 578: changed default amount XXX99999999999999 to locale currency and 0 sese.020.002.01 and semt.013.002.01 to MT524 fixed generation of LINK sequences seev, semt, sese, setr to MT5xx: fixed generation of field 36B with quantity of financial instrument semt.020.002.01 to MT578: changed translation to generate the alleged instruction indicator (:22H::PAYM) in sequence B with codeword FREE instead of APMT to be compliant with MT semantic 283 pain.001.001.03 to MT101: fixed mapping for multiline field 77B and fixed MX paths when checking the available payment information instances setr.006.002.01 and setr.012.002.01 to MT515: fixed mapping for multiline field 70C semt and sese to MTs 544, 545, 546, 547 and 548: added link sequence with RELA to be compliant with MT semantic rules 73 semt.020.002.01 to MTs 535, 536, 537, 538 and 586: changed translations to set Activity Flag (field :17B:ACTI) to 'N' to be compliant with MT semantic rules 256, 266 and 267 semt.020.002.01 to MT508 and sese.020.002.01 to 524: changed translations to be compliant with MT semantic rule 281 MX to MT: fixed collapsing data in output MT, due to bug in handling repeat predicates from MX path MX to MT: fixed generic bug when creating fieldset with multiple letter options MX to MT: general mappings fixes for MX categories seev, semt, sese and setr Generic fix for proper handling of repetitive fields/elements in target message MX to MT: fixed bug when creating fieldset with multiple letter options MX to MT: fixed mappings translations for seev, semt, sese and setr","title":"7.9.2 - August 2017"},{"location":"release-notes/changelog-translations/#79-may-2017","text":"SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX) Removed false positive warning for invalid namespace in header when the header was actually empty","title":"7.9 - May 2017"},{"location":"release-notes/changelog-translations/#789-may-2017","text":"Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"7.8.9 - May 2017"},{"location":"release-notes/changelog-translations/#783-jul-2016","text":"If GrpHdr is present when converting from MX to MT, header BICs are set from it Internal migration from MxNode to XmlNode from SDK","title":"7.8.3 - Jul 2016"},{"location":"release-notes/changelog-validation/","text":"Prowide Integrator Validation - CHANGELOG 9.4.24 - June 2024 (PW-1845) Added an option in the RITS (HVCS) validation engine to opt-in strict mode validation (rules not checked by the HVCS portal) 9.4.23 - May 2024 (PW-1845) Added new RITS (HVCS) validator for pacs.004 9.4.22 - April 2024 (PW-1809) Added a new optional SchemaCache to the validation engine configuration to optimize the MX validation process 9.4.21 - April 2024 (PW-1842) Remove System.exit() call from deprecated class to avoid false positive vulnerability report 9.4.20 - February 2024 (PW-1761) Fixed error message for E92 on MT 545 and 547 Replaced generic KNN errors with specific codeword errors for designated fields such as T03, T04, T20, T35, etc... 9.4.19 - January 2024 (PW-1752) Added new API method 'validateTag' in order to allow to validate singe tags/fields without the need to build a full message (PW-1743) Remove usage of deprecated SafeXMLUtils methods Added field validation rule for pattern used in MT 097 field 109 9.4.18 - January 2024 (PW-1739) Modified the validation of field 23 in order to match the specification for MT102/MT103/MT305/MT601 9.4.17 - January 2024 Disabled 'Missing checksum field CHK (Z04)' block 5 validation because the checksum algorithm is proprietary by SWIFT and not available in the library API 9.4.16 - December 2023 (PW-1732) Enhanced the semantic 292 to also report the error for MT541 when the sequence E3 is missing 9.4.15 - December 2023 (PW-1666) Updated T13 validation logic in order to avoid false positives when validating MTs n92/n95/n96 9.4.14 - December 2023 (PW-1708) Fix concurrency issue with BICDirectory in semantic 257 and 5 implementations Added missing implementation for SCORE UG rules in MT798<700> 9.4.13 - November 2023 (PW-1697) Changed field 29O validation to be compatible with the field model changes 9.4.12 - November 2023 (PW-1691) CBPR+: NPE fix in the validation of the specific business service for each message type Minor fix in the validation of field 29O 9.4.11 - November 2023 (PW-1691) CBPR+ fixed validation of specific business service for each message type (version could vary depending on the specific message type) 9.4.10 - November 2023 (PW-1675) Fixed specific validations for SCORE messages in SRU2023 9.4.9 - October 2023 Updated the default ISO 20022 external code set XSD resource to the 2Q2023_ExternalCodeSets_v1.xsd release 9.4.8 - October 2023 MT370 and MT670 messages are now verified to have a size less than 10,000 9.4.7 - October 2023 (PW-1653) MT671 message is now verified to have a size less than 10,000 9.4.6 - September 2023 (PW-1613) fixed validation of field 44J narrative to enable 65 characters after the mandatory starting slash 9.4.5 - September 2023 (PW-1628) fixed validation of new Field 44A, 44B, 44E and 44F enabling multilines since they now use character 'z' 9.4.4 - September 2023 (PW-1478) fixed validation of new Field 44J 9.4.3 - September 2023 (PW-1480) More accurate implementation of semantic rule C25 (MTn92): field 79 or at least any fields from the original message (or both) must be present 9.4.2 - August 2023 (PW-1472) Fixed validation of 23X in MT767 (PW-1431) CBPR+: Implemented UG validation for CBPR+ 2023 messages (PW-1448) Fixed size validation for field 24G (PW-1431) CBPR+: Implemented UG validation for CBPR+ 2023 messages Added CROSS RULES validation for new CBPR+ 2023 messages 9.4.1 - June 2023 ValidationEngine add explicit API to validate the MX Business Application Header version 3 9.4.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 9.3.18 - June 2023 Fixed field 79 /REJT/ or /RETN/ validation of lines containing /TEXT/ narrative 9.3.17 - May 2023 (PW-1373) Minor fix in semantic validation for MT 798<720> 9.3.16 - May 2023 (PW-1377) Fixed NPE validating semantic rule 2 in MT 798_750 9.3.15 - May 2023 (PW-1373) MT SCORE 798<720>: Fixed codewords and rules for fields 40B and 41a (PW-1367) Added MT SCORE 798 sub-message types: 722_LC_C2B, 726_LC_C2B, 735_LC_C2B, 770_LC_C2B, 772_LC_C2B (PW-1359) Added missing T47 problem properties 9.3.14 - April 2023 MX validation: Added a general rule to check the maximum bytes allowed for the message 9.3.13 - February 2023 (PW-1206) Added message model for the MT SCORE subtypes 707/708/710/711/720/721/732/734/750 (PW-1198) Added validation for MT SCORE subtype 767 - Sequence B optional for 22A ISCA or ICCA 9.3.12 - January 2023 (PW-1154) Enhanced block 2 input validation; when priority is \"S\" (System) delivery monitoring and obsolesce period are not allowed (PW-1150) Added validation for MT SCORE subtypes 731/736/748/753/755/757/771/773 9.3.11 - December 2022 Removed the org.mozilla:rhino dependency 9.3.10 - November 2022 Minor backward compatibility fix in the ValidationConfiguration IBICDirectory initialization 9.3.9 - November 2022 Updated Apache Commons Text dependency to 1.10 to fix reported CVE (PW-1097) Fixed BIC validation against directory in CBPR+ messages (PW-1090) Enhanced validation of field 11T in SCORE messages, with specific check for the allowed sub-message type (PW-1085) Moved the custom BIC directory implementation setter from the SDK singleton configuration to the ValidationConfiguration 9.3.8 - October 2022 Code enhancements review 9.3.7 - October 2022 (PW-1074) MT568: fixed typo in qualifier name \"PTNI\" (PW-1071) MX cross-element rules are not applied when validating a custom schema, such as SIC4 (PW-1064) Fallback option to system classloader in resource loading SRU2022 update review: MT540 Removed field 99C SRU2022 update review: MT548 Added field 98C::SCTS SRU2022 update review: Field 35C changed validation to 9.3.6 - September 2022 Added support for MUG validations (CLSB and AU/PDS) 9.3.5 - September 2022 MT structure validation: enhanced report of missing required fields, adding the path of sequences when applicable MT structure validation: enhanced report of unexpected fields, when the possible cause is the fields ordering 9.3.4 - August 2022 Permanently replaced the legacy ValidationEngine.Configuration inner class by the ValidationConfiguration MT structure validation refactor to decommission the need for the Rhino dependency 9.3.3 - August 2022 (PW-1015) Added validation for sub-message types 700, 701 and 774 (SCORE) (PW-1007) Changed the AppHdr message definition against Document namespace validation to be more flexible, allowing subtypes such as \"CORE\" 9.3.2 - August 2022 PW-1007: Changed the AppHdr message definition against Document namespace validation to be more flexible, allowing subtypes such as \"CORE\" Implemented cross-element rules for pacs.004.001.10 and 11 Implemented cross-element rules for pain.001.001.10 and 11 Implemented cross-element rules for pain.002.001.10, 11 and 12 Implemented cross-element rules for camt.029.001.10 and 11 Added internal loops API to MTs: 110, 201, 203, 210, 410, 412, 420, 422, 450, 456, 604, 605, 801, 920, 973 (PW-968) Field 72: fixed validation of optional text after INSTR codes, that cannot be a complete set of blanks 9.3.1 - July 2022 (PW-968) Field 72: fixed validation of optional text after INSTR codes, that cannot be a complete set of blanks (PW-963) Fixes message length validation rule to compute also CRLF characters (PW-931) Added a field check for unexpected slash separator, in fields having an optional second component separated by slash (PW-867) Enhanced validation of party fields starting with /C/ or /D/ to avoid false negative errors on /D /C prefixes in the account Fixed SRU2022 changes in semantic rules 258 and 267 MT semantic validations minor fixes and enhancements Implemented cross-element rules for newer versions of camt.052 Implemented cross-element rules for newer versions of camt.053 Implemented cross-element rules for newer versions of camt.054 Implemented cross-element rules for newer versions of camt.056 Implemented cross-element rules for newer versions of camt.057 Implemented cross-element rules for newer versions of camt.060 Implemented cross-element rules for newer versions of pacs.010 Implemented cross-element rules for: Pacs.008 v9 & v10 (standard and STP), pacs.009 v9 & v10 9.3.0 - May 2022 SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.2.31 - May 2022 (PW-813) Internal enhancement to fix CVE Deprecation API review 9.2.30 - May 2022 MT semantic rules review and minor fixes MX cross-element checks review and enhancements 9.2.29 - May 2022 MX cross-element checks review and enhancements 9.2.28 - April 2022 Fixed MX cross-element checks Changed the ValidationResult to have the valid flag as transient field, set dynamically depending on the problems list size Added missing validations for CBPR+ pacs.009 9.2.27 - April 2022 CBPR+ UG validation fixes 9.2.26 - March 2022 (PW-882) SCORE 798_760 fixed validation of sequence B which is optional if purpose of message is ICCO or ISCO MT104: Fixed validation problem description in semantic rule 96 9.2.25 - March 2022 CBPR+ validation: apply schema from Document namespace when AppHdr message type does not match pacs.002.001.10: Implemented cross-element rules, and CBPR+ UG rules pain.002.001.10: Implemented cross-element rules, and CBPR+ UG rules 9.2.24 - March 2022 pacs.010.001.03: Implemented cross-element rules, and CBPR+ UG rules camt.060.001.05: Implemented cross-element rules, and CBPR+ UG rules pain.001.001.09: Implemented cross-element rules, and CBPR+ UG rules 9.2.23 - March 2022 Fixed error description in MX validation (cross element checks and CBPR+ rules) MX cross element validation fixes (X00420) 9.2.22 - March 2022 Enhanced the CBPR+ AppHdr validation with constraints from CBPR+ restricted BAH v2 schema 9.2.21 - March 2022 (PW-861) Fixed validation of fields 23X, 21H, 77B (MT734) and 98K that was too strict; slash character is allowed in the component using x character set 9.2.20 - February 2022 (PW-856) GPI: Fixed misleading error description in field 111 validation (PW-835) GPI: Field 111 is optional in MT199 even for GPI members Fixed inconsistency in the ValidationResult valid flag returned by the CbprValidationEngine Fixed MX cross-element validations when too elements cannot be present together, but may both be absent 9.2.19 - February 2022 Updated the default ISO 20022 external code set XSD to the February 2022 update camt.029.001.09: Implemented cross-element rules, and CBPR+ UG rules camt.052.001.08: Implemented cross-element rules, and CBPR+ UG rules camt.053._001.08: Implemented cross-element rules, and CBPR+ UG rules camt.056.001.08: Implemented cross-element rules, and CBPR+ UG rules camt.057.001.06: Implemented cross-element rules, and CBPR+ UG rules pacs.002.001.10: Implemented cross-element rules, and CBPR+ UG rules pacs.004.001.09: Implemented cross-element rules, and CBPR+ UG rules Completed UG rules for CBPR+ pacs.008 and pacs.009 variants (COV, STP, ADV) 9.2.18 - February 2022 (PW-837) In MT message length validation, remove line CRLF when computing the message size 9.2.17 - January 2022 (PW-835) Fixed validation of GPI field 111 (block3) expected values per message type 9.2.16 - January 2022 (PW-833) Fixed mandatory field 77E in MTn98 Added UG implementation for CBPR+ pacs.008 STP and pacs.009 ADV/COV 9.2.15 - January 2022 SCORE messages semantic validations review 9.2.14 - January 2022 (PW-819-820) SCORE message MT798_760 validation fixes Added UG implementation for CBPR+ camt.054 Implemented cross-element rules for camt.054.001.08 Added validation for MX match between AppHdr message identifier and Document namespace 9.2.13 - January 2022 (PW-815) Fixed validation of field 12H (SCORE) where narrative is optional MT530 validation: Fixed semantic 237 rule, where subsequence C1 is repetitive Added UG implementation for CBPR+ pacs.009 Implemented cross-element rules for pacs.009.001.08 9.2.12 - December 2021 Added a specific CbprValidationEngine class to validate CBPR+ messages Added UG implementation for CBPR+ pacs.008 Implemented cross-element rules for pacs.008.001.08 Added com.prowidesoftware.integrator.validation as automatic module name in the MANIFEST for JPMS support 9.2.11 - December 2021 (PW-799) fixed validation of semantic rule 199 in MT564 9.2.10 - December 2021 (PW-780) Added ValidationConfiguration#setGpiMember to override the general static SdkConfiguration#setGpiMember (PW-764) Fixed error description in field 119 (block 3) validation 9.2.9 - November 2021 (PW-772) Enable empty lines in MT568 field 70F as it is exceptionally allowed in the ISO 15022 usage guidelines In Mx IBAN validation added specific error code D00003 9.2.8 - November 2021 (PW-764) Reviewed validation of field 119 (block 3) (PW-703) Clearer validation results for MT block 2 with invalid identifier Added IBAN validation (including local account format) for MX elements containing IBAN numbers Added optional IBAN validation for MT messages, for specific fields where IBAN validation is explicitly requested by configuration MX validation: renamed proprietary error codes for invalid currency and country codes by standard codes D00004 and D00005 Fixed validation of letter options in B/98a 9.2.7 - October 2021 Added validation of block 2 Output (only Input was validated before, while Output was ignored) Fixed validation of value for Field 26A ( ) 9.2.6 - October 2021 (PW-705) Added validation of mandatory CHK in block 5 when the trailer block is present (PW-703) More verbose MT headers validation (PW-677) MT670, MT671: fixed implementation of semantic check 112 (D12) 9.2.4 - September 2021 (PW-664) Parser enhancement to detect LF before block identifier as validation problem (not exception) 9.2.3 - August 2021 Added german translation for validation problems 9.2.2 - August 2021 (PW-599) MT564: Minor scheme fix, 92a TAXR and WITL can be repeated in CASHMOVE (E2) MT548: Minor scheme fix, added letter option \"C\" in field \"98C:SCTS\" in sequence \"C1a1B1\" (PW-578) Fixed SAX logging with misleading parse errors 9.2.1 - June 2021 (PW-536) Replaced deprecated API in the MX validation (PW-536) Fixed misleading typo in semantic E94 error description (PW-517) Removed the actual licensed BICs information from the unlicensed error description in the validator 9.2.0 - May 2021 SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) More accurate structure problems reporting, with a customizable lookahead for sequence resynchronization after a field partial match Enhanced unexpected fields problem reporting, in some situations it used to trigger also misleading errors about the unexpected field repetitions 9.1.16 - April 2021 Added support for ISO 20022 external code set validations Externalized the validation engine configuration into a ValidationConfiguration class (PW-517) Removed the actual licensed BICs information from the unlicensed error description in the validator 9.1.15 - April 2021 (PW-460) Divided the internal schemas package into packages by category to allow trimming the jar by use 9.1.14 - April 2021 (PW-500) Fixed validation of qualifiers when the component is optional Fixed qualifier error reporting in fields 41A and 41D Replaced generic error code KNN with specific code for each field, such as K41, K23, K92 9.1.13 - April 2021 (PW-508) Fixed validator pattern in field 98K 9.1.12 - April 2021 Enhanced MT structure error detection and reporting (missing and unexpected fields) Fixed validation of fields 12 and 27A in MT SCORE messages 9.1.11 - March 2021 Added semantic validation for available SCORE messages (PW-499) Fixed schemes for MT513, MT564 and MT566: invalid qualifier in field 69D 9.1.10 - March 2021 (PW-494) Fixed schemes for MT565 (sequence B can be repeated up to 1) and MT568 (sequence B is optional, not mandatory) 9.1.9 - March 2021 (PW-493) Fixed scheme for MT671, missing :22H::PRCD//PREF in Other Details sequence Added mtInSequenceResyncLookAhead parameter in the ValidationEngine#Configuration to control the error reporting accuracy Added mtEnhancedRepetitionProblemReportingMode parameter in the ValidationEngine#Configuration to switch off redundant field repetition related errors Removed T13 rule from MTn98 proprietary messages validation (only kept for n92, n95 and n96) Changed default toString in ValidationProblem to use the human-friendly error description 9.1.8 - December 2020 (PW-424) Fixed validation of mandatory field 111 (PW-398) Added check for expected values in field 111 (U14 error code) 9.1.7 - December 2020 License check review 9.1.6 - November 2020 Field validation changes in 83J, 86J, 50F and 59F are now parked until SRU2021 (only cat 5 changes are in force in SRU2020) 9.1.5 - November 2020 (PW-413) 564 added qualifier option SRDC in field 17B in sequence D 530 added qualifiers options BYIY and BDEF in field 22 in sequence B 530 added optional fields 90[A,B] and 19A BCAM in sequence C 565 minor fix in conditional qualifier check in field 92K in sequence C 9.1.4 - September 2020 In MTs 300, 305, 306, 320, 330, 340, 341 and 350 added a missing network rule validating the reference number in fields 22 and 22C against the message rate field Added internal BIC validation skip for SWIFT special BIC codes such as: TRCKCHZZ (GPI) and TRGTXEPM (Target) Fixed semantic check 254 to handle 23E field repetitions properly 9.1.3 - September 2020 Minor fix in semantic 204, 209 and 210 checks when the party identifier is only slashes 9.1.2 - August 2020 (PW-325) Added ValidationEngine.Configuration#addRegisteredBic to programmatically register valid BICs not available in the embedded BIC directory (PW-325) Enhanced de BIC directory validation to avoid false error for Test & Training BIC codes (query will match any equivalent production BIC) 9.1.1 - Jun 2020 Removed a false positive deprecation warning when configuring ignored validation codes 9.1.0 - May 2020 SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.0.2 - May 2020 Added validation of ISO business header version 2 (head.001.001.02) when found in a message Added a configuration in the ValidationEngine.Configuration to optionally disable ERI validation Added validation for ERI in fields 61, 72, 77A, 79 and 86, when ERI is present and depending on the message type Fixed amount validation when the whole number part is not present 9.0.1 - May 2020 Fixed validation of field 72 in MT760 9.0.0 - May 2020 Validation module extracted to its own jar in the distribution, with its own version from now on 8.0.9 - May 2020 Fixed scheme for 564, typo in MET2 and MET3 qualifiers 8.0.8 - April 2020 Fixed validation of field 50F party line, was accepting up to 34 characters instead of the 35 allowed limit for the field Enabled presence of field 121 in all payment messages (category 1 and 2) Added support to validate restricted ISO20022 for CBPR+ (PW-259) Fixed semantic 157 check, when amount is zero with decimals Fixed schemes for MT537 adn 458, in sequence PENDET required field is 99A and not 99B Enhanced error reporting for semantic checks: 41, 131, 132, 146 and 147 8.0.7 - March 2020 Added support to validate restricted ISO20022 for SIC (Swiss RTGS) MT548: Fixed repetitions of field 94 in sequence C1a1A1 MT537: Fixed structure for D1a1A1 MT537: Fixed sequence B2b where field 98 option EXSE is mandatory Fixed semantic check 256 affecting validation for message 535 and 536 8.0.6 - February 2020 Fixed T96 check in SB-LC function (affecting fields 22 and 22C) where alphanumeric order must give precedence to letters over numbers 8.0.4 - December 2019 Fixed resource bundle for MX messages when retrieved for specific locale Added convenient toJson with preformatted validaiton problem messages, to the ValidationResult DTO Fixed detection of invalid trailing empty lines in MT field values 8.0.3 - September 2019 (PW-185) Replaced custom error codes with SWIFT standard FIN error codes such as Hnn and Tnn Added new validation entry points for MX messages to use specific XSD schemas (useful to validate SEPA messages) Added missing field validations: T14, T49, T70, T75, T88 Fixed validation of conditional qualifier in field 93C in MT566 8.0.2 - August 2019 Fixed validation of conditional qualifier in field 93C in MT566 Fixed bin/validator CLI app that stopped reading input on the first line break Fixed occasional BIC truncation validating large MX messages 8.0.1 - July 2019 Enhanced the configuration to enable ignoring validation problems by specific key, by name or by type Fixed validation of BIC codes in MX when the BIC directory is disabled Fixed BIC not registered error reporting when validating MX messages Fixed semantic check 196 affecting MTs 362 8.0.0 - May 2019 JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Fixed semantic check 157 affecting MTs 320, 330 adn 620 7.10.9 - May 2019 Fixed SB-LC validation, affecting fields 22 and 22C (common reference); added the missing alphabetic sort check in the parties code and location Fixed lines count check in multiline fields with optional party identifier in first line (ex: 58D) 7.10.8 - March 2019 Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Fixed obfuscation to keep directories in jar 7.10.7 - January 2019 Added missing path when reporting invalid country code in MX Fixed duplicated error reporting when validating MX messages Added the XsdRegistry interface to allow overwriting the default schemas when validating MX messages Enhanced the MX error reporting to include the repetitive element index in the validation problem xPath Added support for custom MX validation rules Enhanced validation and error reporting for fields 50F and 59F Minor performance enhancement for validation process with exit on first error Added support in MX validation to optionally ignore XSD ERROR 7.10.6 - November 2018 Added ISO country code validation for CountryCode elements in MX messages Fixed GPI validation to NAK non-GPI messages with fields 121 or 111 Fixed GPI validation to NAK GPI-message with field 111 when the institution is not a GPI member Fixed error description for structure validation problem TOO_BIG Enabled the UETR validation for any message type, it is still mandatory for GPI messages only though (PW-103) Activated the UETR format validation also for output messages (received from SWIFT) Fixed semantic validation 201 affecting MT564 7.10.4 - September 2018 Bugfix validating empty first line in fields value Enhanced error reporting in BIC validation, including details of the BIC subfield where the validation problem is found Enhanced the BIC validation checking the country code within the BIC is a valid ISO country MX: Added BIC validation using the BIC directory (optional by configuration) for elements containing BIC codes MT: Added BIC validation using the BIC directory (optional by configuration) for the sender and receiver address in the headers 7.10.3 - July 2018 Added a specific PARSE_ERROR validation problem to report when the message has an invalid block structure Prevention of IllegalArgumentException when the hyphen is missing in the closing bracket of block 4 Added MX currency validation using ISO currencies from ISOUtils 7.10.2 - July 2018 Fixed spanish description of semantic E45 check Fixed component size check in validation of Field 59F 7.10.1 - May 2018 Added field 434 in block 3 validation 7.10.0 - April 2018 SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 7.9.8 - April 2018 Enhanced validation of IBAN numbers verifying the check digits and the custom account number per country (BBAN) MT306: message scheme fix, added the missing 57 ADJ optional field at the end of sequence L Minor fixes in semantic validation rule 40 and rule 122 7.9.7 - January 2018 Changes in the distribution package: Command line tools in the bic directory changed from jar files to wrapper scripts Dependencies directory renamed to lib Removed the BUILD id timestamp from the jar files Removed the BaseTestCase class from the public API to avoid Junit dependency Added ValidationProblem#printout to generate a human friendly printout of a validation problem list Updated dependency: org.mozilla 1.7R4 -> org.mozilla 1.7.7.2 7.9.6 - December 2017 Minor fix in semantic27 affecting malformed MT942 7.9.4 - November 2017 JRE requirement backported to Java 1.6 Fixed validation for field 77J: 50x[\u2019CRLF\u201950x]0-69 7.9.3 - October 2017 Added support to validate MX system messages (xsys category) Fixed currency validation (T52) in fields 60F, 62F, 64, 65 and 33B 7.9.2 - August 2017 Fixed T26 validation in fields 13B, 22W, 94B, 95a and 98K MT537 fixed qualifier validation for field 98a in transaction details sequence (C2) MT524 fixed implementation for rule 208 when several LINK sequences are present in the message MT545 and MT547: fixed validation for field set 98a in Trade Details sequence (B), qualifier ESET is mandatory while SETT is optional Fixed error code and message throw by semantic rule 267 Added more details when reporting semantic rule 266 errors. Added IsoUtils singleton to allow customization and exceptions for currency and country codes validation Currency and Country codes validation is now implemented using data from Java Currency and Locale Validation of maximum fraction digits per currency (semantic rule 3) is now implemented using data from Java Currency 7.9.1 - June 2017 Fixed semantic 167 for MT103 plan (not STP and not REMIT) MT801 first loop can be repeated Fixed semantic 282 affecting MT535 Fixed scheme for MT940 field 60[F,M] is now required 7.9 - May 2017 SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX) MT536: fixed false positive semantic 252 check, fixed qualifiers check in field 98a (sequence B1a2) MT575: transaction details sequence C2, field 98 with SETT or TRAD set as optional MT537: fixed false positive semantic 285 check MT576: additional information sequence C set as optional Fixed semantic rule 259 affecting MT517 link sequence check MT569: fixed incorrect definitions in sequence C1a1 (valuation details) MT506, 569 and 575: field 28E mandatory MT513; sequence A added TRAD qualifier to field 22F, sequence B1 (partial fill details) fields 98 and 94 are optional MT513 and 514: fixed letter option from H to F in field 22F:SETR in settlement details 7.8.9 - May 2017 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Fixed validation of fields 72 and 79 of a Rejected/Return message Renamed FieldProblem.REJT_RETN_0n to more specific errors: REJT_RETN_LINE_n, REJT_RETN_REASON_CODE, REJT_RETN_MREF, REJT_RETN_TREF, REJT_RETN_CHGS, REJT_RETN_TEXT Enhanced validation of user block 3, checking all fields are expected for the message type and checking fields order. Fixed NPE in semantic 119 affecting MTs 102 and 103 STP when IBAN component was not present Added a common type ValidationProblemKey implemented by all problem key enumerations Fixed false positive error validating field 59F when multiple address lines (line label 2) are defined Fixed false positive restriction field 37a second component Fixed scheme for MT505, added missing field 98A:AGRE in sequence A1 Enhanced MX validation to allow MX messages with bank-to-bank namespace declaration Fixed false positive semantic 293 validation for MT507 when sequence B1a1 was not present Fixed letter option in scheme for MT506, sequence D (Collateral Details) field 19 A -> B Fixed qualifier in scheme for MT506, sequence D (Collateral Details) DEAL-> COLL Fixed scheme for MT506, sequence B (Summary) field 95 is mandatory and field 19B only mandatory with qualifier COVA Fixed Semantic 82 implementation affecting MT104 and MT107 Fixed false positive case in Semantic 75, affecting MT104 Fixed validation of leading characters, colon (':') not allowed in second and subsequent lines except for fields 77E and 77T Fixed semantic 103 affecting MT535 7.8.8 - March 2017 Added support for nested Document elements when validating MX messages Removed invalid fields following linkages in GENL sequence Cleaner log in semantic rule 3 validation 7.8.7 - December 2016 Added check for validation flag (STP, REMIT, COV) in user header block Fixed missing semantic associations to MTs 700, 705, 707, 710, 720, 730, 732, 734, 740, 742, 747, 750, 752, 754, 756, 768, 768, 769, 800, 801, 802, 824 MT518 fixed fieldset for Field 70 MT330 fixed qualifier in Field 22 MT513 and MT514 Field 11 moved outside previous fieldset MT541 to MT547 Field 90[A,B] changed to fieldset. MT564 fixed fieldset items in Field93[B,C] MT565 to MT567 Sequence D, fixed field 13 MT609 and MT798_763 fixed qualifiers in Field 29 7.8.6 - November 2016 JRE requirement increased to Java 1.7 (only for Integrator SDK and modules, Core still works on 1.5) semantic 175 minnor fix affecting MT104 and MT107 when multiple sequence B are present 7.8.5 - October 2016 Minor fixes in semantic validations: 206 (used in MTs: 103, 564, 566), 279 (used in MTs: 549, 564, 565) MT564: Minor fixes in semantic validations: 199, 211, 224 MT564: field 93 UNBA instead of UMBA MT564: CAOPT sequence, field 92 INTP, missing conditional qualifier NILP MT564: SECMOVE sequence, field 90 PRPP, missing letter option K MT564: SECMOVE sequence, field 92 NEWO, missing letter option M MT564: CASHMOVE sequence, field 92 ESOF, missing letter options F and M MT564: CASHMOVE sequence, field 92 TXIN, missing letter option F MT564: CASHMOVE sequence, field 92 WITL, missing letter option R and its conditional qualifier eval MT564: fixed field 92J subfield ACTU INDI validation MT565: CAINST sequence, field 90 OFFR, missing letter option L MT566: CADETL sequence, field 92 BIDI missing letter option P MT566:CACONF sequence, field 69, removed invalid letter option J MT566: Fixed qualifier in field 13a to allow UNS MT566:SECMOVE sequence, field 90 OFFR, missing letter option L MT566:SECMOVE sequence, field 90 PRPP, missing letter option K MT566:SECMOVE sequence, field 92 NEWO, missing letter option M MT566:SECMOVE sequence, field 92 TAXC, removed invalid letter option K MT566:CASHMOVE sequence, field 92 TXIN, missing letter option F MT566:CASHMOVE sequence, field 90 PRPP, missing letter option K MT566:fixed field 92J subfield ACTU INDI validation MT567: CADETL sequence, field 35B, removed invalid qualifier check SAFE MT567: field19 changed to fieldset 7.8.4 - Oct 2016 Fixed JS expression in schemes for 564, 565, 566 and 620 Important enhancement in MX validation problem reporting, including full XPATH, line and column of errors. Fixed semantic 291 (affecting 540, 541, 544, 545) Fixed semantic 112 (affecting MTs 670 and 671) Fixed semantic 113 (affecting MTs 380, 381, 503, 504, 506, 670, 671) 7.8.3 - Jul 2016 Added support for changed currency in Belorussia from 974 (BYR) to 933 (BYN). Fixed semantic 210 affecting messages 103, 102, 104 and 107 7.8.2 - Jul 2016 Fixed schemes: definition of field 12A in FIA subsequences of MTs 54x Semantic 283 bugfix (used in MTs 307,503,504,505,506,536,537,548,578,586) 2016 June Added field repetition validation in block 3 2016 April Added detection of extra data in message content or blocks when validating a message 2016 February Fixed validation of min and max repetition in fieldsets, when the attributes are set only in the items 2016 January Fixed scheme 307, typo in semantic rules attribute Added API in SchemeField to retrieve qualifiers information from parsed scripting expressions 2015 December Fixed schemes for 600, 601, 604, 605, 606, 607, 608, 609, 620, wrong qualifier for field 26C 2015 November Fixed validation of repetitive sequence in MT940 2015 October Fixed validation for fields 129, 12A, 13B, 20E, 23A, 26N, 26P, 92C and 94D; removed restriction on amount of slashes because components use charset x where slash is allowed Fixed validation for fields 14G, 27A, 27, 28[D,E], 29[L,N], 38[G,H], 39[A,P], 68C, 69C, 70[C,D,E,G], 90F, 92R, 93B, 94E, 94G 95[Q,T,U,V] and 98F; added restriction on amount of slashes 2015 September Fixed scheme for MT567, removed invalid 25D field in sequence A 2015 August Fixed qualifiers validation scripting in xml schemas for MTs: 306, 360, 361, 362, 364, 365, 500, 501, 535, 564, 565, 566 Enhanced validation patterns naming for better consistency 2015 April Enhanced structure validation error reporting, when JS expressions are used to check conditional qualifiers. The new scheme validation rule generates a proper message indicating the expected and found qualifiers instead of a generic fail expression error. 2015 March Bugfix Field validations, new restriction, start of line character cannot be '-'. Bugfix MT535 subsequence B1a, it can be at most one and the scheme was allowing multiple repetitions 2015 February ValidationEngine enhancement in the default scheme to use, detecting automatically if a 102/103 is STP or if a 202/205 is COV Fixed validation for field 22S, was requiring a 35 characters fixed length for component 2, while the correct validation is up to 35 characters (not fixed) Added more restrictive party field validation when a slash is followed by a blank content, affecting fields 42a, 50a, 51a, 52a, 53a, 54a, 55a, 56a, 57a, 58a, 59a, 81a, 82a 83a, 84a, 85a, 86a, 87a, 88a, 89a, 91a, 96a SchemeValidationRule version 2: new version of structure validation for MT, with several enhancements and bug fixes over the previous version. Important performance enhancement in MT structure validation (30% in average, reaching a 60% for some message structures). Important enhancement in structure error reporting, errors are now more specific and detailed with more details. Better error localization, avoiding duplicated error field validation in some situations. Improvement in scheme's scripting validations, isolating script compile errors from unsatisfied logic conditions. Fixed scheme validation for MT300 that was throwing a false problems for some combination of subsequences E, E1 and E1a. 2015 January RuleManager: fixed loading of field rules, that was skipping incorrectly field validation to fields derived from fieldsets 2014 December Better error message format in BaseTestCase Fixed error message for E73 Review of semantic rules 85,86,198 ValidationEngine: Added API to validate from AbstractMT ValidationEngine: Added exclusive API to use when validating messages in strings or files (with swift format, not parsed objects) therefore detecting more error conditions AbstractTagValidationRule: Fixed validation that had a bug in special conditions, Output messages (received from swift) and with sender and receiver within the same institution 2014 November Bugfix in schemas 515, 536 Enhanced MT expression validation reporting, diferenciating invalid expressions, from runtime errors or failed expression evaluation. Bugfix. Fixed expressions in schemes xml for MT576 and MT568, replacing deprecated function call addQuaifiers by qualifier Bugfix. Added validation of T13 rule to MTs n98 2014 September Bugfix. Missing resource bundle for invalid BIC validation problem Added addVariable method to ValidationProblem Bugfix. Fields 95Q and 70C were restricted to maximum 3 lines, while 4 lines are compliant as well. Bugfix. Fixed XML for MT537, field 22H conditional qualifier STAN changed to STAT 2014 July Enhanced structure validation incorporating special field exceptions and required code words (standard PIII Fields Chapter 4) directly into the xml schemes configurations. Affected MTs: 102 STP, 103, 103 STP, 300, 303, 304, 305, 306, 320, 340, 341, 350, 360, 361, 362, 364, 365, 600, 601, 620, 920, 973 Enhanced structure validation error messages to separate unexpected fields problems reporting, from field qualifier problems or expression evaluation problems Enhanced field validation to avoid repetitive checks for empty content and/or empty lines Bugfix. MT306 optional field 12G changed to 12D and added missing field class Bugfix. SchemeXmlReader to properly set fieldset items' qualifiers and letter options when inherited from container fieldset Bugfix. Added null controls to several semantic validations to prevent NPE that would previously arise when applying semantic checks to messages with specific invalid structures Bugfix. Fixed XML for MT540, field 90 changed to fieldset 90 to allow qualifier validation for items Review and code clean of semantic rule 24, 52 SRU 2014. Affected MTs: 300, 304, 305, 306, 340, 341, 360, 361, 380, 381, 502, 506, 508, 509, 513, 514, 515, 518, 527, 530, 536, 537, 538, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 558, 564, 565, 566, 567, 568, 569, 575, 600, 601, 942 Added description and release attributes to Scheme Minor fix in MT300 sequences structure, B1 and B2 inside B, and named D's subsequence as D1 Bugfix. MT300 optional field 17A changed to optional field 77A (field number was wrong) Bugfix. MT514 fixed missing mandatory fields 36B and 35B between end of sequence B1 and start of sequence B2 Bugfix. MT515 fixed field 90[A,B] with qualifier DEAL at sequence C, changed from optional to mandatory (minRepetition was wrong) 2014 May Review and code clean of semantic rule 184 Review and code clean of semantic rule 176 Review and code clean of semantic rule 152, 153, 154 Performance enhancements: execution speed reduced by approx 71% measured in global test suite 2014 April Review and code clean of semantic rule 131, 253, 133, 135 Fixed semantic 116 rule incorrectly interpreting sequence C absence for MT306 2014 March MT564: Added missing option K to field 90 in sequence E2 cash movements Review and code clean of semantic rule 92, 95 Review and code clean of semantic rule 66, 67, 68 ,78, 84, 93 Review and code clean of semantic rule 61, 57, 58, 62 Added validation problems translation to Italian. Bugfix. Fixed invalid check for X in 8th position for logical terminals without A, B, C identifier Bugfix. Fixed Block1 validation, allowing Logical terminal without the A, B, C identifier (11 characters length) Bugfix. Field validation was not accepting 999 as a valid MT number (example field 11R) 2014 February Bugfix. Affected MTs:n92, n95, n96, n98. Fixed isolation of fields copied from original message from the fields of the message being validated Bugfix semantic rule 31 that was throwing false positives when field 79 was included in the appended original message's fields Initial addition of FieldFilter and FieldFilterUtils API Maintenance review of semantic rule 71 Review and code clean of semantic rule 211, 221, 262 Added API to BaseTestCase Review and code clean of semantic rule 209 Review and code clean of semantic rule 201, 202, 206 Bugfix. Affected MTs: 564. Fixed semantic rule 71 that was throwing IOB exceptions for some valid combinations of fields 93B Bugfix. Affected MTs: 568, 569, 574, 575, 576, 578, 586, 670, 671. Fixed xml schemes, changing the invalid scripting method conditionalQualifiers to conditionalQualifier Review and code clean of semantic rule 203, 206, 209, 221 Review and code clean of semantic rule 201, 202 Bugfix. Affected MTs: 305. Fixed false positive missing field errors when the message ends with nested optional subsequences with inner mandatory fields Review and code clean of semantic rule 192, 72, 199 Review and code clean of semantic rule 71 Review and code clean of semantic rules impacting MT305 Added a code generation tool that can be run from command line to create custom version of Field and MT classes Added a command line application to use the messages validation in standalone mode, validating messages from file system 2014 January Added validation rules for fields belonging to system messages (i.e. 451) Adding constants to Literals class to avoid usage of hardcoded strings and cleaner code with static imports Bugfix. Affected MTs: 207. Fixed maximum repetitions of sequence B from 1 to unlimited Maintenance(Review and performance updates) semantic rule #167, #54, #55 Maintenance(Review and performance updates) semantic rule #161 Maintenance(Review and performance updates) semantic rule #168, #246, #254 Added filter() to AbstractSemanticValidationRule Maintenance(Review and performance updates) semantic rule #162, #166 Added BaseTestCase.assertValid(String) Fixed issue in semantic rule 154 which did not consider properly B sequences Maintenance(Review and performance updates) semantic rule #160, #164 2014-01-15 Fixed issue in semantic rule 77 affecting MTs 730, 768 and 769 2013 October Maintenance(Review and performance updates) semantic rule #44, #45, #46, $47, #48, #51, #53 Maintenance(Review and performance updates) semantic rule #106, #108, #30, #40, #42 Review and performance updates on S102 Refactored max msg length validation to use enum in structure problem for reporting errors Review and performance updates on S79 2013 September SRU 2013 update Fixed incomplete validation for field 77E 2013 March Bugfix: fixed typo at field 22H in MT380, BUYI->BUY1 2012 June Added API to specify locale on ValidationProblem.getMessage method","title":"Prowide Integrator Validation"},{"location":"release-notes/changelog-validation/#prowide-integrator-validation-changelog","text":"","title":"Prowide Integrator Validation - CHANGELOG"},{"location":"release-notes/changelog-validation/#9424-june-2024","text":"(PW-1845) Added an option in the RITS (HVCS) validation engine to opt-in strict mode validation (rules not checked by the HVCS portal)","title":"9.4.24 - June 2024"},{"location":"release-notes/changelog-validation/#9423-may-2024","text":"(PW-1845) Added new RITS (HVCS) validator for pacs.004","title":"9.4.23 - May 2024"},{"location":"release-notes/changelog-validation/#9422-april-2024","text":"(PW-1809) Added a new optional SchemaCache to the validation engine configuration to optimize the MX validation process","title":"9.4.22 - April 2024"},{"location":"release-notes/changelog-validation/#9421-april-2024","text":"(PW-1842) Remove System.exit() call from deprecated class to avoid false positive vulnerability report","title":"9.4.21 - April 2024"},{"location":"release-notes/changelog-validation/#9420-february-2024","text":"(PW-1761) Fixed error message for E92 on MT 545 and 547 Replaced generic KNN errors with specific codeword errors for designated fields such as T03, T04, T20, T35, etc...","title":"9.4.20 - February 2024"},{"location":"release-notes/changelog-validation/#9419-january-2024","text":"(PW-1752) Added new API method 'validateTag' in order to allow to validate singe tags/fields without the need to build a full message (PW-1743) Remove usage of deprecated SafeXMLUtils methods Added field validation rule for pattern used in MT 097 field 109","title":"9.4.19 - January 2024"},{"location":"release-notes/changelog-validation/#9418-january-2024","text":"(PW-1739) Modified the validation of field 23 in order to match the specification for MT102/MT103/MT305/MT601","title":"9.4.18 - January 2024"},{"location":"release-notes/changelog-validation/#9417-january-2024","text":"Disabled 'Missing checksum field CHK (Z04)' block 5 validation because the checksum algorithm is proprietary by SWIFT and not available in the library API","title":"9.4.17 - January 2024"},{"location":"release-notes/changelog-validation/#9416-december-2023","text":"(PW-1732) Enhanced the semantic 292 to also report the error for MT541 when the sequence E3 is missing","title":"9.4.16 - December 2023"},{"location":"release-notes/changelog-validation/#9415-december-2023","text":"(PW-1666) Updated T13 validation logic in order to avoid false positives when validating MTs n92/n95/n96","title":"9.4.15 - December 2023"},{"location":"release-notes/changelog-validation/#9414-december-2023","text":"(PW-1708) Fix concurrency issue with BICDirectory in semantic 257 and 5 implementations Added missing implementation for SCORE UG rules in MT798<700>","title":"9.4.14 - December 2023"},{"location":"release-notes/changelog-validation/#9413-november-2023","text":"(PW-1697) Changed field 29O validation to be compatible with the field model changes","title":"9.4.13 - November 2023"},{"location":"release-notes/changelog-validation/#9412-november-2023","text":"(PW-1691) CBPR+: NPE fix in the validation of the specific business service for each message type Minor fix in the validation of field 29O","title":"9.4.12 - November 2023"},{"location":"release-notes/changelog-validation/#9411-november-2023","text":"(PW-1691) CBPR+ fixed validation of specific business service for each message type (version could vary depending on the specific message type)","title":"9.4.11 - November 2023"},{"location":"release-notes/changelog-validation/#9410-november-2023","text":"(PW-1675) Fixed specific validations for SCORE messages in SRU2023","title":"9.4.10 - November 2023"},{"location":"release-notes/changelog-validation/#949-october-2023","text":"Updated the default ISO 20022 external code set XSD resource to the 2Q2023_ExternalCodeSets_v1.xsd release","title":"9.4.9 - October 2023"},{"location":"release-notes/changelog-validation/#948-october-2023","text":"MT370 and MT670 messages are now verified to have a size less than 10,000","title":"9.4.8 - October 2023"},{"location":"release-notes/changelog-validation/#947-october-2023","text":"(PW-1653) MT671 message is now verified to have a size less than 10,000","title":"9.4.7 - October 2023"},{"location":"release-notes/changelog-validation/#946-september-2023","text":"(PW-1613) fixed validation of field 44J narrative to enable 65 characters after the mandatory starting slash","title":"9.4.6 - September 2023"},{"location":"release-notes/changelog-validation/#945-september-2023","text":"(PW-1628) fixed validation of new Field 44A, 44B, 44E and 44F enabling multilines since they now use character 'z'","title":"9.4.5 - September 2023"},{"location":"release-notes/changelog-validation/#944-september-2023","text":"(PW-1478) fixed validation of new Field 44J","title":"9.4.4 - September 2023"},{"location":"release-notes/changelog-validation/#943-september-2023","text":"(PW-1480) More accurate implementation of semantic rule C25 (MTn92): field 79 or at least any fields from the original message (or both) must be present","title":"9.4.3 - September 2023"},{"location":"release-notes/changelog-validation/#942-august-2023","text":"(PW-1472) Fixed validation of 23X in MT767 (PW-1431) CBPR+: Implemented UG validation for CBPR+ 2023 messages (PW-1448) Fixed size validation for field 24G (PW-1431) CBPR+: Implemented UG validation for CBPR+ 2023 messages Added CROSS RULES validation for new CBPR+ 2023 messages","title":"9.4.2 - August 2023"},{"location":"release-notes/changelog-validation/#941-june-2023","text":"ValidationEngine add explicit API to validate the MX Business Application Header version 3","title":"9.4.1 - June 2023"},{"location":"release-notes/changelog-validation/#940-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"9.4.0 - May 2023"},{"location":"release-notes/changelog-validation/#9318-june-2023","text":"Fixed field 79 /REJT/ or /RETN/ validation of lines containing /TEXT/ narrative","title":"9.3.18 - June 2023"},{"location":"release-notes/changelog-validation/#9317-may-2023","text":"(PW-1373) Minor fix in semantic validation for MT 798<720>","title":"9.3.17 - May 2023"},{"location":"release-notes/changelog-validation/#9316-may-2023","text":"(PW-1377) Fixed NPE validating semantic rule 2 in MT 798_750","title":"9.3.16 - May 2023"},{"location":"release-notes/changelog-validation/#9315-may-2023","text":"(PW-1373) MT SCORE 798<720>: Fixed codewords and rules for fields 40B and 41a (PW-1367) Added MT SCORE 798 sub-message types: 722_LC_C2B, 726_LC_C2B, 735_LC_C2B, 770_LC_C2B, 772_LC_C2B (PW-1359) Added missing T47 problem properties","title":"9.3.15 - May 2023"},{"location":"release-notes/changelog-validation/#9314-april-2023","text":"MX validation: Added a general rule to check the maximum bytes allowed for the message","title":"9.3.14 - April 2023"},{"location":"release-notes/changelog-validation/#9313-february-2023","text":"(PW-1206) Added message model for the MT SCORE subtypes 707/708/710/711/720/721/732/734/750 (PW-1198) Added validation for MT SCORE subtype 767 - Sequence B optional for 22A ISCA or ICCA","title":"9.3.13 - February 2023"},{"location":"release-notes/changelog-validation/#9312-january-2023","text":"(PW-1154) Enhanced block 2 input validation; when priority is \"S\" (System) delivery monitoring and obsolesce period are not allowed (PW-1150) Added validation for MT SCORE subtypes 731/736/748/753/755/757/771/773","title":"9.3.12 - January 2023"},{"location":"release-notes/changelog-validation/#9311-december-2022","text":"Removed the org.mozilla:rhino dependency","title":"9.3.11 - December 2022"},{"location":"release-notes/changelog-validation/#9310-november-2022","text":"Minor backward compatibility fix in the ValidationConfiguration IBICDirectory initialization","title":"9.3.10 - November 2022"},{"location":"release-notes/changelog-validation/#939-november-2022","text":"Updated Apache Commons Text dependency to 1.10 to fix reported CVE (PW-1097) Fixed BIC validation against directory in CBPR+ messages (PW-1090) Enhanced validation of field 11T in SCORE messages, with specific check for the allowed sub-message type (PW-1085) Moved the custom BIC directory implementation setter from the SDK singleton configuration to the ValidationConfiguration","title":"9.3.9 - November 2022"},{"location":"release-notes/changelog-validation/#938-october-2022","text":"Code enhancements review","title":"9.3.8 - October 2022"},{"location":"release-notes/changelog-validation/#937-october-2022","text":"(PW-1074) MT568: fixed typo in qualifier name \"PTNI\" (PW-1071) MX cross-element rules are not applied when validating a custom schema, such as SIC4 (PW-1064) Fallback option to system classloader in resource loading SRU2022 update review: MT540 Removed field 99C SRU2022 update review: MT548 Added field 98C::SCTS SRU2022 update review: Field 35C changed validation to","title":"9.3.7 - October 2022"},{"location":"release-notes/changelog-validation/#936-september-2022","text":"Added support for MUG validations (CLSB and AU/PDS)","title":"9.3.6 - September 2022"},{"location":"release-notes/changelog-validation/#935-september-2022","text":"MT structure validation: enhanced report of missing required fields, adding the path of sequences when applicable MT structure validation: enhanced report of unexpected fields, when the possible cause is the fields ordering","title":"9.3.5 - September 2022"},{"location":"release-notes/changelog-validation/#934-august-2022","text":"Permanently replaced the legacy ValidationEngine.Configuration inner class by the ValidationConfiguration MT structure validation refactor to decommission the need for the Rhino dependency","title":"9.3.4 - August 2022"},{"location":"release-notes/changelog-validation/#933-august-2022","text":"(PW-1015) Added validation for sub-message types 700, 701 and 774 (SCORE) (PW-1007) Changed the AppHdr message definition against Document namespace validation to be more flexible, allowing subtypes such as \"CORE\"","title":"9.3.3 - August 2022"},{"location":"release-notes/changelog-validation/#932-august-2022","text":"PW-1007: Changed the AppHdr message definition against Document namespace validation to be more flexible, allowing subtypes such as \"CORE\" Implemented cross-element rules for pacs.004.001.10 and 11 Implemented cross-element rules for pain.001.001.10 and 11 Implemented cross-element rules for pain.002.001.10, 11 and 12 Implemented cross-element rules for camt.029.001.10 and 11 Added internal loops API to MTs: 110, 201, 203, 210, 410, 412, 420, 422, 450, 456, 604, 605, 801, 920, 973 (PW-968) Field 72: fixed validation of optional text after INSTR codes, that cannot be a complete set of blanks","title":"9.3.2 - August 2022"},{"location":"release-notes/changelog-validation/#931-july-2022","text":"(PW-968) Field 72: fixed validation of optional text after INSTR codes, that cannot be a complete set of blanks (PW-963) Fixes message length validation rule to compute also CRLF characters (PW-931) Added a field check for unexpected slash separator, in fields having an optional second component separated by slash (PW-867) Enhanced validation of party fields starting with /C/ or /D/ to avoid false negative errors on /D /C prefixes in the account Fixed SRU2022 changes in semantic rules 258 and 267 MT semantic validations minor fixes and enhancements Implemented cross-element rules for newer versions of camt.052 Implemented cross-element rules for newer versions of camt.053 Implemented cross-element rules for newer versions of camt.054 Implemented cross-element rules for newer versions of camt.056 Implemented cross-element rules for newer versions of camt.057 Implemented cross-element rules for newer versions of camt.060 Implemented cross-element rules for newer versions of pacs.010 Implemented cross-element rules for: Pacs.008 v9 & v10 (standard and STP), pacs.009 v9 & v10","title":"9.3.1 - July 2022"},{"location":"release-notes/changelog-validation/#930-may-2022","text":"SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.3.0 - May 2022"},{"location":"release-notes/changelog-validation/#9231-may-2022","text":"(PW-813) Internal enhancement to fix CVE Deprecation API review","title":"9.2.31 - May 2022"},{"location":"release-notes/changelog-validation/#9230-may-2022","text":"MT semantic rules review and minor fixes MX cross-element checks review and enhancements","title":"9.2.30 - May 2022"},{"location":"release-notes/changelog-validation/#9229-may-2022","text":"MX cross-element checks review and enhancements","title":"9.2.29 - May 2022"},{"location":"release-notes/changelog-validation/#9228-april-2022","text":"Fixed MX cross-element checks Changed the ValidationResult to have the valid flag as transient field, set dynamically depending on the problems list size Added missing validations for CBPR+ pacs.009","title":"9.2.28 - April 2022"},{"location":"release-notes/changelog-validation/#9227-april-2022","text":"CBPR+ UG validation fixes","title":"9.2.27 - April 2022"},{"location":"release-notes/changelog-validation/#9226-march-2022","text":"(PW-882) SCORE 798_760 fixed validation of sequence B which is optional if purpose of message is ICCO or ISCO MT104: Fixed validation problem description in semantic rule 96","title":"9.2.26 - March 2022"},{"location":"release-notes/changelog-validation/#9225-march-2022","text":"CBPR+ validation: apply schema from Document namespace when AppHdr message type does not match pacs.002.001.10: Implemented cross-element rules, and CBPR+ UG rules pain.002.001.10: Implemented cross-element rules, and CBPR+ UG rules","title":"9.2.25 - March 2022"},{"location":"release-notes/changelog-validation/#9224-march-2022","text":"pacs.010.001.03: Implemented cross-element rules, and CBPR+ UG rules camt.060.001.05: Implemented cross-element rules, and CBPR+ UG rules pain.001.001.09: Implemented cross-element rules, and CBPR+ UG rules","title":"9.2.24 - March 2022"},{"location":"release-notes/changelog-validation/#9223-march-2022","text":"Fixed error description in MX validation (cross element checks and CBPR+ rules) MX cross element validation fixes (X00420)","title":"9.2.23 - March 2022"},{"location":"release-notes/changelog-validation/#9222-march-2022","text":"Enhanced the CBPR+ AppHdr validation with constraints from CBPR+ restricted BAH v2 schema","title":"9.2.22 - March 2022"},{"location":"release-notes/changelog-validation/#9221-march-2022","text":"(PW-861) Fixed validation of fields 23X, 21H, 77B (MT734) and 98K that was too strict; slash character is allowed in the component using x character set","title":"9.2.21 - March 2022"},{"location":"release-notes/changelog-validation/#9220-february-2022","text":"(PW-856) GPI: Fixed misleading error description in field 111 validation (PW-835) GPI: Field 111 is optional in MT199 even for GPI members Fixed inconsistency in the ValidationResult valid flag returned by the CbprValidationEngine Fixed MX cross-element validations when too elements cannot be present together, but may both be absent","title":"9.2.20 - February 2022"},{"location":"release-notes/changelog-validation/#9219-february-2022","text":"Updated the default ISO 20022 external code set XSD to the February 2022 update camt.029.001.09: Implemented cross-element rules, and CBPR+ UG rules camt.052.001.08: Implemented cross-element rules, and CBPR+ UG rules camt.053._001.08: Implemented cross-element rules, and CBPR+ UG rules camt.056.001.08: Implemented cross-element rules, and CBPR+ UG rules camt.057.001.06: Implemented cross-element rules, and CBPR+ UG rules pacs.002.001.10: Implemented cross-element rules, and CBPR+ UG rules pacs.004.001.09: Implemented cross-element rules, and CBPR+ UG rules Completed UG rules for CBPR+ pacs.008 and pacs.009 variants (COV, STP, ADV)","title":"9.2.19 - February 2022"},{"location":"release-notes/changelog-validation/#9218-february-2022","text":"(PW-837) In MT message length validation, remove line CRLF when computing the message size","title":"9.2.18 - February 2022"},{"location":"release-notes/changelog-validation/#9217-january-2022","text":"(PW-835) Fixed validation of GPI field 111 (block3) expected values per message type","title":"9.2.17 - January 2022"},{"location":"release-notes/changelog-validation/#9216-january-2022","text":"(PW-833) Fixed mandatory field 77E in MTn98 Added UG implementation for CBPR+ pacs.008 STP and pacs.009 ADV/COV","title":"9.2.16 - January 2022"},{"location":"release-notes/changelog-validation/#9215-january-2022","text":"SCORE messages semantic validations review","title":"9.2.15 - January 2022"},{"location":"release-notes/changelog-validation/#9214-january-2022","text":"(PW-819-820) SCORE message MT798_760 validation fixes Added UG implementation for CBPR+ camt.054 Implemented cross-element rules for camt.054.001.08 Added validation for MX match between AppHdr message identifier and Document namespace","title":"9.2.14 - January 2022"},{"location":"release-notes/changelog-validation/#9213-january-2022","text":"(PW-815) Fixed validation of field 12H (SCORE) where narrative is optional MT530 validation: Fixed semantic 237 rule, where subsequence C1 is repetitive Added UG implementation for CBPR+ pacs.009 Implemented cross-element rules for pacs.009.001.08","title":"9.2.13 - January 2022"},{"location":"release-notes/changelog-validation/#9212-december-2021","text":"Added a specific CbprValidationEngine class to validate CBPR+ messages Added UG implementation for CBPR+ pacs.008 Implemented cross-element rules for pacs.008.001.08 Added com.prowidesoftware.integrator.validation as automatic module name in the MANIFEST for JPMS support","title":"9.2.12 - December 2021"},{"location":"release-notes/changelog-validation/#9211-december-2021","text":"(PW-799) fixed validation of semantic rule 199 in MT564","title":"9.2.11 - December 2021"},{"location":"release-notes/changelog-validation/#9210-december-2021","text":"(PW-780) Added ValidationConfiguration#setGpiMember to override the general static SdkConfiguration#setGpiMember (PW-764) Fixed error description in field 119 (block 3) validation","title":"9.2.10 - December 2021"},{"location":"release-notes/changelog-validation/#929-november-2021","text":"(PW-772) Enable empty lines in MT568 field 70F as it is exceptionally allowed in the ISO 15022 usage guidelines In Mx IBAN validation added specific error code D00003","title":"9.2.9 - November 2021"},{"location":"release-notes/changelog-validation/#928-november-2021","text":"(PW-764) Reviewed validation of field 119 (block 3) (PW-703) Clearer validation results for MT block 2 with invalid identifier Added IBAN validation (including local account format) for MX elements containing IBAN numbers Added optional IBAN validation for MT messages, for specific fields where IBAN validation is explicitly requested by configuration MX validation: renamed proprietary error codes for invalid currency and country codes by standard codes D00004 and D00005 Fixed validation of letter options in B/98a","title":"9.2.8 - November 2021"},{"location":"release-notes/changelog-validation/#927-october-2021","text":"Added validation of block 2 Output (only Input was validated before, while Output was ignored) Fixed validation of value for Field 26A ( )","title":"9.2.7 - October 2021"},{"location":"release-notes/changelog-validation/#926-october-2021","text":"(PW-705) Added validation of mandatory CHK in block 5 when the trailer block is present (PW-703) More verbose MT headers validation (PW-677) MT670, MT671: fixed implementation of semantic check 112 (D12)","title":"9.2.6 - October 2021"},{"location":"release-notes/changelog-validation/#924-september-2021","text":"(PW-664) Parser enhancement to detect LF before block identifier as validation problem (not exception)","title":"9.2.4 - September 2021"},{"location":"release-notes/changelog-validation/#923-august-2021","text":"Added german translation for validation problems","title":"9.2.3 - August 2021"},{"location":"release-notes/changelog-validation/#922-august-2021","text":"(PW-599) MT564: Minor scheme fix, 92a TAXR and WITL can be repeated in CASHMOVE (E2) MT548: Minor scheme fix, added letter option \"C\" in field \"98C:SCTS\" in sequence \"C1a1B1\" (PW-578) Fixed SAX logging with misleading parse errors","title":"9.2.2 - August 2021"},{"location":"release-notes/changelog-validation/#921-june-2021","text":"(PW-536) Replaced deprecated API in the MX validation (PW-536) Fixed misleading typo in semantic E94 error description (PW-517) Removed the actual licensed BICs information from the unlicensed error description in the validator","title":"9.2.1 - June 2021"},{"location":"release-notes/changelog-validation/#920-may-2021","text":"SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) More accurate structure problems reporting, with a customizable lookahead for sequence resynchronization after a field partial match Enhanced unexpected fields problem reporting, in some situations it used to trigger also misleading errors about the unexpected field repetitions","title":"9.2.0 - May 2021"},{"location":"release-notes/changelog-validation/#9116-april-2021","text":"Added support for ISO 20022 external code set validations Externalized the validation engine configuration into a ValidationConfiguration class (PW-517) Removed the actual licensed BICs information from the unlicensed error description in the validator","title":"9.1.16 - April 2021"},{"location":"release-notes/changelog-validation/#9115-april-2021","text":"(PW-460) Divided the internal schemas package into packages by category to allow trimming the jar by use","title":"9.1.15 - April 2021"},{"location":"release-notes/changelog-validation/#9114-april-2021","text":"(PW-500) Fixed validation of qualifiers when the component is optional Fixed qualifier error reporting in fields 41A and 41D Replaced generic error code KNN with specific code for each field, such as K41, K23, K92","title":"9.1.14 - April 2021"},{"location":"release-notes/changelog-validation/#9113-april-2021","text":"(PW-508) Fixed validator pattern in field 98K","title":"9.1.13 - April 2021"},{"location":"release-notes/changelog-validation/#9112-april-2021","text":"Enhanced MT structure error detection and reporting (missing and unexpected fields) Fixed validation of fields 12 and 27A in MT SCORE messages","title":"9.1.12 - April 2021"},{"location":"release-notes/changelog-validation/#9111-march-2021","text":"Added semantic validation for available SCORE messages (PW-499) Fixed schemes for MT513, MT564 and MT566: invalid qualifier in field 69D","title":"9.1.11 - March 2021"},{"location":"release-notes/changelog-validation/#9110-march-2021","text":"(PW-494) Fixed schemes for MT565 (sequence B can be repeated up to 1) and MT568 (sequence B is optional, not mandatory)","title":"9.1.10 - March 2021"},{"location":"release-notes/changelog-validation/#919-march-2021","text":"(PW-493) Fixed scheme for MT671, missing :22H::PRCD//PREF in Other Details sequence Added mtInSequenceResyncLookAhead parameter in the ValidationEngine#Configuration to control the error reporting accuracy Added mtEnhancedRepetitionProblemReportingMode parameter in the ValidationEngine#Configuration to switch off redundant field repetition related errors Removed T13 rule from MTn98 proprietary messages validation (only kept for n92, n95 and n96) Changed default toString in ValidationProblem to use the human-friendly error description","title":"9.1.9 - March 2021"},{"location":"release-notes/changelog-validation/#918-december-2020","text":"(PW-424) Fixed validation of mandatory field 111 (PW-398) Added check for expected values in field 111 (U14 error code)","title":"9.1.8 - December 2020"},{"location":"release-notes/changelog-validation/#917-december-2020","text":"License check review","title":"9.1.7 - December 2020"},{"location":"release-notes/changelog-validation/#916-november-2020","text":"Field validation changes in 83J, 86J, 50F and 59F are now parked until SRU2021 (only cat 5 changes are in force in SRU2020)","title":"9.1.6 - November 2020"},{"location":"release-notes/changelog-validation/#915-november-2020","text":"(PW-413) 564 added qualifier option SRDC in field 17B in sequence D 530 added qualifiers options BYIY and BDEF in field 22 in sequence B 530 added optional fields 90[A,B] and 19A BCAM in sequence C 565 minor fix in conditional qualifier check in field 92K in sequence C","title":"9.1.5 - November 2020"},{"location":"release-notes/changelog-validation/#914-september-2020","text":"In MTs 300, 305, 306, 320, 330, 340, 341 and 350 added a missing network rule validating the reference number in fields 22 and 22C against the message rate field Added internal BIC validation skip for SWIFT special BIC codes such as: TRCKCHZZ (GPI) and TRGTXEPM (Target) Fixed semantic check 254 to handle 23E field repetitions properly","title":"9.1.4 - September 2020"},{"location":"release-notes/changelog-validation/#913-september-2020","text":"Minor fix in semantic 204, 209 and 210 checks when the party identifier is only slashes","title":"9.1.3 - September 2020"},{"location":"release-notes/changelog-validation/#912-august-2020","text":"(PW-325) Added ValidationEngine.Configuration#addRegisteredBic to programmatically register valid BICs not available in the embedded BIC directory (PW-325) Enhanced de BIC directory validation to avoid false error for Test & Training BIC codes (query will match any equivalent production BIC)","title":"9.1.2 - August 2020"},{"location":"release-notes/changelog-validation/#911-jun-2020","text":"Removed a false positive deprecation warning when configuring ignored validation codes","title":"9.1.1 - Jun 2020"},{"location":"release-notes/changelog-validation/#910-may-2020","text":"SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.1.0 - May 2020"},{"location":"release-notes/changelog-validation/#902-may-2020","text":"Added validation of ISO business header version 2 (head.001.001.02) when found in a message Added a configuration in the ValidationEngine.Configuration to optionally disable ERI validation Added validation for ERI in fields 61, 72, 77A, 79 and 86, when ERI is present and depending on the message type Fixed amount validation when the whole number part is not present","title":"9.0.2 - May 2020"},{"location":"release-notes/changelog-validation/#901-may-2020","text":"Fixed validation of field 72 in MT760","title":"9.0.1 - May 2020"},{"location":"release-notes/changelog-validation/#900-may-2020","text":"Validation module extracted to its own jar in the distribution, with its own version from now on","title":"9.0.0 - May 2020"},{"location":"release-notes/changelog-validation/#809-may-2020","text":"Fixed scheme for 564, typo in MET2 and MET3 qualifiers","title":"8.0.9 - May 2020"},{"location":"release-notes/changelog-validation/#808-april-2020","text":"Fixed validation of field 50F party line, was accepting up to 34 characters instead of the 35 allowed limit for the field Enabled presence of field 121 in all payment messages (category 1 and 2) Added support to validate restricted ISO20022 for CBPR+ (PW-259) Fixed semantic 157 check, when amount is zero with decimals Fixed schemes for MT537 adn 458, in sequence PENDET required field is 99A and not 99B Enhanced error reporting for semantic checks: 41, 131, 132, 146 and 147","title":"8.0.8 - April 2020"},{"location":"release-notes/changelog-validation/#807-march-2020","text":"Added support to validate restricted ISO20022 for SIC (Swiss RTGS) MT548: Fixed repetitions of field 94 in sequence C1a1A1 MT537: Fixed structure for D1a1A1 MT537: Fixed sequence B2b where field 98 option EXSE is mandatory Fixed semantic check 256 affecting validation for message 535 and 536","title":"8.0.7 - March 2020"},{"location":"release-notes/changelog-validation/#806-february-2020","text":"Fixed T96 check in SB-LC function (affecting fields 22 and 22C) where alphanumeric order must give precedence to letters over numbers","title":"8.0.6 - February 2020"},{"location":"release-notes/changelog-validation/#804-december-2019","text":"Fixed resource bundle for MX messages when retrieved for specific locale Added convenient toJson with preformatted validaiton problem messages, to the ValidationResult DTO Fixed detection of invalid trailing empty lines in MT field values","title":"8.0.4 - December 2019"},{"location":"release-notes/changelog-validation/#803-september-2019","text":"(PW-185) Replaced custom error codes with SWIFT standard FIN error codes such as Hnn and Tnn Added new validation entry points for MX messages to use specific XSD schemas (useful to validate SEPA messages) Added missing field validations: T14, T49, T70, T75, T88 Fixed validation of conditional qualifier in field 93C in MT566","title":"8.0.3 - September 2019"},{"location":"release-notes/changelog-validation/#802-august-2019","text":"Fixed validation of conditional qualifier in field 93C in MT566 Fixed bin/validator CLI app that stopped reading input on the first line break Fixed occasional BIC truncation validating large MX messages","title":"8.0.2 - August 2019"},{"location":"release-notes/changelog-validation/#801-july-2019","text":"Enhanced the configuration to enable ignoring validation problems by specific key, by name or by type Fixed validation of BIC codes in MX when the BIC directory is disabled Fixed BIC not registered error reporting when validating MX messages Fixed semantic check 196 affecting MTs 362","title":"8.0.1 - July 2019"},{"location":"release-notes/changelog-validation/#800-may-2019","text":"JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Fixed semantic check 157 affecting MTs 320, 330 adn 620","title":"8.0.0 - May 2019"},{"location":"release-notes/changelog-validation/#7109-may-2019","text":"Fixed SB-LC validation, affecting fields 22 and 22C (common reference); added the missing alphabetic sort check in the parties code and location Fixed lines count check in multiline fields with optional party identifier in first line (ex: 58D)","title":"7.10.9 - May 2019"},{"location":"release-notes/changelog-validation/#7108-march-2019","text":"Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Fixed obfuscation to keep directories in jar","title":"7.10.8 - March 2019"},{"location":"release-notes/changelog-validation/#7107-january-2019","text":"Added missing path when reporting invalid country code in MX Fixed duplicated error reporting when validating MX messages Added the XsdRegistry interface to allow overwriting the default schemas when validating MX messages Enhanced the MX error reporting to include the repetitive element index in the validation problem xPath Added support for custom MX validation rules Enhanced validation and error reporting for fields 50F and 59F Minor performance enhancement for validation process with exit on first error Added support in MX validation to optionally ignore XSD ERROR","title":"7.10.7 - January 2019"},{"location":"release-notes/changelog-validation/#7106-november-2018","text":"Added ISO country code validation for CountryCode elements in MX messages Fixed GPI validation to NAK non-GPI messages with fields 121 or 111 Fixed GPI validation to NAK GPI-message with field 111 when the institution is not a GPI member Fixed error description for structure validation problem TOO_BIG Enabled the UETR validation for any message type, it is still mandatory for GPI messages only though (PW-103) Activated the UETR format validation also for output messages (received from SWIFT) Fixed semantic validation 201 affecting MT564","title":"7.10.6 - November 2018"},{"location":"release-notes/changelog-validation/#7104-september-2018","text":"Bugfix validating empty first line in fields value Enhanced error reporting in BIC validation, including details of the BIC subfield where the validation problem is found Enhanced the BIC validation checking the country code within the BIC is a valid ISO country MX: Added BIC validation using the BIC directory (optional by configuration) for elements containing BIC codes MT: Added BIC validation using the BIC directory (optional by configuration) for the sender and receiver address in the headers","title":"7.10.4 - September 2018"},{"location":"release-notes/changelog-validation/#7103-july-2018","text":"Added a specific PARSE_ERROR validation problem to report when the message has an invalid block structure Prevention of IllegalArgumentException when the hyphen is missing in the closing bracket of block 4 Added MX currency validation using ISO currencies from ISOUtils","title":"7.10.3 - July 2018"},{"location":"release-notes/changelog-validation/#7102-july-2018","text":"Fixed spanish description of semantic E45 check Fixed component size check in validation of Field 59F","title":"7.10.2 - July 2018"},{"location":"release-notes/changelog-validation/#7101-may-2018","text":"Added field 434 in block 3 validation","title":"7.10.1 - May 2018"},{"location":"release-notes/changelog-validation/#7100-april-2018","text":"SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"7.10.0 - April 2018"},{"location":"release-notes/changelog-validation/#798-april-2018","text":"Enhanced validation of IBAN numbers verifying the check digits and the custom account number per country (BBAN) MT306: message scheme fix, added the missing 57 ADJ optional field at the end of sequence L Minor fixes in semantic validation rule 40 and rule 122","title":"7.9.8 - April 2018"},{"location":"release-notes/changelog-validation/#797-january-2018","text":"Changes in the distribution package: Command line tools in the bic directory changed from jar files to wrapper scripts Dependencies directory renamed to lib Removed the BUILD id timestamp from the jar files Removed the BaseTestCase class from the public API to avoid Junit dependency Added ValidationProblem#printout to generate a human friendly printout of a validation problem list Updated dependency: org.mozilla 1.7R4 -> org.mozilla 1.7.7.2","title":"7.9.7 - January 2018"},{"location":"release-notes/changelog-validation/#796-december-2017","text":"Minor fix in semantic27 affecting malformed MT942","title":"7.9.6 - December 2017"},{"location":"release-notes/changelog-validation/#794-november-2017","text":"JRE requirement backported to Java 1.6 Fixed validation for field 77J: 50x[\u2019CRLF\u201950x]0-69","title":"7.9.4 - November 2017"},{"location":"release-notes/changelog-validation/#793-october-2017","text":"Added support to validate MX system messages (xsys category) Fixed currency validation (T52) in fields 60F, 62F, 64, 65 and 33B","title":"7.9.3 - October 2017"},{"location":"release-notes/changelog-validation/#792-august-2017","text":"Fixed T26 validation in fields 13B, 22W, 94B, 95a and 98K MT537 fixed qualifier validation for field 98a in transaction details sequence (C2) MT524 fixed implementation for rule 208 when several LINK sequences are present in the message MT545 and MT547: fixed validation for field set 98a in Trade Details sequence (B), qualifier ESET is mandatory while SETT is optional Fixed error code and message throw by semantic rule 267 Added more details when reporting semantic rule 266 errors. Added IsoUtils singleton to allow customization and exceptions for currency and country codes validation Currency and Country codes validation is now implemented using data from Java Currency and Locale Validation of maximum fraction digits per currency (semantic rule 3) is now implemented using data from Java Currency","title":"7.9.2 - August 2017"},{"location":"release-notes/changelog-validation/#791-june-2017","text":"Fixed semantic 167 for MT103 plan (not STP and not REMIT) MT801 first loop can be repeated Fixed semantic 282 affecting MT535 Fixed scheme for MT940 field 60[F,M] is now required","title":"7.9.1 - June 2017"},{"location":"release-notes/changelog-validation/#79-may-2017","text":"SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX) MT536: fixed false positive semantic 252 check, fixed qualifiers check in field 98a (sequence B1a2) MT575: transaction details sequence C2, field 98 with SETT or TRAD set as optional MT537: fixed false positive semantic 285 check MT576: additional information sequence C set as optional Fixed semantic rule 259 affecting MT517 link sequence check MT569: fixed incorrect definitions in sequence C1a1 (valuation details) MT506, 569 and 575: field 28E mandatory MT513; sequence A added TRAD qualifier to field 22F, sequence B1 (partial fill details) fields 98 and 94 are optional MT513 and 514: fixed letter option from H to F in field 22F:SETR in settlement details","title":"7.9 - May 2017"},{"location":"release-notes/changelog-validation/#789-may-2017","text":"Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Fixed validation of fields 72 and 79 of a Rejected/Return message Renamed FieldProblem.REJT_RETN_0n to more specific errors: REJT_RETN_LINE_n, REJT_RETN_REASON_CODE, REJT_RETN_MREF, REJT_RETN_TREF, REJT_RETN_CHGS, REJT_RETN_TEXT Enhanced validation of user block 3, checking all fields are expected for the message type and checking fields order. Fixed NPE in semantic 119 affecting MTs 102 and 103 STP when IBAN component was not present Added a common type ValidationProblemKey implemented by all problem key enumerations Fixed false positive error validating field 59F when multiple address lines (line label 2) are defined Fixed false positive restriction field 37a second component Fixed scheme for MT505, added missing field 98A:AGRE in sequence A1 Enhanced MX validation to allow MX messages with bank-to-bank namespace declaration Fixed false positive semantic 293 validation for MT507 when sequence B1a1 was not present Fixed letter option in scheme for MT506, sequence D (Collateral Details) field 19 A -> B Fixed qualifier in scheme for MT506, sequence D (Collateral Details) DEAL-> COLL Fixed scheme for MT506, sequence B (Summary) field 95 is mandatory and field 19B only mandatory with qualifier COVA Fixed Semantic 82 implementation affecting MT104 and MT107 Fixed false positive case in Semantic 75, affecting MT104 Fixed validation of leading characters, colon (':') not allowed in second and subsequent lines except for fields 77E and 77T Fixed semantic 103 affecting MT535","title":"7.8.9 - May 2017"},{"location":"release-notes/changelog-validation/#788-march-2017","text":"Added support for nested Document elements when validating MX messages Removed invalid fields following linkages in GENL sequence Cleaner log in semantic rule 3 validation","title":"7.8.8 - March 2017"},{"location":"release-notes/changelog-validation/#787-december-2016","text":"Added check for validation flag (STP, REMIT, COV) in user header block Fixed missing semantic associations to MTs 700, 705, 707, 710, 720, 730, 732, 734, 740, 742, 747, 750, 752, 754, 756, 768, 768, 769, 800, 801, 802, 824 MT518 fixed fieldset for Field 70 MT330 fixed qualifier in Field 22 MT513 and MT514 Field 11 moved outside previous fieldset MT541 to MT547 Field 90[A,B] changed to fieldset. MT564 fixed fieldset items in Field93[B,C] MT565 to MT567 Sequence D, fixed field 13 MT609 and MT798_763 fixed qualifiers in Field 29","title":"7.8.7 - December 2016"},{"location":"release-notes/changelog-validation/#786-november-2016","text":"JRE requirement increased to Java 1.7 (only for Integrator SDK and modules, Core still works on 1.5) semantic 175 minnor fix affecting MT104 and MT107 when multiple sequence B are present","title":"7.8.6 - November 2016"},{"location":"release-notes/changelog-validation/#785-october-2016","text":"Minor fixes in semantic validations: 206 (used in MTs: 103, 564, 566), 279 (used in MTs: 549, 564, 565) MT564: Minor fixes in semantic validations: 199, 211, 224 MT564: field 93 UNBA instead of UMBA MT564: CAOPT sequence, field 92 INTP, missing conditional qualifier NILP MT564: SECMOVE sequence, field 90 PRPP, missing letter option K MT564: SECMOVE sequence, field 92 NEWO, missing letter option M MT564: CASHMOVE sequence, field 92 ESOF, missing letter options F and M MT564: CASHMOVE sequence, field 92 TXIN, missing letter option F MT564: CASHMOVE sequence, field 92 WITL, missing letter option R and its conditional qualifier eval MT564: fixed field 92J subfield ACTU INDI validation MT565: CAINST sequence, field 90 OFFR, missing letter option L MT566: CADETL sequence, field 92 BIDI missing letter option P MT566:CACONF sequence, field 69, removed invalid letter option J MT566: Fixed qualifier in field 13a to allow UNS MT566:SECMOVE sequence, field 90 OFFR, missing letter option L MT566:SECMOVE sequence, field 90 PRPP, missing letter option K MT566:SECMOVE sequence, field 92 NEWO, missing letter option M MT566:SECMOVE sequence, field 92 TAXC, removed invalid letter option K MT566:CASHMOVE sequence, field 92 TXIN, missing letter option F MT566:CASHMOVE sequence, field 90 PRPP, missing letter option K MT566:fixed field 92J subfield ACTU INDI validation MT567: CADETL sequence, field 35B, removed invalid qualifier check SAFE MT567: field19 changed to fieldset","title":"7.8.5 - October 2016"},{"location":"release-notes/changelog-validation/#784-oct-2016","text":"Fixed JS expression in schemes for 564, 565, 566 and 620 Important enhancement in MX validation problem reporting, including full XPATH, line and column of errors. Fixed semantic 291 (affecting 540, 541, 544, 545) Fixed semantic 112 (affecting MTs 670 and 671) Fixed semantic 113 (affecting MTs 380, 381, 503, 504, 506, 670, 671)","title":"7.8.4 - Oct 2016"},{"location":"release-notes/changelog-validation/#783-jul-2016","text":"Added support for changed currency in Belorussia from 974 (BYR) to 933 (BYN). Fixed semantic 210 affecting messages 103, 102, 104 and 107","title":"7.8.3 - Jul 2016"},{"location":"release-notes/changelog-validation/#782-jul-2016","text":"Fixed schemes: definition of field 12A in FIA subsequences of MTs 54x Semantic 283 bugfix (used in MTs 307,503,504,505,506,536,537,548,578,586)","title":"7.8.2 - Jul 2016"},{"location":"release-notes/changelog-validation/#2016-june","text":"Added field repetition validation in block 3","title":"2016 June"},{"location":"release-notes/changelog-validation/#2016-april","text":"Added detection of extra data in message content or blocks when validating a message","title":"2016 April"},{"location":"release-notes/changelog-validation/#2016-february","text":"Fixed validation of min and max repetition in fieldsets, when the attributes are set only in the items","title":"2016 February"},{"location":"release-notes/changelog-validation/#2016-january","text":"Fixed scheme 307, typo in semantic rules attribute Added API in SchemeField to retrieve qualifiers information from parsed scripting expressions","title":"2016 January"},{"location":"release-notes/changelog-validation/#2015-december","text":"Fixed schemes for 600, 601, 604, 605, 606, 607, 608, 609, 620, wrong qualifier for field 26C","title":"2015 December"},{"location":"release-notes/changelog-validation/#2015-november","text":"Fixed validation of repetitive sequence in MT940","title":"2015 November"},{"location":"release-notes/changelog-validation/#2015-october","text":"Fixed validation for fields 129, 12A, 13B, 20E, 23A, 26N, 26P, 92C and 94D; removed restriction on amount of slashes because components use charset x where slash is allowed Fixed validation for fields 14G, 27A, 27, 28[D,E], 29[L,N], 38[G,H], 39[A,P], 68C, 69C, 70[C,D,E,G], 90F, 92R, 93B, 94E, 94G 95[Q,T,U,V] and 98F; added restriction on amount of slashes","title":"2015 October"},{"location":"release-notes/changelog-validation/#2015-september","text":"Fixed scheme for MT567, removed invalid 25D field in sequence A","title":"2015 September"},{"location":"release-notes/changelog-validation/#2015-august","text":"Fixed qualifiers validation scripting in xml schemas for MTs: 306, 360, 361, 362, 364, 365, 500, 501, 535, 564, 565, 566 Enhanced validation patterns naming for better consistency","title":"2015 August"},{"location":"release-notes/changelog-validation/#2015-april","text":"Enhanced structure validation error reporting, when JS expressions are used to check conditional qualifiers. The new scheme validation rule generates a proper message indicating the expected and found qualifiers instead of a generic fail expression error.","title":"2015 April"},{"location":"release-notes/changelog-validation/#2015-march","text":"Bugfix Field validations, new restriction, start of line character cannot be '-'. Bugfix MT535 subsequence B1a, it can be at most one and the scheme was allowing multiple repetitions","title":"2015 March"},{"location":"release-notes/changelog-validation/#2015-february","text":"ValidationEngine enhancement in the default scheme to use, detecting automatically if a 102/103 is STP or if a 202/205 is COV Fixed validation for field 22S, was requiring a 35 characters fixed length for component 2, while the correct validation is up to 35 characters (not fixed) Added more restrictive party field validation when a slash is followed by a blank content, affecting fields 42a, 50a, 51a, 52a, 53a, 54a, 55a, 56a, 57a, 58a, 59a, 81a, 82a 83a, 84a, 85a, 86a, 87a, 88a, 89a, 91a, 96a SchemeValidationRule version 2: new version of structure validation for MT, with several enhancements and bug fixes over the previous version. Important performance enhancement in MT structure validation (30% in average, reaching a 60% for some message structures). Important enhancement in structure error reporting, errors are now more specific and detailed with more details. Better error localization, avoiding duplicated error field validation in some situations. Improvement in scheme's scripting validations, isolating script compile errors from unsatisfied logic conditions. Fixed scheme validation for MT300 that was throwing a false problems for some combination of subsequences E, E1 and E1a.","title":"2015 February"},{"location":"release-notes/changelog-validation/#2015-january","text":"RuleManager: fixed loading of field rules, that was skipping incorrectly field validation to fields derived from fieldsets","title":"2015 January"},{"location":"release-notes/changelog-validation/#2014-december","text":"Better error message format in BaseTestCase Fixed error message for E73 Review of semantic rules 85,86,198 ValidationEngine: Added API to validate from AbstractMT ValidationEngine: Added exclusive API to use when validating messages in strings or files (with swift format, not parsed objects) therefore detecting more error conditions AbstractTagValidationRule: Fixed validation that had a bug in special conditions, Output messages (received from swift) and with sender and receiver within the same institution","title":"2014 December"},{"location":"release-notes/changelog-validation/#2014-november","text":"Bugfix in schemas 515, 536 Enhanced MT expression validation reporting, diferenciating invalid expressions, from runtime errors or failed expression evaluation. Bugfix. Fixed expressions in schemes xml for MT576 and MT568, replacing deprecated function call addQuaifiers by qualifier Bugfix. Added validation of T13 rule to MTs n98","title":"2014 November"},{"location":"release-notes/changelog-validation/#2014-september","text":"Bugfix. Missing resource bundle for invalid BIC validation problem Added addVariable method to ValidationProblem Bugfix. Fields 95Q and 70C were restricted to maximum 3 lines, while 4 lines are compliant as well. Bugfix. Fixed XML for MT537, field 22H conditional qualifier STAN changed to STAT","title":"2014 September"},{"location":"release-notes/changelog-validation/#2014-july","text":"Enhanced structure validation incorporating special field exceptions and required code words (standard PIII Fields Chapter 4) directly into the xml schemes configurations. Affected MTs: 102 STP, 103, 103 STP, 300, 303, 304, 305, 306, 320, 340, 341, 350, 360, 361, 362, 364, 365, 600, 601, 620, 920, 973 Enhanced structure validation error messages to separate unexpected fields problems reporting, from field qualifier problems or expression evaluation problems Enhanced field validation to avoid repetitive checks for empty content and/or empty lines Bugfix. MT306 optional field 12G changed to 12D and added missing field class Bugfix. SchemeXmlReader to properly set fieldset items' qualifiers and letter options when inherited from container fieldset Bugfix. Added null controls to several semantic validations to prevent NPE that would previously arise when applying semantic checks to messages with specific invalid structures Bugfix. Fixed XML for MT540, field 90 changed to fieldset 90 to allow qualifier validation for items Review and code clean of semantic rule 24, 52 SRU 2014. Affected MTs: 300, 304, 305, 306, 340, 341, 360, 361, 380, 381, 502, 506, 508, 509, 513, 514, 515, 518, 527, 530, 536, 537, 538, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 558, 564, 565, 566, 567, 568, 569, 575, 600, 601, 942 Added description and release attributes to Scheme Minor fix in MT300 sequences structure, B1 and B2 inside B, and named D's subsequence as D1 Bugfix. MT300 optional field 17A changed to optional field 77A (field number was wrong) Bugfix. MT514 fixed missing mandatory fields 36B and 35B between end of sequence B1 and start of sequence B2 Bugfix. MT515 fixed field 90[A,B] with qualifier DEAL at sequence C, changed from optional to mandatory (minRepetition was wrong)","title":"2014 July"},{"location":"release-notes/changelog-validation/#2014-may","text":"Review and code clean of semantic rule 184 Review and code clean of semantic rule 176 Review and code clean of semantic rule 152, 153, 154 Performance enhancements: execution speed reduced by approx 71% measured in global test suite","title":"2014 May"},{"location":"release-notes/changelog-validation/#2014-april","text":"Review and code clean of semantic rule 131, 253, 133, 135 Fixed semantic 116 rule incorrectly interpreting sequence C absence for MT306","title":"2014 April"},{"location":"release-notes/changelog-validation/#2014-march","text":"MT564: Added missing option K to field 90 in sequence E2 cash movements Review and code clean of semantic rule 92, 95 Review and code clean of semantic rule 66, 67, 68 ,78, 84, 93 Review and code clean of semantic rule 61, 57, 58, 62 Added validation problems translation to Italian. Bugfix. Fixed invalid check for X in 8th position for logical terminals without A, B, C identifier Bugfix. Fixed Block1 validation, allowing Logical terminal without the A, B, C identifier (11 characters length) Bugfix. Field validation was not accepting 999 as a valid MT number (example field 11R)","title":"2014 March"},{"location":"release-notes/changelog-validation/#2014-february","text":"Bugfix. Affected MTs:n92, n95, n96, n98. Fixed isolation of fields copied from original message from the fields of the message being validated Bugfix semantic rule 31 that was throwing false positives when field 79 was included in the appended original message's fields Initial addition of FieldFilter and FieldFilterUtils API Maintenance review of semantic rule 71 Review and code clean of semantic rule 211, 221, 262 Added API to BaseTestCase Review and code clean of semantic rule 209 Review and code clean of semantic rule 201, 202, 206 Bugfix. Affected MTs: 564. Fixed semantic rule 71 that was throwing IOB exceptions for some valid combinations of fields 93B Bugfix. Affected MTs: 568, 569, 574, 575, 576, 578, 586, 670, 671. Fixed xml schemes, changing the invalid scripting method conditionalQualifiers to conditionalQualifier Review and code clean of semantic rule 203, 206, 209, 221 Review and code clean of semantic rule 201, 202 Bugfix. Affected MTs: 305. Fixed false positive missing field errors when the message ends with nested optional subsequences with inner mandatory fields Review and code clean of semantic rule 192, 72, 199 Review and code clean of semantic rule 71 Review and code clean of semantic rules impacting MT305 Added a code generation tool that can be run from command line to create custom version of Field and MT classes Added a command line application to use the messages validation in standalone mode, validating messages from file system","title":"2014 February"},{"location":"release-notes/changelog-validation/#2014-january","text":"Added validation rules for fields belonging to system messages (i.e. 451) Adding constants to Literals class to avoid usage of hardcoded strings and cleaner code with static imports Bugfix. Affected MTs: 207. Fixed maximum repetitions of sequence B from 1 to unlimited Maintenance(Review and performance updates) semantic rule #167, #54, #55 Maintenance(Review and performance updates) semantic rule #161 Maintenance(Review and performance updates) semantic rule #168, #246, #254 Added filter() to AbstractSemanticValidationRule Maintenance(Review and performance updates) semantic rule #162, #166 Added BaseTestCase.assertValid(String) Fixed issue in semantic rule 154 which did not consider properly B sequences Maintenance(Review and performance updates) semantic rule #160, #164","title":"2014 January"},{"location":"release-notes/changelog-validation/#2014-01-15","text":"Fixed issue in semantic rule 77 affecting MTs 730, 768 and 769","title":"2014-01-15"},{"location":"release-notes/changelog-validation/#2013-october","text":"Maintenance(Review and performance updates) semantic rule #44, #45, #46, $47, #48, #51, #53 Maintenance(Review and performance updates) semantic rule #106, #108, #30, #40, #42 Review and performance updates on S102 Refactored max msg length validation to use enum in structure problem for reporting errors Review and performance updates on S79","title":"2013 October"},{"location":"release-notes/changelog-validation/#2013-september","text":"SRU 2013 update Fixed incomplete validation for field 77E","title":"2013 September"},{"location":"release-notes/changelog-validation/#2013-march","text":"Bugfix: fixed typo at field 22H in MT380, BUYI->BUY1","title":"2013 March"},{"location":"release-notes/changelog-validation/#2012-june","text":"Added API to specify locale on ValidationProblem.getMessage method","title":"2012 June"},{"location":"release-notes/mule/","text":"Prowide MULE connector The Prowide Mule connector is hosted in Mule Exchange and facilitates the integration and usage of the Prowide libraries for MT, ISO 20022 and CBPR+ in Mule applications. https://www.anypoint.mulesoft.com/exchange/ 1.0.0 - September 2020 (Not released yet) Mule Runtime compatibility: 4.1.0+ Initial version including operations for validation and translation for MT, ISO 20022 and CBPR+","title":"Prowide Mule connector"},{"location":"release-notes/mule/#prowide-mule-connector","text":"The Prowide Mule connector is hosted in Mule Exchange and facilitates the integration and usage of the Prowide libraries for MT, ISO 20022 and CBPR+ in Mule applications. https://www.anypoint.mulesoft.com/exchange/","title":"Prowide MULE connector"},{"location":"release-notes/mule/#100-september-2020-not-released-yet","text":"Mule Runtime compatibility: 4.1.0+ Initial version including operations for validation and translation for MT, ISO 20022 and CBPR+","title":"1.0.0 - September 2020 (Not released yet)"}]} \ No newline at end of file +{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"","title":"Home"},{"location":"getting-started/","text":"Getting Started The Open Source section covers the Prowide open source libraries for FIN MT and ISO 20022. The Prowide Integrator section covers the complemetary licensed libraries and tools. Other content in this section provides general information about the standards, and also references for the libraries impementation and maintenance policies. Download The open source libraries are available at Maven Central. The following links provide the coordinates for each libraries: Download coordinates Download Prowide Core Download Prowide ISO 20022 The Prowide Integrator is licensed software, thus download and usage is restricted to licensed customers. To see the changelog of each release, check the release notes section. All libraries are compatible with Java 8+ . Learn by example The online examples at GitHub cover key features of each library. For the open source projects you can just checkout the example project and start running the examples in your IDE. Each example cover a specific feature and is self contained, so you can just run the main method of each example class. The default setup uses Gradle . For the Prowide Integrator, in order to compile and run the examples you need either a production or trial distribution of the required libraries. Examples Prowide Core examples Prowide ISO 20022 examples Prowide Integrator examples Compile and Run The primary intention of the examples is to show code. Most of them produce some kind of output though. All example classes have a main method that you can easily run in your IDE. This project can serve as a template for your own, allowing you to copy and customize examples to fit your requirements. To leverage this, you must incorporate Prowide libraries into your project. There are two main approaches to integrate Prowide dependencies: 1) Direct Use of JARs from Your Local Environment: This approach suits projects that manually manage dependencies. Obtain the JARs by downloading the open-source libraries from core and iso20022 , or by extracting them from a Prowide-provided zip file. Follow these steps to use this method: After downloading the necessary JAR files, copy them to your project's lib folder. In the root directory of the prowide integrator examples project, find the lib folder containing a put_your_jars_here.txt placeholder. Replace this file with the JAR files you've downloaded, ensuring they're placed at the same level as the placeholder. This placeholder file lists example JAR names for reference. For Maven projects, start with the mvn local pom.xml example as a template and customize it as needed. For Gradle projects, begin with the build.gradle example and modify accordingly. If not using Maven or Gradle, directly include all necessary JARs in your classpath. 2) Accessing Libraries via Prowide's Remote Repository: : Most projects benefit from this method, as it simplifies dependency management and ensures access to the latest library versions. Configure your project to use the Prowide Nexus repository. We offer templates for both Maven and Gradle to facilitate this process. This method also applies if you have local access to the libraries and wish to copy them to your local repository. For Maven projects: Use the pom.xml example as a starting template and adapt it to your project. Incorporate settings from our settings.xml example into your Maven settings file to configure Nexus repository access. For Gradle projects: Start with the build.gradle example and adjust as necessary. Ensure to include the gradle.properties example in your Gradle settings for proper Nexus repository configuration. These guidelines help you effectively incorporate Prowide libraries into your project, whether by direct JAR integration or through remote repository access. Each of these methods offers a different approach to managing dependencies, so select the one that aligns best with your project setup and management preferences. Important Note on Library Versions Prowide regularly releases new versions of its libraries. As such, the versions of the libraries you use may need to be updated over time. To check the latest versions and relevant changes, please visit the Prowide Release Notes . It is recommended to regularly review this page and update your project's library versions accordingly to ensure compatibility and access to the latest features and fixes. Learn by reading If you prefer to learn concepts step by step, our developer guides is the best place to start. Every chapter cover a specific feature and it is no necesarry built on the knowledge introduced in the previous chapters, so you can freely navigate to the sections you are interested in. Most of the online examples are also covered in the developer guides, so if you rather use the documentation pages you will not be missing anything. The developer guides are a permament reference you can reach at any time, while starting your journey with the libraries or when you need additional knowledge about a specific feature in an advance stage. Notice the Prowide Integrator developer guides are not public. A password is required to access the full content. The guides are constantly updated and improved, so you can always check for new content. Documentation Prowide Core developer guide Prowide ISO 20022 developer guide Prowide Integrator developer guides API reference The Javadoc is the reference for the API of each library. It is automatically generated from the source code and it is available online. Javadoc Prowide Core Javadoc Prowide ISO 20022 Javadoc Prowide Integrator SDK Javadoc SRU2023-9.4.x Prowide Integrator Validation Javadoc SRU2023-9.4.x Prowide Integrator Translations Javadoc SRU2023-9.4.x Prowide Integrator MyFormat Javadoc SRU2023-9.4.x Prowide Integrator CBPR+ Javadoc SRU2023-9.4.x Prowide Integrator SEPA Javadoc SRU2023-9.4.x Prowide Integrator SIC Javadoc SRU2023-9.4.x Prowide Integrator SCORE Javadoc SRU2023-9.4.x Note the Prowide Integrator Javadoc is not public. A password is required to access. SWIFT Resources The development documentation assumes some familiarity with the SWIFT MT and ISO 20022 standards. You don\u2019t have to be an expert, but it\u2019s harder to learn how to use the libraries API without the fundamental ideas of the message structures it handles. The About SWIFT section provides a brief introduction to the standards, and links to the official SWIFT documentation. Issues For open source users, you can post Issues or questions at the relevant GitHub repositories: Issues Prowide Core Issues Prowide ISO 20022 Issues Please check the existing opened and closed tickets first before posting a new one. A Prowide developer or any other community user would normally reverts back within a few days. Prowide Integrator customers For commercial customers, please use the support email or Jira portal for your inquiries. Notice that request from non-registered email address are not catched by the Service Desk, and thus ignored.","title":"Getting Started"},{"location":"getting-started/#getting-started","text":"The Open Source section covers the Prowide open source libraries for FIN MT and ISO 20022. The Prowide Integrator section covers the complemetary licensed libraries and tools. Other content in this section provides general information about the standards, and also references for the libraries impementation and maintenance policies.","title":"Getting Started"},{"location":"getting-started/#download","text":"The open source libraries are available at Maven Central. The following links provide the coordinates for each libraries: Download coordinates Download Prowide Core Download Prowide ISO 20022 The Prowide Integrator is licensed software, thus download and usage is restricted to licensed customers. To see the changelog of each release, check the release notes section. All libraries are compatible with Java 8+ .","title":"Download"},{"location":"getting-started/#learn-by-example","text":"The online examples at GitHub cover key features of each library. For the open source projects you can just checkout the example project and start running the examples in your IDE. Each example cover a specific feature and is self contained, so you can just run the main method of each example class. The default setup uses Gradle . For the Prowide Integrator, in order to compile and run the examples you need either a production or trial distribution of the required libraries. Examples Prowide Core examples Prowide ISO 20022 examples Prowide Integrator examples","title":"Learn by example"},{"location":"getting-started/#compile-and-run","text":"The primary intention of the examples is to show code. Most of them produce some kind of output though. All example classes have a main method that you can easily run in your IDE. This project can serve as a template for your own, allowing you to copy and customize examples to fit your requirements. To leverage this, you must incorporate Prowide libraries into your project. There are two main approaches to integrate Prowide dependencies: 1) Direct Use of JARs from Your Local Environment: This approach suits projects that manually manage dependencies. Obtain the JARs by downloading the open-source libraries from core and iso20022 , or by extracting them from a Prowide-provided zip file. Follow these steps to use this method: After downloading the necessary JAR files, copy them to your project's lib folder. In the root directory of the prowide integrator examples project, find the lib folder containing a put_your_jars_here.txt placeholder. Replace this file with the JAR files you've downloaded, ensuring they're placed at the same level as the placeholder. This placeholder file lists example JAR names for reference. For Maven projects, start with the mvn local pom.xml example as a template and customize it as needed. For Gradle projects, begin with the build.gradle example and modify accordingly. If not using Maven or Gradle, directly include all necessary JARs in your classpath. 2) Accessing Libraries via Prowide's Remote Repository: : Most projects benefit from this method, as it simplifies dependency management and ensures access to the latest library versions. Configure your project to use the Prowide Nexus repository. We offer templates for both Maven and Gradle to facilitate this process. This method also applies if you have local access to the libraries and wish to copy them to your local repository. For Maven projects: Use the pom.xml example as a starting template and adapt it to your project. Incorporate settings from our settings.xml example into your Maven settings file to configure Nexus repository access. For Gradle projects: Start with the build.gradle example and adjust as necessary. Ensure to include the gradle.properties example in your Gradle settings for proper Nexus repository configuration. These guidelines help you effectively incorporate Prowide libraries into your project, whether by direct JAR integration or through remote repository access. Each of these methods offers a different approach to managing dependencies, so select the one that aligns best with your project setup and management preferences. Important Note on Library Versions Prowide regularly releases new versions of its libraries. As such, the versions of the libraries you use may need to be updated over time. To check the latest versions and relevant changes, please visit the Prowide Release Notes . It is recommended to regularly review this page and update your project's library versions accordingly to ensure compatibility and access to the latest features and fixes.","title":"Compile and Run"},{"location":"getting-started/#learn-by-reading","text":"If you prefer to learn concepts step by step, our developer guides is the best place to start. Every chapter cover a specific feature and it is no necesarry built on the knowledge introduced in the previous chapters, so you can freely navigate to the sections you are interested in. Most of the online examples are also covered in the developer guides, so if you rather use the documentation pages you will not be missing anything. The developer guides are a permament reference you can reach at any time, while starting your journey with the libraries or when you need additional knowledge about a specific feature in an advance stage. Notice the Prowide Integrator developer guides are not public. A password is required to access the full content. The guides are constantly updated and improved, so you can always check for new content. Documentation Prowide Core developer guide Prowide ISO 20022 developer guide Prowide Integrator developer guides","title":"Learn by reading"},{"location":"getting-started/#api-reference","text":"The Javadoc is the reference for the API of each library. It is automatically generated from the source code and it is available online. Javadoc Prowide Core Javadoc Prowide ISO 20022 Javadoc Prowide Integrator SDK Javadoc SRU2023-9.4.x Prowide Integrator Validation Javadoc SRU2023-9.4.x Prowide Integrator Translations Javadoc SRU2023-9.4.x Prowide Integrator MyFormat Javadoc SRU2023-9.4.x Prowide Integrator CBPR+ Javadoc SRU2023-9.4.x Prowide Integrator SEPA Javadoc SRU2023-9.4.x Prowide Integrator SIC Javadoc SRU2023-9.4.x Prowide Integrator SCORE Javadoc SRU2023-9.4.x Note the Prowide Integrator Javadoc is not public. A password is required to access.","title":"API reference"},{"location":"getting-started/#swift-resources","text":"The development documentation assumes some familiarity with the SWIFT MT and ISO 20022 standards. You don\u2019t have to be an expert, but it\u2019s harder to learn how to use the libraries API without the fundamental ideas of the message structures it handles. The About SWIFT section provides a brief introduction to the standards, and links to the official SWIFT documentation.","title":"SWIFT Resources"},{"location":"getting-started/#issues","text":"For open source users, you can post Issues or questions at the relevant GitHub repositories: Issues Prowide Core Issues Prowide ISO 20022 Issues Please check the existing opened and closed tickets first before posting a new one. A Prowide developer or any other community user would normally reverts back within a few days. Prowide Integrator customers For commercial customers, please use the support email or Jira portal for your inquiries. Notice that request from non-registered email address are not catched by the Service Desk, and thus ignored.","title":"Issues"},{"location":"getting-started/deprecation/","text":"Deprecation Policy Description of Prowide policy to deprecate API and workaround for backward compatibility Version 1.0 April 2016 Introduction Deprecation and eventual deletion of pieces of code are an essential part of evolution. It's impossible to evolve efficiently without discarding some obsolete or non functional pieces that are naturally left behind in the process of evolving. The main question we address with this policy is how to make this evolution process smooth to our users. If you are facing a blocking issue with some deprecated API check the compatible mode switch below Phases Our deprecation policy consists of a set of phases, from a java deprecation mark for start and throwing an exception at the last phase. Each phase will last at least one year. A method may be retained in a deprecation phase for more time if required. Users are welcome to provide us feedback and comments about deprecation decisions. Phase 1: Initial deprecation In the initial deprecation phase elements are annotated as deprecated. Javadoc explains how to replace that code and why the deprecation occurred. Period: at least 1 year Source Level Compatible: Yes , source code that uses deprecated elements will still compile without modification during this phase. Runtime Level Compatible: Yes , compiled artifacts that use deprecated elements will still execute without modification during this phase. Phase 2: Warn and delay In the second phase a log is printed each time a deprecated method is called. The log explains the replacement that should be used and any specific information related to that API. In order to make sure this log is visible a small pause is made to enable casual revisions to be alert of the situation. This delay is not compulsive and can be turned off by means of an environment variable . Period: at least 2 years from deprecation mark Source Level Compatible: * Yes**, source code that uses deprecated elements will still compile without modification during this phase. Runtime Level Compatible: Yes , compiled artifacts that use deprecated elements will still execute without modification during this phase. However, there will be a visible impact on the runtime due to the log being printed and the pause introduced. Phase 3: Runtime exception In the third phase a runtime exception is thrown each time a deprecated method is called. The exception message explains the replacement that should be used and any specific information related to that API. This exception throwing can be turned off by means of an environment variable in order to enable old behavior. Period: at least 3 years from deprecation mark Source Level Compatible: Yes , source code that uses deprecated elements will still compile without modification during this phase. Runtime Level Compatible: No , a runtime exception will be thrown each time a deprecated method is called, which can break the execution of compiled artifacts that use those elements. However, this impact can be turned off by means of an environment variable. Phase 4: Delete The forth phase involves deleting the deprecated API. This is done only in situations where the code cleaning is justified in order to have a more understandable API. Also note that this would be done at least 4 years after the initial deprecation mark. Period: at least 4 years from deprecation mark Source Level Compatible: No , deprecated elements will be deleted and will no longer be available, so source code that uses those elements will no longer compile without modification. Runtime Level Compatible: No , compiled artifacts that use deprecated elements will no longer execute without modification, since those elements will have been deleted. Compatible mode switch Both phase 2 and phase 3 of deprecation have a visible impact on the runtime. This impact can be turned off in case of emergency, or if for some reason the code can not be adapted to the new API. In order to bypass the deprecation and preserve the old behaviour set the environment variable: PW_DEPRECATED=[nolog][,nodelay][,noexception] For convenience this can also be set directly from Java, adding the following line within your application initialization: DeprecationUtils.setEnv(EnvironmentVariableKey.NODELAY, EnvironmentVariableKey.NOEXCEPTION); Definitions Compatibility is a wide concept, so we'll refine it here: Source Level Compatibility (SLC): means that our software may be upgraded without modification of existing source code that uses it. Note that source level compatibility does not exempt from recompilation, and that's why we also specify the next level of compatibility, which includes this. Runtime Level Compatibility (RLC): means that our software may be upgraded by just replacing the artifacts in a runtime environment without need for recompilation. For example: void setFoo(String) Foo setFoo(String) L1 and L2 are SLC but not RLC. For this type of changes we'll add, if necessary, the practice of creating a new package and using the newer version classes from the new package. For the old classes/packages, we handle what we believe is very important for long term software, a clear deprecation/deletion policy.","title":"Deprecation policy"},{"location":"getting-started/deprecation/#deprecation-policy","text":"Description of Prowide policy to deprecate API and workaround for backward compatibility Version 1.0 April 2016","title":"Deprecation Policy"},{"location":"getting-started/deprecation/#introduction","text":"Deprecation and eventual deletion of pieces of code are an essential part of evolution. It's impossible to evolve efficiently without discarding some obsolete or non functional pieces that are naturally left behind in the process of evolving. The main question we address with this policy is how to make this evolution process smooth to our users. If you are facing a blocking issue with some deprecated API check the compatible mode switch below","title":"Introduction"},{"location":"getting-started/deprecation/#phases","text":"Our deprecation policy consists of a set of phases, from a java deprecation mark for start and throwing an exception at the last phase. Each phase will last at least one year. A method may be retained in a deprecation phase for more time if required. Users are welcome to provide us feedback and comments about deprecation decisions.","title":"Phases"},{"location":"getting-started/deprecation/#phase-1-initial-deprecation","text":"In the initial deprecation phase elements are annotated as deprecated. Javadoc explains how to replace that code and why the deprecation occurred. Period: at least 1 year Source Level Compatible: Yes , source code that uses deprecated elements will still compile without modification during this phase. Runtime Level Compatible: Yes , compiled artifacts that use deprecated elements will still execute without modification during this phase.","title":"Phase 1: Initial deprecation"},{"location":"getting-started/deprecation/#phase-2-warn-and-delay","text":"In the second phase a log is printed each time a deprecated method is called. The log explains the replacement that should be used and any specific information related to that API. In order to make sure this log is visible a small pause is made to enable casual revisions to be alert of the situation. This delay is not compulsive and can be turned off by means of an environment variable . Period: at least 2 years from deprecation mark Source Level Compatible: * Yes**, source code that uses deprecated elements will still compile without modification during this phase. Runtime Level Compatible: Yes , compiled artifacts that use deprecated elements will still execute without modification during this phase. However, there will be a visible impact on the runtime due to the log being printed and the pause introduced.","title":"Phase 2: Warn and delay"},{"location":"getting-started/deprecation/#phase-3-runtime-exception","text":"In the third phase a runtime exception is thrown each time a deprecated method is called. The exception message explains the replacement that should be used and any specific information related to that API. This exception throwing can be turned off by means of an environment variable in order to enable old behavior. Period: at least 3 years from deprecation mark Source Level Compatible: Yes , source code that uses deprecated elements will still compile without modification during this phase. Runtime Level Compatible: No , a runtime exception will be thrown each time a deprecated method is called, which can break the execution of compiled artifacts that use those elements. However, this impact can be turned off by means of an environment variable.","title":"Phase 3: Runtime exception"},{"location":"getting-started/deprecation/#phase-4-delete","text":"The forth phase involves deleting the deprecated API. This is done only in situations where the code cleaning is justified in order to have a more understandable API. Also note that this would be done at least 4 years after the initial deprecation mark. Period: at least 4 years from deprecation mark Source Level Compatible: No , deprecated elements will be deleted and will no longer be available, so source code that uses those elements will no longer compile without modification. Runtime Level Compatible: No , compiled artifacts that use deprecated elements will no longer execute without modification, since those elements will have been deleted.","title":"Phase 4: Delete"},{"location":"getting-started/deprecation/#compatible-mode-switch","text":"Both phase 2 and phase 3 of deprecation have a visible impact on the runtime. This impact can be turned off in case of emergency, or if for some reason the code can not be adapted to the new API. In order to bypass the deprecation and preserve the old behaviour set the environment variable: PW_DEPRECATED=[nolog][,nodelay][,noexception] For convenience this can also be set directly from Java, adding the following line within your application initialization: DeprecationUtils.setEnv(EnvironmentVariableKey.NODELAY, EnvironmentVariableKey.NOEXCEPTION);","title":"Compatible mode switch"},{"location":"getting-started/deprecation/#definitions","text":"Compatibility is a wide concept, so we'll refine it here: Source Level Compatibility (SLC): means that our software may be upgraded without modification of existing source code that uses it. Note that source level compatibility does not exempt from recompilation, and that's why we also specify the next level of compatibility, which includes this. Runtime Level Compatibility (RLC): means that our software may be upgraded by just replacing the artifacts in a runtime environment without need for recompilation. For example: void setFoo(String) Foo setFoo(String) L1 and L2 are SLC but not RLC. For this type of changes we'll add, if necessary, the practice of creating a new package and using the newer version classes from the new package. For the old classes/packages, we handle what we believe is very important for long term software, a clear deprecation/deletion policy.","title":"Definitions"},{"location":"getting-started/download-core/","text":"Prowide Core Download Information to grab the library from Maven central repository or download. Gradle compile group: 'com.prowidesoftware' , name: 'pw-swift-core' , version: 'SRU2023-9.4.16' Maven com.prowidesoftware pw-swift-core SRU2023-9.4.16 You can also check out our listing at https://mvnrepository.com/artifact/com.prowidesoftware/pw-swift-core Zip archive For non-maven projects you need to download the full distribution zip and setup your IDE to include the pw-swift-core-SRU2023-9.4.16.jar and the external dependencies in your project classpath. The downloaded package is always a single zip file with the full distribution including: pw-swift-core-SRU2023-9.4.16.jar: the library itself pw-swift-core-SRU2023-9.4.16-javadoc.jar: the javadoc, also available online pw-swift-core-SRU2023-9.4.16-sources.jar: the source code, also available at GitHub lib: required dependency jar files Download SRU2023-9.4.16","title":"Download Core"},{"location":"getting-started/download-core/#prowide-core-download","text":"Information to grab the library from Maven central repository or download.","title":"Prowide Core Download"},{"location":"getting-started/download-core/#gradle","text":"compile group: 'com.prowidesoftware' , name: 'pw-swift-core' , version: 'SRU2023-9.4.16'","title":"Gradle"},{"location":"getting-started/download-core/#maven","text":" com.prowidesoftware pw-swift-core SRU2023-9.4.16 You can also check out our listing at https://mvnrepository.com/artifact/com.prowidesoftware/pw-swift-core","title":"Maven"},{"location":"getting-started/download-core/#zip-archive","text":"For non-maven projects you need to download the full distribution zip and setup your IDE to include the pw-swift-core-SRU2023-9.4.16.jar and the external dependencies in your project classpath. The downloaded package is always a single zip file with the full distribution including: pw-swift-core-SRU2023-9.4.16.jar: the library itself pw-swift-core-SRU2023-9.4.16-javadoc.jar: the javadoc, also available online pw-swift-core-SRU2023-9.4.16-sources.jar: the source code, also available at GitHub lib: required dependency jar files Download SRU2023-9.4.16","title":"Zip archive"},{"location":"getting-started/download-iso20022/","text":"Prowide ISO 20022 Download Information to grab the library from Maven central repository or download. Gradle compile group: 'com.prowidesoftware' , name: 'pw-iso20022' , version: 'SRU2023-9.4.5' Maven com.prowidesoftware pw-iso20022 SRU2023-9.4.5 You can also check out our listing at https://mvnrepository.com/artifact/com.prowidesoftware/pw-iso20022 Zip archive For non-maven projects you need to download the full distribution zip and setup your IDE to include the pw-iso20022-SRU2023-9.4.5.jar and the external dependencies in your project classpath. The downloaded package is always a single zip file with the full distribution including: pw-iso20022-SRU2023-9.4.5.jar: the library itself pw-iso20022-SRU2023-9.4.5-javadoc.jar: the javadoc, also available online pw-iso20022-SRU2023-9.4.5-sources.jar: the source code, also available at GitHub lib: required dependency jar files Download SRU2023-9.4.5","title":"Download ISO 20022"},{"location":"getting-started/download-iso20022/#prowide-iso-20022-download","text":"Information to grab the library from Maven central repository or download.","title":"Prowide ISO 20022 Download"},{"location":"getting-started/download-iso20022/#gradle","text":"compile group: 'com.prowidesoftware' , name: 'pw-iso20022' , version: 'SRU2023-9.4.5'","title":"Gradle"},{"location":"getting-started/download-iso20022/#maven","text":" com.prowidesoftware pw-iso20022 SRU2023-9.4.5 You can also check out our listing at https://mvnrepository.com/artifact/com.prowidesoftware/pw-iso20022","title":"Maven"},{"location":"getting-started/download-iso20022/#zip-archive","text":"For non-maven projects you need to download the full distribution zip and setup your IDE to include the pw-iso20022-SRU2023-9.4.5.jar and the external dependencies in your project classpath. The downloaded package is always a single zip file with the full distribution including: pw-iso20022-SRU2023-9.4.5.jar: the library itself pw-iso20022-SRU2023-9.4.5-javadoc.jar: the javadoc, also available online pw-iso20022-SRU2023-9.4.5-sources.jar: the source code, also available at GitHub lib: required dependency jar files Download SRU2023-9.4.5","title":"Zip archive"},{"location":"getting-started/versioning/","text":"Prowide versioning All Prowide artifacts are versioned using a semantic version with an SRU prefix. SRU stands for SWIFT Standard release Update, and it refers to the yearly updates of the MT and MX standards. The new release specification is normally available in the first quarter of the year, entering production by late November. All participants have to upgrade their systems the same day, and there is one and only one version of the standards per year. Since Prowide artifacts are packaged for a specific version of the standard; the SRU is part of the artifacts version, for example: SRU2021-7.8.9 The first part indicates the yearly standard the artifact is compliant to, and the second part uses the traditional format of http://semver.org/ with the following semantic features: The major version number is only changed when we do a big breaking change, just as upgrading the required Java version for the library products. The minnor number, although it is for minor version, we are aligning it to the SRUs. That is, it is increased annually so that the version alone also has the version of the standard implicit. If SRU2021 is 7.8, then SRU2022 is 7.9, and so forth. Meaning the minor version is redundant with the SRU prefix. The patch number is the one we actually change on all intermediate releases. Depending on the product this could be monthly or weekly. Which version should I use? Normally, from January to late November you should use for production the SRU matching the previous calendar year. Since that would be the version of the standards that is live in the network. Prowide mades available the upcoming SRU packages for the general public by late October, one month before production. And six months in advance, by May, for commercial customers. You can check the SWIFT standard releases schedule at https://www.swift.com/standards/standards-releases","title":"Versioning"},{"location":"getting-started/versioning/#prowide-versioning","text":"All Prowide artifacts are versioned using a semantic version with an SRU prefix. SRU stands for SWIFT Standard release Update, and it refers to the yearly updates of the MT and MX standards. The new release specification is normally available in the first quarter of the year, entering production by late November. All participants have to upgrade their systems the same day, and there is one and only one version of the standards per year. Since Prowide artifacts are packaged for a specific version of the standard; the SRU is part of the artifacts version, for example: SRU2021-7.8.9 The first part indicates the yearly standard the artifact is compliant to, and the second part uses the traditional format of http://semver.org/ with the following semantic features: The major version number is only changed when we do a big breaking change, just as upgrading the required Java version for the library products. The minnor number, although it is for minor version, we are aligning it to the SRUs. That is, it is increased annually so that the version alone also has the version of the standard implicit. If SRU2021 is 7.8, then SRU2022 is 7.9, and so forth. Meaning the minor version is redundant with the SRU prefix. The patch number is the one we actually change on all intermediate releases. Depending on the product this could be monthly or weekly.","title":"Prowide versioning"},{"location":"getting-started/versioning/#which-version-should-i-use","text":"Normally, from January to late November you should use for production the SRU matching the previous calendar year. Since that would be the version of the standards that is live in the network. Prowide mades available the upcoming SRU packages for the general public by late October, one month before production. And six months in advance, by May, for commercial customers. You can check the SWIFT standard releases schedule at https://www.swift.com/standards/standards-releases","title":"Which version should I use?"},{"location":"getting-started/swift/","text":"About SWIFT This information is provided as a quick introduction to the SWIFT standard and the MT format. For detail information please check out www.swift.com The acronym stands for Society for Worldwide Interbank Financial Telecommunications. SWIFT is a cooperative society under Belgian law and it is owned by its member financial institutions. It has offices around the world, and SWIFT headquarters are in La Hulpe, Belgium, near Brussels. It mainly provides a network that enables financial institutions worldwide to send and receive information about financial transactions in a secure, standardized and reliable environment. The term SWIFT is normally used indistinctly to reference the society, the network, the system, and the message protocol. Each financial institution, to exchange banking transactions, must have a banking relationship by either being a bank or affiliating itself with one (or more). The organizations types that can access the service are: Banks, Trading Institutions, Money Brokers, Securities Broker Dealers, Investment Management Institutions, Clearing Systems and Central Depositories, Recognised Exchanges, Trust and Fiduciary Service Companies, Subsidiary Providers of Custody and Nominees, Treasury Counterparties, Treasury ETC Service Providers and Corporates. SWIFT has become the industry standard for syntax in financial messages. Messages formatted to SWIFT standards can be read by, and processed by, many well-known financial processing systems, whether or not the message traveled over the SWIFT network. The SWIFT network support two message standards: MT (ISO 15022): standard based on a proprietary format, composed of boundary delimited blocks, also knonw as FIN MX (ISO 20022): the new standard based on XML syntax and XSD schemas.","title":"About SWIFT"},{"location":"getting-started/swift/#about-swift","text":"This information is provided as a quick introduction to the SWIFT standard and the MT format. For detail information please check out www.swift.com The acronym stands for Society for Worldwide Interbank Financial Telecommunications. SWIFT is a cooperative society under Belgian law and it is owned by its member financial institutions. It has offices around the world, and SWIFT headquarters are in La Hulpe, Belgium, near Brussels. It mainly provides a network that enables financial institutions worldwide to send and receive information about financial transactions in a secure, standardized and reliable environment. The term SWIFT is normally used indistinctly to reference the society, the network, the system, and the message protocol. Each financial institution, to exchange banking transactions, must have a banking relationship by either being a bank or affiliating itself with one (or more). The organizations types that can access the service are: Banks, Trading Institutions, Money Brokers, Securities Broker Dealers, Investment Management Institutions, Clearing Systems and Central Depositories, Recognised Exchanges, Trust and Fiduciary Service Companies, Subsidiary Providers of Custody and Nominees, Treasury Counterparties, Treasury ETC Service Providers and Corporates. SWIFT has become the industry standard for syntax in financial messages. Messages formatted to SWIFT standards can be read by, and processed by, many well-known financial processing systems, whether or not the message traveled over the SWIFT network. The SWIFT network support two message standards: MT (ISO 15022): standard based on a proprietary format, composed of boundary delimited blocks, also knonw as FIN MX (ISO 20022): the new standard based on XML syntax and XSD schemas.","title":"About SWIFT"},{"location":"getting-started/swift/swift-mt/","text":"SWIFT MT The following section describes the MT message structure and key concepts of the standard. Message Types FIN MT messages are identified by a 3-digit number, the first digit representing the Category and the following two representing the specific message inside the category. The categories are: Category Description Prowide Model classes 0 System Messages MT0nn 1 Customer Payments MT1nn 2 Financial Institution Transfers MT2nn 3 MT3nn - FX, Money Market & Derivatives MT3nn 4 Collections and cash letters MT4nn 5 Securities Markets MT5nn 6 Precious Metals & Syndications MT6nn 7 Documentary Credits & Guarantees MT7nn 8 Travellers Cheques MT8nn 9 Cash Management & Customer Status MT9nn For example MT103 is a Single Customer Credit Transfer, while MT202 is a General Financial Institution Transfer. There are several hundred of message types in total. MT Message Block Structure FIN MT messages consist of five blocks of data including three headers, message content, and a trailer. {1: Basic Header Block}{2: Application Header Block}{3: User Header Block} {4: Text Block or body} {5: Trailer Block} All blocks have the same basic format: {n:...}. The curly braces indicate the beginning and end of a block and n is the block identifier (between 1 and 5). There is no carriage return or line feed between blocks. Blocks 3, 4, and 5 may contain sub-blocks or fields delimited by field tags. Block 3 is optional. {1: Basic Header Block} The basic header block is fixed-length and continuous with no field delimiters. It includes the following fields: Application ID (F for financial application, A for general purpose application or L for login and session management) Service ID (01 = FIN/GPA, 21 = ACK/NAK) Logical terminal (LT) address. It is fixed at 12 characters; it must not have X in position 9. Example BANKBEBBAXXX. Session number (four digits) and Sequence number (six digits). {2: Application Header Block} There are two types of application headers: Input and Output (from the network perspective). Both are fixed-length and continuous with no field delimiters. Input Used in outgoing messages, when a message is input to the SWIFT network. It includes the following fields: I = Input Message type Receiver's address with X in position 9/ It is padded with Xs if no branch is required. Example: BANKDEFFXXXX The message priority (S = System, N = Normal, U = Urgent) Delivery monitoring (1 = Non delivery warning, 2 = Delivery notification, 3 = Both valid Obsolescence period. It specifies when a non-delivery notification (003 - 15 minutes, 020 - 100 minutes) Output Used in incoming messages, when a message is output from the SWIFT network. It includes the following fields; for example: O 101 1200 220112 BANKBEBBAXXX 2222 123456 220112 1201 N O = Output 101 = Message type 1200 = Input time with respect to the sender 220112 = the MIR date (message input reference) in YYMMDD format BANKBEBBAXXX = 12 characters containing the logical terminal field of the MIR (address of the sender of the message) 2222 = 4 characters containing the session number field of the MIR 123456 = 6 characters containing the sequence number field of the MIR 220112 = String of 6 characters containing the Output date local to the receiver, written in the following format: YYMMDD 1201 = 4 characters containing the Output time local to the receiver, written in the following format: HHMM N = Priority The Message Input Reference (MIR) is sometimes confusing because it is an output block with an input reference. The important thing to understand here is that the MIR information is related to the original sender of the message that has been received. {3: User Header Block} This is an optional block and can include several tags, being the most common: 113:xxxx = Optional banking priority code The Message User Reference (MUR) used by applications for reconciliation with ACK. {4: Text Block or body} This block is where the actual message content. The format, which is variable length and requires use of CRLF as a field delimiter, is as follows: {4: [CRLF] :20:PAYREFTB54302 [CRLF] :32A:970103BEF1000000, [CRLF] :50:CUSTOMER NAME [CRLF] AND ADDRESS [CRLF] :59:/123-456-789 [CRLF] BENEFICIARY NAME [CRLF] AND ADDRESS [CRLF] -} Where the CRLF is the carriage return and line feed and is the mandatory fields delimiter. The content of the text block is a collection of ordered fields in the order specified for the message type. For some message types, the fields are logically grouped into sequences. Sequences can be mandatory or optional, and can repeat. Sequences also can be divided into subsequences. In addition, single fields and groups of consecutive fields can repeat. {5: Trailer Block} This block is mostly for SWIFT system use and contains a number of fields that are denoted by keywords and put into curly braces, for example: {5: {MAC:12345678}{CHK:123456789ABC}} The most common fields used in the trailer block are MAC: Message Authentication Code calculated based on the entire contents of the message using a pre exchanged key and a secret algorithm. CHK: Checksum calculated for all message types. PDE: Possible Duplicate Emission added if user thinks the same message was sent previously. DLM: Added by SWIFT if an urgent message (U) has not been delivered within 15 minutes, or a normal message (N) within 100 minutes. MIR and MOR MIR (message input reference) and MOR (message output reference) are messages unique identifiers containing the date, logical terminal (including branch code), session and sequence numbers. Nevertheless this identifiers can be confusing sometimes because they must be thought from SWIFT perspective. A message created by the sender user/application is considered an INPUT message, because it gets into the SWIFT network. When the message is delivered and gets out of the network it is considered an OUTPUT message. Therefore the headers of a sent message are not exactly the same as the headers of the received message at the destination party. Analogous the headers of a message that the receiving user/application gets from SWIFT are not exactly the same as the headers when the message was created and sent by the sending party. The usage of MIR and MOR are clear when analyzing system messages. A non delivery warning for example, includes the original MIR of the sent message, but not the MOR because the message was not delivered yet. But a delivery confirmation on the other hand, includes both, the sender's MIR and the receiver's MOR. System messages provide MIR/MOR information using fields 106 and 107 respectively. SCORE Standardised CORporate Environment (SCORE) is a SWIFT standard for the exchange of financial information between corporate customers and their banks. For MT messages, it is based on exchanges of the MT798 proprietary envelop message with many sub-message types. Some of the inner payloads are MT messages, but other are proprietary messages defined just for SCORE. The Prowide Core library contains several helper API to handle the MT798 envelop and the inner messages. And the Prowide Integrator library complements that, by adding a set of specific model classes for each SCORE message such as the MT798<745>, 798<760>, 798<726>, etc... along the full structure validation of the envelop and the inner messages.","title":"SWIFT MT"},{"location":"getting-started/swift/swift-mt/#swift-mt","text":"The following section describes the MT message structure and key concepts of the standard.","title":"SWIFT MT"},{"location":"getting-started/swift/swift-mt/#message-types","text":"FIN MT messages are identified by a 3-digit number, the first digit representing the Category and the following two representing the specific message inside the category. The categories are: Category Description Prowide Model classes 0 System Messages MT0nn 1 Customer Payments MT1nn 2 Financial Institution Transfers MT2nn 3 MT3nn - FX, Money Market & Derivatives MT3nn 4 Collections and cash letters MT4nn 5 Securities Markets MT5nn 6 Precious Metals & Syndications MT6nn 7 Documentary Credits & Guarantees MT7nn 8 Travellers Cheques MT8nn 9 Cash Management & Customer Status MT9nn For example MT103 is a Single Customer Credit Transfer, while MT202 is a General Financial Institution Transfer. There are several hundred of message types in total.","title":"Message Types"},{"location":"getting-started/swift/swift-mt/#mt-message-block-structure","text":"FIN MT messages consist of five blocks of data including three headers, message content, and a trailer. {1: Basic Header Block}{2: Application Header Block}{3: User Header Block} {4: Text Block or body} {5: Trailer Block} All blocks have the same basic format: {n:...}. The curly braces indicate the beginning and end of a block and n is the block identifier (between 1 and 5). There is no carriage return or line feed between blocks. Blocks 3, 4, and 5 may contain sub-blocks or fields delimited by field tags. Block 3 is optional.","title":"MT Message Block Structure"},{"location":"getting-started/swift/swift-mt/#1-basic-header-block","text":"The basic header block is fixed-length and continuous with no field delimiters. It includes the following fields: Application ID (F for financial application, A for general purpose application or L for login and session management) Service ID (01 = FIN/GPA, 21 = ACK/NAK) Logical terminal (LT) address. It is fixed at 12 characters; it must not have X in position 9. Example BANKBEBBAXXX. Session number (four digits) and Sequence number (six digits).","title":"{1: Basic Header Block}"},{"location":"getting-started/swift/swift-mt/#2-application-header-block","text":"There are two types of application headers: Input and Output (from the network perspective). Both are fixed-length and continuous with no field delimiters.","title":"{2: Application Header Block}"},{"location":"getting-started/swift/swift-mt/#input","text":"Used in outgoing messages, when a message is input to the SWIFT network. It includes the following fields: I = Input Message type Receiver's address with X in position 9/ It is padded with Xs if no branch is required. Example: BANKDEFFXXXX The message priority (S = System, N = Normal, U = Urgent) Delivery monitoring (1 = Non delivery warning, 2 = Delivery notification, 3 = Both valid Obsolescence period. It specifies when a non-delivery notification (003 - 15 minutes, 020 - 100 minutes)","title":"Input"},{"location":"getting-started/swift/swift-mt/#output","text":"Used in incoming messages, when a message is output from the SWIFT network. It includes the following fields; for example: O 101 1200 220112 BANKBEBBAXXX 2222 123456 220112 1201 N O = Output 101 = Message type 1200 = Input time with respect to the sender 220112 = the MIR date (message input reference) in YYMMDD format BANKBEBBAXXX = 12 characters containing the logical terminal field of the MIR (address of the sender of the message) 2222 = 4 characters containing the session number field of the MIR 123456 = 6 characters containing the sequence number field of the MIR 220112 = String of 6 characters containing the Output date local to the receiver, written in the following format: YYMMDD 1201 = 4 characters containing the Output time local to the receiver, written in the following format: HHMM N = Priority The Message Input Reference (MIR) is sometimes confusing because it is an output block with an input reference. The important thing to understand here is that the MIR information is related to the original sender of the message that has been received.","title":"Output"},{"location":"getting-started/swift/swift-mt/#3-user-header-block","text":"This is an optional block and can include several tags, being the most common: 113:xxxx = Optional banking priority code The Message User Reference (MUR) used by applications for reconciliation with ACK.","title":"{3: User Header Block}"},{"location":"getting-started/swift/swift-mt/#4-text-block-or-body","text":"This block is where the actual message content. The format, which is variable length and requires use of CRLF as a field delimiter, is as follows: {4: [CRLF] :20:PAYREFTB54302 [CRLF] :32A:970103BEF1000000, [CRLF] :50:CUSTOMER NAME [CRLF] AND ADDRESS [CRLF] :59:/123-456-789 [CRLF] BENEFICIARY NAME [CRLF] AND ADDRESS [CRLF] -} Where the CRLF is the carriage return and line feed and is the mandatory fields delimiter. The content of the text block is a collection of ordered fields in the order specified for the message type. For some message types, the fields are logically grouped into sequences. Sequences can be mandatory or optional, and can repeat. Sequences also can be divided into subsequences. In addition, single fields and groups of consecutive fields can repeat.","title":"{4: Text Block or body}"},{"location":"getting-started/swift/swift-mt/#5-trailer-block","text":"This block is mostly for SWIFT system use and contains a number of fields that are denoted by keywords and put into curly braces, for example: {5: {MAC:12345678}{CHK:123456789ABC}} The most common fields used in the trailer block are MAC: Message Authentication Code calculated based on the entire contents of the message using a pre exchanged key and a secret algorithm. CHK: Checksum calculated for all message types. PDE: Possible Duplicate Emission added if user thinks the same message was sent previously. DLM: Added by SWIFT if an urgent message (U) has not been delivered within 15 minutes, or a normal message (N) within 100 minutes.","title":"{5: Trailer Block}"},{"location":"getting-started/swift/swift-mt/#mir-and-mor","text":"MIR (message input reference) and MOR (message output reference) are messages unique identifiers containing the date, logical terminal (including branch code), session and sequence numbers. Nevertheless this identifiers can be confusing sometimes because they must be thought from SWIFT perspective. A message created by the sender user/application is considered an INPUT message, because it gets into the SWIFT network. When the message is delivered and gets out of the network it is considered an OUTPUT message. Therefore the headers of a sent message are not exactly the same as the headers of the received message at the destination party. Analogous the headers of a message that the receiving user/application gets from SWIFT are not exactly the same as the headers when the message was created and sent by the sending party. The usage of MIR and MOR are clear when analyzing system messages. A non delivery warning for example, includes the original MIR of the sent message, but not the MOR because the message was not delivered yet. But a delivery confirmation on the other hand, includes both, the sender's MIR and the receiver's MOR. System messages provide MIR/MOR information using fields 106 and 107 respectively.","title":"MIR and MOR"},{"location":"getting-started/swift/swift-mt/#score","text":"Standardised CORporate Environment (SCORE) is a SWIFT standard for the exchange of financial information between corporate customers and their banks. For MT messages, it is based on exchanges of the MT798 proprietary envelop message with many sub-message types. Some of the inner payloads are MT messages, but other are proprietary messages defined just for SCORE. The Prowide Core library contains several helper API to handle the MT798 envelop and the inner messages. And the Prowide Integrator library complements that, by adding a set of specific model classes for each SCORE message such as the MT798<745>, 798<760>, 798<726>, etc... along the full structure validation of the envelop and the inner messages.","title":"SCORE"},{"location":"getting-started/swift/swift-mx/","text":"ISO 20022 The ISO 20022 is a framework for the electronic exchange of financial information, composed by a catalog of items and message types, structured as XML payloads. The framework allows communities of users and message development organizations to define message sets according to an internationally agreed approach using internationally agreed business semantics. By creating a common language and model for payments data, ISO 20022 significantly improves the quality of data across the payments ecosystem. ISO 20022 creates a common language and model for payments data, ISO 20022 significantly improves the quality of data across the payments ecosystem. Richer, structured, meaningful data enable new client experiences, while improving compliance and efficiency. ISO 20022 defines many message categories, including: Payments and Cash Management: Messages supporting cash account management, payments initiation, clearing and settlement, and cash management, etc. Securities: Messages supporting pre-trade, trade, post-trade, clearing and settlement, securities management, securities account management, reconciliation, asset servicing, collateral management, etc. Trade Services: Messages supporting procurement, trade finance products and services, forecasting, reconciliation, accounting, remittance information, etc. Card Payments: Messages supporting card transactions between acceptor and acquirer, acquirer and issuer, sale system and POI, terminal management, clearing and settlement, fee collection, etc. Foreign Exchange: Messages supporting pre-trade, trade, post-trade, notification, clearing and settlement, reporting and reconciliation of FX products. MX An MX is an XML message definition for use on the SWIFT network. Documentation is only provided for base messages developed by SWIFT. Most MX messages are also ISO 20022 messages. Other ISO 20022 messages are published on www.iso20022.org. Within our libraries implementatino we use the terns ISO 20022 and MX interchangeably. CBPR+ Cross-border Payments and Reporting Plus(CBPR+) specification define how ISO 20022 should be used for cross-border payments and cash reporting on the SWIFT network. Conformance to CBPR+ specification is validated by the SWIFT message service, so it imperative that users implement the specification correctly. The CBPR+ specification includes a set of restricted ISO 20022 message schemas, along a set of rules that payment message must follow. CBPR+ also includes standardized rules that define translation from the MT standard to CBPR+ ISO 20022 and from CBPR+ ISO 20022 to MT. The Prowide Integrator libraries, contain comprehensive support for the CBPR+ restricted model, parser, validators and translators to and from MT. SEPA Developed by the European Payments Council (EPC), the Single Euro Payments Area (SEPA) is a payment-integration and payment standardization initiative that aims to facilitate and harmonize payments in EURO across the SEPA zone. ISO 20022 XML is mandatory for the exchange of SEPA payments between Banks and for the Client-to-Bank instructions. Thus it can be seen as a restricted version of ISO 20022, or as an implementation of the ISO 20022 framework. The Prowide Integrator libraries, contain comprehensive support for the SEPA restricted model, parser and validator. SIC Swiss Interbank Clearing (SIC) is the Swiss RGTS in which the participating financial institutions process their large-value payments as well as a part of their retail payments in Swiss francs. While SIC is also based on the ISO20022 framework, the namespace is different used by the XSD schemas are different. The Prowide Integrator libraries, contain a specific model for SIC messages, as well as some specific translations between MT and SIC.","title":"ISO 20022"},{"location":"getting-started/swift/swift-mx/#iso-20022","text":"The ISO 20022 is a framework for the electronic exchange of financial information, composed by a catalog of items and message types, structured as XML payloads. The framework allows communities of users and message development organizations to define message sets according to an internationally agreed approach using internationally agreed business semantics. By creating a common language and model for payments data, ISO 20022 significantly improves the quality of data across the payments ecosystem. ISO 20022 creates a common language and model for payments data, ISO 20022 significantly improves the quality of data across the payments ecosystem. Richer, structured, meaningful data enable new client experiences, while improving compliance and efficiency. ISO 20022 defines many message categories, including: Payments and Cash Management: Messages supporting cash account management, payments initiation, clearing and settlement, and cash management, etc. Securities: Messages supporting pre-trade, trade, post-trade, clearing and settlement, securities management, securities account management, reconciliation, asset servicing, collateral management, etc. Trade Services: Messages supporting procurement, trade finance products and services, forecasting, reconciliation, accounting, remittance information, etc. Card Payments: Messages supporting card transactions between acceptor and acquirer, acquirer and issuer, sale system and POI, terminal management, clearing and settlement, fee collection, etc. Foreign Exchange: Messages supporting pre-trade, trade, post-trade, notification, clearing and settlement, reporting and reconciliation of FX products.","title":"ISO 20022"},{"location":"getting-started/swift/swift-mx/#mx","text":"An MX is an XML message definition for use on the SWIFT network. Documentation is only provided for base messages developed by SWIFT. Most MX messages are also ISO 20022 messages. Other ISO 20022 messages are published on www.iso20022.org. Within our libraries implementatino we use the terns ISO 20022 and MX interchangeably.","title":"MX"},{"location":"getting-started/swift/swift-mx/#cbpr","text":"Cross-border Payments and Reporting Plus(CBPR+) specification define how ISO 20022 should be used for cross-border payments and cash reporting on the SWIFT network. Conformance to CBPR+ specification is validated by the SWIFT message service, so it imperative that users implement the specification correctly. The CBPR+ specification includes a set of restricted ISO 20022 message schemas, along a set of rules that payment message must follow. CBPR+ also includes standardized rules that define translation from the MT standard to CBPR+ ISO 20022 and from CBPR+ ISO 20022 to MT. The Prowide Integrator libraries, contain comprehensive support for the CBPR+ restricted model, parser, validators and translators to and from MT.","title":"CBPR+"},{"location":"getting-started/swift/swift-mx/#sepa","text":"Developed by the European Payments Council (EPC), the Single Euro Payments Area (SEPA) is a payment-integration and payment standardization initiative that aims to facilitate and harmonize payments in EURO across the SEPA zone. ISO 20022 XML is mandatory for the exchange of SEPA payments between Banks and for the Client-to-Bank instructions. Thus it can be seen as a restricted version of ISO 20022, or as an implementation of the ISO 20022 framework. The Prowide Integrator libraries, contain comprehensive support for the SEPA restricted model, parser and validator.","title":"SEPA"},{"location":"getting-started/swift/swift-mx/#sic","text":"Swiss Interbank Clearing (SIC) is the Swiss RGTS in which the participating financial institutions process their large-value payments as well as a part of their retail payments in Swiss francs. While SIC is also based on the ISO20022 framework, the namespace is different used by the XSD schemas are different. The Prowide Integrator libraries, contain a specific model for SIC messages, as well as some specific translations between MT and SIC.","title":"SIC"},{"location":"integrator/","text":"Prowide Integrator - Overview Prowide Integrator is a set of complementary Java libraries built on top of the open source. These libraries are licensed software , thus download and usage is restricted to licensed customers. Libraries stack The SDK is the cornerstone library. It provides a set of APIs to interact with SWIFT networks and services, such as SWIFT Alliance Access (SAA). And also extended model classes for specific sub-standards such as CBPR+, SEPA, SIC and SCORE. Complementing the SDK, each additional library provides specific features for standard compliance validation, MT/MX automatic translations and conversions to proprietary formats. Getting a license If you are interested on the Prowide Integrator libraries and features contact Prowide by using the online contact form . Info More information regarding Prowide solutions at www.prowidesoftware.com","title":"Prowide Integrator - Overview"},{"location":"integrator/#prowide-integrator-overview","text":"Prowide Integrator is a set of complementary Java libraries built on top of the open source. These libraries are licensed software , thus download and usage is restricted to licensed customers.","title":"Prowide Integrator - Overview"},{"location":"integrator/#libraries-stack","text":"The SDK is the cornerstone library. It provides a set of APIs to interact with SWIFT networks and services, such as SWIFT Alliance Access (SAA). And also extended model classes for specific sub-standards such as CBPR+, SEPA, SIC and SCORE. Complementing the SDK, each additional library provides specific features for standard compliance validation, MT/MX automatic translations and conversions to proprietary formats.","title":"Libraries stack"},{"location":"integrator/#getting-a-license","text":"If you are interested on the Prowide Integrator libraries and features contact Prowide by using the online contact form . Info More information regarding Prowide solutions at www.prowidesoftware.com","title":"Getting a license"},{"location":"integrator/cbpr/","text":"Prowide Integrator CBPR+ Overview The key feature provided by the CBPR+ extension is the specific model implementation for the Cross Border Payments Reporting Plus specification messages. This is a restricted ISO 20022 version with a subset of messages with specific constraints. The supported schemas and guidelines version is 2.1 effective November 2022. Supported message schemes The following table includes all the supported message types: camt_029_001_09 camt_052_001_08 camt_053_001_08 camt_054_001_08 camt_056_001_08 camt_057_001_06 camt_060_001_05 pacs_002_001_10 pacs_004_001_09 pacs_008_001_08 pacs_008_001_08_STP pacs_009_001_08 pacs_009_001_08_ADV pacs_009_001_08_COV pacs_010_001_03 pain_001_001_09 pain_002_001_10 Message model For each of the described message types, a specific implementation message class is provided, into a single common package: com . prowidesoftware . swift . model . mx . cbpr The CBPR+ message subset uses the same namespaces as the ISO standard. Unknown message type parsing To facilitate message type detection and parsing, a CBPR message factory is included in the package: AbstractMX mx = CbprMessageFactory . createMessage ( xmlContent ); The createMessage method accepts a plain string with the whole XML content. The specific message type is detected using information from the AppHdr element. In particular, using the: pacs.009.001.08 swift.cbprplus.adv.02 Notice the BAH v2 header is mandatory for CBPR+ messages, as well as the BizSvc. If the message is detected as a CBPR+ the method returns its content parsed into a specific model object such as: com.prowidesoftware.swift.model.mx.cbpr.MxPacs00900108ADV The parent class AbstractMX is still as in the generic ISO 20022 model messages, however the specific model for CBPR+ is a class within the cbpr package. Known message type parsing When you already know the message type to parse, you can use the specific model class directly. MxPacs00900108ADV mx = MxPacs00900108ADV . parse ( xmlContent ); The parser imposes no restriction on the validity of the message, just the namespace in the Document must match. And it will fill the model object with all the corresponding elements read from the XML content. The xml could be just the clean payload, or it could also contain any type of wrapper/envelope content that will be silently ignored. Since the class name of the CBPR messages is the same as the class name of the standard ISO 20022 message model, make sure your source code is importing the model class within the cbpr package . Building a message The creation of a new CBPR+ message is similar to the creation of any standard ISO message. You just populate the Java object and the model will already include the constraints from the CBPR+ schema. For example: MxPacs00800108 mx = new MxPacs00800108 (); mx . setFIToFICstmrCdtTrf ( new FIToFICustomerCreditTransferV08 ()); mx . getFIToFICstmrCdtTrf (). setGrpHdr ( new GroupHeader931Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setMsgId ( \"1234\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setCreDtTm ( now ()); // include timezone here mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setNbOfTxs ( \"1\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setSttlmInf ( new SettlementInstruction71Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getSttlmInf (). setSttlmMtd ( SettlementMethod1Code1Pacs008 . INDA ); mx . getFIToFICstmrCdtTrf (). setCdtTrfTxInf ( new CreditTransferTransaction391 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setPmtId ( new PaymentIdentification71 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtId (). setInstrId ( \"REF\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtId (). setEndToEndId ( \"gwwg8dluwzG\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtId (). setTxId ( \"bbbb\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtId (). setUETR ( \"8a562c67-ca16-48ba-b074-65581be6f011\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setPmtTpInf ( new PaymentTypeInformation281 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtTpInf (). setLclInstrm ( new LocalInstrument2Choice1 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtTpInf (). getLclInstrm (). setCd ( \"FOO\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setIntrBkSttlmAmt ( new CBPRAmount1 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getIntrBkSttlmAmt (). setCcy ( \"EUR\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getIntrBkSttlmAmt (). setValue ( new BigDecimal ( \"1234.56\" )); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setChrgBr ( ChargeBearerType1Code1 . CRED ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setDbtr ( new PartyIdentification1352Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getDbtr (). setNm ( \"Foo1\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setDbtrAgt ( new BranchAndFinancialInstitutionIdentification61Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getDbtrAgt (). setFinInstnId ( new FinancialInstitutionIdentification181 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getDbtrAgt (). getFinInstnId (). setBICFI ( \"AAAAUSXXXXX\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setCdtr ( new PartyIdentification1353Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getCdtr (). setNm ( \"Foo2\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setCdtrAgt ( new BranchAndFinancialInstitutionIdentification62Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getCdtrAgt (). setFinInstnId ( new FinancialInstitutionIdentification181 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getCdtrAgt (). getFinInstnId (). setBICFI ( \"AAAAUSXXXXX\" ); String xml = mx . message (); As a small remark, beware when creating date and time objects that the XMLGregorianCalendar object used in the setter should have the time zone set. This is because for CBPR+ the timezone is mandatory. So when creating the object for the setter you should do something like this: LocalDateTime localDate = LocalDateTime . now (); XMLGregorianCalendar cal = DatatypeFactory . newInstance (). newXMLGregorianCalendar ( localDate . toString ()); cal . setTimezone ( - 3 ); Message types enumeration An enumeration CbprMessageType is provided with the list of supported CBPR+ messages. This enumeration implements the internal SchemaProvider interface, so it can be used with the Prowide Integrator Validator library to run the CBPR+ validation for an XML. The enum also includes a few helper methods, for example to detect the specific type from an AppHdr. CBPR+ validation Only available if you have a license of the Prowide Integrator Validation module. Along the standard ISO 20022 model, the Validation module provides an out-of-the-box validation for CBPR+ messages. There are two possible scenarios: * You are validating a message created by you in your application with the message model. * You are validating a message created externally and received in XML format. The main entry point to validate CBPR+ messages is the CbprValidationEngine class. The class provides an entry point using the plain XML content, and also an entry if you already have a model object from the com.prowidesoftware.swift.model.mx.cbpr package, such as MxPain00800108 . This specific validation engine implementation will already apply the CBPR+ specific schema and on top of the standard ISO 20022 and cross-element validations it will check the CBPR+ UG rules. When your source content is already the XML it is always recommended to use the XML as parameter for the validation. If you parse the XML into an MX object first, and then call the validation using the parsed message as parameter, some errors may not be detected. The validation call with the model object is only intended for scenarios where you are building the message using the model API. CBPR+ translations Only available if you have a license of the Prowide Integrator MT/MX Translations module. Along the standard ISO 20022 model, the MT/MX translations module provides out-of-the-box translations for CBPR+ messages. Specific translation classes are provided in the com.prowidesoftware.swift.translations.cbpr Automatic translation Since there are several translation options depending on the message type, a CBPR+ translation factory is provided. AbstractMX mx = CbprMessageFactory . createMessage ( xmlContent ); Translator translator = CbprTranslatorFactory . getTranslator ( mx ); if ( translator == null ) { AbstractMT mt = ( AbstractMT ) translator . translate ( mx ); } First thing is to parse the source XML into a CBPR+ model object. When the message type is unknown, you can do that with ease with the CBPR message factory. The parsed object is then passed to the translator factory. The factory checks the specific message type and in some cases the message content, and determines automatically which translation to apply. If a translator is found, meaning the source message has been detected and satisfies the translation preconditions, the specific translator is returned. All translator classes implement a common interface with the translate method, that given the MX input returns the corresponding MT model output. Analogously, to run a translation from MT to CBPR+, the factory provides an entry to pass the MT model as parameter. This translation procedure is the same as in the ISO 20022 translations, with the only difference being the implementation classes package. Specific translations When the message types are known, the specific translation classes can be used directly. The class name reflects the specific source and target message type, including the available variant combinations. For example, the class MxPacs00400109_MT103_Translation is used to translate a pacs.004 payment return into an MT103 return message. Once the class is identified, the main entry for the translation is the translate method. This method has several options, where the most simple expects the source message as parameter and returns the target message model as output. This translation procedure is the same as in the ISO 20022 translations, with the only difference being the implementation classes package. Javadoc Online javadoc Prowide Integrator CBPR+ Javadoc SRU2023-9.4.x","title":"CBPR+"},{"location":"integrator/cbpr/#prowide-integrator-cbpr","text":"","title":"Prowide Integrator CBPR+"},{"location":"integrator/cbpr/#overview","text":"The key feature provided by the CBPR+ extension is the specific model implementation for the Cross Border Payments Reporting Plus specification messages. This is a restricted ISO 20022 version with a subset of messages with specific constraints. The supported schemas and guidelines version is 2.1 effective November 2022.","title":"Overview"},{"location":"integrator/cbpr/#supported-message-schemes","text":"The following table includes all the supported message types: camt_029_001_09 camt_052_001_08 camt_053_001_08 camt_054_001_08 camt_056_001_08 camt_057_001_06 camt_060_001_05 pacs_002_001_10 pacs_004_001_09 pacs_008_001_08 pacs_008_001_08_STP pacs_009_001_08 pacs_009_001_08_ADV pacs_009_001_08_COV pacs_010_001_03 pain_001_001_09 pain_002_001_10","title":"Supported message schemes"},{"location":"integrator/cbpr/#message-model","text":"For each of the described message types, a specific implementation message class is provided, into a single common package: com . prowidesoftware . swift . model . mx . cbpr The CBPR+ message subset uses the same namespaces as the ISO standard.","title":"Message model"},{"location":"integrator/cbpr/#unknown-message-type-parsing","text":"To facilitate message type detection and parsing, a CBPR message factory is included in the package: AbstractMX mx = CbprMessageFactory . createMessage ( xmlContent ); The createMessage method accepts a plain string with the whole XML content. The specific message type is detected using information from the AppHdr element. In particular, using the: pacs.009.001.08 swift.cbprplus.adv.02 Notice the BAH v2 header is mandatory for CBPR+ messages, as well as the BizSvc. If the message is detected as a CBPR+ the method returns its content parsed into a specific model object such as: com.prowidesoftware.swift.model.mx.cbpr.MxPacs00900108ADV The parent class AbstractMX is still as in the generic ISO 20022 model messages, however the specific model for CBPR+ is a class within the cbpr package.","title":"Unknown message type parsing"},{"location":"integrator/cbpr/#known-message-type-parsing","text":"When you already know the message type to parse, you can use the specific model class directly. MxPacs00900108ADV mx = MxPacs00900108ADV . parse ( xmlContent ); The parser imposes no restriction on the validity of the message, just the namespace in the Document must match. And it will fill the model object with all the corresponding elements read from the XML content. The xml could be just the clean payload, or it could also contain any type of wrapper/envelope content that will be silently ignored. Since the class name of the CBPR messages is the same as the class name of the standard ISO 20022 message model, make sure your source code is importing the model class within the cbpr package .","title":"Known message type parsing"},{"location":"integrator/cbpr/#building-a-message","text":"The creation of a new CBPR+ message is similar to the creation of any standard ISO message. You just populate the Java object and the model will already include the constraints from the CBPR+ schema. For example: MxPacs00800108 mx = new MxPacs00800108 (); mx . setFIToFICstmrCdtTrf ( new FIToFICustomerCreditTransferV08 ()); mx . getFIToFICstmrCdtTrf (). setGrpHdr ( new GroupHeader931Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setMsgId ( \"1234\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setCreDtTm ( now ()); // include timezone here mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setNbOfTxs ( \"1\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setSttlmInf ( new SettlementInstruction71Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getSttlmInf (). setSttlmMtd ( SettlementMethod1Code1Pacs008 . INDA ); mx . getFIToFICstmrCdtTrf (). setCdtTrfTxInf ( new CreditTransferTransaction391 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setPmtId ( new PaymentIdentification71 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtId (). setInstrId ( \"REF\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtId (). setEndToEndId ( \"gwwg8dluwzG\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtId (). setTxId ( \"bbbb\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtId (). setUETR ( \"8a562c67-ca16-48ba-b074-65581be6f011\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setPmtTpInf ( new PaymentTypeInformation281 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtTpInf (). setLclInstrm ( new LocalInstrument2Choice1 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getPmtTpInf (). getLclInstrm (). setCd ( \"FOO\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setIntrBkSttlmAmt ( new CBPRAmount1 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getIntrBkSttlmAmt (). setCcy ( \"EUR\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getIntrBkSttlmAmt (). setValue ( new BigDecimal ( \"1234.56\" )); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setChrgBr ( ChargeBearerType1Code1 . CRED ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setDbtr ( new PartyIdentification1352Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getDbtr (). setNm ( \"Foo1\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setDbtrAgt ( new BranchAndFinancialInstitutionIdentification61Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getDbtrAgt (). setFinInstnId ( new FinancialInstitutionIdentification181 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getDbtrAgt (). getFinInstnId (). setBICFI ( \"AAAAUSXXXXX\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setCdtr ( new PartyIdentification1353Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getCdtr (). setNm ( \"Foo2\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). setCdtrAgt ( new BranchAndFinancialInstitutionIdentification62Pacs008 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getCdtrAgt (). setFinInstnId ( new FinancialInstitutionIdentification181 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getCdtrAgt (). getFinInstnId (). setBICFI ( \"AAAAUSXXXXX\" ); String xml = mx . message (); As a small remark, beware when creating date and time objects that the XMLGregorianCalendar object used in the setter should have the time zone set. This is because for CBPR+ the timezone is mandatory. So when creating the object for the setter you should do something like this: LocalDateTime localDate = LocalDateTime . now (); XMLGregorianCalendar cal = DatatypeFactory . newInstance (). newXMLGregorianCalendar ( localDate . toString ()); cal . setTimezone ( - 3 );","title":"Building a message"},{"location":"integrator/cbpr/#message-types-enumeration","text":"An enumeration CbprMessageType is provided with the list of supported CBPR+ messages. This enumeration implements the internal SchemaProvider interface, so it can be used with the Prowide Integrator Validator library to run the CBPR+ validation for an XML. The enum also includes a few helper methods, for example to detect the specific type from an AppHdr.","title":"Message types enumeration"},{"location":"integrator/cbpr/#cbpr-validation","text":"Only available if you have a license of the Prowide Integrator Validation module. Along the standard ISO 20022 model, the Validation module provides an out-of-the-box validation for CBPR+ messages. There are two possible scenarios: * You are validating a message created by you in your application with the message model. * You are validating a message created externally and received in XML format. The main entry point to validate CBPR+ messages is the CbprValidationEngine class. The class provides an entry point using the plain XML content, and also an entry if you already have a model object from the com.prowidesoftware.swift.model.mx.cbpr package, such as MxPain00800108 . This specific validation engine implementation will already apply the CBPR+ specific schema and on top of the standard ISO 20022 and cross-element validations it will check the CBPR+ UG rules. When your source content is already the XML it is always recommended to use the XML as parameter for the validation. If you parse the XML into an MX object first, and then call the validation using the parsed message as parameter, some errors may not be detected. The validation call with the model object is only intended for scenarios where you are building the message using the model API.","title":"CBPR+ validation"},{"location":"integrator/cbpr/#cbpr-translations","text":"Only available if you have a license of the Prowide Integrator MT/MX Translations module. Along the standard ISO 20022 model, the MT/MX translations module provides out-of-the-box translations for CBPR+ messages. Specific translation classes are provided in the com.prowidesoftware.swift.translations.cbpr","title":"CBPR+ translations"},{"location":"integrator/cbpr/#automatic-translation","text":"Since there are several translation options depending on the message type, a CBPR+ translation factory is provided. AbstractMX mx = CbprMessageFactory . createMessage ( xmlContent ); Translator translator = CbprTranslatorFactory . getTranslator ( mx ); if ( translator == null ) { AbstractMT mt = ( AbstractMT ) translator . translate ( mx ); } First thing is to parse the source XML into a CBPR+ model object. When the message type is unknown, you can do that with ease with the CBPR message factory. The parsed object is then passed to the translator factory. The factory checks the specific message type and in some cases the message content, and determines automatically which translation to apply. If a translator is found, meaning the source message has been detected and satisfies the translation preconditions, the specific translator is returned. All translator classes implement a common interface with the translate method, that given the MX input returns the corresponding MT model output. Analogously, to run a translation from MT to CBPR+, the factory provides an entry to pass the MT model as parameter. This translation procedure is the same as in the ISO 20022 translations, with the only difference being the implementation classes package.","title":"Automatic translation"},{"location":"integrator/cbpr/#specific-translations","text":"When the message types are known, the specific translation classes can be used directly. The class name reflects the specific source and target message type, including the available variant combinations. For example, the class MxPacs00400109_MT103_Translation is used to translate a pacs.004 payment return into an MT103 return message. Once the class is identified, the main entry for the translation is the translate method. This method has several options, where the most simple expects the source message as parameter and returns the target message model as output. This translation procedure is the same as in the ISO 20022 translations, with the only difference being the implementation classes package.","title":"Specific translations"},{"location":"integrator/cbpr/#javadoc","text":"Online javadoc Prowide Integrator CBPR+ Javadoc SRU2023-9.4.x","title":"Javadoc"},{"location":"integrator/mule/","text":"Prowide MULE Connector The Prowide Mule Connector for Mule 4 facilitates an out-of-the-box integration of key features from the Prowide libraries in MULE applications. The key features enable validation and translation of SWIFT messages in Mule flows. Including operations for the legacy SWIFT MT standard and the ISO 20022 MX standard. Current implementation implements the following operations: Validate MT messages Validate ISO 20022 (MX) messages Validate CBPR+ messages Translate MT to ISO 20022 (MX) Translate ISO 20022 (MX) to MT Translate CBPR+ to MT Additional operations might be included in future releases. Application/Service Version Mule Runtime 4.0.1 Java 8+ Requirements The Prowide Integrator is a set of licensed Java libraries that complements the open source libraries Prowide Core and Prowide ISO 20022. Thus in order to use the Prowide Mule connector, you need to have a valid license and access to the Prowide Integrator libraries distribution. More information about the Prowide Integrator can be found in the Prowide Integrator product page. Installation The Prowide Mule connector is hosted in Mule Exchange and can be installed from the Exchange UI or from the Exchange API. https://www.anypoint.mulesoft.com/exchange/ Add this dependency to your application pom.xml org.mule.modules.prowide-integrator mule-prowide-integrator-connector 1.0.0 mule-plugin Configuration The Prowide Mule connector requires a valid license to be able to use the Prowide Integrator libraries. The license is provided as a file in the Prowide Integrator distribution. The license file must be placed in the Mule application classpath. The Prowide Mule connector can be configured in the Mule application configuration file or in the Mule application properties file. Check the Prowide Integrator developer guides for additional information. Usage","title":"Prowide MULE Connector"},{"location":"integrator/mule/#prowide-mule-connector","text":"The Prowide Mule Connector for Mule 4 facilitates an out-of-the-box integration of key features from the Prowide libraries in MULE applications. The key features enable validation and translation of SWIFT messages in Mule flows. Including operations for the legacy SWIFT MT standard and the ISO 20022 MX standard. Current implementation implements the following operations: Validate MT messages Validate ISO 20022 (MX) messages Validate CBPR+ messages Translate MT to ISO 20022 (MX) Translate ISO 20022 (MX) to MT Translate CBPR+ to MT Additional operations might be included in future releases. Application/Service Version Mule Runtime 4.0.1 Java 8+","title":"Prowide MULE Connector"},{"location":"integrator/mule/#requirements","text":"The Prowide Integrator is a set of licensed Java libraries that complements the open source libraries Prowide Core and Prowide ISO 20022. Thus in order to use the Prowide Mule connector, you need to have a valid license and access to the Prowide Integrator libraries distribution. More information about the Prowide Integrator can be found in the Prowide Integrator product page.","title":"Requirements"},{"location":"integrator/mule/#installation","text":"The Prowide Mule connector is hosted in Mule Exchange and can be installed from the Exchange UI or from the Exchange API. https://www.anypoint.mulesoft.com/exchange/ Add this dependency to your application pom.xml org.mule.modules.prowide-integrator mule-prowide-integrator-connector 1.0.0 mule-plugin ","title":"Installation"},{"location":"integrator/mule/#configuration","text":"The Prowide Mule connector requires a valid license to be able to use the Prowide Integrator libraries. The license is provided as a file in the Prowide Integrator distribution. The license file must be placed in the Mule application classpath. The Prowide Mule connector can be configured in the Mule application configuration file or in the Mule application properties file. Check the Prowide Integrator developer guides for additional information.","title":"Configuration"},{"location":"integrator/mule/#usage","text":"","title":"Usage"},{"location":"integrator/score/","text":"Prowide Integrator SCORE Overview The key feature provided by the SCORE extension is the specific model implementation for SWIFT for Corporate message structures. Which is a combination of sub-message types enclosed within an MT798 envelop. Parsing For message parsing, specific model classes are provided for each SWIFT for Corporates message type. For example, the 763 sub-message type, letter of credit, Customer to Bank, type can be parsed like this: MT798_763_LC_C2B mt = MT798_763_LC_C2B.parse(fin); And from there the model provides different getters to access the message content. WHen the sub-message type is also a standard SWIFT MT message, there is also a generic way to parse it. For example, the MT798 mt798 = MT798.parse(fin); /* * Get the sub-message (content after field 77E) as another model object */ SwiftMessage subMessage = mt798.getSubMessage(); /* * Convert and cast to MT760 * (the type of the inner message is indicated in field 12 of the MT798) */ MT760 mt = (MT760) subMessage.toMT(); Where we use a generic parse of the envelop message, MT798, into the model. And then we use a special function to get the inner payload. The inner payload is a generic SwiftMessage object, which can be converted to a specific MT. Creating a new message There are different ways to create SCORE messages. The most simple way is just to create an MT798 envelop and then just append the specific fields of the inner sub-message type in order. // create the envelope message MT798 mt = new MT798(\"AAAAUSXXXXX\", \"BBBBUSXXXXX\"); // add mandatory fields from the envelope mt.append(new Field20(\"MNN9843\")); mt.append(new Field12(\"745\")); // add the separatory field mt.append(new Field77E()); // add the submessage type (745) fields mt.append(new Field27A(\"1/2\")); mt.append(new Field21P(\"34567AC1-1239\")); mt.append(new Field21S(\"34567AC1\")); mt.append(new Field20(\"PGFFA0815999\")); mt.append(new Field31C(\"200506\")); mt.append(new Field13E(\"202005061045\")); mt.append(new Field29B(\"Arthur Foo\")); Then if the sub-message type is also a sntandard MT type, and you already have its payload in a model message. Then you can create the envelop fields and append the whole inner content from the specific message model. // Source content of an MT760 to use as sub-message String fin = \"{1:F01AAAADEM0AXXX0000000000}{2:I760BBBBITRRXMCEN2020}{4:\\n\" + \":27A:2/2\\n\" + \":21A:2201091711320000\\n\" + \":15A:\\n\" + \":27:1/1\\n\" + \":22A:ISSU\\n\" + \":15B:\\n\" + \":20:Bla Blah\\n\" + \":30:250109\\n\" + \":22D:DGAR\\n\" + \":40C:ISPR\\n\" + \":23B:FIXD\\n\" + \":31E:250109\\n\" + \":35G:If things happen\\n\" + \":50:Mr. App\\n\" + \"This Way\\n\" + \"Our City\\n\" + \":51:Mr. Obligor\\n\" + \"His stay\\n\" + \":52D:Mr. Issue\\n\" + \":59:Mr. Bene\\n\" + \"In Road\\n\" + \":56A:ANLAITRRMFE\\n\" + \":32B:USD23456789,\\n\" + \":77U:Terms and conditions\\n\" + \"have been defined\\n\" + \":45L:Some details\\n\" + \"about the underlying tx\\n\" + \":24E:MAIL\\n\" + \":24G:OTHR\\n\" + \"Foobar\\n\" + \"-}\"; MT760 subMessage = MT760.parse(fin); // Create a new MT798 envelop message, copying the seder, receiver and message type from the MT760 MT798 mt798 = new MT798(subMessage.getSender(), subMessage.getReceiver()); mt798 .append(Field20.tag(\"1234\")) .append(Field12.tag(subMessage.getMessageType())) .append(Field77E.emptyTag()); // After field 77E copy all fields from the sub-message MT760 subMessage.getSwiftMessage().getBlock4().getTags().forEach(t -> mt798.append(t)); Validating a SCORE message In order to validate a SCORE message, if you just pass the plain message to the ValidationEngine , only the MT798 envelop fields will be validated. While the inner structure for the sub-message type will not be strictly checked. Thus to apply the specific constraints for the sub-message type, you need to use the specific validation scheme to use in the validation call. ValidationEngine engine = new ValidationEngine(); engine.initialize(); String fin = \"{1:F01AAAADEM0AXXX0000000000}{2:I798BBBBITRRXMCEN2020}{4: etc...}\"; List r = engine.validateMtMessage(fin, MtTypeScore.MT798_712_LC_C2B.scheme()); In the above validation call we are using the specific validation scheme for the MT798<712> LC C2B sub-message type. The MtTypeScore is a convenience enum containing all supported SCORE model structures, and can be used to access its scheme definition. For more information on MT schemes, check the Prowide Integrator Validation guide. Javadoc Online javadoc Prowide Integrator SCORE Javadoc SRU2023-9.4.x","title":"SCORE"},{"location":"integrator/score/#prowide-integrator-score","text":"","title":"Prowide Integrator SCORE"},{"location":"integrator/score/#overview","text":"The key feature provided by the SCORE extension is the specific model implementation for SWIFT for Corporate message structures. Which is a combination of sub-message types enclosed within an MT798 envelop.","title":"Overview"},{"location":"integrator/score/#parsing","text":"For message parsing, specific model classes are provided for each SWIFT for Corporates message type. For example, the 763 sub-message type, letter of credit, Customer to Bank, type can be parsed like this: MT798_763_LC_C2B mt = MT798_763_LC_C2B.parse(fin); And from there the model provides different getters to access the message content. WHen the sub-message type is also a standard SWIFT MT message, there is also a generic way to parse it. For example, the MT798 mt798 = MT798.parse(fin); /* * Get the sub-message (content after field 77E) as another model object */ SwiftMessage subMessage = mt798.getSubMessage(); /* * Convert and cast to MT760 * (the type of the inner message is indicated in field 12 of the MT798) */ MT760 mt = (MT760) subMessage.toMT(); Where we use a generic parse of the envelop message, MT798, into the model. And then we use a special function to get the inner payload. The inner payload is a generic SwiftMessage object, which can be converted to a specific MT.","title":"Parsing"},{"location":"integrator/score/#creating-a-new-message","text":"There are different ways to create SCORE messages. The most simple way is just to create an MT798 envelop and then just append the specific fields of the inner sub-message type in order. // create the envelope message MT798 mt = new MT798(\"AAAAUSXXXXX\", \"BBBBUSXXXXX\"); // add mandatory fields from the envelope mt.append(new Field20(\"MNN9843\")); mt.append(new Field12(\"745\")); // add the separatory field mt.append(new Field77E()); // add the submessage type (745) fields mt.append(new Field27A(\"1/2\")); mt.append(new Field21P(\"34567AC1-1239\")); mt.append(new Field21S(\"34567AC1\")); mt.append(new Field20(\"PGFFA0815999\")); mt.append(new Field31C(\"200506\")); mt.append(new Field13E(\"202005061045\")); mt.append(new Field29B(\"Arthur Foo\")); Then if the sub-message type is also a sntandard MT type, and you already have its payload in a model message. Then you can create the envelop fields and append the whole inner content from the specific message model. // Source content of an MT760 to use as sub-message String fin = \"{1:F01AAAADEM0AXXX0000000000}{2:I760BBBBITRRXMCEN2020}{4:\\n\" + \":27A:2/2\\n\" + \":21A:2201091711320000\\n\" + \":15A:\\n\" + \":27:1/1\\n\" + \":22A:ISSU\\n\" + \":15B:\\n\" + \":20:Bla Blah\\n\" + \":30:250109\\n\" + \":22D:DGAR\\n\" + \":40C:ISPR\\n\" + \":23B:FIXD\\n\" + \":31E:250109\\n\" + \":35G:If things happen\\n\" + \":50:Mr. App\\n\" + \"This Way\\n\" + \"Our City\\n\" + \":51:Mr. Obligor\\n\" + \"His stay\\n\" + \":52D:Mr. Issue\\n\" + \":59:Mr. Bene\\n\" + \"In Road\\n\" + \":56A:ANLAITRRMFE\\n\" + \":32B:USD23456789,\\n\" + \":77U:Terms and conditions\\n\" + \"have been defined\\n\" + \":45L:Some details\\n\" + \"about the underlying tx\\n\" + \":24E:MAIL\\n\" + \":24G:OTHR\\n\" + \"Foobar\\n\" + \"-}\"; MT760 subMessage = MT760.parse(fin); // Create a new MT798 envelop message, copying the seder, receiver and message type from the MT760 MT798 mt798 = new MT798(subMessage.getSender(), subMessage.getReceiver()); mt798 .append(Field20.tag(\"1234\")) .append(Field12.tag(subMessage.getMessageType())) .append(Field77E.emptyTag()); // After field 77E copy all fields from the sub-message MT760 subMessage.getSwiftMessage().getBlock4().getTags().forEach(t -> mt798.append(t));","title":"Creating a new message"},{"location":"integrator/score/#validating-a-score-message","text":"In order to validate a SCORE message, if you just pass the plain message to the ValidationEngine , only the MT798 envelop fields will be validated. While the inner structure for the sub-message type will not be strictly checked. Thus to apply the specific constraints for the sub-message type, you need to use the specific validation scheme to use in the validation call. ValidationEngine engine = new ValidationEngine(); engine.initialize(); String fin = \"{1:F01AAAADEM0AXXX0000000000}{2:I798BBBBITRRXMCEN2020}{4: etc...}\"; List r = engine.validateMtMessage(fin, MtTypeScore.MT798_712_LC_C2B.scheme()); In the above validation call we are using the specific validation scheme for the MT798<712> LC C2B sub-message type. The MtTypeScore is a convenience enum containing all supported SCORE model structures, and can be used to access its scheme definition. For more information on MT schemes, check the Prowide Integrator Validation guide.","title":"Validating a SCORE message"},{"location":"integrator/score/#javadoc","text":"Online javadoc Prowide Integrator SCORE Javadoc SRU2023-9.4.x","title":"Javadoc"},{"location":"integrator/sepa/","text":"Prowide Integrator SEPA Overview The key feature provided by the SEPA extension is the specific model implementation for the Single Euro Payments Area messages. This is a restricted ISO 20022 version with a subset of messages with specific constraints. The implementation is based on the publications by the European Payments Council (EPC). For more information for SEPA check https://www.europeanpaymentscouncil.eu The supported rulebook is the 2019 version 1.0 , in force from 17 November 2019 until November 2021. Supported message schemes The following table includes all the supported message types grouped into payment schemes. For each of them the first column indicates the message type identifier, the second column the usage description in SEPA and the third column the usage of the equivalent message type in ISO. SEPA Credit Transfer - Customer to Bank - SCT C2B (EPC132) pain.001.001.03 Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.001.001.03_ERI_Update Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.001.001.03_TransferBack Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.002.001.03 Customer Payment Status Report Customer Payment Status Report SEPA Instant Credit Transfer - Customer to Bank - SCT C2B INST (EPC121) pain.001.001.03 Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.001.001.03_TransferBack Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.002.001.03 Customer Payment Status Report Customer Payment Status Report SEPA Credit Transfer - Interbank - SCT INT (EPC115) camt.027.001.06 Interbank SCT Inquiry Claim Non-Receipt camt.029.001.03_NegAnRecall Interbank Negative Answer to a Recall of SEPA Credit Transfer Resolution of Investigation camt.029.001.03_NegReRFRO Interbank Negative Response to the Request for Recall by the Originator Resolution of Investigation camt.029.001.08_Conf_PosRecamt.087_Update Interbank Confirmed Positive Response to Claim for Value Date Correction Resolution of Investigation camt.029.001.08_NegRecamt.027_Update Interbank Negative Response to Claim Non-Receipt Resolution of Investigation camt.029.001.08_NegRecamt.087 Interbank Negative Response to Claim for Value Date Correction Resolution of Investigation camt.029.001.08_PosRecamt.027_Update Interbank Positive Response to Claim Non-Receipt Resolution of Investigation camt.029.001.08_PosRecamt.087_Update Interbank Positive Response to Claim for Value Date Correction With Request for Interest Compensation Resolution of Investigation camt.056.001.01_Recall Interbank Recall of SEPA Credit Transfer FI to FI Payment Cancellation Request camt.056.001.01_RFRO Request for Recall by the Originator FI to FI Payment Cancellation Request camt.087.001.05 Interbank SCT Inquiry Request to Modify Payment pacs.002.001.03 Interbank Reject SEPA Credit Transfer FI to FI Payment Status Report pacs.004.001.02_PosAnRecall Interbank Positive Answer to a Recall of SEPA Credit Transfer Interbank Return Credit Transfer pacs.004.001.02_PosReRFRO Interbank Positive Response to the Request for Recall by the Originator Interbank Return Credit Transfer pacs.004.001.02_Return Interbank Return SEPA Credit Transfer Interbank Return Credit Transfer pacs.008.001.02 Interbank Payment FI to FI Customer Credit Transfer pacs.008.001.02_ERI_Update Interbank Payment FI to FI Customer Credit Transfer pacs.028.001.01_INQ Request for a Status Update on a SEPA Credit Transfer Inquiry FI to FI Payment Status Request pacs.028.001.01_Recall Request for Status on a Recall of SEPA Credit Transfer FI to FI Payment Status Request pacs.028.001.01_RFRO_Update Request for a Status Update on a Request for Recall by the Originator FI to FI Payment Status Request SEPA Instant Credit Transfer - Interbank - SCT INT INST (EPC 122) camt.029.001.03_NegAnRecall Interbank Negative Answer to a Recall of SEPA Credit Transfer Resolution of Investigation camt.029.001.03_NegReRFRO Interbank Negative Response to the Request for Recall by the Originator Resolution of Investigation camt.056.001.01_Recall Interbank Recall of SEPA Credit Transfer FI to FI Payment Cancellation Request camt.056.001.01_RFRO Request for Recall by the Originator FI to FI Payment Cancellation Request pacs.002.001.03_Negative Interbank Reject SEPA Credit Transfer FI to FI Payment Status Report pacs.002.001.03_Positive_Update Interbank Accept SEPA Credit Transfer FI to FI Payment Status Report pacs.004.001.02_PosAnRecall Interbank Positive Answer to a Recall of SEPA Credit Transfer Interbank Return Credit Transfer pacs.004.001.02_PosReRFRO Interbank Positive Response to the Request for Recall by the Originator Interbank Return Credit Transfer pacs.008.001.02 Interbank Payment FI to FI Customer Credit Transfer pacs.028.001.01_Recall_Update Request for Status Update on a Recall of SEPA Credit Transfer FI to FI Payment Status Request pacs.028.001.01_RFRO_Update Request for a Status Update on a Request for Recall by the Originator FI to FI Payment Status Request pacs.028.001.01_Status Request for Status on a Recall of SEPA Credit Transfer FI to FI Payment Status Request SEPA DIrect Debit - Customer to Bank - SDD C2B (EPC130) pain.002.001.03 Bank to Customer Direct Debit Reject Payment Status Report pain.007.001.02 Customer to Bank Reversal Instruction for a Collection Customer to Bank Payment Reversal pain.008.001.02 Customer to Bank Direct Debit Collection Customer Direct Debit Initiation SEPA Direct Debit - E-Mandate Service - SDD EMS (EPC002) pain.009.001.01 Request Message \u2013 Issuing Initiation Request pain.010.001.01 Request Message \u2013 Amendment Amendment Request pain.011.001.01 Request Message \u2013 Cancellation Cancellation Request pain.012.001.01 Validation Message Acceptance Report SEPA Direct Debit - Interbank - SDD INT (EPC114) pacs.002.001.03 Interbank Direct Debit Reject FI to FI Payment Status Report pacs.003.001.02 Interbank Collection FI to FI Customer Direct Debit pacs.004.001.02 Interbank Direct Debit Return/Refund of a Collection Payment Return pacs.007.001.03 Interbank Reversal Instruction for a Collection Payment Reversal Message model For each of the described message types, a specific implementation message class is provided. The SEPA message subset shares the same ISO standard namespaces , however for each namespace, and thus for each message type, there can be more than one message model . In order to handle this situation, the SEPA message classes are organized into a package, where the package name maps part of the SEPA schema. For example, the pacs.002.001.03 from the SDD INT schema is located in a package: com . prowidesoftware . swift . model . mx . sepa . sdd . interbank . pacs002 For several message schemes, the same message types have different versions depending on the usage. In these cases, the model class includes the same suffix defined in the schemas from the EPC. For example, for SCT C2B pain.001you will find the default MxPain00100103 class but also the MxPain00100103TransferBack and MxPain00100103ERIUpdate variants. The three messages implement a SCT C2B pain.001, but depending on the usage they have different constraints. Therefore, in order to build a SEPA message, the specific use case, has to be identified in advance. Once the message class is identified, the creation of a new SEPA message is similar to the creation of any standard ISO message. You just populate the Java object and the model will already include the constraints from the SEPA schema. For example: MxPacs00400102Return mx = new MxPacs00400102Return (); mx . setPmtRtr ( new PaymentReturnV02SepaReturn ()); mx . getPmtRtr (). setGrpHdr ( new GroupHeader38Sepa ()); mx . getPmtRtr (). getGrpHdr (). setMsgId ( \"REFERENCE1234\" ); mx . getPmtRtr (). getGrpHdr (). setNbOfTxs ( \"1\" ); mx . getPmtRtr (). getGrpHdr (). setIntrBkSttlmDt ( DatatypeFactory . newInstance (). newXMLGregorianCalendar ( Instant . now (). toString ())); mx . getPmtRtr (). getGrpHdr (). setSttlmInf ( new SettlementInformation13Sepa ()); mx . getPmtRtr (). getGrpHdr (). getSttlmInf (). setSttlmMtd ( SettlementMethod1Code . INDA ); mx . getPmtRtr (). getGrpHdr (). setTtlRtrdIntrBkSttlmAmt ( new ActiveCurrencyAndAmountSepa ()); mx . getPmtRtr (). getGrpHdr (). getTtlRtrdIntrBkSttlmAmt (). setCcy ( ActiveCurrencyCodeSepa . EUR ); mx . getPmtRtr (). getGrpHdr (). getTtlRtrdIntrBkSttlmAmt (). setValue ( new BigDecimal ( \"1234.56\" )); The message object can then be serialized into XML using the message() method. Notice a SEPA message in XML format will be indistinguishable from a standard ISO message because SEPA is just a constraint of ISO messages, sharing the same namespace. Moreover, a SEPA message will always be a valid ISO message. To complement the message model, an enumeration SepaMessageType is provided with the list of supported SEPA message types. This enumeration implements the internal SchemaProvider interface, so it can be used with the Prowide Integrator Validator library to run the SEPA validation for an XML. SEPA validation Only available if you have a license of the Prowide Integrator Validation module. Along the standard ISO 20022 validation, the Validation module supports out-of-the-box validation for SEPA . There are two possible scenarios: * You are validating a message created by you in your application with the message model. * You are validating a message created externally and received in XML format. In the first case, you should have created a specific message object such as MxPain00100103 from the com.prowidesoftware.swift.model.mx.sepa.sct.c2b.pain001 package. Therefore, the model has already constrained the elements and elements values with the restrictions from the SEPA schemas. Moreover, the object implements the SchemaProvider interface. So when you call the validation engine passing the object as a parameter, the engine will already apply the corresponding SEPA schema. You can just use the validation call: validateMessage ( final AbstractMX msg ) In the second scenario, you just have the XML so the message itself cannot be distinguished from a regular ISO message. Notice, SEPA messages are a subset of ISO messages with special restrictions, but the XML namespace in a SEPA message is the same as the standard ISO namespace. So in order to validate these messages you need to provide additional information to the validation call to clearly identify the SEPA message type you intend to validate. For that, you should use the validation call: validateMxMessage ( final String xml , SchemaProvider schemaProvider ) Where for the SchemaProvider parameter you can use any value of the SepaMessageType enum. Restricted SEPA validation The model and validation we support out-of-the-box for SEPA is based on the schema publications by the European Payments Council (EPC) . Some institutions, such as the Deutsche Bundesbank have their own restriction for SEPA-Clearer . This restricted version of the SEPA messages require additional validation that is not available in the EPC schemas. So in order to do that, a recommended workaround is to use the Prowide Integrator SEPA model classes to build the messages, but then pass the specific SEPA restricted schema to the validation. Therefore, the overall message structure will be ensured by the model while the specific constraints will be detected by the validation. For Example: com . prowidesoftware . swift . model . mx . sepa . sct . interbank . pacs008 . MxPacs00800102 mx = new MxPacs00800102 (); mx . setFIToFICstmrCdtTrf ( new FIToFICustomerCreditTransferV02Sepa ()); mx . getFIToFICstmrCdtTrf (). setGrpHdr ( new GroupHeader33Sepa ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setMsgId ( \"1234\" ); [ More setters here \u2026 ] // load restricted SEPA schema from Bundesbank String xsd = Lib . readStream ( getClass (). getResourceAsStream ( \"sepa-bundesbank-pacs.008.001.02.xsd\" )); // assert the message is valid for the Bundesbank schema String xml = mx . message (); StreamSource streamSource = new StreamSource ( new StringReader ( xsd )); List < ValidationProblem > problems = engine . validateMxMessage ( xml , streamSource ); System . out . println ( ValidationProblem . printout ( problems )); Javadoc Online javadoc Prowide Integrator SEPA Javadoc SRU2023-9.4.x","title":"SEPA"},{"location":"integrator/sepa/#prowide-integrator-sepa","text":"","title":"Prowide Integrator SEPA"},{"location":"integrator/sepa/#overview","text":"The key feature provided by the SEPA extension is the specific model implementation for the Single Euro Payments Area messages. This is a restricted ISO 20022 version with a subset of messages with specific constraints. The implementation is based on the publications by the European Payments Council (EPC). For more information for SEPA check https://www.europeanpaymentscouncil.eu The supported rulebook is the 2019 version 1.0 , in force from 17 November 2019 until November 2021.","title":"Overview"},{"location":"integrator/sepa/#supported-message-schemes","text":"The following table includes all the supported message types grouped into payment schemes. For each of them the first column indicates the message type identifier, the second column the usage description in SEPA and the third column the usage of the equivalent message type in ISO.","title":"Supported message schemes"},{"location":"integrator/sepa/#sepa-credit-transfer-customer-to-bank-sct-c2b-epc132","text":"pain.001.001.03 Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.001.001.03_ERI_Update Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.001.001.03_TransferBack Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.002.001.03 Customer Payment Status Report Customer Payment Status Report SEPA Instant Credit Transfer - Customer to Bank - SCT C2B INST (EPC121) pain.001.001.03 Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.001.001.03_TransferBack Customer Credit Transfer Initiation Customer Credit Transfer Initiation pain.002.001.03 Customer Payment Status Report Customer Payment Status Report","title":"SEPA Credit Transfer - Customer to Bank - SCT C2B (EPC132)"},{"location":"integrator/sepa/#sepa-credit-transfer-interbank-sct-int-epc115","text":"camt.027.001.06 Interbank SCT Inquiry Claim Non-Receipt camt.029.001.03_NegAnRecall Interbank Negative Answer to a Recall of SEPA Credit Transfer Resolution of Investigation camt.029.001.03_NegReRFRO Interbank Negative Response to the Request for Recall by the Originator Resolution of Investigation camt.029.001.08_Conf_PosRecamt.087_Update Interbank Confirmed Positive Response to Claim for Value Date Correction Resolution of Investigation camt.029.001.08_NegRecamt.027_Update Interbank Negative Response to Claim Non-Receipt Resolution of Investigation camt.029.001.08_NegRecamt.087 Interbank Negative Response to Claim for Value Date Correction Resolution of Investigation camt.029.001.08_PosRecamt.027_Update Interbank Positive Response to Claim Non-Receipt Resolution of Investigation camt.029.001.08_PosRecamt.087_Update Interbank Positive Response to Claim for Value Date Correction With Request for Interest Compensation Resolution of Investigation camt.056.001.01_Recall Interbank Recall of SEPA Credit Transfer FI to FI Payment Cancellation Request camt.056.001.01_RFRO Request for Recall by the Originator FI to FI Payment Cancellation Request camt.087.001.05 Interbank SCT Inquiry Request to Modify Payment pacs.002.001.03 Interbank Reject SEPA Credit Transfer FI to FI Payment Status Report pacs.004.001.02_PosAnRecall Interbank Positive Answer to a Recall of SEPA Credit Transfer Interbank Return Credit Transfer pacs.004.001.02_PosReRFRO Interbank Positive Response to the Request for Recall by the Originator Interbank Return Credit Transfer pacs.004.001.02_Return Interbank Return SEPA Credit Transfer Interbank Return Credit Transfer pacs.008.001.02 Interbank Payment FI to FI Customer Credit Transfer pacs.008.001.02_ERI_Update Interbank Payment FI to FI Customer Credit Transfer pacs.028.001.01_INQ Request for a Status Update on a SEPA Credit Transfer Inquiry FI to FI Payment Status Request pacs.028.001.01_Recall Request for Status on a Recall of SEPA Credit Transfer FI to FI Payment Status Request pacs.028.001.01_RFRO_Update Request for a Status Update on a Request for Recall by the Originator FI to FI Payment Status Request","title":"SEPA Credit Transfer - Interbank - SCT INT (EPC115)"},{"location":"integrator/sepa/#sepa-instant-credit-transfer-interbank-sct-int-inst-epc-122","text":"camt.029.001.03_NegAnRecall Interbank Negative Answer to a Recall of SEPA Credit Transfer Resolution of Investigation camt.029.001.03_NegReRFRO Interbank Negative Response to the Request for Recall by the Originator Resolution of Investigation camt.056.001.01_Recall Interbank Recall of SEPA Credit Transfer FI to FI Payment Cancellation Request camt.056.001.01_RFRO Request for Recall by the Originator FI to FI Payment Cancellation Request pacs.002.001.03_Negative Interbank Reject SEPA Credit Transfer FI to FI Payment Status Report pacs.002.001.03_Positive_Update Interbank Accept SEPA Credit Transfer FI to FI Payment Status Report pacs.004.001.02_PosAnRecall Interbank Positive Answer to a Recall of SEPA Credit Transfer Interbank Return Credit Transfer pacs.004.001.02_PosReRFRO Interbank Positive Response to the Request for Recall by the Originator Interbank Return Credit Transfer pacs.008.001.02 Interbank Payment FI to FI Customer Credit Transfer pacs.028.001.01_Recall_Update Request for Status Update on a Recall of SEPA Credit Transfer FI to FI Payment Status Request pacs.028.001.01_RFRO_Update Request for a Status Update on a Request for Recall by the Originator FI to FI Payment Status Request pacs.028.001.01_Status Request for Status on a Recall of SEPA Credit Transfer FI to FI Payment Status Request","title":"SEPA Instant Credit Transfer - Interbank - SCT INT INST (EPC 122)"},{"location":"integrator/sepa/#sepa-direct-debit-customer-to-bank-sdd-c2b-epc130","text":"pain.002.001.03 Bank to Customer Direct Debit Reject Payment Status Report pain.007.001.02 Customer to Bank Reversal Instruction for a Collection Customer to Bank Payment Reversal pain.008.001.02 Customer to Bank Direct Debit Collection Customer Direct Debit Initiation","title":"SEPA DIrect Debit - Customer to Bank - SDD C2B (EPC130)"},{"location":"integrator/sepa/#sepa-direct-debit-e-mandate-service-sdd-ems-epc002","text":"pain.009.001.01 Request Message \u2013 Issuing Initiation Request pain.010.001.01 Request Message \u2013 Amendment Amendment Request pain.011.001.01 Request Message \u2013 Cancellation Cancellation Request pain.012.001.01 Validation Message Acceptance Report","title":"SEPA Direct Debit - E-Mandate Service - SDD EMS (EPC002)"},{"location":"integrator/sepa/#sepa-direct-debit-interbank-sdd-int-epc114","text":"pacs.002.001.03 Interbank Direct Debit Reject FI to FI Payment Status Report pacs.003.001.02 Interbank Collection FI to FI Customer Direct Debit pacs.004.001.02 Interbank Direct Debit Return/Refund of a Collection Payment Return pacs.007.001.03 Interbank Reversal Instruction for a Collection Payment Reversal","title":"SEPA Direct Debit - Interbank - SDD INT (EPC114)"},{"location":"integrator/sepa/#message-model","text":"For each of the described message types, a specific implementation message class is provided. The SEPA message subset shares the same ISO standard namespaces , however for each namespace, and thus for each message type, there can be more than one message model . In order to handle this situation, the SEPA message classes are organized into a package, where the package name maps part of the SEPA schema. For example, the pacs.002.001.03 from the SDD INT schema is located in a package: com . prowidesoftware . swift . model . mx . sepa . sdd . interbank . pacs002 For several message schemes, the same message types have different versions depending on the usage. In these cases, the model class includes the same suffix defined in the schemas from the EPC. For example, for SCT C2B pain.001you will find the default MxPain00100103 class but also the MxPain00100103TransferBack and MxPain00100103ERIUpdate variants. The three messages implement a SCT C2B pain.001, but depending on the usage they have different constraints. Therefore, in order to build a SEPA message, the specific use case, has to be identified in advance. Once the message class is identified, the creation of a new SEPA message is similar to the creation of any standard ISO message. You just populate the Java object and the model will already include the constraints from the SEPA schema. For example: MxPacs00400102Return mx = new MxPacs00400102Return (); mx . setPmtRtr ( new PaymentReturnV02SepaReturn ()); mx . getPmtRtr (). setGrpHdr ( new GroupHeader38Sepa ()); mx . getPmtRtr (). getGrpHdr (). setMsgId ( \"REFERENCE1234\" ); mx . getPmtRtr (). getGrpHdr (). setNbOfTxs ( \"1\" ); mx . getPmtRtr (). getGrpHdr (). setIntrBkSttlmDt ( DatatypeFactory . newInstance (). newXMLGregorianCalendar ( Instant . now (). toString ())); mx . getPmtRtr (). getGrpHdr (). setSttlmInf ( new SettlementInformation13Sepa ()); mx . getPmtRtr (). getGrpHdr (). getSttlmInf (). setSttlmMtd ( SettlementMethod1Code . INDA ); mx . getPmtRtr (). getGrpHdr (). setTtlRtrdIntrBkSttlmAmt ( new ActiveCurrencyAndAmountSepa ()); mx . getPmtRtr (). getGrpHdr (). getTtlRtrdIntrBkSttlmAmt (). setCcy ( ActiveCurrencyCodeSepa . EUR ); mx . getPmtRtr (). getGrpHdr (). getTtlRtrdIntrBkSttlmAmt (). setValue ( new BigDecimal ( \"1234.56\" )); The message object can then be serialized into XML using the message() method. Notice a SEPA message in XML format will be indistinguishable from a standard ISO message because SEPA is just a constraint of ISO messages, sharing the same namespace. Moreover, a SEPA message will always be a valid ISO message. To complement the message model, an enumeration SepaMessageType is provided with the list of supported SEPA message types. This enumeration implements the internal SchemaProvider interface, so it can be used with the Prowide Integrator Validator library to run the SEPA validation for an XML.","title":"Message model"},{"location":"integrator/sepa/#sepa-validation","text":"Only available if you have a license of the Prowide Integrator Validation module. Along the standard ISO 20022 validation, the Validation module supports out-of-the-box validation for SEPA . There are two possible scenarios: * You are validating a message created by you in your application with the message model. * You are validating a message created externally and received in XML format. In the first case, you should have created a specific message object such as MxPain00100103 from the com.prowidesoftware.swift.model.mx.sepa.sct.c2b.pain001 package. Therefore, the model has already constrained the elements and elements values with the restrictions from the SEPA schemas. Moreover, the object implements the SchemaProvider interface. So when you call the validation engine passing the object as a parameter, the engine will already apply the corresponding SEPA schema. You can just use the validation call: validateMessage ( final AbstractMX msg ) In the second scenario, you just have the XML so the message itself cannot be distinguished from a regular ISO message. Notice, SEPA messages are a subset of ISO messages with special restrictions, but the XML namespace in a SEPA message is the same as the standard ISO namespace. So in order to validate these messages you need to provide additional information to the validation call to clearly identify the SEPA message type you intend to validate. For that, you should use the validation call: validateMxMessage ( final String xml , SchemaProvider schemaProvider ) Where for the SchemaProvider parameter you can use any value of the SepaMessageType enum.","title":"SEPA validation"},{"location":"integrator/sepa/#restricted-sepa-validation","text":"The model and validation we support out-of-the-box for SEPA is based on the schema publications by the European Payments Council (EPC) . Some institutions, such as the Deutsche Bundesbank have their own restriction for SEPA-Clearer . This restricted version of the SEPA messages require additional validation that is not available in the EPC schemas. So in order to do that, a recommended workaround is to use the Prowide Integrator SEPA model classes to build the messages, but then pass the specific SEPA restricted schema to the validation. Therefore, the overall message structure will be ensured by the model while the specific constraints will be detected by the validation. For Example: com . prowidesoftware . swift . model . mx . sepa . sct . interbank . pacs008 . MxPacs00800102 mx = new MxPacs00800102 (); mx . setFIToFICstmrCdtTrf ( new FIToFICustomerCreditTransferV02Sepa ()); mx . getFIToFICstmrCdtTrf (). setGrpHdr ( new GroupHeader33Sepa ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setMsgId ( \"1234\" ); [ More setters here \u2026 ] // load restricted SEPA schema from Bundesbank String xsd = Lib . readStream ( getClass (). getResourceAsStream ( \"sepa-bundesbank-pacs.008.001.02.xsd\" )); // assert the message is valid for the Bundesbank schema String xml = mx . message (); StreamSource streamSource = new StreamSource ( new StringReader ( xsd )); List < ValidationProblem > problems = engine . validateMxMessage ( xml , streamSource ); System . out . println ( ValidationProblem . printout ( problems ));","title":"Restricted SEPA validation"},{"location":"integrator/sepa/#javadoc","text":"Online javadoc Prowide Integrator SEPA Javadoc SRU2023-9.4.x","title":"Javadoc"},{"location":"integrator/sic/","text":"Prowide Integrator SIC Overview The key feature provided by the SIC extension is the specific model implementation for the Swiss RGTS messages. This is a restricted ISO 20022 version with a subset of messages with specific constraints. For more information for SIC check https://www.six-group.com/interbank-clearing/en/home/standardization/iso-payments/iso20022/implementation-guidelines.html The supported schemas and guidelines version is 4.9 . Supported message schemes The following table includes all the supported message types: camt.003.001.07.ch.02 camt.004.001.08.ch.02 camt.005.001.08.ch.01 camt.006.001.08.ch.02 camt.007.001.08.ch.01 camt.008.001.08.ch.01 camt.019.001.07.ch.02 camt.025.001.05.ch.01 camt.027.001.06.chsepa.01 camt.029.001.08.chsepa.01 camt.029.001.09.ch.01 camt.048.001.05.ch.01 camt.050.001.05.ch.01 camt.052.001.08.ch.02 camt.054.001.08.ch.02 camt.056.001.08.ch.02 camt.087.001.05.chsepa.01 pacs.002.001.10.ch.02 pacs.004.001.09.ch.02 pacs.008.001.08.ch.02 pacs.009.001.08.ch.02 pacs.028.001.01.chsepa.02 Legacy from release 4.6: camt.003.001.05.ch.01 camt.004.001.06.ch.01 camt.005.001.06.ch.03 camt.006.001.06.ch.02 camt.007.001.06.ch.01 camt.008.001.06.ch.01 camt.019.001.05.ch.01 camt.025.001.03.ch.01 camt.027.001.06.chsepa.01 camt.029.001.03.ch.01 camt.029.001.08.chsepa.01 camt.048.001.03.ch.01 camt.050.001.03.ch.01 camt.052.001.02.ch.01 camt.054.001.02.ch.01 camt.056.001.01.ch.01 camt.087.001.05.chsepa.01 pacs.002.001.03.ch.01 pacs.004.001.02.ch.02 pacs.008.001.02.ch.02 pacs.009.001.02.ch.02 pacs.028.001.01.chsepa.02 Message model For each of the described message types, a specific implementation message class is provided, into a single common package: com . prowidesoftware . swift . model . mx . sic The package above always contains the latest release availalbe. For older releases, the package name includes the release version, for example: com . prowidesoftware . swift . model . mx . sic . v4_6 The SIC message subset uses custom namespaces , not aligned to the ISO standard namespaces. Once the message class is identified, the creation of a new SIC message is similar to the creation of any standard ISO message. You just populate the Java object and the model will already include the constraints from the SIC schema. For example: MxPacs00800102Ch02 mx = new MxPacs00800102Ch02 (); mx . setFIToFICstmrCdtTrf ( new FIToFICustomerCreditTransferV02 ()); mx . getFIToFICstmrCdtTrf (). setGrpHdr ( new GroupHeader33 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setMsgId ( \"1234\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setCreDtTm ( now ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setNbOfTxs ( \"1\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setIntrBkSttlmDt ( now ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setSttlmInf ( new SettlementInformation13Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getSttlmInf (). setSttlmMtd ( SettlementMethod1Code . CLRG ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setInstgAgt ( new BranchAndFinancialInstitutionIdentification4Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getInstgAgt (). setFinInstnId ( new FinancialInstitutionIdentification7 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getInstgAgt (). getFinInstnId (). setBIC ( \"ABCDUSXXXXX\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setInstdAgt ( new BranchAndFinancialInstitutionIdentification4Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getInstdAgt (). setFinInstnId ( new FinancialInstitutionIdentification7 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getInstdAgt (). getFinInstnId (). setBIC ( \"EFGHUSXXXXX\" ); mx . getFIToFICstmrCdtTrf (). addCdtTrfTxInf ( new CreditTransferTransactionInformation11 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setPmtId ( new PaymentIdentification3 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getPmtId (). setEndToEndId ( \"aaaa\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getPmtId (). setTxId ( \"bbbb\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setPmtTpInf ( new PaymentTypeInformation21 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getPmtTpInf (). setLclInstrm ( new LocalInstrument2Choice ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getPmtTpInf (). getLclInstrm (). setCd ( \"ESRPMT\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setIntrBkSttlmAmt ( new ActiveCurrencyAndAmount ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getIntrBkSttlmAmt (). setCcy ( \"USD\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getIntrBkSttlmAmt (). setValue ( new BigDecimal ( \"1234.56\" )); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setChrgBr ( ChargeBearerType1Code . CRED ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setDbtr ( new PartyIdentification32 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getDbtr (). setNm ( \"Foo1\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setDbtrAgt ( new BranchAndFinancialInstitutionIdentification4Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getDbtrAgt (). setFinInstnId ( new FinancialInstitutionIdentification7 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getDbtrAgt (). getFinInstnId (). setBIC ( \"AAAAUSXXXXX\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setCdtr ( new PartyIdentification32 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getCdtr (). setNm ( \"Foo2\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setCdtrAgt ( new BranchAndFinancialInstitutionIdentification4Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getCdtrAgt (). setFinInstnId ( new FinancialInstitutionIdentification7 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getCdtrAgt (). getFinInstnId (). setBIC ( \"AAAAUSXXXXX\" ); String xml = mx . message (); The serialized XML will have the proper custom SIC namespace. To complement the message model, an enumeration SicMessageType is provided with the list of supported SIC messages. This enumeration implements the internal SchemaProvider interface, so it can be used with the Prowide Integrator Validator library to run the SIC validation for an XML. SIC validation Only available if you have a license of the Prowide Integrator Validation module. Along the standard ISO 20022 validation, the Validation module supports out-of-the-box validation for SIC (Swiss RTGS). There are two possible scenarios: You are validating a message created by you in your application with the message model. You are validating a message created externally and received in XML format. In the first case, you should have created a specific message object such as MxPain00800102Ch02 from the com.prowidesoftware.swift.model.mx.sic package. Therefore, the model has already constrained the elements and elements values with the restrictions from the SIC schemas including binding to the custom SIC namespace . Moreover, the object implements the SchemaProvider interface. So when you call the validation engine passing the object as a parameter, the engine will already apply the corresponding SIC schema. You can just use the validation call: validateMessage ( final AbstractMX msg ) In the second scenario, you just have the XML, so the message structure cannot be distinguished from a regular ISO message. So in order to validate these messages, you need to provide additional information to the validation call to clearly identify the SIC message type you intend to validate. For that, you should use the validation call: validateMxMessage ( final String xml , SchemaProvider schemaProvider ) Where for the SchemaProvider parameter you can use any value of the SicMessageType enum. When your source content is already the XML it is always recommended to use the XML as parameter for the validation. If you parse the XML into an MX object first, and then call the validation using the parsed message as parameter, some errors may not be detected. The validation call with the model object is only intended for scenarios where you are building the message using the model API. SIC MT-MX Translations Only available if you have a license of the Prowide Integrator Translations module. Along the standard ISO 20022 translations, the MT-MX Translations module provides some specific out-of-the-box translations between MT messages and SIC ISO 20022 messages. The following translations are supported for the restricted ISO 20022 for SIC, the Swiss RTGS. The input and output MX model class is the specific class for the restricted ISO version. Such as MxPain00800102Ch02 instead of the standard ISO MxPain00800102 . MT to MX 103 Single Customer Credit Transfer pacs.008.001.02.ch.02 FIToFICustomerCreditTransferV02 SIC v2 202 General Financial Institution Transfer pacs.009.001.02.ch.02 FinancialInstitutionCreditTransferV02 SIC v2 202.COV General Financial Institution Transfer, Cover Payment pacs.009.001.02.ch.02 FinancialInstitutionCreditTransferV02 SIC v2 MX to MT pacs.008.001.02.ch.02 Single Customer Credit Transfer 2 SIC v2 103 Single Customer Credit Transfer pacs.009.001.02.ch.02 FinancialInstitutionCreditTransferV02 SIC v2 202 General Financial Institution Transfer pacs.009.001.02.ch.02 FinancialInstitutionCreditTransferV02 SIC v2 202.COV General Financial Institution Transfer, Cover Payment pacs.004.001.02.ch.02 PaymentReturnV02 103 RETURN Single Customer Credit Transfer Return pacs.002.001.03 FIToFIPaymentStatusReportV03 ACK / NACK Service message 21 Each of these translations is implemented in its own translation class. For information on the translation API, please check the Prowide Integrator Translations developer guide. Javadoc Online javadoc Prowide Integrator SDK Javadoc SRU2023-9.4.x","title":"SIC"},{"location":"integrator/sic/#prowide-integrator-sic","text":"","title":"Prowide Integrator SIC"},{"location":"integrator/sic/#overview","text":"The key feature provided by the SIC extension is the specific model implementation for the Swiss RGTS messages. This is a restricted ISO 20022 version with a subset of messages with specific constraints. For more information for SIC check https://www.six-group.com/interbank-clearing/en/home/standardization/iso-payments/iso20022/implementation-guidelines.html The supported schemas and guidelines version is 4.9 .","title":"Overview"},{"location":"integrator/sic/#supported-message-schemes","text":"The following table includes all the supported message types: camt.003.001.07.ch.02 camt.004.001.08.ch.02 camt.005.001.08.ch.01 camt.006.001.08.ch.02 camt.007.001.08.ch.01 camt.008.001.08.ch.01 camt.019.001.07.ch.02 camt.025.001.05.ch.01 camt.027.001.06.chsepa.01 camt.029.001.08.chsepa.01 camt.029.001.09.ch.01 camt.048.001.05.ch.01 camt.050.001.05.ch.01 camt.052.001.08.ch.02 camt.054.001.08.ch.02 camt.056.001.08.ch.02 camt.087.001.05.chsepa.01 pacs.002.001.10.ch.02 pacs.004.001.09.ch.02 pacs.008.001.08.ch.02 pacs.009.001.08.ch.02 pacs.028.001.01.chsepa.02 Legacy from release 4.6: camt.003.001.05.ch.01 camt.004.001.06.ch.01 camt.005.001.06.ch.03 camt.006.001.06.ch.02 camt.007.001.06.ch.01 camt.008.001.06.ch.01 camt.019.001.05.ch.01 camt.025.001.03.ch.01 camt.027.001.06.chsepa.01 camt.029.001.03.ch.01 camt.029.001.08.chsepa.01 camt.048.001.03.ch.01 camt.050.001.03.ch.01 camt.052.001.02.ch.01 camt.054.001.02.ch.01 camt.056.001.01.ch.01 camt.087.001.05.chsepa.01 pacs.002.001.03.ch.01 pacs.004.001.02.ch.02 pacs.008.001.02.ch.02 pacs.009.001.02.ch.02 pacs.028.001.01.chsepa.02","title":"Supported message schemes"},{"location":"integrator/sic/#message-model","text":"For each of the described message types, a specific implementation message class is provided, into a single common package: com . prowidesoftware . swift . model . mx . sic The package above always contains the latest release availalbe. For older releases, the package name includes the release version, for example: com . prowidesoftware . swift . model . mx . sic . v4_6 The SIC message subset uses custom namespaces , not aligned to the ISO standard namespaces. Once the message class is identified, the creation of a new SIC message is similar to the creation of any standard ISO message. You just populate the Java object and the model will already include the constraints from the SIC schema. For example: MxPacs00800102Ch02 mx = new MxPacs00800102Ch02 (); mx . setFIToFICstmrCdtTrf ( new FIToFICustomerCreditTransferV02 ()); mx . getFIToFICstmrCdtTrf (). setGrpHdr ( new GroupHeader33 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setMsgId ( \"1234\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setCreDtTm ( now ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setNbOfTxs ( \"1\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setIntrBkSttlmDt ( now ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setSttlmInf ( new SettlementInformation13Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getSttlmInf (). setSttlmMtd ( SettlementMethod1Code . CLRG ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setInstgAgt ( new BranchAndFinancialInstitutionIdentification4Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getInstgAgt (). setFinInstnId ( new FinancialInstitutionIdentification7 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getInstgAgt (). getFinInstnId (). setBIC ( \"ABCDUSXXXXX\" ); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). setInstdAgt ( new BranchAndFinancialInstitutionIdentification4Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getInstdAgt (). setFinInstnId ( new FinancialInstitutionIdentification7 ()); mx . getFIToFICstmrCdtTrf (). getGrpHdr (). getInstdAgt (). getFinInstnId (). setBIC ( \"EFGHUSXXXXX\" ); mx . getFIToFICstmrCdtTrf (). addCdtTrfTxInf ( new CreditTransferTransactionInformation11 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setPmtId ( new PaymentIdentification3 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getPmtId (). setEndToEndId ( \"aaaa\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getPmtId (). setTxId ( \"bbbb\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setPmtTpInf ( new PaymentTypeInformation21 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getPmtTpInf (). setLclInstrm ( new LocalInstrument2Choice ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getPmtTpInf (). getLclInstrm (). setCd ( \"ESRPMT\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setIntrBkSttlmAmt ( new ActiveCurrencyAndAmount ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getIntrBkSttlmAmt (). setCcy ( \"USD\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getIntrBkSttlmAmt (). setValue ( new BigDecimal ( \"1234.56\" )); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setChrgBr ( ChargeBearerType1Code . CRED ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setDbtr ( new PartyIdentification32 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getDbtr (). setNm ( \"Foo1\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setDbtrAgt ( new BranchAndFinancialInstitutionIdentification4Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getDbtrAgt (). setFinInstnId ( new FinancialInstitutionIdentification7 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getDbtrAgt (). getFinInstnId (). setBIC ( \"AAAAUSXXXXX\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setCdtr ( new PartyIdentification32 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getCdtr (). setNm ( \"Foo2\" ); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). setCdtrAgt ( new BranchAndFinancialInstitutionIdentification4Pacs00800102 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getCdtrAgt (). setFinInstnId ( new FinancialInstitutionIdentification7 ()); mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). get ( 0 ). getCdtrAgt (). getFinInstnId (). setBIC ( \"AAAAUSXXXXX\" ); String xml = mx . message (); The serialized XML will have the proper custom SIC namespace. To complement the message model, an enumeration SicMessageType is provided with the list of supported SIC messages. This enumeration implements the internal SchemaProvider interface, so it can be used with the Prowide Integrator Validator library to run the SIC validation for an XML.","title":"Message model"},{"location":"integrator/sic/#sic-validation","text":"Only available if you have a license of the Prowide Integrator Validation module. Along the standard ISO 20022 validation, the Validation module supports out-of-the-box validation for SIC (Swiss RTGS). There are two possible scenarios: You are validating a message created by you in your application with the message model. You are validating a message created externally and received in XML format. In the first case, you should have created a specific message object such as MxPain00800102Ch02 from the com.prowidesoftware.swift.model.mx.sic package. Therefore, the model has already constrained the elements and elements values with the restrictions from the SIC schemas including binding to the custom SIC namespace . Moreover, the object implements the SchemaProvider interface. So when you call the validation engine passing the object as a parameter, the engine will already apply the corresponding SIC schema. You can just use the validation call: validateMessage ( final AbstractMX msg ) In the second scenario, you just have the XML, so the message structure cannot be distinguished from a regular ISO message. So in order to validate these messages, you need to provide additional information to the validation call to clearly identify the SIC message type you intend to validate. For that, you should use the validation call: validateMxMessage ( final String xml , SchemaProvider schemaProvider ) Where for the SchemaProvider parameter you can use any value of the SicMessageType enum. When your source content is already the XML it is always recommended to use the XML as parameter for the validation. If you parse the XML into an MX object first, and then call the validation using the parsed message as parameter, some errors may not be detected. The validation call with the model object is only intended for scenarios where you are building the message using the model API.","title":"SIC validation"},{"location":"integrator/sic/#sic-mt-mx-translations","text":"Only available if you have a license of the Prowide Integrator Translations module. Along the standard ISO 20022 translations, the MT-MX Translations module provides some specific out-of-the-box translations between MT messages and SIC ISO 20022 messages. The following translations are supported for the restricted ISO 20022 for SIC, the Swiss RTGS. The input and output MX model class is the specific class for the restricted ISO version. Such as MxPain00800102Ch02 instead of the standard ISO MxPain00800102 .","title":"SIC MT-MX Translations"},{"location":"integrator/sic/#mt-to-mx","text":"103 Single Customer Credit Transfer pacs.008.001.02.ch.02 FIToFICustomerCreditTransferV02 SIC v2 202 General Financial Institution Transfer pacs.009.001.02.ch.02 FinancialInstitutionCreditTransferV02 SIC v2 202.COV General Financial Institution Transfer, Cover Payment pacs.009.001.02.ch.02 FinancialInstitutionCreditTransferV02 SIC v2","title":"MT to MX"},{"location":"integrator/sic/#mx-to-mt","text":"pacs.008.001.02.ch.02 Single Customer Credit Transfer 2 SIC v2 103 Single Customer Credit Transfer pacs.009.001.02.ch.02 FinancialInstitutionCreditTransferV02 SIC v2 202 General Financial Institution Transfer pacs.009.001.02.ch.02 FinancialInstitutionCreditTransferV02 SIC v2 202.COV General Financial Institution Transfer, Cover Payment pacs.004.001.02.ch.02 PaymentReturnV02 103 RETURN Single Customer Credit Transfer Return pacs.002.001.03 FIToFIPaymentStatusReportV03 ACK / NACK Service message 21 Each of these translations is implemented in its own translation class. For information on the translation API, please check the Prowide Integrator Translations developer guide.","title":"MX to MT"},{"location":"integrator/sic/#javadoc","text":"Online javadoc Prowide Integrator SDK Javadoc SRU2023-9.4.x","title":"Javadoc"},{"location":"integrator/myformat/","text":"Prowide Integrator MyFormat - Overview The MyFormat module facilitates the conversion between SWIFT and proprietary data in any of these formats: Proprietary formats XML -> Custom XML structures JSON -> Custom Json structures CSV -> Custom CSV files with one or many messages Fixed-Length -> Custom fixed-length files with any record structure SWIFT standards FIN -> Any message type in the SWIFT MT standard (ISO 15022) MX -> Any message type in the SWIFT MX standard (ISO 20022) Any combination of formats is supported; as well as any message flow, inbound or outbound. Our library helps define detailed field to field mappings easily. The mappings are then embedded and deployed in your application to perform the translation on the fly . The translation process loads the source message and generates the target message dynamically, by applying your mapping rules. Since the module is packaged as a Java library, a simple API call to the library is enough to generate the output. Unlike other tools, in MyFormat there is no need to generate and compile code or to use any proprietary mapping UI. Javadoc Online javadoc Prowide Integrator MyFormat Javadoc SRU2023-9.4.x","title":"Prowide Integrator MyFormat - Overview"},{"location":"integrator/myformat/#prowide-integrator-myformat-overview","text":"The MyFormat module facilitates the conversion between SWIFT and proprietary data in any of these formats: Proprietary formats XML -> Custom XML structures JSON -> Custom Json structures CSV -> Custom CSV files with one or many messages Fixed-Length -> Custom fixed-length files with any record structure SWIFT standards FIN -> Any message type in the SWIFT MT standard (ISO 15022) MX -> Any message type in the SWIFT MX standard (ISO 20022) Any combination of formats is supported; as well as any message flow, inbound or outbound. Our library helps define detailed field to field mappings easily. The mappings are then embedded and deployed in your application to perform the translation on the fly . The translation process loads the source message and generates the target message dynamically, by applying your mapping rules. Since the module is packaged as a Java library, a simple API call to the library is enough to generate the output. Unlike other tools, in MyFormat there is no need to generate and compile code or to use any proprietary mapping UI.","title":"Prowide Integrator MyFormat - Overview"},{"location":"integrator/myformat/#javadoc","text":"Online javadoc Prowide Integrator MyFormat Javadoc SRU2023-9.4.x","title":"Javadoc"},{"location":"integrator/myformat/myformat-config/","text":"Mapping configuration The implementation for mapping configuration is the MappingTable class. When calling the translation, the engine expects as parameters this table along the source message to convert. This table contains basically the source and target formats definition, along a list of mapping rules The mapping rules can be added to the table programmatically, or they can be externalized and loaded from Excel files or from a Database. The following sections describe the different options. Programmatic Configuration When the mappings are a small set, or when doing a POC, it is possible to define the mapping configuration in your application code. The engine will use the mapping configuration defined in the code to perform the translation. This alternative to define the rules is more efficient and less error-prone, but any change to the mapping will require you to compile and deploy a new version of your solution. In this case, the conversion rules are programmatically coded. The MappingTable class defines the source and target formats and provides methods to set and modify the list of mapping rules. Example 1 : MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MT ); t . add ( new MappingRule ( \"1\" , \"32B/1\" )); t . add ( new MappingRule ( \"2\" , \"32B/2\" , WriteMode . APPEND , new Transformation ( Transformation . Key . replace , \".\" , \",\" ))); In this example, a mapping table is created to convert a CSV into an MT. Then two mapping rules are added to the table. The first rule will copy the content of the second column in the CSV (columns are zero-based) file into the first component of a field 32B of the MT. The second rule will append to the same field 32B, setting the content of the third column in the CSV file into the second component of the field. Notice the second rule also defines a transformation to replace the decimal separator in the CSV file (a dot) by a comma, which is the expected format in the MT. Example 2 : MappingTable t = new MappingTable ( FileFormat . XML , FileFormat . MT ); t . add ( new MappingRule ( \"/document/foo\" , \"20\" , new Transformation ( Transformation . Key . replace , \" \" , \"\" ), new Transformation ( Transformation . Key . upperCase ), new Transformation ( Transformation . Key . prepend , \"Hi \" ))); t . add ( new MappingRule ( \"\\\" 1234\\\"\" , \"20\" , WriteMode . APPEND )); t . add ( new MappingRule ( \"\\\"NOREF\\\"\" , \"21\" )); t . add ( new MappingRule ( \"/bad/path\" , \"16\" )); In this example, a mapping table is created to convert an XML into an MT. Then four mapping rules are added to the table. An method is also provided in the is provided in the MappingTable to validate the mapping rules. The validation will check that all selectors are well-formed according to the defined source and target file formats, and also that the transformation functions are defined with proper parameters. This validation is helpful for sanity check and to prevent exceptions during the actual translation in runtime. The validation is static, meaning it will not prevent creating wrong content because of invalid mapping rules logic or invalid input data. Since mapping tables are maintained as local variables in your program, you can instantiate as many mapping tables as a combination of source and target messages you need to process. If you\u2019ve implemented and want to use a custom transformation in a rule, you just create an instance of transformation passing your own implementing class, for example: t . add ( new MappingRule ( \"2\" , \"32B/2\" , WriteMode . APPEND , new Transformation ( new CustomTransformer ()))); External Configuration When the mapping configuration is a large set, or when its definition are closer to the business than to technical mappings, it is possible to define the mapping configuration in a separate file. The engine will load the mapping configuration from the file and use it to perform the translation. Thus, the maintenance of the mapping configuration is decoupled from the application code. Externalized mappings can be loaded from Excel sheets or database tables. In this case, the rules are defined and maintained decoupled from the translation code, loaded from an Excel spreadsheet or database . This usage is convenient when the conversion rules should be maintained by system analysts, and not developers, because it requires no coding during maintenance. Example : An Excel for this configuration way. The database option is similar, it uses a simple table schema with a similar syntax as in the sheet. The following sections describe the details of the mapping configuration in Excel and in Database. Mapping configuration in Excel files Mapping rules configurations can be loaded from files using Excel spreadsheets. Within an Excel file, each sheet (tab) can contain an independent mapping table. Each mapping table consists of the list of mapping rules to convert from a specific source message to a specific target message. The mapping table in an Excel sheet must contain three columns : Column 1 : The source selector with an expression according to the source message file format. The selector can optionally contain a read mode, such as \"foreach\". The source column is mandatory , cannot be left blank. It can contain literals (wrapped in double quotes or within a literal function) or selector expressions (example XPath or MtPath). Multiple source selectors may be defined in a single mapping rule according to the read mode; in such case, a comma separates the selectors. Examples in different file formats: E/E1/95Q \"FOO\" literal(FOO) /Document/PmtInf/PmtDtls/CshTxTp Document.CstmrCdtTrfInitn.GrpHdr.MsgId foreach(/Document/PmtInf[{N}]/PmtDtl[{M}]/CshTxCode) concat(/A/B/C, \"-\", /A/D/@attr) Column 2 : The optional transformation calls separated by a semicolon. The transformation column is optional, if it is left blank no transformations will be applied. Transformations are expressed as parameterized functions. Multiple transformations may be defined for a single mapping rule, in such case the functions are indicated in a single cell. Parameters are indicated between brackets next to the function name, and separated by commas. Integer parameters are indicated as plain digits, while string parameters wrapped in double quotes. The order of the transformations is important because they are applied from left to right, with the output of a transformation becoming the input for the next one. Examples: stripStart(\"/\"); formatMTDecimal(); append(\"$\") fromPIC(X(10)); stripToNull(); upperCase(); map(\"BENEFICIARY\", \"BEN\", \"SHARED\", \"SHA\", \"CUSTOMER\", \"OUR\"); Column 3 : The target selector with an expression according to the target message file format. The target column is mandatory , cannot be left blank, and must contain a single selector expression, proper to the target format. For example, an XPath expression if the message to create is an XML, or an MtPath if the created message is an MT. Column 4 : An optional write mode. The write mode column is optional . The accepted values for the columns are CREATE, UPDATE and APPEND. By default, the mapping rule will use the Create mode. Note this column also accept the SETUP value as valid. This is not a write mode but a transformation config expression. SETUP options will be described later in this doc. Each row in the sheet defines a specific mapping rule , with the first row intentionally skipped, so it can be used as a header reference. Notice that rules, order is important . The conversion flow will process the mapping table from top to bottom. This is particularly significant when creating MT messages because block 4 of a SWIFT MT message is a sorted list of fields. For other file formats, such as XML based messages, the rules order does not affect the structure of the created message. All cells in the spreadsheet must be in plain text format (numeric cells will be read as strings). Notice all selectors and transformation functions are expressed as strings. Loading the configuration To simplify loading the mapping configuration from Excel files, a specially suited MappingTableExcelLoader class is provided. The following example shows how to load a mapping configuration from a SpreadSheet on disk. MappingTableExcelLoader loader = new MappingTableExcelLoader ( getClass (). getResourceAsStream ( \"/sample.xls\" )); MappingTable mappingTable = loader . load ( \"A\" , FileFormat . XML , FileFormat . MT ); List < String > problems = loader . getProblems (); Notice that the source and target formats can be explicitly indicated when loading the table. This information is used for static validation and also in runtime to create proper reader and writer objects. You can also create the reader and writer object and pass those as parameter. For certain operations you will prefer to use this dependency-injection alternative. Depending on your particular needs you have several similar options for the table loading such as: MappingTable mappingTable = new MappingTable ( FileFormat . XML , FileFormat . MT ); MappingTableExcelLoader loader = new MappingTableExcelLoader ( getClass (). getResourceAsStream ( \"/sample.xls\" )); loader . load ( \"A\" , mappingTable ); Mapping tables can be handled individually or, if the same Spreadsheets contain several mapping tables, a full load can be called, reading each of the sheets (tabs). MappingTableExcelLoader loader = new MappingTableExcelLoader ( getClass (). getResourceAsStream ( \"/multi_tab.xls\" )); List < MappingTable > mappingTables = loader . load (); in the above example, all sheets in the file will be loaded and returned as a list of mapping tables. The problems list will contain all errors found in all sheets. The read MappingTable object will be passed as a parameter to the conversion engine along with the source message when a translation is performed. When translating multiple files, the mappings should be read only once in the lifecycle of the controlling program. Excel error handling The loading process will perform static syntax validations on each defined rule, and the provided file formats are used to validate the content selectors. If all rows are ok, the returned list from loader.getProblems() is empty. Otherwise, the list contains a comprehensive detail of found errors in plain English. List < String > problems = loader . getProblems (); Any excel inquiry error during the load will be caught and reported as plain Strings. When the MappingTableExcelLoader is used, the errors are stored in the loader object and can be retrieved with the getProblems() method. Since the loader is reentrant, the problems list is emptied before each load call. Although excel and syntax errors are reported by the loading, a call afterwards to the MappingTable#validate() is highly recommended. That manually triggered validation on the mapping table will ensure the rules are also semantically correct and will perform as expected. Since the mapping is normally loaded once during your application initialization, this syntax and semantic validation checks will be done only once and the report is static, in the sense that it is a validation on the mapping definition regardless of the actual runtime translations calls you do afterwards. So this is useful to detect mapping errors when the mapping rules are created or maintained. Mapping configuration in Database Mapping rules configurations can be loaded from a database table. The database structure is minimal to simplify setup and maintenance. It is conformed by a single database table, with fixed table and column names, and with the rules stored as text. Multiple mapping configurations can be stored in the same single database table; when the query is performed, a discriminator column with the configuration name is used to load specific subsets of rules. Each row in the database table defines a specific mapping rule, and contains seven columns as follows: Id : This is the internal unique identifier of the table record and is normally set to auto increment in the database. The mapping engine does not use this column. pw_conf_name column : This column is the discriminator and is used to group a set of mapping rules corresponding to a Mapping Table configuration. It would normally exist one configuration name for each source and target message combination. The value for the column has no restrictions but should be consistently set to all records belonging to the same configuration, and it cannot be null. Example: mt202_seev031 This discriminator is necessary to keep the single table design, instead of defining a more complex model with one-to-many relation between the mapping table and rules. pw_order column : When the rules are retrieved from the database, this column is used to order the results. It normally should contain a sequential number, local to the mapping configuration. Meaning, per each pw_conf_name an independent order counter. The order cannot be null. Notice that rules, order is important . The conversion flow will process the mapping table in ascending order of rules. This is particularly significant when creating MT messages because block 4 of a SWIFT MT message is a sorted list of fields. When creating XML based messages, the rules order does not affect the structure of the created XML. pw_source column : The source column is mandatory, cannot be null. It can contain literals (wrapped in double quotes) or selector expressions (example XPath or MtPath ). Please refer to the description of Column 1 in the configuration from Excel section above. pw_transformation column : The transformation column is optional, if it is left null no transformations will be applied. Transformations are expressed as parameterized functions. Multiple transformations may be defined for a single mapping rule, in such case the functions are indicated in the same database column, separated by a semicolon. Please refer to the description of Column 2 in the configuration from Excel section above. pw_target column : The target column is mandatory, cannot be null, and must contain a single selector expression, proper to the target format. For example, an XPath expression if the message to create is an XML, or an MtPath if the created message is an MT. Please refer to the description of Column 3 in the configuration from Excel section above. pw_mode column : The write mode column is optional. The accepted values for the columns are CREATE, UPDATE and APPEND. By default, the mapping rule will use the Create mode. Please refer to Setup commands for further details about SETUP mode. Loading the configuration The engine uses direct JDBC queries to access the database and load the rules, so the driver for your particular database must be available in the runtime classpath (for example: mysql-connector-java-version-bin.jar for MySQL). The MappingTable class provides a few methods called loadFromDatabase to load the rules. Such as: MappingTable table = new MappingTable ( FileFormat . XML , FileFormat . MT ); List < String > problems = MappingTable . loadFromDatabase ( \"jdbc:mysql://localhost/myformat\" , \"root\" , null , \"202_seev031\" , table ); Similar methods are available with connection, dataSource and datasource context name. Notice that the source and target formats must be explicitly indicated when creating the mapping table object parameter, there are no part of the loaded data. The read MappingTable object will be passed as a parameter to the conversion engine along with the source message when a translation is performed. When translating multiple files, the mappings should be read only once in the lifecycle of the controlling program. Custom table and scheme For additional flexibility when loading the mappings from the database, a specially suited MappingTableDatabaseLoader is also available. This utility class is intended for reuse. You can create a single loader instance with any of the construction options ( url, datasource, connection, etc...) and then call the load method multiple times to retrieve different mapping tables. For each load call you can provide the configuration name and optionally further customize the loader with the setters for the main table name, schema name, etc... Example 1: This code creates the loader with a Datasource as constructor parameter, and then two different mapping tables are loaded, each from a different database schema. MappingTableDatabaseLoader loader = new MappingTableDatabaseLoader ( datasource ); loader . setSchemaName ( \"CUSTOM_SCHEMA_1\" ); MappingTable table1 = loader . load ( \"test\" , FileFormat . XML , FileFormat . MT ); loader . setSchemaName ( \"CUSTOM_SCHEMA_2\" ); MappingTable table2 = loader . load ( \"test\" , FileFormat . XML , FileFormat . MX ); Example 2: This example creates a loader from a Connection as constructor parameter, and then loads the mapping table from a customized table, where the actual table name and columns have different names. MappingTableDatabaseLoader loader = new MappingTableDatabaseLoader ( conn ); loader . setMainTableName ( \"custom_table\" ); loader . getCustomColumnNames (). pw_conf_name = \"custom_pw_conf_name\" ; loader . getCustomColumnNames (). pw_order = \"custom_pw_order\" ; MappingTable table = loader . load ( \"test\" , FileFormat . XML , FileFormat . MT ); Notice that the source and target formats can be explicitly indicated when loading the mapping, since are not part of the loaded data. DB error handling Any database inquiry error during the load will be catched and reported as plain Strings. When the direct MappingTable#loadFromDatabase method is used, the method returns the errors as return value. And when the MappingTableDatabaseLoader is used, the errors are stored in the loader object and can be retrieved with the getProblems() method. Since the loader is reentrant, the problems list is emptied before each load call. Besides the database access errors, the imported rules are syntactically checked during parsing and a comprehensive detail of found errors will be catched and reported in the problems list. Although database and syntax errors are reported by the loading, a call afterwards to the MappingTable#validate() is highly recommended. That manually triggered validation on the mapping table will ensure the rules are also ** semantically** correct and will perform as expected. Since the mapping is normally loaded once during your application initialization, this syntax and semantic validation checks will be done only once and the report is static, in the sense that it is a validation on the mapping definition regardless of the actual runtime translations calls you do afterwards. So this is useful to detect mapping errors when the mapping rules are created or maintained. Setup commands In the externalized mapping configuration, spreadsheet or DB, several special rules can be added to probide global configuration for the mapping. These rules are called SETUP rules and are identified by the SETUP keyword in the write mode column. Then source in the rule is used to provide the command value, while the target is used to provide the actual command. For example: Source Transformations Target Write Mode \"CSV\" sourceFormat SETUP The following commands are supported: sourceFormat : To indicate the source format of the mapping table. Setting this in the mapping is the same as passing the Format parameter when creating a MappingTable instance. targetFormat : To indicate the target format of the mapping table. Setting this in the mapping is the same as passing the Format parameter when creating a MappingTable instance. mappingName : To indicate the name of the mapping table. mxType : To indicate the specific MX type in conversions from/into MX, for example \"pacs.008.001.08\". This parameter is used for two purposes: it will validate that all the MX expression paths in the source/target selectors are valid paths for the given message type. And, if the target message is MX, it initializes the message header and namespace declarations in the target message. appHdrType : To indicate the specific MX Application Header type in conversions into MX, for example \"BAH_V1\". This parameter is used mainly to set the message header type in the target message. Setting this in the mapping is the same as passing the AppHdrType parameter when creating a MxWriter instance. mtType : To indicate the specific MT type in conversions into MT, for example \"103\". This parameter is used mainly to initialize the message block 2 header in the target message. Setting this in the mapping is the same as passing the MtType parameter when creating a MtWriter instance. More setup commands are described in the specific file formats documentation. Validation The validate() method in the mapping table can be used to run a static syntax analysis of the mapping rules. You can then incorporate the validation as part of your development and testing procedures. The validation is especially useful when the mapping table is loaded from an external source (rules are not programmatically defined). The validation will parse all source and target selectors and will report any syntax error. The transformation expressions are also parsed to check the function calls are recognizable and with the expected number of arguments. MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MX ); ... t . add ( new MappingRule ( \"6\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/Dbtr/Nm\" )); t . add ( new MappingRule ( \"2\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/DbtrAcct/Nm\" )); ... if ( t . validate (). isEmpty ()) { ... } Many typical errors can be discovered with this static check. Notice, however, that a syntactically valid mapping table does not imply the mapping will produce a valid result at runtime. The compliance of the generated file depends on the source message content and on the business logic of the configured mapping rules.","title":"Mapping configuration"},{"location":"integrator/myformat/myformat-config/#mapping-configuration","text":"The implementation for mapping configuration is the MappingTable class. When calling the translation, the engine expects as parameters this table along the source message to convert. This table contains basically the source and target formats definition, along a list of mapping rules The mapping rules can be added to the table programmatically, or they can be externalized and loaded from Excel files or from a Database. The following sections describe the different options.","title":"Mapping configuration"},{"location":"integrator/myformat/myformat-config/#programmatic-configuration","text":"When the mappings are a small set, or when doing a POC, it is possible to define the mapping configuration in your application code. The engine will use the mapping configuration defined in the code to perform the translation. This alternative to define the rules is more efficient and less error-prone, but any change to the mapping will require you to compile and deploy a new version of your solution. In this case, the conversion rules are programmatically coded. The MappingTable class defines the source and target formats and provides methods to set and modify the list of mapping rules. Example 1 : MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MT ); t . add ( new MappingRule ( \"1\" , \"32B/1\" )); t . add ( new MappingRule ( \"2\" , \"32B/2\" , WriteMode . APPEND , new Transformation ( Transformation . Key . replace , \".\" , \",\" ))); In this example, a mapping table is created to convert a CSV into an MT. Then two mapping rules are added to the table. The first rule will copy the content of the second column in the CSV (columns are zero-based) file into the first component of a field 32B of the MT. The second rule will append to the same field 32B, setting the content of the third column in the CSV file into the second component of the field. Notice the second rule also defines a transformation to replace the decimal separator in the CSV file (a dot) by a comma, which is the expected format in the MT. Example 2 : MappingTable t = new MappingTable ( FileFormat . XML , FileFormat . MT ); t . add ( new MappingRule ( \"/document/foo\" , \"20\" , new Transformation ( Transformation . Key . replace , \" \" , \"\" ), new Transformation ( Transformation . Key . upperCase ), new Transformation ( Transformation . Key . prepend , \"Hi \" ))); t . add ( new MappingRule ( \"\\\" 1234\\\"\" , \"20\" , WriteMode . APPEND )); t . add ( new MappingRule ( \"\\\"NOREF\\\"\" , \"21\" )); t . add ( new MappingRule ( \"/bad/path\" , \"16\" )); In this example, a mapping table is created to convert an XML into an MT. Then four mapping rules are added to the table. An method is also provided in the is provided in the MappingTable to validate the mapping rules. The validation will check that all selectors are well-formed according to the defined source and target file formats, and also that the transformation functions are defined with proper parameters. This validation is helpful for sanity check and to prevent exceptions during the actual translation in runtime. The validation is static, meaning it will not prevent creating wrong content because of invalid mapping rules logic or invalid input data. Since mapping tables are maintained as local variables in your program, you can instantiate as many mapping tables as a combination of source and target messages you need to process. If you\u2019ve implemented and want to use a custom transformation in a rule, you just create an instance of transformation passing your own implementing class, for example: t . add ( new MappingRule ( \"2\" , \"32B/2\" , WriteMode . APPEND , new Transformation ( new CustomTransformer ())));","title":"Programmatic Configuration"},{"location":"integrator/myformat/myformat-config/#external-configuration","text":"When the mapping configuration is a large set, or when its definition are closer to the business than to technical mappings, it is possible to define the mapping configuration in a separate file. The engine will load the mapping configuration from the file and use it to perform the translation. Thus, the maintenance of the mapping configuration is decoupled from the application code. Externalized mappings can be loaded from Excel sheets or database tables. In this case, the rules are defined and maintained decoupled from the translation code, loaded from an Excel spreadsheet or database . This usage is convenient when the conversion rules should be maintained by system analysts, and not developers, because it requires no coding during maintenance. Example : An Excel for this configuration way. The database option is similar, it uses a simple table schema with a similar syntax as in the sheet. The following sections describe the details of the mapping configuration in Excel and in Database.","title":"External Configuration"},{"location":"integrator/myformat/myformat-config/#mapping-configuration-in-excel-files","text":"Mapping rules configurations can be loaded from files using Excel spreadsheets. Within an Excel file, each sheet (tab) can contain an independent mapping table. Each mapping table consists of the list of mapping rules to convert from a specific source message to a specific target message. The mapping table in an Excel sheet must contain three columns : Column 1 : The source selector with an expression according to the source message file format. The selector can optionally contain a read mode, such as \"foreach\". The source column is mandatory , cannot be left blank. It can contain literals (wrapped in double quotes or within a literal function) or selector expressions (example XPath or MtPath). Multiple source selectors may be defined in a single mapping rule according to the read mode; in such case, a comma separates the selectors. Examples in different file formats: E/E1/95Q \"FOO\" literal(FOO) /Document/PmtInf/PmtDtls/CshTxTp Document.CstmrCdtTrfInitn.GrpHdr.MsgId foreach(/Document/PmtInf[{N}]/PmtDtl[{M}]/CshTxCode) concat(/A/B/C, \"-\", /A/D/@attr) Column 2 : The optional transformation calls separated by a semicolon. The transformation column is optional, if it is left blank no transformations will be applied. Transformations are expressed as parameterized functions. Multiple transformations may be defined for a single mapping rule, in such case the functions are indicated in a single cell. Parameters are indicated between brackets next to the function name, and separated by commas. Integer parameters are indicated as plain digits, while string parameters wrapped in double quotes. The order of the transformations is important because they are applied from left to right, with the output of a transformation becoming the input for the next one. Examples: stripStart(\"/\"); formatMTDecimal(); append(\"$\") fromPIC(X(10)); stripToNull(); upperCase(); map(\"BENEFICIARY\", \"BEN\", \"SHARED\", \"SHA\", \"CUSTOMER\", \"OUR\"); Column 3 : The target selector with an expression according to the target message file format. The target column is mandatory , cannot be left blank, and must contain a single selector expression, proper to the target format. For example, an XPath expression if the message to create is an XML, or an MtPath if the created message is an MT. Column 4 : An optional write mode. The write mode column is optional . The accepted values for the columns are CREATE, UPDATE and APPEND. By default, the mapping rule will use the Create mode. Note this column also accept the SETUP value as valid. This is not a write mode but a transformation config expression. SETUP options will be described later in this doc. Each row in the sheet defines a specific mapping rule , with the first row intentionally skipped, so it can be used as a header reference. Notice that rules, order is important . The conversion flow will process the mapping table from top to bottom. This is particularly significant when creating MT messages because block 4 of a SWIFT MT message is a sorted list of fields. For other file formats, such as XML based messages, the rules order does not affect the structure of the created message. All cells in the spreadsheet must be in plain text format (numeric cells will be read as strings). Notice all selectors and transformation functions are expressed as strings.","title":"Mapping configuration in Excel files"},{"location":"integrator/myformat/myformat-config/#loading-the-configuration","text":"To simplify loading the mapping configuration from Excel files, a specially suited MappingTableExcelLoader class is provided. The following example shows how to load a mapping configuration from a SpreadSheet on disk. MappingTableExcelLoader loader = new MappingTableExcelLoader ( getClass (). getResourceAsStream ( \"/sample.xls\" )); MappingTable mappingTable = loader . load ( \"A\" , FileFormat . XML , FileFormat . MT ); List < String > problems = loader . getProblems (); Notice that the source and target formats can be explicitly indicated when loading the table. This information is used for static validation and also in runtime to create proper reader and writer objects. You can also create the reader and writer object and pass those as parameter. For certain operations you will prefer to use this dependency-injection alternative. Depending on your particular needs you have several similar options for the table loading such as: MappingTable mappingTable = new MappingTable ( FileFormat . XML , FileFormat . MT ); MappingTableExcelLoader loader = new MappingTableExcelLoader ( getClass (). getResourceAsStream ( \"/sample.xls\" )); loader . load ( \"A\" , mappingTable ); Mapping tables can be handled individually or, if the same Spreadsheets contain several mapping tables, a full load can be called, reading each of the sheets (tabs). MappingTableExcelLoader loader = new MappingTableExcelLoader ( getClass (). getResourceAsStream ( \"/multi_tab.xls\" )); List < MappingTable > mappingTables = loader . load (); in the above example, all sheets in the file will be loaded and returned as a list of mapping tables. The problems list will contain all errors found in all sheets. The read MappingTable object will be passed as a parameter to the conversion engine along with the source message when a translation is performed. When translating multiple files, the mappings should be read only once in the lifecycle of the controlling program.","title":"Loading the configuration"},{"location":"integrator/myformat/myformat-config/#excel-error-handling","text":"The loading process will perform static syntax validations on each defined rule, and the provided file formats are used to validate the content selectors. If all rows are ok, the returned list from loader.getProblems() is empty. Otherwise, the list contains a comprehensive detail of found errors in plain English. List < String > problems = loader . getProblems (); Any excel inquiry error during the load will be caught and reported as plain Strings. When the MappingTableExcelLoader is used, the errors are stored in the loader object and can be retrieved with the getProblems() method. Since the loader is reentrant, the problems list is emptied before each load call. Although excel and syntax errors are reported by the loading, a call afterwards to the MappingTable#validate() is highly recommended. That manually triggered validation on the mapping table will ensure the rules are also semantically correct and will perform as expected. Since the mapping is normally loaded once during your application initialization, this syntax and semantic validation checks will be done only once and the report is static, in the sense that it is a validation on the mapping definition regardless of the actual runtime translations calls you do afterwards. So this is useful to detect mapping errors when the mapping rules are created or maintained.","title":"Excel error handling"},{"location":"integrator/myformat/myformat-config/#mapping-configuration-in-database","text":"Mapping rules configurations can be loaded from a database table. The database structure is minimal to simplify setup and maintenance. It is conformed by a single database table, with fixed table and column names, and with the rules stored as text. Multiple mapping configurations can be stored in the same single database table; when the query is performed, a discriminator column with the configuration name is used to load specific subsets of rules. Each row in the database table defines a specific mapping rule, and contains seven columns as follows: Id : This is the internal unique identifier of the table record and is normally set to auto increment in the database. The mapping engine does not use this column. pw_conf_name column : This column is the discriminator and is used to group a set of mapping rules corresponding to a Mapping Table configuration. It would normally exist one configuration name for each source and target message combination. The value for the column has no restrictions but should be consistently set to all records belonging to the same configuration, and it cannot be null. Example: mt202_seev031 This discriminator is necessary to keep the single table design, instead of defining a more complex model with one-to-many relation between the mapping table and rules. pw_order column : When the rules are retrieved from the database, this column is used to order the results. It normally should contain a sequential number, local to the mapping configuration. Meaning, per each pw_conf_name an independent order counter. The order cannot be null. Notice that rules, order is important . The conversion flow will process the mapping table in ascending order of rules. This is particularly significant when creating MT messages because block 4 of a SWIFT MT message is a sorted list of fields. When creating XML based messages, the rules order does not affect the structure of the created XML. pw_source column : The source column is mandatory, cannot be null. It can contain literals (wrapped in double quotes) or selector expressions (example XPath or MtPath ). Please refer to the description of Column 1 in the configuration from Excel section above. pw_transformation column : The transformation column is optional, if it is left null no transformations will be applied. Transformations are expressed as parameterized functions. Multiple transformations may be defined for a single mapping rule, in such case the functions are indicated in the same database column, separated by a semicolon. Please refer to the description of Column 2 in the configuration from Excel section above. pw_target column : The target column is mandatory, cannot be null, and must contain a single selector expression, proper to the target format. For example, an XPath expression if the message to create is an XML, or an MtPath if the created message is an MT. Please refer to the description of Column 3 in the configuration from Excel section above. pw_mode column : The write mode column is optional. The accepted values for the columns are CREATE, UPDATE and APPEND. By default, the mapping rule will use the Create mode. Please refer to Setup commands for further details about SETUP mode.","title":"Mapping configuration in Database"},{"location":"integrator/myformat/myformat-config/#loading-the-configuration_1","text":"The engine uses direct JDBC queries to access the database and load the rules, so the driver for your particular database must be available in the runtime classpath (for example: mysql-connector-java-version-bin.jar for MySQL). The MappingTable class provides a few methods called loadFromDatabase to load the rules. Such as: MappingTable table = new MappingTable ( FileFormat . XML , FileFormat . MT ); List < String > problems = MappingTable . loadFromDatabase ( \"jdbc:mysql://localhost/myformat\" , \"root\" , null , \"202_seev031\" , table ); Similar methods are available with connection, dataSource and datasource context name. Notice that the source and target formats must be explicitly indicated when creating the mapping table object parameter, there are no part of the loaded data. The read MappingTable object will be passed as a parameter to the conversion engine along with the source message when a translation is performed. When translating multiple files, the mappings should be read only once in the lifecycle of the controlling program.","title":"Loading the configuration"},{"location":"integrator/myformat/myformat-config/#custom-table-and-scheme","text":"For additional flexibility when loading the mappings from the database, a specially suited MappingTableDatabaseLoader is also available. This utility class is intended for reuse. You can create a single loader instance with any of the construction options ( url, datasource, connection, etc...) and then call the load method multiple times to retrieve different mapping tables. For each load call you can provide the configuration name and optionally further customize the loader with the setters for the main table name, schema name, etc... Example 1: This code creates the loader with a Datasource as constructor parameter, and then two different mapping tables are loaded, each from a different database schema. MappingTableDatabaseLoader loader = new MappingTableDatabaseLoader ( datasource ); loader . setSchemaName ( \"CUSTOM_SCHEMA_1\" ); MappingTable table1 = loader . load ( \"test\" , FileFormat . XML , FileFormat . MT ); loader . setSchemaName ( \"CUSTOM_SCHEMA_2\" ); MappingTable table2 = loader . load ( \"test\" , FileFormat . XML , FileFormat . MX ); Example 2: This example creates a loader from a Connection as constructor parameter, and then loads the mapping table from a customized table, where the actual table name and columns have different names. MappingTableDatabaseLoader loader = new MappingTableDatabaseLoader ( conn ); loader . setMainTableName ( \"custom_table\" ); loader . getCustomColumnNames (). pw_conf_name = \"custom_pw_conf_name\" ; loader . getCustomColumnNames (). pw_order = \"custom_pw_order\" ; MappingTable table = loader . load ( \"test\" , FileFormat . XML , FileFormat . MT ); Notice that the source and target formats can be explicitly indicated when loading the mapping, since are not part of the loaded data.","title":"Custom table and scheme"},{"location":"integrator/myformat/myformat-config/#db-error-handling","text":"Any database inquiry error during the load will be catched and reported as plain Strings. When the direct MappingTable#loadFromDatabase method is used, the method returns the errors as return value. And when the MappingTableDatabaseLoader is used, the errors are stored in the loader object and can be retrieved with the getProblems() method. Since the loader is reentrant, the problems list is emptied before each load call. Besides the database access errors, the imported rules are syntactically checked during parsing and a comprehensive detail of found errors will be catched and reported in the problems list. Although database and syntax errors are reported by the loading, a call afterwards to the MappingTable#validate() is highly recommended. That manually triggered validation on the mapping table will ensure the rules are also ** semantically** correct and will perform as expected. Since the mapping is normally loaded once during your application initialization, this syntax and semantic validation checks will be done only once and the report is static, in the sense that it is a validation on the mapping definition regardless of the actual runtime translations calls you do afterwards. So this is useful to detect mapping errors when the mapping rules are created or maintained.","title":"DB error handling"},{"location":"integrator/myformat/myformat-config/#setup-commands","text":"In the externalized mapping configuration, spreadsheet or DB, several special rules can be added to probide global configuration for the mapping. These rules are called SETUP rules and are identified by the SETUP keyword in the write mode column. Then source in the rule is used to provide the command value, while the target is used to provide the actual command. For example: Source Transformations Target Write Mode \"CSV\" sourceFormat SETUP The following commands are supported: sourceFormat : To indicate the source format of the mapping table. Setting this in the mapping is the same as passing the Format parameter when creating a MappingTable instance. targetFormat : To indicate the target format of the mapping table. Setting this in the mapping is the same as passing the Format parameter when creating a MappingTable instance. mappingName : To indicate the name of the mapping table. mxType : To indicate the specific MX type in conversions from/into MX, for example \"pacs.008.001.08\". This parameter is used for two purposes: it will validate that all the MX expression paths in the source/target selectors are valid paths for the given message type. And, if the target message is MX, it initializes the message header and namespace declarations in the target message. appHdrType : To indicate the specific MX Application Header type in conversions into MX, for example \"BAH_V1\". This parameter is used mainly to set the message header type in the target message. Setting this in the mapping is the same as passing the AppHdrType parameter when creating a MxWriter instance. mtType : To indicate the specific MT type in conversions into MT, for example \"103\". This parameter is used mainly to initialize the message block 2 header in the target message. Setting this in the mapping is the same as passing the MtType parameter when creating a MtWriter instance. More setup commands are described in the specific file formats documentation.","title":"Setup commands"},{"location":"integrator/myformat/myformat-config/#validation","text":"The validate() method in the mapping table can be used to run a static syntax analysis of the mapping rules. You can then incorporate the validation as part of your development and testing procedures. The validation is especially useful when the mapping table is loaded from an external source (rules are not programmatically defined). The validation will parse all source and target selectors and will report any syntax error. The transformation expressions are also parsed to check the function calls are recognizable and with the expected number of arguments. MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MX ); ... t . add ( new MappingRule ( \"6\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/Dbtr/Nm\" )); t . add ( new MappingRule ( \"2\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/DbtrAcct/Nm\" )); ... if ( t . validate (). isEmpty ()) { ... } Many typical errors can be discovered with this static check. Notice, however, that a syntactically valid mapping table does not imply the mapping will produce a valid result at runtime. The compliance of the generated file depends on the source message content and on the business logic of the configured mapping rules.","title":"Validation"},{"location":"integrator/myformat/myformat-csv/","text":"Format > CSV CSV files can be used as source or target for a translation. Single or multiple line messages are supported. The selectors are flexible enough to read or write content with complex structures and record types. If the message is a CSV, the source selector will be just a number indicating the position of the element in the CSV row. This number is zero-based , meaning the first element in the row will be selected by a 0. CSV Selector The same CSV selector syntax is used for source and target. Meaning to express what content from a CSV input message is read, or to express where in the output CSV message the content is written. The basic selector format indicates the column of the field with a plain zero-based number. Since CSV messages can have elaborated structures, with different types of lines, identified by a record identifier (you could have the first column defining the structure of the following columns), then the selector supports also more complex variants. Those variants are defined by the csv-selector grammar. Structure The grammar enables defining basically three components, each serves a different purpose: Field (required): Provides a method to extract information from a line and can be expressed in two different ways: By Positions : This method requires just a number indicating the zero-based order of the column to select. By Name : This method uses a static map of field names. The field names must be defined as an initial setup, then in the selectors the field name can be used without the need to indicate column number every time. Variables (optional): The variables are optional and are used to reorder the input content read in a FOREACH. In CSV the FOREACH is used when the CSV contains multiple lines. The primary use case for variables in this context is for line numbers, but a variable can also be used to store content, and thus to reorder the input based on the content of an element (for example to group transactions per account or currency). Condition (optional): Provides a method to filter a subset of lines from the input, for example could be used to select the records based on a record type identified by the first column value in each line. Field Examples By Positions: By Name: // create the field definitions CsvFieldsDef defs = new CsvFieldsDef () . addField ( \"IBAN\" , \"1\" ) . addField ( \"ADDR1\" , \"2\" ) . addField ( \"ADDR2\" , \"3\" ) . addField ( \"ADDR3\" , \"4\" ) . addField ( \"BIC\" , \"5\" ); // create reader instance for source message String inputMsg = \"...\" ; CsvReader reader = CsvReader . builder ( inputMsg ). fieldsDef ( defs ). build (); Variables Examples Condition Examples Grammar The grammar structure for de CSV selector is as follows: The selector contains 2 subcomponents: Field : a column number (zero based) Selector-options : A list of variables ( opt-variables ) and/or conditions ( opt-condition-list ). Or Empty value (these subcomponents are optional) The opt-variables is an optional variable list that can contain any number of elements: variable : Valid values are \"{\" name \"}\" , \"{\" name \":\" field opt-field-condition \"}\" . The opt-condition-list is an optional condition (or opt-field-condition ) list that can contain any number of elements: condition : Valid values are \"\" , \"\" , \"<\" field \">\" , \"<\" field \"='\" value \"'>\" . Expressed in a formal way selector ::= field selector-options field ::= column number (zero based) selector-options ::= \"[\" opt-variables opt-condition-list \"]\" | EMPTY opt-variables ::= variables-list | EMPTY variables-list ::= variables-list variable | variable variable ::= \"{\" name \"}\" | \"{\" name \":\" field opt-field-condition \"}\" opt-condition-list ::= condition-list | EMPTY opt-field-condition ::= \"[\" condition-list \"]\" | EMPTY condition-list ::= condition-list condition | condition condition ::= \"\" | \"\" | \"<\" field \">\" | \"<\" field \"='\" value \"'>\" Grammar Behavior Examples Basic selectors 0 Selects the value in the first column. 3 Selects the value in the 4th column. Selectors with conditions 5[] Selects the value in the 5th column from the first row in the document. 0[<0='DTL'>] Selects the value in the 1st column from a line where the first column contains the record identifier \"DTL\". 3[<0='HDR'>] Selects the value in the 4th column from the first row starting with record identifier \"HDR\". 1[<0='DTL'>] Selects the value in the 2nd column from the lines 4 to 5 where the first column contains the record identifier \"DTL\". Selectors with variables 3[{N}] Selects the value in the 4th column, and stores the current line number in a variable \"N\". Variables are used in the context of a mapping rule with \"foreach\", when multiple message lines are being read or written. 2[{M:9}] Selects the value in the 3rd column, and stores the value in the 10th column in a variable \"M\". 6[{M:9}{N}] Selects the value in the 7th column, and stores the value in the 10th column in a variable \"M\" and the current line in a variable \"N\". Selectors with variables and conditions 1[{N}] Selects the value in the 2nd column from lines 1 to 4, and stores the line number in a variable \"N\". 3[{N}<0='DTL'>] Selects the value in the 4th column from all lines where the first column contains the record identifier \"DTL\", and stores the line number in a variable \"N\". 8[{M:9}<0='HDR'>] Selects the value in the 9th column from the first row having record identifier \"HRD\", and stores the value from the 10th column in a variable \"M\". 5[{M:9}{N}<0='DTL'>] Selects the value in the 6th column from all lines with record identifier \"DTL\", and stores the value from column 10 in a variable \"M\" and the line number in a variable \"N\". 3[{M:9[<0='HDR'>]}<0='DTL'>] Selects the value in the 4th column from all lines with record identifier \"DTL\", and stores the value in the 10th column from the first row in the header, in a variable \"M\". This complex variable definition can be handy to group content, in this case we are grouping by a value in the header. Notice the condition order is important. <0='DTL'> finds all DTL lines and then selects the first four lines <0='DTL'> finds the first four lines and from those, selects the ones with DTL Field name definition When the mapping is done programmatically, you can configure a dictionary of field names. You give a name to the field column in the CSV, and then you just use the naming in the mapping rules. This feature makes the mapping rules less error-prone. For example: CsvFieldsDef defs = new CsvLenFieldsDef () . addField ( \"RECORD\" , \"0\" ) . addField ( \"REFERENCE\" , \"4\" ) . addField ( \"SOURCE_ACCT\" , \"5\" ); MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MX ); // add the mx type to the message t . add ( new MappingRule ( \"pain.001.001.03\" , \"mxType\" , WriteMode . SETUP )); // file ref from HDR as message identifier t . add ( new MappingRule ( \"REFERENCE[]\" , \"/Document/CstmrCdtTrfInitn/GrpHdr/MsgId\" )); // source account t . add ( new MappingRule ( \"foreach(SOURCE_ACCT[{n}])\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/DbtrAcct/Id/Othr/Id\" )); In the example above, instead of \"5\" to select the 6th column in the CSV, we used a human-friendly term as \"SOURCE_ACCT\". The field definitions are provided to the translation process in the reader (the reader may allow more configuration options, such as the split separator). So you must call the translation passing your own instance of the reader and writer like this: // create reader instance for source message CsvReader reader = CsvReader . builder ( input ). separator ( '|' ). fieldsDef ( defs ). build (); // create writer and call translation MxWriter writer = new MxWriter ( MxType . pacs_008_001_02 ); // call the translation passing the reader, writer and the rules MyFormatEngine . translate ( reader , writer , t . getRules ()); Conversion FROM CSV When working with CSV as source message, you have two options. To generate a single target message with content from all source rows, or to generate on target message per source row. You can think of it as n to n, or n to 1. Generating one message per row (n to n) When the source message format contains multiple messages, you have to code the iteration in your process. For instance, if the source message is a CSV file where each row contains the data to produce a target MX message must create a CSV file reader first, then call the translation with a CsvReader per row like this: CsvFileReader fileReader = new CsvFileReader ( input ); while ( reader . hasNext ()) { // each element in the file reader is a message reader Csvreader reader = fileReader . next (); // a new writer instance must be provided on each iteration MxWriter writer = new MxWriter ( MxType . pain_001_001_03 ); // call the translation providing the reader, writer and rules MyFormatEngine . translate ( reader . next (), writer , rules ); // this is the created MX for the row MxPain00100103 mx = ( MxPain00100103 ) writer . mx (); } On each iteration, a new Mx is produced. A similar approach applies for an Excel source message. Generating one message per csv (n to 1) If your source message contains the data for a single target message distributed within different rows, you can use foreach selectors that will automatically iterate on your CSV rows and create repetitive elements in the target message. For example: t . add ( new MappingRule ( \"foreach(5)\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/CdtTrfTxInf/Cdtr/Nm\" )); The above rule will get the content on the 6th column in all rows of the source CSV and will generate one PmtInf element in the target MX per row. Notice the variable \"n\" in the target selector is implicit, it will be replaced by a number from 1 to the number of rows in the CSV. Special \"concat\" In case that you need to combine source values in order to create complex select rules, you can use the special expression \"concat\" . This expression concatenates the values of the fields indicated in the parameters. It also allows to add literal strings in order to add value separators. The expression should be double-quoted in order to be recognized as a string. For example the selector 0, \"|\", 1, \"|\", 2 will concatenate the values of the columns 0, 1 and 2 using a pipe symbol \"|\" as separator. Thus, if the source CSV contains the following line; foo,bar, baz, the result will be foo|bar|baz. When reading content from CSV, the concat can also be used within the value selector of a foreach expression, to produce more interesting and sometimes handy results. As explained in the Mapping Rule section, the foreach expression can be used to iterate over all rows in a CSV file. So for instance the selector foreach(0) will iterate over all rows in the CSV file, and the value read and propagated in each iteration will be the value of the first column in the CSV. Then a selector such as foreach(0, 1) will also iterate all column 0 in the CSV, but the value to propagate will be actually the content of column 1 in each line. Then when used together, the foreach and the concat, can produce the following results: For example: In this case, the engine will iterate over all CSV lines, and in each iteration it will propagate as value the content of the columns 0, 1 and 3 using # and : as separators. Given this input: The result will be: 11#AAA:12.34 55#XXX:55.55 99#ZZZ:67.89 This is useful when you need to write a value that depends on the content of multiple columns. That should be done by combining this expression with some transformations in order to obtain the desired result. Given the example above, if you need to write the value of the 2nd column only for rows where the 1st column value is larger than 55, you can use the following selector: The result will be: ZZZ Another example, if you need to format the value of the 3rd column to ##.#### format only for rows where the 2nd column value is \"XXX\", otherwise, remove decimals, you can use the following selector: The result will be: 12 55.5500 67 Conversion TO CSV The target CSV file could have a simple structure where all lines are the same. Or a more complex structure with record identifiers and different line types, each with a different number of columns. In the case where the structure is more complex, and you want to use target selectors with record identifiers (such as 3[<0='DTL'>] ) you might need to initialize your target message with default data . Setup: addRow The first part of your mapping table should consist of instructions to build the empty template of your target message. By doing this, you ensure the overall structure of the output file is valid, even though it will be empty until the actual mapping rules are processed. A special write mode called SETUP is used for this purpose, combined with a special \"command\" named addRow . In a setup mapping rule, the command replaces the target selector. For example, if your message structure contains a header record, followed by multiple detail records and with a footer record at the end; the following setup commands will initialize the file. MappingTable t = new MappingTable ( FileFormat . MX , FileFormat . CSV ); // create an empty header row identifier by HR t . add ( new MappingRule ( \"literal(HR,,,,)\" , \"addRow\" , WriteMode . SETUP )); // create multiple detail records identifier by TX t . add ( new MappingRule ( \"FOREACH(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf, \\\"TX,,,\\\")\" , \"addRow\" , WriteMode . SETUP )); // create a single footer record at the end, identified by FR t . add ( new MappingRule ( \"literal(FR,,)\" , \"addRow\" , WriteMode . SETUP )); Notice we used literal values to fill the rows with a record identifier in the first column, and just the split separator to generate empty columns for each row. Only one header and footer is generated, but the detailed record is generated as many times as actual transactions in the source file; meaning the initialization is not static but dynamic , it can use input data . After setup and regardless of the following mapping rules, the output will have a valid structure. The setup is also important for the filter selectors to work. Suppose you want to define a rule such as t . add ( new MappingRule ( \"foreach(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/CdtrAcct/Id/IBAN)\" , \"BEN_IBAN[]\" )); This rule will iterate the IBAN numbers in all transactions of the source message, and will write them in the \"BEN_IBAN\" field of all \"TX\" records in the target message. Without the setup, this filter would have written a single transaction row in the output. Setup: other commands Other optional SETUP commands are available when the target format is CSV. When the mapping is defined programmatically, these options are also available through plain Java API in the CsvWriter. However, in order to have the process configuration encapsulated along the mappings in the externalized (Excel or database) configuration, you can provide all these customizations in the mapping table. separator : The character to use as column's separator, it is comma by default. When used, this command should be placed before the addRow. smartQuotes : The string content \"true\" or \"false\" to enable or disable smart quoting. It is true by default, meaning column values will be quoted only if needed. When this is set to false, all column values will be quoted. smartEscapes : The string content \"true\" or \"false\" to enable or disable smart escaping. It is false by default, meaning column values will not be escaped. addFieldNames : The string content \"true\" or \"false\" to include or not the column names in an output CSV header line. columnNames : Comma separated list of column names.","title":"Format > CSV"},{"location":"integrator/myformat/myformat-csv/#format-csv","text":"CSV files can be used as source or target for a translation. Single or multiple line messages are supported. The selectors are flexible enough to read or write content with complex structures and record types. If the message is a CSV, the source selector will be just a number indicating the position of the element in the CSV row. This number is zero-based , meaning the first element in the row will be selected by a 0.","title":"Format > CSV"},{"location":"integrator/myformat/myformat-csv/#csv-selector","text":"The same CSV selector syntax is used for source and target. Meaning to express what content from a CSV input message is read, or to express where in the output CSV message the content is written. The basic selector format indicates the column of the field with a plain zero-based number. Since CSV messages can have elaborated structures, with different types of lines, identified by a record identifier (you could have the first column defining the structure of the following columns), then the selector supports also more complex variants. Those variants are defined by the csv-selector grammar.","title":"CSV Selector"},{"location":"integrator/myformat/myformat-csv/#structure","text":"The grammar enables defining basically three components, each serves a different purpose: Field (required): Provides a method to extract information from a line and can be expressed in two different ways: By Positions : This method requires just a number indicating the zero-based order of the column to select. By Name : This method uses a static map of field names. The field names must be defined as an initial setup, then in the selectors the field name can be used without the need to indicate column number every time. Variables (optional): The variables are optional and are used to reorder the input content read in a FOREACH. In CSV the FOREACH is used when the CSV contains multiple lines. The primary use case for variables in this context is for line numbers, but a variable can also be used to store content, and thus to reorder the input based on the content of an element (for example to group transactions per account or currency). Condition (optional): Provides a method to filter a subset of lines from the input, for example could be used to select the records based on a record type identified by the first column value in each line.","title":"Structure"},{"location":"integrator/myformat/myformat-csv/#field-examples","text":"By Positions: By Name: // create the field definitions CsvFieldsDef defs = new CsvFieldsDef () . addField ( \"IBAN\" , \"1\" ) . addField ( \"ADDR1\" , \"2\" ) . addField ( \"ADDR2\" , \"3\" ) . addField ( \"ADDR3\" , \"4\" ) . addField ( \"BIC\" , \"5\" ); // create reader instance for source message String inputMsg = \"...\" ; CsvReader reader = CsvReader . builder ( inputMsg ). fieldsDef ( defs ). build ();","title":"Field Examples"},{"location":"integrator/myformat/myformat-csv/#variables-examples","text":"","title":"Variables Examples"},{"location":"integrator/myformat/myformat-csv/#condition-examples","text":"","title":"Condition Examples"},{"location":"integrator/myformat/myformat-csv/#grammar","text":"The grammar structure for de CSV selector is as follows: The selector contains 2 subcomponents: Field : a column number (zero based) Selector-options : A list of variables ( opt-variables ) and/or conditions ( opt-condition-list ). Or Empty value (these subcomponents are optional) The opt-variables is an optional variable list that can contain any number of elements: variable : Valid values are \"{\" name \"}\" , \"{\" name \":\" field opt-field-condition \"}\" . The opt-condition-list is an optional condition (or opt-field-condition ) list that can contain any number of elements: condition : Valid values are \"\" , \"\" , \"<\" field \">\" , \"<\" field \"='\" value \"'>\" .","title":"Grammar"},{"location":"integrator/myformat/myformat-csv/#expressed-in-a-formal-way","text":"selector ::= field selector-options field ::= column number (zero based) selector-options ::= \"[\" opt-variables opt-condition-list \"]\" | EMPTY opt-variables ::= variables-list | EMPTY variables-list ::= variables-list variable | variable variable ::= \"{\" name \"}\" | \"{\" name \":\" field opt-field-condition \"}\" opt-condition-list ::= condition-list | EMPTY opt-field-condition ::= \"[\" condition-list \"]\" | EMPTY condition-list ::= condition-list condition | condition condition ::= \"\" | \"\" | \"<\" field \">\" | \"<\" field \"='\" value \"'>\"","title":"Expressed in a formal way"},{"location":"integrator/myformat/myformat-csv/#grammar-behavior-examples","text":"Basic selectors 0 Selects the value in the first column. 3 Selects the value in the 4th column. Selectors with conditions 5[] Selects the value in the 5th column from the first row in the document. 0[<0='DTL'>] Selects the value in the 1st column from a line where the first column contains the record identifier \"DTL\". 3[<0='HDR'>] Selects the value in the 4th column from the first row starting with record identifier \"HDR\". 1[<0='DTL'>] Selects the value in the 2nd column from the lines 4 to 5 where the first column contains the record identifier \"DTL\". Selectors with variables 3[{N}] Selects the value in the 4th column, and stores the current line number in a variable \"N\". Variables are used in the context of a mapping rule with \"foreach\", when multiple message lines are being read or written. 2[{M:9}] Selects the value in the 3rd column, and stores the value in the 10th column in a variable \"M\". 6[{M:9}{N}] Selects the value in the 7th column, and stores the value in the 10th column in a variable \"M\" and the current line in a variable \"N\". Selectors with variables and conditions 1[{N}] Selects the value in the 2nd column from lines 1 to 4, and stores the line number in a variable \"N\". 3[{N}<0='DTL'>] Selects the value in the 4th column from all lines where the first column contains the record identifier \"DTL\", and stores the line number in a variable \"N\". 8[{M:9}<0='HDR'>] Selects the value in the 9th column from the first row having record identifier \"HRD\", and stores the value from the 10th column in a variable \"M\". 5[{M:9}{N}<0='DTL'>] Selects the value in the 6th column from all lines with record identifier \"DTL\", and stores the value from column 10 in a variable \"M\" and the line number in a variable \"N\". 3[{M:9[<0='HDR'>]}<0='DTL'>] Selects the value in the 4th column from all lines with record identifier \"DTL\", and stores the value in the 10th column from the first row in the header, in a variable \"M\". This complex variable definition can be handy to group content, in this case we are grouping by a value in the header. Notice the condition order is important. <0='DTL'> finds all DTL lines and then selects the first four lines <0='DTL'> finds the first four lines and from those, selects the ones with DTL","title":"Grammar Behavior Examples"},{"location":"integrator/myformat/myformat-csv/#field-name-definition","text":"When the mapping is done programmatically, you can configure a dictionary of field names. You give a name to the field column in the CSV, and then you just use the naming in the mapping rules. This feature makes the mapping rules less error-prone. For example: CsvFieldsDef defs = new CsvLenFieldsDef () . addField ( \"RECORD\" , \"0\" ) . addField ( \"REFERENCE\" , \"4\" ) . addField ( \"SOURCE_ACCT\" , \"5\" ); MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MX ); // add the mx type to the message t . add ( new MappingRule ( \"pain.001.001.03\" , \"mxType\" , WriteMode . SETUP )); // file ref from HDR as message identifier t . add ( new MappingRule ( \"REFERENCE[]\" , \"/Document/CstmrCdtTrfInitn/GrpHdr/MsgId\" )); // source account t . add ( new MappingRule ( \"foreach(SOURCE_ACCT[{n}])\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/DbtrAcct/Id/Othr/Id\" )); In the example above, instead of \"5\" to select the 6th column in the CSV, we used a human-friendly term as \"SOURCE_ACCT\". The field definitions are provided to the translation process in the reader (the reader may allow more configuration options, such as the split separator). So you must call the translation passing your own instance of the reader and writer like this: // create reader instance for source message CsvReader reader = CsvReader . builder ( input ). separator ( '|' ). fieldsDef ( defs ). build (); // create writer and call translation MxWriter writer = new MxWriter ( MxType . pacs_008_001_02 ); // call the translation passing the reader, writer and the rules MyFormatEngine . translate ( reader , writer , t . getRules ());","title":"Field name definition"},{"location":"integrator/myformat/myformat-csv/#conversion-from-csv","text":"When working with CSV as source message, you have two options. To generate a single target message with content from all source rows, or to generate on target message per source row. You can think of it as n to n, or n to 1.","title":"Conversion FROM CSV"},{"location":"integrator/myformat/myformat-csv/#generating-one-message-per-row-n-to-n","text":"When the source message format contains multiple messages, you have to code the iteration in your process. For instance, if the source message is a CSV file where each row contains the data to produce a target MX message must create a CSV file reader first, then call the translation with a CsvReader per row like this: CsvFileReader fileReader = new CsvFileReader ( input ); while ( reader . hasNext ()) { // each element in the file reader is a message reader Csvreader reader = fileReader . next (); // a new writer instance must be provided on each iteration MxWriter writer = new MxWriter ( MxType . pain_001_001_03 ); // call the translation providing the reader, writer and rules MyFormatEngine . translate ( reader . next (), writer , rules ); // this is the created MX for the row MxPain00100103 mx = ( MxPain00100103 ) writer . mx (); } On each iteration, a new Mx is produced. A similar approach applies for an Excel source message.","title":"Generating one message per row (n to n)"},{"location":"integrator/myformat/myformat-csv/#generating-one-message-per-csv-n-to-1","text":"If your source message contains the data for a single target message distributed within different rows, you can use foreach selectors that will automatically iterate on your CSV rows and create repetitive elements in the target message. For example: t . add ( new MappingRule ( \"foreach(5)\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/CdtTrfTxInf/Cdtr/Nm\" )); The above rule will get the content on the 6th column in all rows of the source CSV and will generate one PmtInf element in the target MX per row. Notice the variable \"n\" in the target selector is implicit, it will be replaced by a number from 1 to the number of rows in the CSV.","title":"Generating one message per csv (n to 1)"},{"location":"integrator/myformat/myformat-csv/#special-concat","text":"In case that you need to combine source values in order to create complex select rules, you can use the special expression \"concat\" . This expression concatenates the values of the fields indicated in the parameters. It also allows to add literal strings in order to add value separators. The expression should be double-quoted in order to be recognized as a string. For example the selector 0, \"|\", 1, \"|\", 2 will concatenate the values of the columns 0, 1 and 2 using a pipe symbol \"|\" as separator. Thus, if the source CSV contains the following line; foo,bar, baz, the result will be foo|bar|baz. When reading content from CSV, the concat can also be used within the value selector of a foreach expression, to produce more interesting and sometimes handy results. As explained in the Mapping Rule section, the foreach expression can be used to iterate over all rows in a CSV file. So for instance the selector foreach(0) will iterate over all rows in the CSV file, and the value read and propagated in each iteration will be the value of the first column in the CSV. Then a selector such as foreach(0, 1) will also iterate all column 0 in the CSV, but the value to propagate will be actually the content of column 1 in each line. Then when used together, the foreach and the concat, can produce the following results: For example: In this case, the engine will iterate over all CSV lines, and in each iteration it will propagate as value the content of the columns 0, 1 and 3 using # and : as separators. Given this input: The result will be: 11#AAA:12.34 55#XXX:55.55 99#ZZZ:67.89 This is useful when you need to write a value that depends on the content of multiple columns. That should be done by combining this expression with some transformations in order to obtain the desired result. Given the example above, if you need to write the value of the 2nd column only for rows where the 1st column value is larger than 55, you can use the following selector: The result will be: ZZZ Another example, if you need to format the value of the 3rd column to ##.#### format only for rows where the 2nd column value is \"XXX\", otherwise, remove decimals, you can use the following selector: The result will be: 12 55.5500 67","title":"Special \"concat\""},{"location":"integrator/myformat/myformat-csv/#conversion-to-csv","text":"The target CSV file could have a simple structure where all lines are the same. Or a more complex structure with record identifiers and different line types, each with a different number of columns. In the case where the structure is more complex, and you want to use target selectors with record identifiers (such as 3[<0='DTL'>] ) you might need to initialize your target message with default data .","title":"Conversion TO CSV"},{"location":"integrator/myformat/myformat-csv/#setup-addrow","text":"The first part of your mapping table should consist of instructions to build the empty template of your target message. By doing this, you ensure the overall structure of the output file is valid, even though it will be empty until the actual mapping rules are processed. A special write mode called SETUP is used for this purpose, combined with a special \"command\" named addRow . In a setup mapping rule, the command replaces the target selector. For example, if your message structure contains a header record, followed by multiple detail records and with a footer record at the end; the following setup commands will initialize the file. MappingTable t = new MappingTable ( FileFormat . MX , FileFormat . CSV ); // create an empty header row identifier by HR t . add ( new MappingRule ( \"literal(HR,,,,)\" , \"addRow\" , WriteMode . SETUP )); // create multiple detail records identifier by TX t . add ( new MappingRule ( \"FOREACH(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf, \\\"TX,,,\\\")\" , \"addRow\" , WriteMode . SETUP )); // create a single footer record at the end, identified by FR t . add ( new MappingRule ( \"literal(FR,,)\" , \"addRow\" , WriteMode . SETUP )); Notice we used literal values to fill the rows with a record identifier in the first column, and just the split separator to generate empty columns for each row. Only one header and footer is generated, but the detailed record is generated as many times as actual transactions in the source file; meaning the initialization is not static but dynamic , it can use input data . After setup and regardless of the following mapping rules, the output will have a valid structure. The setup is also important for the filter selectors to work. Suppose you want to define a rule such as t . add ( new MappingRule ( \"foreach(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/CdtrAcct/Id/IBAN)\" , \"BEN_IBAN[]\" )); This rule will iterate the IBAN numbers in all transactions of the source message, and will write them in the \"BEN_IBAN\" field of all \"TX\" records in the target message. Without the setup, this filter would have written a single transaction row in the output.","title":"Setup: addRow"},{"location":"integrator/myformat/myformat-csv/#setup-other-commands","text":"Other optional SETUP commands are available when the target format is CSV. When the mapping is defined programmatically, these options are also available through plain Java API in the CsvWriter. However, in order to have the process configuration encapsulated along the mappings in the externalized (Excel or database) configuration, you can provide all these customizations in the mapping table. separator : The character to use as column's separator, it is comma by default. When used, this command should be placed before the addRow. smartQuotes : The string content \"true\" or \"false\" to enable or disable smart quoting. It is true by default, meaning column values will be quoted only if needed. When this is set to false, all column values will be quoted. smartEscapes : The string content \"true\" or \"false\" to enable or disable smart escaping. It is false by default, meaning column values will not be escaped. addFieldNames : The string content \"true\" or \"false\" to include or not the column names in an output CSV header line. columnNames : Comma separated list of column names.","title":"Setup: other commands"},{"location":"integrator/myformat/myformat-engine/","text":"Conversion Engine The conversion of messages is handled by the MyFormatEngine class. This class is stateless, meaning there is no need for initialization and disposal. The main entrypoint are the static translate methods. Different options for translation are available to ease conversion in common use cases. Generic translation The generic translation allows converting any source message to any target message with minimum restrictions. In this case, the translation method to use receives the source message as a String parameter along with the mapping table instance, and produces as a result the converted message also in String format. Once the mapping table and the source message is loaded, the translation call is straightforward: MappingTable mappings = ...; String source msg = ...; String target = MyFormatEngine . translate ( source , mappings ); Source message validation is out of scope in the translation. The provided content should be in the expected format as defined in the mapping table. If the selectors in the mapping rule cannot gather content due to a malformed source message, the translated result will be a null string. MT to MX translation To translate an MT message into an MX message, a specific translate method is provided. The difference between this translation and the generic translation is that model objects are used for source and target messages, instead of plain Strings. Therefore, the translate call receives the source MT as an AbstractMT and produces the result into an AbstractMX . Notice that the API defines the method with references to the generic abstract types, however specific MT and MX objects are actually used. Along with the source MT message object, the translate call receives the mapping rules as parameters. A complete mapping table is not necessary because the source and target file formats are implicit and constrained to MT and MX respectively. Finally, for the target message, the MxId object is used to properly identify the specific MX to create. For example: MT103 mt = MT103 . parse ( \"{1:F01\u2026\" ); List < MappingRule > rules = new ArrayList < MappingRule > (); rules . add ( new MappingRule ( \"sender\" , \"/AppHdr/Fr/FIId/FinInstnId/BICFI\" )); rules . add ( new MappingRule ( \"receiver\" , \"/AppHdr/To/FIId/FinInstnId/BICFI\" )); rules . add ( new MappingRule ( \"b3/121\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/PmtId/UETR\" )); rules . add ( new MappingRule ( \"32A/3\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt\" , new Transformation ( Transformation . Key . formatDecimal ))); rules . add ( new MappingRule ( \"32A/2\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt/@Ccy\" , WriteMode . APPEND )); rules . add ( new MappingRule ( \"32A/1\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmDt\" , new Transformation ( Transformation . Key . formatDateTime , \"yyMMdd\" , \"yyyy-MM-dd\" ))); MxId id = new MxId ( \"pacs.008.001.08\" ) MxPacs00800108 mx = ( MxPacs00800108 ) MyFormatEngine . translate ( mt , id , rules ); System . out . println ( mx . message ()); System . out . println ( mx . mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getIntrBkSttlmAmt (). getValue ()); Notice, a cast is required to use the getters of the specific created MX. In the rules, the target path should be either for the header (starting with /AppHdr ) or for the document body (starting with /Document ); and must be a valid path for the specific MX message being created. Rules with an unrecognized target path are ignored. MX to MT translation To translate an MX message into an MT message, a specific translate method is provided. The difference between this translation and the generic translation is that model objects are used for source and target messages, instead of plain Strings. Therefore, the translate call receives the source MX as an AbstractMX and produces the result into an AbstractMT . Notice that the API defines the method with references to the generic abstract types, however specific MT and MX objects are actually used. Along with the source MX message object, the translate call receives the mapping rules as parameter. A complete mapping table is not necessary because the source and target file formats are implicit and constrained to MX and MT respectively. Finally, for the target message, the message type must be provided to identify the specific MT message to create. For example: MxCamt00300105 mx = new MxCamt00300105 (); BusinessApplicationHeaderV01 header = new BusinessApplicationHeaderV01 (); header . setFr ( new Party9Choice ()); ... mx . setBusinessHeader ( new BusinessHeader ( header )); mx . setGetAcct ( new GetAccountV05 ()); mx . getGetAcct (). setAcctQryDef ( new AccountQuery1 ()); mx . getGetAcct (). getAcctQryDef (). setQryTp ( QueryType2Code . CHNG ); System . out . println ( mx . message ( \"message\" )); List < MappingRule > rules = new ArrayList < MappingRule > (); rules . add ( new MappingRule ( \"/AppHdr/Fr/FIId/BrnchId/Id\" , \"20\" )); rules . add ( new MappingRule ( \"/Document/GetAcct/AcctQryDef/QryTp\" , \"21\" )); MT202 mt = ( MT202 ) MyFormatEngine . translate ( mx , MtType . MT202 , rules ); System . out . println ( mt . message ()); System . out . println ( mt . getField20 (). getValue ()); System . out . println ( mt . getField21 (). getValue ()); Notice a cast is required to use the getters of the specific created MT. In the rules, the source path should be either for the header (starting with /AppHdr ) or for the document body (starting with /Document ); and must be a valid path for the specific MX message being read. Rules with an unrecognized source path are ignored. Rules order is particularly important when creating MT messages because in an MT message the text block (block 4) is not structured. Fields are appended to the message in the same order as they appear in the list of rules. Furthermore, a rule with write mode set to append or update will only take effect if the target field is exactly the same target field from the preceding rule.","title":"Conversion Engine"},{"location":"integrator/myformat/myformat-engine/#conversion-engine","text":"The conversion of messages is handled by the MyFormatEngine class. This class is stateless, meaning there is no need for initialization and disposal. The main entrypoint are the static translate methods. Different options for translation are available to ease conversion in common use cases.","title":"Conversion Engine"},{"location":"integrator/myformat/myformat-engine/#generic-translation","text":"The generic translation allows converting any source message to any target message with minimum restrictions. In this case, the translation method to use receives the source message as a String parameter along with the mapping table instance, and produces as a result the converted message also in String format. Once the mapping table and the source message is loaded, the translation call is straightforward: MappingTable mappings = ...; String source msg = ...; String target = MyFormatEngine . translate ( source , mappings ); Source message validation is out of scope in the translation. The provided content should be in the expected format as defined in the mapping table. If the selectors in the mapping rule cannot gather content due to a malformed source message, the translated result will be a null string.","title":"Generic translation"},{"location":"integrator/myformat/myformat-engine/#mt-to-mx-translation","text":"To translate an MT message into an MX message, a specific translate method is provided. The difference between this translation and the generic translation is that model objects are used for source and target messages, instead of plain Strings. Therefore, the translate call receives the source MT as an AbstractMT and produces the result into an AbstractMX . Notice that the API defines the method with references to the generic abstract types, however specific MT and MX objects are actually used. Along with the source MT message object, the translate call receives the mapping rules as parameters. A complete mapping table is not necessary because the source and target file formats are implicit and constrained to MT and MX respectively. Finally, for the target message, the MxId object is used to properly identify the specific MX to create. For example: MT103 mt = MT103 . parse ( \"{1:F01\u2026\" ); List < MappingRule > rules = new ArrayList < MappingRule > (); rules . add ( new MappingRule ( \"sender\" , \"/AppHdr/Fr/FIId/FinInstnId/BICFI\" )); rules . add ( new MappingRule ( \"receiver\" , \"/AppHdr/To/FIId/FinInstnId/BICFI\" )); rules . add ( new MappingRule ( \"b3/121\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/PmtId/UETR\" )); rules . add ( new MappingRule ( \"32A/3\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt\" , new Transformation ( Transformation . Key . formatDecimal ))); rules . add ( new MappingRule ( \"32A/2\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt/@Ccy\" , WriteMode . APPEND )); rules . add ( new MappingRule ( \"32A/1\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmDt\" , new Transformation ( Transformation . Key . formatDateTime , \"yyMMdd\" , \"yyyy-MM-dd\" ))); MxId id = new MxId ( \"pacs.008.001.08\" ) MxPacs00800108 mx = ( MxPacs00800108 ) MyFormatEngine . translate ( mt , id , rules ); System . out . println ( mx . message ()); System . out . println ( mx . mx . getFIToFICstmrCdtTrf (). getCdtTrfTxInf (). getIntrBkSttlmAmt (). getValue ()); Notice, a cast is required to use the getters of the specific created MX. In the rules, the target path should be either for the header (starting with /AppHdr ) or for the document body (starting with /Document ); and must be a valid path for the specific MX message being created. Rules with an unrecognized target path are ignored.","title":"MT to MX translation"},{"location":"integrator/myformat/myformat-engine/#mx-to-mt-translation","text":"To translate an MX message into an MT message, a specific translate method is provided. The difference between this translation and the generic translation is that model objects are used for source and target messages, instead of plain Strings. Therefore, the translate call receives the source MX as an AbstractMX and produces the result into an AbstractMT . Notice that the API defines the method with references to the generic abstract types, however specific MT and MX objects are actually used. Along with the source MX message object, the translate call receives the mapping rules as parameter. A complete mapping table is not necessary because the source and target file formats are implicit and constrained to MX and MT respectively. Finally, for the target message, the message type must be provided to identify the specific MT message to create. For example: MxCamt00300105 mx = new MxCamt00300105 (); BusinessApplicationHeaderV01 header = new BusinessApplicationHeaderV01 (); header . setFr ( new Party9Choice ()); ... mx . setBusinessHeader ( new BusinessHeader ( header )); mx . setGetAcct ( new GetAccountV05 ()); mx . getGetAcct (). setAcctQryDef ( new AccountQuery1 ()); mx . getGetAcct (). getAcctQryDef (). setQryTp ( QueryType2Code . CHNG ); System . out . println ( mx . message ( \"message\" )); List < MappingRule > rules = new ArrayList < MappingRule > (); rules . add ( new MappingRule ( \"/AppHdr/Fr/FIId/BrnchId/Id\" , \"20\" )); rules . add ( new MappingRule ( \"/Document/GetAcct/AcctQryDef/QryTp\" , \"21\" )); MT202 mt = ( MT202 ) MyFormatEngine . translate ( mx , MtType . MT202 , rules ); System . out . println ( mt . message ()); System . out . println ( mt . getField20 (). getValue ()); System . out . println ( mt . getField21 (). getValue ()); Notice a cast is required to use the getters of the specific created MT. In the rules, the source path should be either for the header (starting with /AppHdr ) or for the document body (starting with /Document ); and must be a valid path for the specific MX message being read. Rules with an unrecognized source path are ignored. Rules order is particularly important when creating MT messages because in an MT message the text block (block 4) is not structured. Fields are appended to the message in the same order as they appear in the list of rules. Furthermore, a rule with write mode set to append or update will only take effect if the target field is exactly the same target field from the preceding rule.","title":"MX to MT translation"},{"location":"integrator/myformat/myformat-fin/","text":"Format > FIN (MT) This message format is the SWIFT MT (ISO 15022), used in the SWIFT FIN service. It can be used either as source or target for a translation. MT Selector For FIN messages, the selector in the mapping rules uses the MtPath , a proprietary and convenient way to localize any field or component in a FIN message. The same MTPath expressions can be used to select content from a source message when converting from FIN to something else, and also to indicate what field to write when converting from something else to FIN. For a detailed description of the MtPath please refer to the SDK developer guide. We just provide here a few examples to illustrate the selector capabilities: 21 selects the value of field 21 at block4 in the source message. A/20C/SEME selects value of generic field 20C, with qualifier SEME at sequence A B1/98A/2 selects component 2, of field 98A in sequence B1 92B/FirstCurrencyCode selects \"FirstCurrencyCode\" component, of field 92B 59/Line[2] selects the second line of component 59, with the name & address information. 70E/2/Line[1] selects the first line of the narrative in field 70E 70E/2/Line[*] selects all text of the narrative in field 70E. 93a selects value of the first field 93, for any letter option found b1/LogicalTerminal selects the logical terminal field of header block 1 b3/108 selects the value of field 108 at block header 3. E/E1/95Q selects the field 95Q in subsequence E1 within sequence E All features from MtPath expressions can be used for content selection. When the source message in the translation is an MT, the selector indicates which field or component within a field must be read. For example, a rule having A/20C/SEME in the source selector will get the value of the reference field, and pass that as content for the translation. Analogously, when the target message in the translation is an MT, the selector indicates what field or component must be written in the target message. For example, a target selector having E/E1/95Q will take the translation content and create in the target MT a field 95Q, within a sequence E1, nested in a sequence E. All sequence boundaries will be created automatically. Predicates The MtPath supports predicates to indicate repetition indexes. The predicates can be in the sequences or field segments of the path and are surrounded by brackets. For example: A/22F[1] selects the first repetition of field 22F in sequence A 22F[3] selects the third repetition of field 22F in sequence A E/E[2]/95Q selects the field 95Q in the second subsequence E1 within first sequence E A1[2]/13A[3] selects the third field 13A in the second instance of sequence A1 In the above examples, all predicates have numbers, meaning they reference a specific instance of the repetitive sequence of fields. When the selector is used in rule processing of multiple elements, the number can be replaced by a variable name. For example, the source selector foreach(A/22F[{n}]) will read all instances of field 22F in sequence A, and will propagate a variable named n with the repetition index. Repetition in a foreach is 1 based, meaning the first read 22F will have n=1 . These repetition variables can then be used in the target selector, to map each repetitive 22F to a specific repetitive element in the target message. When a path such as A/22F[{n}] is used in the target selector, to indicate what content to create, then the variable n will be replaced by the repetition index in the source selector. This can be used for instance to map a repetitive element in a source XML into a repetitive sequence or field in a target MX. Prefilled target message When translating into MT, the mandatory headers data will be initialized with default content. However, some header fields such as the message type , sender , and receiver are important. These fields can be set using mapping rules (The MtPath expression can target any field in any header block) but you can also apply the conversion to an existing MT object. This can be accomplished easily by passing your own instance of MT to the MtWriter . To use a prefilled writer, you need to call the Engine with your own instances of reader and writer for the specific file format involved in the translation. For example: // we create a message object with the sender and receiver MT101 init = new MT101 ( \"GULBKWKWXXX\" , \"ICBKARBAXXX\" ); // we initialize the writer with this message MtWriter writer = new MtWriter ( init ); // we define or load the mappings MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MT ); t . add ( new MappingRule ( \"0\" , \"21\" )); t . add ( new MappingRule ( \"1\" , \"32B/1\" )); t . add ( new MappingRule ( \"2\" , \"32B/2\" , WriteMode . APPEND )); t . add ( new MappingRule ( \"3\" , \"59/2\" )); // we create a reader as well CsvFileReader reader = new CsvFileReader ( input ); // we call the translation with the specific reader and writer instances MyFormatEngine . translate ( reader , writer , t . getRules ()); // we cast the created MT MT101 mt = ( MT101 ) writer . mt (); Note that the sample above can be also written like the one below, and will produce the pretty same result: // we create a message object with the sender and receiver MT101 init = new MT101 ( \"GULBKWKWXXX\" , \"ICBKARBAXXX\" ); // we initialize the writer with this message MtWriter writer = new MtWriter ( init ); // we define or load the mappings MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MT ); t . add ( new MappingRule ( \"0\" , \"21\" )); t . add ( new MappingRule ( \"1\" , \"32B/Currency\" )); t . add ( new MappingRule ( \"2\" , \"32B/Amount\" , WriteMode . APPEND )); t . add ( new MappingRule ( \"3\" , \"59/NameAndAddress\" )); // we create a reader as well CsvFileReader reader = new CsvFileReader ( input ); // we call the translation with the specific reader and writer instances MyFormatEngine . translate ( reader , writer , t . getRules ()); // we cast the created MT MT101 mt = ( MT101 ) writer . mt (); Note that all the component name's format is Camel Case. Please refer to SDK MtPath for further details about Mt path format. This procedure can be used to prefill any field in the target message. Since the rules are processed in order, if you prefill part of the target MT programmatically, beware that fields created from the mapping will always be appended after any field you had set. Using the MtWriter as a message builder The MtWriter can be used as a message builder. This means that you can create a new MT message from scratch, and then use the writer to add fields and components to it. This is useful when you need to create a message that is not a translation of another message, but a new message that you want to build programmatically. To use the MtWriter as a message builder, you need to create an instance of the writer with no arguments, and then use the write method to add fields and components to it. For example: // we create a writer for and MT509 message MtWriter writer = new MtWriter ( MtType . MT509 ); // we add the data for the mandatory headers (will be initialized with default values anyway) writer . write ( \"b1/LogicalTerminal\" , \"AAAAUS30AXXX\" ); writer . write ( \"b2/ReceiverAddress\" , \"BBBBTRRSXXXX\" ); writer . write ( \"b2/DeliveryMonitoring\" , \"2\" ); writer . write ( \"b2/ObsolescencePeriod\" , \"020\" ); // we add the message content leveraging the MtPath expressions writer . write ( \"A/20C/1\" , \"SEME\" ); writer . write ( \"A/20C/2\" , \"MAINREF1234\" , WriteMode . APPEND ); writer . write ( \"A/23G\" , \"INST\" ); writer . write ( \"A/98C/1\" , \"PREP\" ); writer . write ( \"A/98C/2\" , \"20240625101806\" , WriteMode . APPEND ); writer . write ( \"A/A1/13A/1\" , \"LINK\" ); writer . write ( \"A/A1/13A/2\" , \"509\" , WriteMode . APPEND ); writer . write ( \"A/A1/20C/1\" , \"RELA\" ); writer . write ( \"A/A1/20C/2\" , \"RELAREF1234\" , WriteMode . APPEND ); writer . write ( \"A/A1[2]/20C/1\" , \"PREV\" ); writer . write ( \"A/A1[2]/20C/2\" , \"1234\" , WriteMode . APPEND ); writer . write ( \"A/A2/25D/1\" , \"CPRC\" ); writer . write ( \"A/A2/25D/3\" , \"CAND\" , WriteMode . APPEND ); writer . write ( \"A/A2/A2a/24B/1\" , \"REJT\" ); writer . write ( \"A/A2/A2a/24B/3\" , \"ADEA\" , WriteMode . APPEND ); writer . write ( \"B/22H/1\" , \"BUSE\" ); writer . write ( \"B/22H/2\" , \"BUYI\" , WriteMode . APPEND ); writer . write ( \"B/22H/1\" , \"PAYM\" ); writer . write ( \"B/22H/2\" , \"APMT\" , WriteMode . APPEND ); writer . write ( \"B/36B/1\" , \"ORDR\" ); writer . write ( \"B/36B/3\" , \"123,45\" , WriteMode . APPEND ); writer . write ( \"B/35B\" , \"/US/FOO487AE9\" ); // we get the created MT MT509 mt = ( MT509 ) writer . mt (); The sample code above creates a new MT509 message with the following content: {1:F01AAAAUS30AXXX0000000000}{2:I509BBBBTRRSXXXXN2020}{4: :16R:GENL :20C::SEME//MAINREF1234 :23G:INST :98C::PREP//20240625101806 :16R:LINK :13A::LINK//509 :20C::RELA//RELAREF1234 :16S:LINK :16R:LINK :20C::PREV//1234 :16S:LINK :16R:STAT :25D::CPRC//CAND :16R:REAS :24B::REJT//ADEA :16S:REAS :16S:STAT :16S:GENL :16R:TRADE :22H::BUSE//BUYI :22H::PAYM//APMT :36B::ORDR///123,45 :35B:/US/FOO487AE9 :16S:TRADE -}; Notice how the boundary fields (16R and 16S) are automatically added by the writer based on the path expressions used.","title":"Format > FIN (MT)"},{"location":"integrator/myformat/myformat-fin/#format-fin-mt","text":"This message format is the SWIFT MT (ISO 15022), used in the SWIFT FIN service. It can be used either as source or target for a translation.","title":"Format > FIN (MT)"},{"location":"integrator/myformat/myformat-fin/#mt-selector","text":"For FIN messages, the selector in the mapping rules uses the MtPath , a proprietary and convenient way to localize any field or component in a FIN message. The same MTPath expressions can be used to select content from a source message when converting from FIN to something else, and also to indicate what field to write when converting from something else to FIN. For a detailed description of the MtPath please refer to the SDK developer guide. We just provide here a few examples to illustrate the selector capabilities: 21 selects the value of field 21 at block4 in the source message. A/20C/SEME selects value of generic field 20C, with qualifier SEME at sequence A B1/98A/2 selects component 2, of field 98A in sequence B1 92B/FirstCurrencyCode selects \"FirstCurrencyCode\" component, of field 92B 59/Line[2] selects the second line of component 59, with the name & address information. 70E/2/Line[1] selects the first line of the narrative in field 70E 70E/2/Line[*] selects all text of the narrative in field 70E. 93a selects value of the first field 93, for any letter option found b1/LogicalTerminal selects the logical terminal field of header block 1 b3/108 selects the value of field 108 at block header 3. E/E1/95Q selects the field 95Q in subsequence E1 within sequence E All features from MtPath expressions can be used for content selection. When the source message in the translation is an MT, the selector indicates which field or component within a field must be read. For example, a rule having A/20C/SEME in the source selector will get the value of the reference field, and pass that as content for the translation. Analogously, when the target message in the translation is an MT, the selector indicates what field or component must be written in the target message. For example, a target selector having E/E1/95Q will take the translation content and create in the target MT a field 95Q, within a sequence E1, nested in a sequence E. All sequence boundaries will be created automatically.","title":"MT Selector"},{"location":"integrator/myformat/myformat-fin/#predicates","text":"The MtPath supports predicates to indicate repetition indexes. The predicates can be in the sequences or field segments of the path and are surrounded by brackets. For example: A/22F[1] selects the first repetition of field 22F in sequence A 22F[3] selects the third repetition of field 22F in sequence A E/E[2]/95Q selects the field 95Q in the second subsequence E1 within first sequence E A1[2]/13A[3] selects the third field 13A in the second instance of sequence A1 In the above examples, all predicates have numbers, meaning they reference a specific instance of the repetitive sequence of fields. When the selector is used in rule processing of multiple elements, the number can be replaced by a variable name. For example, the source selector foreach(A/22F[{n}]) will read all instances of field 22F in sequence A, and will propagate a variable named n with the repetition index. Repetition in a foreach is 1 based, meaning the first read 22F will have n=1 . These repetition variables can then be used in the target selector, to map each repetitive 22F to a specific repetitive element in the target message. When a path such as A/22F[{n}] is used in the target selector, to indicate what content to create, then the variable n will be replaced by the repetition index in the source selector. This can be used for instance to map a repetitive element in a source XML into a repetitive sequence or field in a target MX.","title":"Predicates"},{"location":"integrator/myformat/myformat-fin/#prefilled-target-message","text":"When translating into MT, the mandatory headers data will be initialized with default content. However, some header fields such as the message type , sender , and receiver are important. These fields can be set using mapping rules (The MtPath expression can target any field in any header block) but you can also apply the conversion to an existing MT object. This can be accomplished easily by passing your own instance of MT to the MtWriter . To use a prefilled writer, you need to call the Engine with your own instances of reader and writer for the specific file format involved in the translation. For example: // we create a message object with the sender and receiver MT101 init = new MT101 ( \"GULBKWKWXXX\" , \"ICBKARBAXXX\" ); // we initialize the writer with this message MtWriter writer = new MtWriter ( init ); // we define or load the mappings MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MT ); t . add ( new MappingRule ( \"0\" , \"21\" )); t . add ( new MappingRule ( \"1\" , \"32B/1\" )); t . add ( new MappingRule ( \"2\" , \"32B/2\" , WriteMode . APPEND )); t . add ( new MappingRule ( \"3\" , \"59/2\" )); // we create a reader as well CsvFileReader reader = new CsvFileReader ( input ); // we call the translation with the specific reader and writer instances MyFormatEngine . translate ( reader , writer , t . getRules ()); // we cast the created MT MT101 mt = ( MT101 ) writer . mt (); Note that the sample above can be also written like the one below, and will produce the pretty same result: // we create a message object with the sender and receiver MT101 init = new MT101 ( \"GULBKWKWXXX\" , \"ICBKARBAXXX\" ); // we initialize the writer with this message MtWriter writer = new MtWriter ( init ); // we define or load the mappings MappingTable t = new MappingTable ( FileFormat . CSV , FileFormat . MT ); t . add ( new MappingRule ( \"0\" , \"21\" )); t . add ( new MappingRule ( \"1\" , \"32B/Currency\" )); t . add ( new MappingRule ( \"2\" , \"32B/Amount\" , WriteMode . APPEND )); t . add ( new MappingRule ( \"3\" , \"59/NameAndAddress\" )); // we create a reader as well CsvFileReader reader = new CsvFileReader ( input ); // we call the translation with the specific reader and writer instances MyFormatEngine . translate ( reader , writer , t . getRules ()); // we cast the created MT MT101 mt = ( MT101 ) writer . mt (); Note that all the component name's format is Camel Case. Please refer to SDK MtPath for further details about Mt path format. This procedure can be used to prefill any field in the target message. Since the rules are processed in order, if you prefill part of the target MT programmatically, beware that fields created from the mapping will always be appended after any field you had set.","title":"Prefilled target message"},{"location":"integrator/myformat/myformat-fin/#using-the-mtwriter-as-a-message-builder","text":"The MtWriter can be used as a message builder. This means that you can create a new MT message from scratch, and then use the writer to add fields and components to it. This is useful when you need to create a message that is not a translation of another message, but a new message that you want to build programmatically. To use the MtWriter as a message builder, you need to create an instance of the writer with no arguments, and then use the write method to add fields and components to it. For example: // we create a writer for and MT509 message MtWriter writer = new MtWriter ( MtType . MT509 ); // we add the data for the mandatory headers (will be initialized with default values anyway) writer . write ( \"b1/LogicalTerminal\" , \"AAAAUS30AXXX\" ); writer . write ( \"b2/ReceiverAddress\" , \"BBBBTRRSXXXX\" ); writer . write ( \"b2/DeliveryMonitoring\" , \"2\" ); writer . write ( \"b2/ObsolescencePeriod\" , \"020\" ); // we add the message content leveraging the MtPath expressions writer . write ( \"A/20C/1\" , \"SEME\" ); writer . write ( \"A/20C/2\" , \"MAINREF1234\" , WriteMode . APPEND ); writer . write ( \"A/23G\" , \"INST\" ); writer . write ( \"A/98C/1\" , \"PREP\" ); writer . write ( \"A/98C/2\" , \"20240625101806\" , WriteMode . APPEND ); writer . write ( \"A/A1/13A/1\" , \"LINK\" ); writer . write ( \"A/A1/13A/2\" , \"509\" , WriteMode . APPEND ); writer . write ( \"A/A1/20C/1\" , \"RELA\" ); writer . write ( \"A/A1/20C/2\" , \"RELAREF1234\" , WriteMode . APPEND ); writer . write ( \"A/A1[2]/20C/1\" , \"PREV\" ); writer . write ( \"A/A1[2]/20C/2\" , \"1234\" , WriteMode . APPEND ); writer . write ( \"A/A2/25D/1\" , \"CPRC\" ); writer . write ( \"A/A2/25D/3\" , \"CAND\" , WriteMode . APPEND ); writer . write ( \"A/A2/A2a/24B/1\" , \"REJT\" ); writer . write ( \"A/A2/A2a/24B/3\" , \"ADEA\" , WriteMode . APPEND ); writer . write ( \"B/22H/1\" , \"BUSE\" ); writer . write ( \"B/22H/2\" , \"BUYI\" , WriteMode . APPEND ); writer . write ( \"B/22H/1\" , \"PAYM\" ); writer . write ( \"B/22H/2\" , \"APMT\" , WriteMode . APPEND ); writer . write ( \"B/36B/1\" , \"ORDR\" ); writer . write ( \"B/36B/3\" , \"123,45\" , WriteMode . APPEND ); writer . write ( \"B/35B\" , \"/US/FOO487AE9\" ); // we get the created MT MT509 mt = ( MT509 ) writer . mt (); The sample code above creates a new MT509 message with the following content: {1:F01AAAAUS30AXXX0000000000}{2:I509BBBBTRRSXXXXN2020}{4: :16R:GENL :20C::SEME//MAINREF1234 :23G:INST :98C::PREP//20240625101806 :16R:LINK :13A::LINK//509 :20C::RELA//RELAREF1234 :16S:LINK :16R:LINK :20C::PREV//1234 :16S:LINK :16R:STAT :25D::CPRC//CAND :16R:REAS :24B::REJT//ADEA :16S:REAS :16S:STAT :16S:GENL :16R:TRADE :22H::BUSE//BUYI :22H::PAYM//APMT :36B::ORDR///123,45 :35B:/US/FOO487AE9 :16S:TRADE -}; Notice how the boundary fields (16R and 16S) are automatically added by the writer based on the path expressions used.","title":"Using the MtWriter as a message builder"},{"location":"integrator/myformat/myformat-fixed/","text":"Format > Fixed-Length Fixed-length files can be used as source or target for a translation, and it is helpful to integrate legacy systems that cannot produce or consume XML, CSV or JSON files. Single or multiple line messages are supported. The selectors are flexible enough to read or write content with complex structures and record types. To ease manipulation of data in fixed-length files, specific transformation functions are provided, based on a subset of COBOL PIC Formats (PICTURE clause). Fixed-Length Selector The same fixlen selector syntax is used for source and target. Meaning to express what content from a fixed-length input message is read, or to express where in the output fixed-length message the content is written. The basic selector format indicates the position of the field, but since fixlen messages can have elaborate structures, then the selector supports also more complex variants, for instance to select records by record identifier. Structure The grammar enables defining basically three components, each serves a different purpose: Field (required): Provides a method to extract information from a line and can be expressed in three different ways, depending on how the file structure is specified one expression might be convenient over the others: By Positions : This method requires the start and end position (both included), in the line. This uses two dots as separator (\"..\") to indicate the range By Length : This method requires the start position and a length of characters (bytes) for the field. A slash (\"/\") is used to separate the start and length. By Name : This method uses a static map of field names. The field names must be defined as an initial setup, then in the selectors the field name can be used without the need to indicate position or length every time. Variables (optional): The variables are optional and are used to reorder the input content read in a FOREACH. The primary use case for variables in this context is for line numbers, but a variable can also be used to store content, and thus to reorder the input based on the content of an element (for example to group transactions per account or currency). Condition (optional): Provides a method to filter a subset of lines from the input, for example could be used to select the records based on a record type identified by the first character in each line. Field Examples By Positions: By Length: By Name: // create the field definitions FixedLenFieldsDef defs = new FixedLenFieldsDef () . addField ( \"IBAN\" , \"1/3\" ) . addField ( \"ADDR1\" , \"4/20\" ) . addField ( \"ADDR2\" , \"24/10\" ) . addField ( \"ADDR3\" , \"89/2\" ) . addField ( \"BIC\" , \"101/4\" ); // create reader instance for source message String inputMsg = \"...\" ; FixedLenReader reader = FixedLenReader . builder ( inputMsg ). fieldsDef ( defs ). build (); Variables Examples Condition Examples Grammar The grammar structure for de Fixed-length selector is as follows: The selector contains 2 subcomponents: Field : Valid values are from \"..\" to , from \"/\" len Selector-options : A list of variables ( opt-variables ) and/or conditions ( opt-condition-list ). Or Empty value (these subcomponents are optional) The opt-variables is an optional variable list that can contain any number of elements: variable : Valid values are \"{\" name \"}\" , \"{\" name \":\" field opt-field-condition \"}\" . The opt-condition-list is an optional condition (or opt-field-condition ) list that can contain any number of elements: condition : Valid values are \"\" , \"\" , \"<\" field \">\" , \"<\" field \"='\" value \"'>\" . Expressed in a formal way selector ::= field selector-options field ::= from \"..\" to |from \"/\" len selector-options ::= \"[\" opt-variables opt-condition-list \"]\" | EMPTY opt-variables ::= variables-list | EMPTY variables-list ::= variables-list variable | variable variable ::= \"{\" name \"}\" | \"{\" name \":\" field opt-field-condition \"}\" opt-condition-list ::= condition-list | EMPTY opt-field-condition ::= \"[\" condition-list \"]\" | EMPTY condition-list ::= condition-list condition | condition condition ::= \"\" | \"\" | \"<\" field \">\" | \"<\" field \"='\" value \"'>\" Grammar Behavior Examples Basic selectors 3..7 Selects the value in the positions 3 to 7. Both numbers, 3 and 7 indicate a position in the row and are always inclusive, meaning the character in position 3 and the character in position 7 are included in the result. Positions are one-based. 3/5 Selects the value in the position 3 to 7. Notice the 5 in this syntax, indicates the length, not the ending position. Selectors with conditions 3/5[] Selects the value in the position 3 to 7 from the first row in the document. 3/5[<1/3='DTL'>] Selects the value in the position 3 to 7 from a line where position 1 to 3 contain the record identifier \"DTL\". 3/5[<1/3='HDR'>] Selects the value in the positions 3 to 7 form the first row starting with record identifier \"HDR\". 3/5[<1/3='DTL'>] Selects the value in the position 3 to 7 from the lines 4 to 5 where position 1 to 3 contains the record identifier \"DTL\". Selectors with variables 3/5[{N}] Selects the value in the positions 3 to 7, and stores the current line number in a variable \"N\". Variables are used in the context of a mapping rule with \"foreach\", when multiple message lines are being read or written. 3/5[{M:9/3}] Selects the value in the positions 3 to 7, and stores the value in position 9 to 11 in a variable \"M\". 3/5[{M:9/3}{N}] Selects the value in the positions 3 to 7, and stores the value in position 9 to 11 in a variable \"M\" and the current line in a variable \"N\". Selectors with variables and conditions 3/5[{N}] Selects the value in the position 3 to 7 from lines 1 to 4, and stores the line number in a variable \"N\". 3/5[{N}<1/3='DTL'>] Selects the value in the position 3 to 7 from all lines where position 1 to 3 contains the record identifier \"DTL\", and stores the line number in a variable \"N\". 3/5[{M:9/3}<1/3='HDR'>] Selects the value in the positions 3 to 7 from the first row starting with record identifier \"HRD\", and stores the value in position 9 to 11 in a variable \"M\". 3/5[{M:9/3}{N}<1/3='DTL'>] Selects the value in the positions 3 to 7 from all lines with record identifier \"DTL\", and stores the value in position 9 to 11 in a variable \"M\" and the line number in variable \"N\". 3/5[{M:9/3[<1/3='HDR'>]}<1/3='DTL'>] Selects the value in the positions 3 to 7 from all lines with record identifier \"DTL\", and stores the value in position 9 to 11 from the first row in the header, in a variable \"M\". This complex variable definition can be handy to group content, in this case we are grouping by a value in the header. Notice the condition order is important. <1/3='DTL'> finds all DTL lines and then selects the first four lines <1/3='DTL'> finds the first four lines and from those, selects the ones with DTL Field name definition When the mapping is done programmatically, you can configure a dictionary of field names. You give a name to the field positions in your fixed-length structure, and then you just use the naming in the mapping rules. This feature makes the mapping rules less error-prone. For example: FixedLenFieldsDef defs = new FixedLenFieldsDef () . addField ( \"RECORD\" , \"1/3\" ) . addField ( \"REFERENCE\" , \"4/20\" ) . addField ( \"SOURCE_ACCT\" , \"24/30\" ); MappingTable t = new MappingTable ( FileFormat . FIXEDLEN , FileFormat . MX ); // add the mx type to the message t . add ( new MappingRule ( \"pain.001.001.03\" , \"mxType\" , WriteMode . SETUP )); // file ref from HDR as message identifier t . add ( new MappingRule ( \"REFERENCE[]\" , \"/Document/CstmrCdtTrfInitn/GrpHdr/MsgId\" , new Transformation ( Key . fromPIC , \"X(20)\" ))); // source account t . add ( new MappingRule ( \"foreach(SOURCE_ACCT[{n}])\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/DbtrAcct/Id/Othr/Id\" , new Transformation ( Key . fromPIC , \"X(30)\" ))); In the example above, instead of repeating the \"1/3\" in each record filter, we just use the term \"RECORD\". And the same applies for any field in any a mapping rule. The field definitions are provided to the translation process in the reader. So you must call the translation passing your own instance of the reader and writer like this: // create reader instance for source message FixedLenReader reader = FixedLenReader . builder ( input ). fieldsDef ( defs ). build (); // create writer and call translation MxWriter writer = new MxWriter ( MxType . pacs_008_001_02 ); // call the translation passing the reader, writer and the rules MyFormatEngine . translate ( reader , writer , t . getRules ()); Conversion FROM Fixed-Length A typical translation from fixed-length to other format will involve filtering by a record type (usually the first part of each row). For each record type, you will then need one rule per field in the record type. Then for repetitive records you would use a foreach while for non-repetitive record types you would use a simple rule. The only thing to remark when converting from fixed-length is that you should use a fromPIC transformation as the first transformation in all your mapping rules. The fromPIC will ensure the fixed-length content is cleaned and formatted before it is propagated to the target message. Conversion TO Fixed-Length Two remarks are important when converting to fixed-length. Setup The first part of your mapping table should consist of instructions to build the empty template of your target message. By doing this, you ensure the overall structure of the output file is valid, even though it will be empty until the actual mapping rules are processed. A special write mode called SETUP is used for this purpose, combined with a special \"command\" named addRow . In a setup mapping rule, the command replaces the target selector. For example, if your message structure contains a header record, followed by multiple detail records and with a footer record at the end; the following setup commands will initialize the file. MappingTable t = new MappingTable ( FileFormat . MX , FileFormat . FIXEDLEN ); // create an empty header row identifier by HR t . add ( new MappingRule ( null , \"addRow\" , WriteMode . SETUP , new Transformation ( Key . filler , \"HR\" , \"X(33)\" ))); // create multiple detail records identifier by TX t . add ( new MappingRule ( \"foreach(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/)\" , \"addRow\" , WriteMode . SETUP , new Transformation ( Key . filler , \"TX\" , \"X(110)\" , \"9(11).999\" , \"X(80)\" ))) // create a single footer record at the end, identified by FR t . add ( new MappingRule ( null , \"addRow\" , WriteMode . SETUP , new Transformation ( Key . filler , \"FR\" , \"9(15)\" , \"9(14).999\" , X ( 25 )))); Notice a special filler transformation is used to generate the empty rows. The filler transformation expects no value as input, and generates an empty line for the given combination of literal content and toPIC parameters. Only one header and footer is generated, but the detailed record is generated as many times as actual transactions in the source file; meaning the initialization is not static but dynamic , it can use input data . After setup and regardless of the following mapping rules, the output will have a valid structure. The setup is also important for the filter selectors to work. Suppose you want to define a rule such as t . add ( new MappingRule ( \"foreach(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/CdtrAcct/Id/IBAN)\" , \"BEN_IBAN[]\" , new Transformation ( Key . fromPIC , \"X(30)\" ) )); This rule will iterate the IBAN numbers in all transactions of the source message, and will write them in the \"BEN_IBAN\" field of all \"TX\" records in the target message. Without the setup, this filter would have written a single transaction row in the output. toPIC The second remark when creating fixed-length as output is that all rules should have a proper toPIC transformation as the last transformation in the pipeline. This is essential to make sure the processed value is finally converted to the expected format, with proper padding. Character Set Fixed-length files (and content, in general) uses 8-bit bytes and has usually been used with ASCII characters only. The module supports ISO-8859-1 characters (which corresponds to the subset of Unicode characters with values between 32 and 255, both inclusive). Given that Java strings use 16 bits characters while in memory, the module Reader and Write will replace characters that are out of valid range with a question mark. This should keep both input and output valid (high unicode characters should not be present in numbers anyway). The output can then be converted to UTF-8 if needed, but it should be noted that records having high ISO-8859-1 characters will not keep the length if converted to UTF-8.","title":"Format > Fixed-Length"},{"location":"integrator/myformat/myformat-fixed/#format-fixed-length","text":"Fixed-length files can be used as source or target for a translation, and it is helpful to integrate legacy systems that cannot produce or consume XML, CSV or JSON files. Single or multiple line messages are supported. The selectors are flexible enough to read or write content with complex structures and record types. To ease manipulation of data in fixed-length files, specific transformation functions are provided, based on a subset of COBOL PIC Formats (PICTURE clause).","title":"Format > Fixed-Length"},{"location":"integrator/myformat/myformat-fixed/#fixed-length-selector","text":"The same fixlen selector syntax is used for source and target. Meaning to express what content from a fixed-length input message is read, or to express where in the output fixed-length message the content is written. The basic selector format indicates the position of the field, but since fixlen messages can have elaborate structures, then the selector supports also more complex variants, for instance to select records by record identifier.","title":"Fixed-Length Selector"},{"location":"integrator/myformat/myformat-fixed/#structure","text":"The grammar enables defining basically three components, each serves a different purpose: Field (required): Provides a method to extract information from a line and can be expressed in three different ways, depending on how the file structure is specified one expression might be convenient over the others: By Positions : This method requires the start and end position (both included), in the line. This uses two dots as separator (\"..\") to indicate the range By Length : This method requires the start position and a length of characters (bytes) for the field. A slash (\"/\") is used to separate the start and length. By Name : This method uses a static map of field names. The field names must be defined as an initial setup, then in the selectors the field name can be used without the need to indicate position or length every time. Variables (optional): The variables are optional and are used to reorder the input content read in a FOREACH. The primary use case for variables in this context is for line numbers, but a variable can also be used to store content, and thus to reorder the input based on the content of an element (for example to group transactions per account or currency). Condition (optional): Provides a method to filter a subset of lines from the input, for example could be used to select the records based on a record type identified by the first character in each line.","title":"Structure"},{"location":"integrator/myformat/myformat-fixed/#field-examples","text":"By Positions: By Length: By Name: // create the field definitions FixedLenFieldsDef defs = new FixedLenFieldsDef () . addField ( \"IBAN\" , \"1/3\" ) . addField ( \"ADDR1\" , \"4/20\" ) . addField ( \"ADDR2\" , \"24/10\" ) . addField ( \"ADDR3\" , \"89/2\" ) . addField ( \"BIC\" , \"101/4\" ); // create reader instance for source message String inputMsg = \"...\" ; FixedLenReader reader = FixedLenReader . builder ( inputMsg ). fieldsDef ( defs ). build ();","title":"Field Examples"},{"location":"integrator/myformat/myformat-fixed/#variables-examples","text":"","title":"Variables Examples"},{"location":"integrator/myformat/myformat-fixed/#condition-examples","text":"","title":"Condition Examples"},{"location":"integrator/myformat/myformat-fixed/#grammar","text":"The grammar structure for de Fixed-length selector is as follows: The selector contains 2 subcomponents: Field : Valid values are from \"..\" to , from \"/\" len Selector-options : A list of variables ( opt-variables ) and/or conditions ( opt-condition-list ). Or Empty value (these subcomponents are optional) The opt-variables is an optional variable list that can contain any number of elements: variable : Valid values are \"{\" name \"}\" , \"{\" name \":\" field opt-field-condition \"}\" . The opt-condition-list is an optional condition (or opt-field-condition ) list that can contain any number of elements: condition : Valid values are \"\" , \"\" , \"<\" field \">\" , \"<\" field \"='\" value \"'>\" .","title":"Grammar"},{"location":"integrator/myformat/myformat-fixed/#expressed-in-a-formal-way","text":"selector ::= field selector-options field ::= from \"..\" to |from \"/\" len selector-options ::= \"[\" opt-variables opt-condition-list \"]\" | EMPTY opt-variables ::= variables-list | EMPTY variables-list ::= variables-list variable | variable variable ::= \"{\" name \"}\" | \"{\" name \":\" field opt-field-condition \"}\" opt-condition-list ::= condition-list | EMPTY opt-field-condition ::= \"[\" condition-list \"]\" | EMPTY condition-list ::= condition-list condition | condition condition ::= \"\" | \"\" | \"<\" field \">\" | \"<\" field \"='\" value \"'>\"","title":"Expressed in a formal way"},{"location":"integrator/myformat/myformat-fixed/#grammar-behavior-examples","text":"Basic selectors 3..7 Selects the value in the positions 3 to 7. Both numbers, 3 and 7 indicate a position in the row and are always inclusive, meaning the character in position 3 and the character in position 7 are included in the result. Positions are one-based. 3/5 Selects the value in the position 3 to 7. Notice the 5 in this syntax, indicates the length, not the ending position. Selectors with conditions 3/5[] Selects the value in the position 3 to 7 from the first row in the document. 3/5[<1/3='DTL'>] Selects the value in the position 3 to 7 from a line where position 1 to 3 contain the record identifier \"DTL\". 3/5[<1/3='HDR'>] Selects the value in the positions 3 to 7 form the first row starting with record identifier \"HDR\". 3/5[<1/3='DTL'>] Selects the value in the position 3 to 7 from the lines 4 to 5 where position 1 to 3 contains the record identifier \"DTL\". Selectors with variables 3/5[{N}] Selects the value in the positions 3 to 7, and stores the current line number in a variable \"N\". Variables are used in the context of a mapping rule with \"foreach\", when multiple message lines are being read or written. 3/5[{M:9/3}] Selects the value in the positions 3 to 7, and stores the value in position 9 to 11 in a variable \"M\". 3/5[{M:9/3}{N}] Selects the value in the positions 3 to 7, and stores the value in position 9 to 11 in a variable \"M\" and the current line in a variable \"N\". Selectors with variables and conditions 3/5[{N}] Selects the value in the position 3 to 7 from lines 1 to 4, and stores the line number in a variable \"N\". 3/5[{N}<1/3='DTL'>] Selects the value in the position 3 to 7 from all lines where position 1 to 3 contains the record identifier \"DTL\", and stores the line number in a variable \"N\". 3/5[{M:9/3}<1/3='HDR'>] Selects the value in the positions 3 to 7 from the first row starting with record identifier \"HRD\", and stores the value in position 9 to 11 in a variable \"M\". 3/5[{M:9/3}{N}<1/3='DTL'>] Selects the value in the positions 3 to 7 from all lines with record identifier \"DTL\", and stores the value in position 9 to 11 in a variable \"M\" and the line number in variable \"N\". 3/5[{M:9/3[<1/3='HDR'>]}<1/3='DTL'>] Selects the value in the positions 3 to 7 from all lines with record identifier \"DTL\", and stores the value in position 9 to 11 from the first row in the header, in a variable \"M\". This complex variable definition can be handy to group content, in this case we are grouping by a value in the header. Notice the condition order is important. <1/3='DTL'> finds all DTL lines and then selects the first four lines <1/3='DTL'> finds the first four lines and from those, selects the ones with DTL","title":"Grammar Behavior Examples"},{"location":"integrator/myformat/myformat-fixed/#field-name-definition","text":"When the mapping is done programmatically, you can configure a dictionary of field names. You give a name to the field positions in your fixed-length structure, and then you just use the naming in the mapping rules. This feature makes the mapping rules less error-prone. For example: FixedLenFieldsDef defs = new FixedLenFieldsDef () . addField ( \"RECORD\" , \"1/3\" ) . addField ( \"REFERENCE\" , \"4/20\" ) . addField ( \"SOURCE_ACCT\" , \"24/30\" ); MappingTable t = new MappingTable ( FileFormat . FIXEDLEN , FileFormat . MX ); // add the mx type to the message t . add ( new MappingRule ( \"pain.001.001.03\" , \"mxType\" , WriteMode . SETUP )); // file ref from HDR as message identifier t . add ( new MappingRule ( \"REFERENCE[]\" , \"/Document/CstmrCdtTrfInitn/GrpHdr/MsgId\" , new Transformation ( Key . fromPIC , \"X(20)\" ))); // source account t . add ( new MappingRule ( \"foreach(SOURCE_ACCT[{n}])\" , \"/Document/CstmrCdtTrfInitn/PmtInf[{n}]/DbtrAcct/Id/Othr/Id\" , new Transformation ( Key . fromPIC , \"X(30)\" ))); In the example above, instead of repeating the \"1/3\" in each record filter, we just use the term \"RECORD\". And the same applies for any field in any a mapping rule. The field definitions are provided to the translation process in the reader. So you must call the translation passing your own instance of the reader and writer like this: // create reader instance for source message FixedLenReader reader = FixedLenReader . builder ( input ). fieldsDef ( defs ). build (); // create writer and call translation MxWriter writer = new MxWriter ( MxType . pacs_008_001_02 ); // call the translation passing the reader, writer and the rules MyFormatEngine . translate ( reader , writer , t . getRules ());","title":"Field name definition"},{"location":"integrator/myformat/myformat-fixed/#conversion-from-fixed-length","text":"A typical translation from fixed-length to other format will involve filtering by a record type (usually the first part of each row). For each record type, you will then need one rule per field in the record type. Then for repetitive records you would use a foreach while for non-repetitive record types you would use a simple rule. The only thing to remark when converting from fixed-length is that you should use a fromPIC transformation as the first transformation in all your mapping rules. The fromPIC will ensure the fixed-length content is cleaned and formatted before it is propagated to the target message.","title":"Conversion FROM Fixed-Length"},{"location":"integrator/myformat/myformat-fixed/#conversion-to-fixed-length","text":"Two remarks are important when converting to fixed-length.","title":"Conversion TO Fixed-Length"},{"location":"integrator/myformat/myformat-fixed/#setup","text":"The first part of your mapping table should consist of instructions to build the empty template of your target message. By doing this, you ensure the overall structure of the output file is valid, even though it will be empty until the actual mapping rules are processed. A special write mode called SETUP is used for this purpose, combined with a special \"command\" named addRow . In a setup mapping rule, the command replaces the target selector. For example, if your message structure contains a header record, followed by multiple detail records and with a footer record at the end; the following setup commands will initialize the file. MappingTable t = new MappingTable ( FileFormat . MX , FileFormat . FIXEDLEN ); // create an empty header row identifier by HR t . add ( new MappingRule ( null , \"addRow\" , WriteMode . SETUP , new Transformation ( Key . filler , \"HR\" , \"X(33)\" ))); // create multiple detail records identifier by TX t . add ( new MappingRule ( \"foreach(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/)\" , \"addRow\" , WriteMode . SETUP , new Transformation ( Key . filler , \"TX\" , \"X(110)\" , \"9(11).999\" , \"X(80)\" ))) // create a single footer record at the end, identified by FR t . add ( new MappingRule ( null , \"addRow\" , WriteMode . SETUP , new Transformation ( Key . filler , \"FR\" , \"9(15)\" , \"9(14).999\" , X ( 25 )))); Notice a special filler transformation is used to generate the empty rows. The filler transformation expects no value as input, and generates an empty line for the given combination of literal content and toPIC parameters. Only one header and footer is generated, but the detailed record is generated as many times as actual transactions in the source file; meaning the initialization is not static but dynamic , it can use input data . After setup and regardless of the following mapping rules, the output will have a valid structure. The setup is also important for the filter selectors to work. Suppose you want to define a rule such as t . add ( new MappingRule ( \"foreach(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/CdtrAcct/Id/IBAN)\" , \"BEN_IBAN[]\" , new Transformation ( Key . fromPIC , \"X(30)\" ) )); This rule will iterate the IBAN numbers in all transactions of the source message, and will write them in the \"BEN_IBAN\" field of all \"TX\" records in the target message. Without the setup, this filter would have written a single transaction row in the output.","title":"Setup"},{"location":"integrator/myformat/myformat-fixed/#topic","text":"The second remark when creating fixed-length as output is that all rules should have a proper toPIC transformation as the last transformation in the pipeline. This is essential to make sure the processed value is finally converted to the expected format, with proper padding.","title":"toPIC"},{"location":"integrator/myformat/myformat-fixed/#character-set","text":"Fixed-length files (and content, in general) uses 8-bit bytes and has usually been used with ASCII characters only. The module supports ISO-8859-1 characters (which corresponds to the subset of Unicode characters with values between 32 and 255, both inclusive). Given that Java strings use 16 bits characters while in memory, the module Reader and Write will replace characters that are out of valid range with a question mark. This should keep both input and output valid (high unicode characters should not be present in numbers anyway). The output can then be converted to UTF-8 if needed, but it should be noted that records having high ISO-8859-1 characters will not keep the length if converted to UTF-8.","title":"Character Set"},{"location":"integrator/myformat/myformat-json/","text":"JSON JSON payloads can be used as source or target for a translation. JSON selector is pretty much similar to XML one. JSON Selector If the message is an JSON, the selector uses JsonPath expressions. All the common syntax for JsonPath expressions can be used, including simple predicates and attributes in the elements. The paths must always be absolute, though. For example: document.sttlmInstrDtls.sttlmDtTm.dtTm selects the value of the element dtTm document.pmtDtls.Debtor.pstlAddr.addrLine[1] selects the value of the first occurrence of element AddrLine within pstlAddr document.pmtDtls.debtor.pstlAddr.addrLine[3] selects the value of the third occurrence of element AddrLine within pstlAddr When the source message in the translation is an JSON message, the selector indicates which element text or attribute must be read. For example, a rule having .document.pmtDtls.sttlmAmt in the source selector will get the value of the element sttlmAmt , and pass that as content for the translation. Analogously, when the target message in the translation is an JSON, the selector indicates what element must be written in the target message. For example, a target selector having document.sttlmInstrDtls.sttlmDtTm.dtTm will take the translation content and create in the target JSON an element dtTm. All elements in the path parent structure will be created automatically. Predicates The JsonPath supports predicates to indicate repetition indexes within array structures. The predicates can be in any segment of the path, where the element is of type array. For example, document.cstmrCdtTrfInitn.pmtInf[2].cdtTrfTxInf[3].cdtrAgt selects the cdtrAgt element in the third repetition of cdtTrfTxInf within the second repetition of pmtInf . In the above examples, all predicates have numbers, meaning they reference a nested structure of arrays in the JSON. When the selector is used in rule processing multiple elements, the number can be replaced by a variable name. For example the source selector document.cstmrCdtTrfInitn.pmtInf[{m}].cdtTrfTxInf[{n}].cdtrAgt will read all instances of the element cdtrAgt , and will propagate a variable named m with the repetition index of pmtInf and a variable n with the repetition of cdtTrfTxInf . Repetition in a foreach is 1 based, meaning the first read pmtInf will have n=1 . These repetition variables can then be used in the target selector, to map repetitive elements read from the source message into elements of an array in the target JSON message. Prefilled target message When translating into JSON, sometimes it is necessary to apply a translation into existing content. This can be accomplished easily, passing your own instances of the reader and writer to the engine. // Mapping definition MappingTable t = new MappingTable ( FileFormat . MT , FileFormat . JSON ); t . add ( new MappingRule ( \"20\" , \"document.header.foo\" , WriteMode . CREATE )); t . add ( new MappingRule ( \"32A/3\" , \"document.transaction.amount\" , new Transformation ( Transformation . Key . formatDecimal ))); assertTrue ( t . validate (). isEmpty ()); // existing JSON message JsonWriter existingJsonWriter = new JsonWriter ( \"{'document': { 'header': { 'uniqueID': 'URGP3225' }}}\" ); // sample source message MT103 mt = new MT103 (); mt . append ( new Field20 ( \"XXX\" )); mt . append ( new Field32A ( \"151019USD1234,5\" )); MtReader mtReader = new MtReader ( mt ); // translation call passing a pre-filled JSON writer instance MyFormatEngine . translate ( mtReader , existingJsonWriter , t . rules );","title":"Format > JSON"},{"location":"integrator/myformat/myformat-json/#json","text":"JSON payloads can be used as source or target for a translation. JSON selector is pretty much similar to XML one.","title":"JSON"},{"location":"integrator/myformat/myformat-json/#json-selector","text":"If the message is an JSON, the selector uses JsonPath expressions. All the common syntax for JsonPath expressions can be used, including simple predicates and attributes in the elements. The paths must always be absolute, though. For example: document.sttlmInstrDtls.sttlmDtTm.dtTm selects the value of the element dtTm document.pmtDtls.Debtor.pstlAddr.addrLine[1] selects the value of the first occurrence of element AddrLine within pstlAddr document.pmtDtls.debtor.pstlAddr.addrLine[3] selects the value of the third occurrence of element AddrLine within pstlAddr When the source message in the translation is an JSON message, the selector indicates which element text or attribute must be read. For example, a rule having .document.pmtDtls.sttlmAmt in the source selector will get the value of the element sttlmAmt , and pass that as content for the translation. Analogously, when the target message in the translation is an JSON, the selector indicates what element must be written in the target message. For example, a target selector having document.sttlmInstrDtls.sttlmDtTm.dtTm will take the translation content and create in the target JSON an element dtTm. All elements in the path parent structure will be created automatically.","title":"JSON Selector"},{"location":"integrator/myformat/myformat-json/#predicates","text":"The JsonPath supports predicates to indicate repetition indexes within array structures. The predicates can be in any segment of the path, where the element is of type array. For example, document.cstmrCdtTrfInitn.pmtInf[2].cdtTrfTxInf[3].cdtrAgt selects the cdtrAgt element in the third repetition of cdtTrfTxInf within the second repetition of pmtInf . In the above examples, all predicates have numbers, meaning they reference a nested structure of arrays in the JSON. When the selector is used in rule processing multiple elements, the number can be replaced by a variable name. For example the source selector document.cstmrCdtTrfInitn.pmtInf[{m}].cdtTrfTxInf[{n}].cdtrAgt will read all instances of the element cdtrAgt , and will propagate a variable named m with the repetition index of pmtInf and a variable n with the repetition of cdtTrfTxInf . Repetition in a foreach is 1 based, meaning the first read pmtInf will have n=1 . These repetition variables can then be used in the target selector, to map repetitive elements read from the source message into elements of an array in the target JSON message.","title":"Predicates"},{"location":"integrator/myformat/myformat-json/#prefilled-target-message","text":"When translating into JSON, sometimes it is necessary to apply a translation into existing content. This can be accomplished easily, passing your own instances of the reader and writer to the engine. // Mapping definition MappingTable t = new MappingTable ( FileFormat . MT , FileFormat . JSON ); t . add ( new MappingRule ( \"20\" , \"document.header.foo\" , WriteMode . CREATE )); t . add ( new MappingRule ( \"32A/3\" , \"document.transaction.amount\" , new Transformation ( Transformation . Key . formatDecimal ))); assertTrue ( t . validate (). isEmpty ()); // existing JSON message JsonWriter existingJsonWriter = new JsonWriter ( \"{'document': { 'header': { 'uniqueID': 'URGP3225' }}}\" ); // sample source message MT103 mt = new MT103 (); mt . append ( new Field20 ( \"XXX\" )); mt . append ( new Field32A ( \"151019USD1234,5\" )); MtReader mtReader = new MtReader ( mt ); // translation call passing a pre-filled JSON writer instance MyFormatEngine . translate ( mtReader , existingJsonWriter , t . rules );","title":"Prefilled target message"},{"location":"integrator/myformat/myformat-rule/","text":"Mapping Rule A mapping rule defines how a portion of content from the source message is transformed and appended into the target message. Therefore, a conversion from a source message into a target message is composed of a list of mapping rules . The mapping rules can be defined programmatically or by providing a configuration file. The configuration file could be a simple Excel spreadsheet with the mappings. The general structure of a mapping rule contains the following elements: Source : The source is used to identify which field in the source message must be read. It is indicated as a selector expression with a syntax corresponding to the source message format. For an MT it could be a field within a sequence, for an XML it is an XPath, and for a Fixed-length it can be a field within a specific record type. Transformation : Transformations are optional and allows changing the read value before appending it into the target message. An out-of-the-box dictionary of transformation is provided. The transformations can be combined, enabling a wide range of data manipulation options. Target : The target selector is used to identify where in the target message to read and optionally transformed content will be set. Read Mode : The read mode is optional, and it is used to define how to read and process content from the source message. The supported modes are: Single : This is the default mode, it reads a single value from the source message, regardless of the content being repetitive or not. Foreach : Reads multiple repetitive values from the source content and process them in a loop. The same mapping rule is applied for each read value. The foreach can receive one or two selectors. When two selectors are received, the first one is used to compute the repetitions, while the second one is used to get the actual value for the translation. This is particularly useful when you need to get a general content from the source message and copy the same value to multiple repetitive instances in the target message. Literal : Instead of providing a content selector, this mode is used to have a fixed value directly in the rule. Literal are defined as literal(foo) and also as quoted text with just \"foo\". Concat : Receives multiple selectors, and concatenates all read content into a single value. This selector will concatenate the values of the fields indicated in the parameters. It also allows quoted literals as parameters. A typical use case is to combine values from the source message along a fixed separator. For example when reading content from an MT you can have as selector something like CONCAT(20, \"|\", 21, \"|\", 59/1) which will generate as value the concatenation of the field 20, a pipe, the field 21, another pipe and the account number from field 59. Write Mode : Finally, the write mode is optional, and it is used to define what to do when the content already exists in the target message, for example, create, overwrite or append. Create : This is the default mode. A new element or field will always be created in the target message, regardless if the element already exists. Update : Checks if the target element or field exists before creating a new one. If the element is found, its value is overwritten with the new value from the rule. If the target element does not exist, this mode is similar to Create. Append : Checks if the target element exists before creating a new one. If the element is found, its value will be kept and the new value from the rule will be appended. If the target element does not exist, this mode is similar to Create. Setup : Used in some file formats, such as fixed-length, to initialize the output like an empty template, or define configuration options for the output message (encoding, namespace, etc\u2026). There are some setup command to define also general attributes of the mapping table, such as the specific source and target format and type. This simple but flexible scheme allows almost all message conversion scenarios. Generic Examples The following tables illustrate different combinations of parameters for a mapping rule, regardless of the message format. A complete translation between a source and a target message is done with a table containing a list of mapping rules. Example 1 - Simple Mapping Source Transformations Target Write Mode Selector 1 Selector 2 Reads the content located at Selector 1 in the source message, and writes the read value, at the position indicated by Selector 2 in the target message. A single value is read. The read value is propagated as is, without transformations. The write mode is not specified, so a new element is created in the target message. Example 2 - Transformation Source Transformations Target Write Mode Selector 1 Transformation 1 Selector 2 Reads content indicated by Selector 1 , applies a transformation Transformation 1 , and writes the manipulated content in Selector 2 in the target message. Example 3 - Multiple Transformations Source Transformations Target Write Mode Selector 1 Transformation 1, Transformation 2, Transformation 3 Selector 2 Reads content indicated by Selector 1 , applies the three transformations 1, 2, and 3, and writes the manipulated content in Selector 2 in the target message. The transformations are processed in a pipeline , where the output of one transformation becomes the input for the next transformation. Example 4 - Write Mode Source Transformations Target Write Mode Selector 1 Transformation 1 Selector 2 Append Reads content indicated by Selector 1 , applies the transformations Transformation 1, and writes the manipulated content in Selector 2 in the target message. If the element indicated by Selector 2 does not exist in the target message, it will be created. If the element exists, the processed value is appended to the existing content of the existing element. Example 5 - Literal Source Transformations Target Write Mode Literal(foo) Selector 2 In this example, instead of providing a selector for the source message, we provide a literal content \"foo\". The value \"foo\" is then written in Selector 2 in the target message. Example 6 - Multiple Sources Source Transformations Target Write Mode Concat(Selector 1, Selector 1') Selector 2 In this example, we provide two selectors for the source message. Combined with a Concat read mode. The concatenation of both read values is then passed through the translation and written in Selector 2 in the target message. Example 7 - Foreach with single selector Source Transformations Target Write Mode Foreach(Selector 1) Transformation 1 Selector 2 Reads multiple values from the source message at the location indicated by Selector 1 . Each read value is passed through Transformation 1 and written in the target message at the location indicated by Selector 2 . Example 8 - Foreach with double selector Source Transformations Target Write Mode Foreach(Selector 1, Selector 1') Transformation 1 Selector 2 Reads multiple values from the source message at the location indicated by the combination of Selector 1 (used to iterate the loop) and Selector 1' (used to get the actual value). Each read value is passed through Transformation 1 and written in the target message at the location indicated by Selector 2 . Note that when reading from Mt (ie. using MtReader) there are some scenarios where the Selector 1' is set to get values from optional fields. In this case it is possible to obtain null values as results if the Field is absent. This will result in a list of values with some null values in it. To avoid this behavior and get a list of not null values there is a special property that can be set in the MtReader that will avoid adding null values to the result list. This property is true by default. MtReader reader = new MtReader ( mt ); reader . setAllowReadManyWithValueSelectorNullItems ( false ); Selectors The selectors are a key feature in a mapping rule. A selector is a plain String defining a precise element or field in a message. The selector expressions are used in a mapping rule to indicate what content from the source message is read, or where in the target message the content is going to be written. The syntax of the selector depends on the file format. Please refer to the specific section for a file format to see the grammar of the selector. We provide here a few simple examples to illustrate the versatility of the selectors and how they are used to getting content from different types of file. Format Selector Description MT E/E1/95Q selects the field 95Q in subsequence E1 within sequence E MT 59/Line[2] selects the second line of component 59, with the name & address information MX /Document/SttlmInstrDtls/DtTm selects the value of the element DtTm MX /Document/PmtDtls/SttlmAmt/@Ccy selects the value of the attribute Ccy in the element SttlmAmt XML /A/B[3]/C Selects the value of element C in the third child B in the root node A JSON X.Y[2].Z Selects the value of element Z in the second sub-element of the array Y in the element X CSV 3 Select the third column in a CSV row CSV 5[ <1='DTL'> ] Selects the fifth column from a CSV line, where column 1 contains \"DTL\" FIXED-LENGTH 3..7[ ] Selects the value in the positions 3 to 7 in the first row FIXED-LENGTH 3/5[ <1/3='DTL'> ] Selects the value in the position 3 to 7 from a line where position 1 to 3 contain the record identified by \"DTL\" Transformation The transformation in a mapping rule is optional. If no transformation is defined, the found source content is copied into the target message unchanged. Transformations are defined as functions, and a mapping rule can define several functions that will be applied one after the other. All parameters are String unless indicated otherwise. All functions include an implicit input parameter. This parameter will be the result of the selector in the mapping rule or the result of a previous transformation if the rule defines more than one transformation. Function names are not case-sensitive when defined in configuration files. If a transformation cannot be applied because of a wrong parameter or an unexpected input, the input content is returned unaltered. This includes content being null. A transformation or a combination of transformation which result is null will not set any content into the target message. Therefore, there is a substantial difference, for example, between striping a content to null or empty. ** Empty strings from the source selector and or as a result of transformations are propagated to the target message. Meaning null and empty have different semantics**. For example, the function upperCase takes no additional argument and will transform the Source content into upper case. But the function substring(start, end) requires two additional parameters for the start and end positions of the truncation to apply. A comprehensive list of available functions is provided in the Transformations section. Pipeline Transformation functions can be combined into a pipeline . Meaning, for a single rule several transformations may be defined and all of them will be called in the defined order. The input for the first transformation function will be the result of the Source selector, and thereafter the output of a transformation becomes the input for the next one. This allows complex transformation of content using a limited set of atomic operations. Conditionals The mapping rules do not support conditional logic and conditional operators. However, a special semantic implemented for null values can overcome this limitation in most situations. There are two ways to produce a null value: With a selector that finds no result: if a Source selector does not produce any result applied to the source message, for example if the element is optional in the source message, then the mapping rule will be skipped. Meaning, it will not create empty content in the target message. This is useful to deal with optional content in the source message, you can just add the mapping for the optional content and if it is not present, the rule will be silently ignored. With a transformation: When the content in the source message is present, you can apply one or many transformations that in some scenarios will produce a null. In particular, you can use the stripToNull transformation. Besides the above simple approaches, there are two power functions especially suited to achieve more complex conditional logic: IfMatches and IfNotMatches . Both functions accept a regex as input and will let the content pass through if they match or not match the regex. Example 1: For example, if you want to achieve this type of simple conditional logic: IF ( Selector A = \"C\" ) THEN \"UNIT\" -> Selector B ELSE \"FAMT\" -> Selector B Where basically if the source selector has a \"C\" you will write the literal \"UNIT\" in the target, otherwise you will write \"FAMT\". The above can be resolved with the ifElse transformation like this: Source Transformations Target Selector A ifElse(\"C\", \"UNIT\", \"FAMT\") Selector B You can achieve the same with the ifMatches and ifNotMatches transformation, using two mapping rules, one to catch the IF and another to catch the ELSE: Source Transformations Target Selector A ifMatches(\"C\"); fixed(\"UNIT\") Selector B Selector A ifNotMatches(\"C\"); fixed(\"FAMT\") Selector B In the first rule when the source content is a \"C\" the IfMatches will match and thus propagate that \"C\" literal as value. Then instead of using the literal, we use a fixed transformation to write something else in the target. IN this same rule when the source content is not the \"C\" literal, the IfMatches will not match, thus it will return null and no further transformation is evaluated, and no content is written to the output. The second rule will do the opposite, it will propagate content and write the fixed value only when the input did not match. Example 2: For example, if you want to achieve this more complex type of conditional logic: IF ( Selector 1 = CANC or Selector 1 = AMD ) THEN Selector 2 -> Selector A ELSE Selector 3 -> Selector B You have three different source selectors. The \"Selector 1\" is used for the conditional logic check, then depending on that you will propagate to the output the content from two other different selectors \"Selector 2\" and \"Selector 3\" conditionally. The above is mapped like this: Source Transformations Target Concat(Selector 1, \";\", Selector 2, \";\", Selector 3) ifMatches(\u2018^(CANC|AMND);.+;\u2019), removeFirst(\u2018^(CANC|AMND);\u2019), removeFirst(\u2018;.*$\u2019) Selector A Concat(Selector 1, \";\", Selector 2, \";\", Selector 3) ifNotMatches(\u2018^(CANC|AMND);.+\u2019), removeFirst(\u2018^.+;') Selector B The source selector is a concatenation of the actual selectors, separated by a semicolon. So the source content selection will produce a semicolon separated string. Then the transformation will pass through the content of Selectors 2 or Selector 3 depending on the content of Selector 1. Then, the second rule will do the same, passing through the content of selector 3. Note that the transformation ifMatches , ifNotMatches can be replaced by ifElse when the Target selector is the same. If a different Target is going to be selected based on the input, then you need to use the ifMatches and ifNotMatches transformation. Let's check an actual example based on transformation above: Selector 1 = CANC Selector 2 = XXX Selector 3 = YYY Given those values and the Concat function, the Source value that the Transfomations receive will be CANC;XXX;YYY . Then the transformations will result like this: For the first row, and the first transformation ifMatches(\u2018^(CANC|AMND);.+;\u2019) , it will be evaluated as true since the input starts with \u00b4CANC;XXX;\u00b4. The output from transformation 1 to transformation 2 , will be the same as the input one (it will be null if the input is evaluated as false). For the first row, and the second transformation removeFirst(\u2018^(CANC|AMND);\u2019) , this will remove the substring CANC; . The output from Transformation 2 to Transformation 3 will be XXX;YYY . For the first row, and the third transformation removeFirst(\u2018;.*$\u2019) , this will remove the substring that is the suffix to the first ; char, that'll be ;YYY . The output from Transformation 3 to Target (in this case Selector A) will be XXX . Note that this is the value from Selector 2 . In this case since the second row transformation doesn't match the input value, so it will produce a null value as a result, and the rest of the transformation will not be applied. Let's check another example, that matches the second row from transformation above: This case will produce null as a result for first row and will perform the transformation for the second one. Selector 1 = AAA Selector 2 = XXX Selector 3 = YYY Given those values and the Concat function, the Source value that the Transfomations receive will be AAA;XXX;YYY . Then the transformations will result like this: For the second row, and the first transformation ifNotMatches(\u2018^(CANC|AMND);.+\u2019) , it will be evaluated to true since the input starts with AAA; that doesn't match the regex expression ^(CANC|AMND);.+ . The output from Transformation 1 to Transformation 2 , will be the same as the input one. For the second row, and the second transformation removeFirst(\u2018^.+;\u2019) , this will remove the substring that is the prefix to the last ; char. The output from Transformation 2 to Target (in this case Selector A) will be YYY . Note that this is the value from Selector 3 . Please this two code examples that are equivalent to what's described above. Example 1 // IF (Selector 1 = CANC or Selector 1 = AMD) // THEN Selector 2 -> Selector A (Target) // ELSE Selector 3-> Selector B String selector1 = \"CANC\" ; String selector2 = \"CLREL\" ; String selector3 = \"ORIGREL\" ; String selectorInput = selector1 + \";\" + selector2 + \";\" + selector3 ; Transformation tNotMatching = new Transformation ( Key . ifNotMatches , \"^(CANC|AMND);.+\" ); assertNull ( tNotMatching . transform ( selectorInput )); Transformation t1 = new Transformation ( Key . ifMatches , \"^(CANC|AMND);.+;\" ); String t1Result = t1 . transform ( selectorInput ); assertEquals ( selectorInput , t1Result ); Transformation t2 = new Transformation ( Key . removeFirst , \"^(CANC|AMND);\" ); String t2Result = t2 . transform ( t1Result ); assertEquals ( \"CLREL;ORIGREL\" , t2Result ); Transformation t3 = new Transformation ( Key . removeFirst , \";.*$\" ); String t3Result = t3 . transform ( t2Result ); assertEquals ( selector2 , t3Result ); // selector2 to Selector A (Target) Example 2 // IF (Selector 1 = CANC or Selector 1 = AMD) // THEN Selector 2 -> Selector A // ELSE Selector 3-> Selector B (Target) String selector1 = \"AAA\" ; String selector2 = \"CLREL\" ; String selector3 = \"ORIGREL\" ; String selectorInput = selector1 + \";\" + selector2 + \";\" + selector3 ; Transformation tNotMatching = new Transformation ( Key . ifMatches , \"^(CANC|AMND);.+;\" ); assertNull ( tNotMatching . transform ( selectorInput )); Transformation t1 = new Transformation ( Key . ifNotMatches , \"^(CANC|AMND);.+\" ); String t1Result = t1 . transform ( selectorInput ); assertEquals ( selectorInput , t1Result ); Transformation t2 = new Transformation ( Key . removeFirst , \"^.+;\" ); String t2Result = t2 . transform ( t1Result ); assertEquals ( selector3 , t2Result ); // selector3 to Selector B (Target) Custom Transformations When the out-of-the-box transformations are not enough, custom functions can be added by implementing the Transformer interface in your own class. class CustomTransformer implements Transformer { @Override public String transform ( String src , Object [] args ) { return StringUtils . upperCase ( src ); } @Override public String getTransformerName () { return \"myTransformer\" ; } @Override public boolean isValid ( Object [] args ) { return true ; } } The example above implements a simple uppercase transformation. The transform method is where the custom manipulation is implemented, the method receives the input to transform and optionally some parameters, and returns the altered content. The getTransformerName is used to provide a unique name to the function so that it can be referenced in the mapping configuration. The isValid method is optional, to validate for example if the provided arguments are valid. If the mapping configuration is done programmatically, then the custom transformer class can be used directly in the code when the MappingRule objects are created. If the mapping configuration is externalized, for example, loaded from an Excel sheet, then the custom transformer must be registered so that the name is recognized when parsing the configuration. In order to register your custom transformer, you just need to call this anywhere in your initialization. TransformationRegistry . register ( \"myTransformer\" , new CustomTransformer ()); Then, in your mapping configuration, you can use \"myTransformer\" along any of the out-of-the-box transformations functions.","title":"Mapping Rule"},{"location":"integrator/myformat/myformat-rule/#mapping-rule","text":"A mapping rule defines how a portion of content from the source message is transformed and appended into the target message. Therefore, a conversion from a source message into a target message is composed of a list of mapping rules . The mapping rules can be defined programmatically or by providing a configuration file. The configuration file could be a simple Excel spreadsheet with the mappings. The general structure of a mapping rule contains the following elements: Source : The source is used to identify which field in the source message must be read. It is indicated as a selector expression with a syntax corresponding to the source message format. For an MT it could be a field within a sequence, for an XML it is an XPath, and for a Fixed-length it can be a field within a specific record type. Transformation : Transformations are optional and allows changing the read value before appending it into the target message. An out-of-the-box dictionary of transformation is provided. The transformations can be combined, enabling a wide range of data manipulation options. Target : The target selector is used to identify where in the target message to read and optionally transformed content will be set. Read Mode : The read mode is optional, and it is used to define how to read and process content from the source message. The supported modes are: Single : This is the default mode, it reads a single value from the source message, regardless of the content being repetitive or not. Foreach : Reads multiple repetitive values from the source content and process them in a loop. The same mapping rule is applied for each read value. The foreach can receive one or two selectors. When two selectors are received, the first one is used to compute the repetitions, while the second one is used to get the actual value for the translation. This is particularly useful when you need to get a general content from the source message and copy the same value to multiple repetitive instances in the target message. Literal : Instead of providing a content selector, this mode is used to have a fixed value directly in the rule. Literal are defined as literal(foo) and also as quoted text with just \"foo\". Concat : Receives multiple selectors, and concatenates all read content into a single value. This selector will concatenate the values of the fields indicated in the parameters. It also allows quoted literals as parameters. A typical use case is to combine values from the source message along a fixed separator. For example when reading content from an MT you can have as selector something like CONCAT(20, \"|\", 21, \"|\", 59/1) which will generate as value the concatenation of the field 20, a pipe, the field 21, another pipe and the account number from field 59. Write Mode : Finally, the write mode is optional, and it is used to define what to do when the content already exists in the target message, for example, create, overwrite or append. Create : This is the default mode. A new element or field will always be created in the target message, regardless if the element already exists. Update : Checks if the target element or field exists before creating a new one. If the element is found, its value is overwritten with the new value from the rule. If the target element does not exist, this mode is similar to Create. Append : Checks if the target element exists before creating a new one. If the element is found, its value will be kept and the new value from the rule will be appended. If the target element does not exist, this mode is similar to Create. Setup : Used in some file formats, such as fixed-length, to initialize the output like an empty template, or define configuration options for the output message (encoding, namespace, etc\u2026). There are some setup command to define also general attributes of the mapping table, such as the specific source and target format and type. This simple but flexible scheme allows almost all message conversion scenarios.","title":"Mapping Rule"},{"location":"integrator/myformat/myformat-rule/#generic-examples","text":"The following tables illustrate different combinations of parameters for a mapping rule, regardless of the message format. A complete translation between a source and a target message is done with a table containing a list of mapping rules. Example 1 - Simple Mapping Source Transformations Target Write Mode Selector 1 Selector 2 Reads the content located at Selector 1 in the source message, and writes the read value, at the position indicated by Selector 2 in the target message. A single value is read. The read value is propagated as is, without transformations. The write mode is not specified, so a new element is created in the target message. Example 2 - Transformation Source Transformations Target Write Mode Selector 1 Transformation 1 Selector 2 Reads content indicated by Selector 1 , applies a transformation Transformation 1 , and writes the manipulated content in Selector 2 in the target message. Example 3 - Multiple Transformations Source Transformations Target Write Mode Selector 1 Transformation 1, Transformation 2, Transformation 3 Selector 2 Reads content indicated by Selector 1 , applies the three transformations 1, 2, and 3, and writes the manipulated content in Selector 2 in the target message. The transformations are processed in a pipeline , where the output of one transformation becomes the input for the next transformation. Example 4 - Write Mode Source Transformations Target Write Mode Selector 1 Transformation 1 Selector 2 Append Reads content indicated by Selector 1 , applies the transformations Transformation 1, and writes the manipulated content in Selector 2 in the target message. If the element indicated by Selector 2 does not exist in the target message, it will be created. If the element exists, the processed value is appended to the existing content of the existing element. Example 5 - Literal Source Transformations Target Write Mode Literal(foo) Selector 2 In this example, instead of providing a selector for the source message, we provide a literal content \"foo\". The value \"foo\" is then written in Selector 2 in the target message. Example 6 - Multiple Sources Source Transformations Target Write Mode Concat(Selector 1, Selector 1') Selector 2 In this example, we provide two selectors for the source message. Combined with a Concat read mode. The concatenation of both read values is then passed through the translation and written in Selector 2 in the target message. Example 7 - Foreach with single selector Source Transformations Target Write Mode Foreach(Selector 1) Transformation 1 Selector 2 Reads multiple values from the source message at the location indicated by Selector 1 . Each read value is passed through Transformation 1 and written in the target message at the location indicated by Selector 2 . Example 8 - Foreach with double selector Source Transformations Target Write Mode Foreach(Selector 1, Selector 1') Transformation 1 Selector 2 Reads multiple values from the source message at the location indicated by the combination of Selector 1 (used to iterate the loop) and Selector 1' (used to get the actual value). Each read value is passed through Transformation 1 and written in the target message at the location indicated by Selector 2 . Note that when reading from Mt (ie. using MtReader) there are some scenarios where the Selector 1' is set to get values from optional fields. In this case it is possible to obtain null values as results if the Field is absent. This will result in a list of values with some null values in it. To avoid this behavior and get a list of not null values there is a special property that can be set in the MtReader that will avoid adding null values to the result list. This property is true by default. MtReader reader = new MtReader ( mt ); reader . setAllowReadManyWithValueSelectorNullItems ( false );","title":"Generic Examples"},{"location":"integrator/myformat/myformat-rule/#selectors","text":"The selectors are a key feature in a mapping rule. A selector is a plain String defining a precise element or field in a message. The selector expressions are used in a mapping rule to indicate what content from the source message is read, or where in the target message the content is going to be written. The syntax of the selector depends on the file format. Please refer to the specific section for a file format to see the grammar of the selector. We provide here a few simple examples to illustrate the versatility of the selectors and how they are used to getting content from different types of file. Format Selector Description MT E/E1/95Q selects the field 95Q in subsequence E1 within sequence E MT 59/Line[2] selects the second line of component 59, with the name & address information MX /Document/SttlmInstrDtls/DtTm selects the value of the element DtTm MX /Document/PmtDtls/SttlmAmt/@Ccy selects the value of the attribute Ccy in the element SttlmAmt XML /A/B[3]/C Selects the value of element C in the third child B in the root node A JSON X.Y[2].Z Selects the value of element Z in the second sub-element of the array Y in the element X CSV 3 Select the third column in a CSV row CSV 5[ <1='DTL'> ] Selects the fifth column from a CSV line, where column 1 contains \"DTL\" FIXED-LENGTH 3..7[ ] Selects the value in the positions 3 to 7 in the first row FIXED-LENGTH 3/5[ <1/3='DTL'> ] Selects the value in the position 3 to 7 from a line where position 1 to 3 contain the record identified by \"DTL\"","title":"Selectors"},{"location":"integrator/myformat/myformat-rule/#transformation","text":"The transformation in a mapping rule is optional. If no transformation is defined, the found source content is copied into the target message unchanged. Transformations are defined as functions, and a mapping rule can define several functions that will be applied one after the other. All parameters are String unless indicated otherwise. All functions include an implicit input parameter. This parameter will be the result of the selector in the mapping rule or the result of a previous transformation if the rule defines more than one transformation. Function names are not case-sensitive when defined in configuration files. If a transformation cannot be applied because of a wrong parameter or an unexpected input, the input content is returned unaltered. This includes content being null. A transformation or a combination of transformation which result is null will not set any content into the target message. Therefore, there is a substantial difference, for example, between striping a content to null or empty. ** Empty strings from the source selector and or as a result of transformations are propagated to the target message. Meaning null and empty have different semantics**. For example, the function upperCase takes no additional argument and will transform the Source content into upper case. But the function substring(start, end) requires two additional parameters for the start and end positions of the truncation to apply. A comprehensive list of available functions is provided in the Transformations section.","title":"Transformation"},{"location":"integrator/myformat/myformat-rule/#pipeline","text":"Transformation functions can be combined into a pipeline . Meaning, for a single rule several transformations may be defined and all of them will be called in the defined order. The input for the first transformation function will be the result of the Source selector, and thereafter the output of a transformation becomes the input for the next one. This allows complex transformation of content using a limited set of atomic operations.","title":"Pipeline"},{"location":"integrator/myformat/myformat-rule/#conditionals","text":"The mapping rules do not support conditional logic and conditional operators. However, a special semantic implemented for null values can overcome this limitation in most situations. There are two ways to produce a null value: With a selector that finds no result: if a Source selector does not produce any result applied to the source message, for example if the element is optional in the source message, then the mapping rule will be skipped. Meaning, it will not create empty content in the target message. This is useful to deal with optional content in the source message, you can just add the mapping for the optional content and if it is not present, the rule will be silently ignored. With a transformation: When the content in the source message is present, you can apply one or many transformations that in some scenarios will produce a null. In particular, you can use the stripToNull transformation. Besides the above simple approaches, there are two power functions especially suited to achieve more complex conditional logic: IfMatches and IfNotMatches . Both functions accept a regex as input and will let the content pass through if they match or not match the regex. Example 1: For example, if you want to achieve this type of simple conditional logic: IF ( Selector A = \"C\" ) THEN \"UNIT\" -> Selector B ELSE \"FAMT\" -> Selector B Where basically if the source selector has a \"C\" you will write the literal \"UNIT\" in the target, otherwise you will write \"FAMT\". The above can be resolved with the ifElse transformation like this: Source Transformations Target Selector A ifElse(\"C\", \"UNIT\", \"FAMT\") Selector B You can achieve the same with the ifMatches and ifNotMatches transformation, using two mapping rules, one to catch the IF and another to catch the ELSE: Source Transformations Target Selector A ifMatches(\"C\"); fixed(\"UNIT\") Selector B Selector A ifNotMatches(\"C\"); fixed(\"FAMT\") Selector B In the first rule when the source content is a \"C\" the IfMatches will match and thus propagate that \"C\" literal as value. Then instead of using the literal, we use a fixed transformation to write something else in the target. IN this same rule when the source content is not the \"C\" literal, the IfMatches will not match, thus it will return null and no further transformation is evaluated, and no content is written to the output. The second rule will do the opposite, it will propagate content and write the fixed value only when the input did not match. Example 2: For example, if you want to achieve this more complex type of conditional logic: IF ( Selector 1 = CANC or Selector 1 = AMD ) THEN Selector 2 -> Selector A ELSE Selector 3 -> Selector B You have three different source selectors. The \"Selector 1\" is used for the conditional logic check, then depending on that you will propagate to the output the content from two other different selectors \"Selector 2\" and \"Selector 3\" conditionally. The above is mapped like this: Source Transformations Target Concat(Selector 1, \";\", Selector 2, \";\", Selector 3) ifMatches(\u2018^(CANC|AMND);.+;\u2019), removeFirst(\u2018^(CANC|AMND);\u2019), removeFirst(\u2018;.*$\u2019) Selector A Concat(Selector 1, \";\", Selector 2, \";\", Selector 3) ifNotMatches(\u2018^(CANC|AMND);.+\u2019), removeFirst(\u2018^.+;') Selector B The source selector is a concatenation of the actual selectors, separated by a semicolon. So the source content selection will produce a semicolon separated string. Then the transformation will pass through the content of Selectors 2 or Selector 3 depending on the content of Selector 1. Then, the second rule will do the same, passing through the content of selector 3. Note that the transformation ifMatches , ifNotMatches can be replaced by ifElse when the Target selector is the same. If a different Target is going to be selected based on the input, then you need to use the ifMatches and ifNotMatches transformation. Let's check an actual example based on transformation above: Selector 1 = CANC Selector 2 = XXX Selector 3 = YYY Given those values and the Concat function, the Source value that the Transfomations receive will be CANC;XXX;YYY . Then the transformations will result like this: For the first row, and the first transformation ifMatches(\u2018^(CANC|AMND);.+;\u2019) , it will be evaluated as true since the input starts with \u00b4CANC;XXX;\u00b4. The output from transformation 1 to transformation 2 , will be the same as the input one (it will be null if the input is evaluated as false). For the first row, and the second transformation removeFirst(\u2018^(CANC|AMND);\u2019) , this will remove the substring CANC; . The output from Transformation 2 to Transformation 3 will be XXX;YYY . For the first row, and the third transformation removeFirst(\u2018;.*$\u2019) , this will remove the substring that is the suffix to the first ; char, that'll be ;YYY . The output from Transformation 3 to Target (in this case Selector A) will be XXX . Note that this is the value from Selector 2 . In this case since the second row transformation doesn't match the input value, so it will produce a null value as a result, and the rest of the transformation will not be applied. Let's check another example, that matches the second row from transformation above: This case will produce null as a result for first row and will perform the transformation for the second one. Selector 1 = AAA Selector 2 = XXX Selector 3 = YYY Given those values and the Concat function, the Source value that the Transfomations receive will be AAA;XXX;YYY . Then the transformations will result like this: For the second row, and the first transformation ifNotMatches(\u2018^(CANC|AMND);.+\u2019) , it will be evaluated to true since the input starts with AAA; that doesn't match the regex expression ^(CANC|AMND);.+ . The output from Transformation 1 to Transformation 2 , will be the same as the input one. For the second row, and the second transformation removeFirst(\u2018^.+;\u2019) , this will remove the substring that is the prefix to the last ; char. The output from Transformation 2 to Target (in this case Selector A) will be YYY . Note that this is the value from Selector 3 . Please this two code examples that are equivalent to what's described above. Example 1 // IF (Selector 1 = CANC or Selector 1 = AMD) // THEN Selector 2 -> Selector A (Target) // ELSE Selector 3-> Selector B String selector1 = \"CANC\" ; String selector2 = \"CLREL\" ; String selector3 = \"ORIGREL\" ; String selectorInput = selector1 + \";\" + selector2 + \";\" + selector3 ; Transformation tNotMatching = new Transformation ( Key . ifNotMatches , \"^(CANC|AMND);.+\" ); assertNull ( tNotMatching . transform ( selectorInput )); Transformation t1 = new Transformation ( Key . ifMatches , \"^(CANC|AMND);.+;\" ); String t1Result = t1 . transform ( selectorInput ); assertEquals ( selectorInput , t1Result ); Transformation t2 = new Transformation ( Key . removeFirst , \"^(CANC|AMND);\" ); String t2Result = t2 . transform ( t1Result ); assertEquals ( \"CLREL;ORIGREL\" , t2Result ); Transformation t3 = new Transformation ( Key . removeFirst , \";.*$\" ); String t3Result = t3 . transform ( t2Result ); assertEquals ( selector2 , t3Result ); // selector2 to Selector A (Target) Example 2 // IF (Selector 1 = CANC or Selector 1 = AMD) // THEN Selector 2 -> Selector A // ELSE Selector 3-> Selector B (Target) String selector1 = \"AAA\" ; String selector2 = \"CLREL\" ; String selector3 = \"ORIGREL\" ; String selectorInput = selector1 + \";\" + selector2 + \";\" + selector3 ; Transformation tNotMatching = new Transformation ( Key . ifMatches , \"^(CANC|AMND);.+;\" ); assertNull ( tNotMatching . transform ( selectorInput )); Transformation t1 = new Transformation ( Key . ifNotMatches , \"^(CANC|AMND);.+\" ); String t1Result = t1 . transform ( selectorInput ); assertEquals ( selectorInput , t1Result ); Transformation t2 = new Transformation ( Key . removeFirst , \"^.+;\" ); String t2Result = t2 . transform ( t1Result ); assertEquals ( selector3 , t2Result ); // selector3 to Selector B (Target)","title":"Conditionals"},{"location":"integrator/myformat/myformat-rule/#custom-transformations","text":"When the out-of-the-box transformations are not enough, custom functions can be added by implementing the Transformer interface in your own class. class CustomTransformer implements Transformer { @Override public String transform ( String src , Object [] args ) { return StringUtils . upperCase ( src ); } @Override public String getTransformerName () { return \"myTransformer\" ; } @Override public boolean isValid ( Object [] args ) { return true ; } } The example above implements a simple uppercase transformation. The transform method is where the custom manipulation is implemented, the method receives the input to transform and optionally some parameters, and returns the altered content. The getTransformerName is used to provide a unique name to the function so that it can be referenced in the mapping configuration. The isValid method is optional, to validate for example if the provided arguments are valid. If the mapping configuration is done programmatically, then the custom transformer class can be used directly in the code when the MappingRule objects are created. If the mapping configuration is externalized, for example, loaded from an Excel sheet, then the custom transformer must be registered so that the name is recognized when parsing the configuration. In order to register your custom transformer, you just need to call this anywhere in your initialization. TransformationRegistry . register ( \"myTransformer\" , new CustomTransformer ()); Then, in your mapping configuration, you can use \"myTransformer\" along any of the out-of-the-box transformations functions.","title":"Custom Transformations"},{"location":"integrator/myformat/myformat-setup-commands/","text":"Setup commands The SETUP commands are a special form of mapping rule used to provide general parameters for the translation. They use the same structure of a normal rule. But instead of defining how to map a value from the source message to the target message, they are used to provide overall configuration options to the mapping process. There are multiple SETUP commands, some are global (for any file format) and others are specific for a given file format. The most clear and simple example is the separator when creating CSV files. By default, a comma is used, but it can be changed to any other character by using a SETUP command. Below there is an example about how to use this command type: Source Transformations Target Write Mode \"\\t\" separator SETUP The Source column is used to indicate the configuration value The Target column is used to indicate the command name (configuration key) The Write Mode is used to indicate this rule is actually a SETUP instruction Other example would be to define in the externalized mapping table the file format of the source and taget message: Source Transformations Target Write Mode \"MT\" sourceFormat SETUP \"CSV\" targetFormat SETUP Most SETUP commands have an equivalent way to be defined directly in the source code, with setters for the MappingTable object, or setters in the different format Writer objects. However, the SETUP commands are the way to achieve the same in the actual mapping configuration, along the transformation rules. This is specially useful when the mapping is externalized in a spreadsheet or database, and the source code is not available. All the available setup command names, its accepted values and behavior are listed below. Some commands are global for any type of translation, while others are specific for a given file format. General setup commands sourceFormat Sets the mapping table input to the indicated format. Accepted values: [\"MX\", \"MT\", \"CSV, \"XML\", \"JSON\", \"FIXEDLEN\"] targetFormat Sets the mapping table output to the indicated format. Accepted values: [\"MX\", \"MT\", \"CSV, \"XML\", \"JSON\", \"FIXEDLEN\"] mappingName Sets the mapping table name. CSV target format specific commands addRow Allow to create a valid the empty template of your target CSV, by adding empty slots that will be set at rule processing time. This is useful when the CSV structure contains multiple lines, such as a first row for a header, multiple rows converted from repetitive elements in the source message, and a trailer row. separator The character to use as column's separator, it is comma by default . When used, this command should be placed before the addRow . smartQuotes Enable/disable smart quoting. True by default , meaning column values will be quoted only if needed, else, if false, all column values will be quoted. When disabled a row might look like '\"2023/04/05\", \"EUR\", \"102.39\"' while, if enabled, it could look like '2023/04/05, EUR, 102.39' Accepted values: [\"true\", \"false\"] smartEscapes Enable/disable smart escaping. False by default , meaning column values will not be escaped. Accepted values: [\"true\", \"false\"] fieldNames This command allows you to define aliases for the CSV columns. The accepted value is a list of labels separated by any character. You can use any separator character, such as a comma, a tab or a semicolon. For example, if you have a CSV with three columns and you want to assign the labels \"Date\" , \"Currency\" , and \"Amount\" to them, you can provide a comma-separated list like '\"Date\", \"Currency\", \"Amount\"' . Another example, let's say you have a CSV file with four columns and you want to assign the labels Name , ID , City , and Country to them. In this case, you can provide a list of these labels separated by a semicolon, such as \"Name;ID;City;Country\" . In the mapping, instead of using column numbers as selectors, these labels can be used instead. You can enable or disable this behavior by using the SETUP command addFieldNames , as described below. addFieldNames Enable/disable to include or not the column names in an output CSV header line. The utilization of this command requires the presence of the SETUP command fieldNames . If the fieldNames command is not present, then this command is bypassed. It is false by default , meaning no header row is generated in the output CSV. Accepted values: [\"true\", \"false\"] MX target format specific commands mxType Allow to indicate the specific MX type in conversions from/into MX Accepted values: [\"pacs.008.001.08\", \"camt.003.001.04\", \"sese.001.001.02\", ..., any ISO20022 valid mx type] appHdrType Allow to indicate the specific MX type in conversions into MX Accepted values: [\"LEGACY\", \"BAH_V1\", \"BAH_V2\", \"BAH_V3\"] MT target format specific commands mtType Allow to indicate the specific MT type in conversions into MT Accepted values: [\"103\", \"MT103\", \"202\", \"MT530\", ..., any valid MT type] FIXLEN target format specific commands addRow Allow to create a valid the empty template of your target fixed-length message, by adding empty slots that will be set at rule processing time. This is useful when the CSV structure contains multiple lines, such as a first row for a header, multiple rows converted from repetitive elements in the source message, and a trailer row.","title":"Setup Commands"},{"location":"integrator/myformat/myformat-setup-commands/#setup-commands","text":"The SETUP commands are a special form of mapping rule used to provide general parameters for the translation. They use the same structure of a normal rule. But instead of defining how to map a value from the source message to the target message, they are used to provide overall configuration options to the mapping process. There are multiple SETUP commands, some are global (for any file format) and others are specific for a given file format. The most clear and simple example is the separator when creating CSV files. By default, a comma is used, but it can be changed to any other character by using a SETUP command. Below there is an example about how to use this command type: Source Transformations Target Write Mode \"\\t\" separator SETUP The Source column is used to indicate the configuration value The Target column is used to indicate the command name (configuration key) The Write Mode is used to indicate this rule is actually a SETUP instruction Other example would be to define in the externalized mapping table the file format of the source and taget message: Source Transformations Target Write Mode \"MT\" sourceFormat SETUP \"CSV\" targetFormat SETUP Most SETUP commands have an equivalent way to be defined directly in the source code, with setters for the MappingTable object, or setters in the different format Writer objects. However, the SETUP commands are the way to achieve the same in the actual mapping configuration, along the transformation rules. This is specially useful when the mapping is externalized in a spreadsheet or database, and the source code is not available. All the available setup command names, its accepted values and behavior are listed below. Some commands are global for any type of translation, while others are specific for a given file format. General setup commands sourceFormat Sets the mapping table input to the indicated format. Accepted values: [\"MX\", \"MT\", \"CSV, \"XML\", \"JSON\", \"FIXEDLEN\"] targetFormat Sets the mapping table output to the indicated format. Accepted values: [\"MX\", \"MT\", \"CSV, \"XML\", \"JSON\", \"FIXEDLEN\"] mappingName Sets the mapping table name. CSV target format specific commands addRow Allow to create a valid the empty template of your target CSV, by adding empty slots that will be set at rule processing time. This is useful when the CSV structure contains multiple lines, such as a first row for a header, multiple rows converted from repetitive elements in the source message, and a trailer row. separator The character to use as column's separator, it is comma by default . When used, this command should be placed before the addRow . smartQuotes Enable/disable smart quoting. True by default , meaning column values will be quoted only if needed, else, if false, all column values will be quoted. When disabled a row might look like '\"2023/04/05\", \"EUR\", \"102.39\"' while, if enabled, it could look like '2023/04/05, EUR, 102.39' Accepted values: [\"true\", \"false\"] smartEscapes Enable/disable smart escaping. False by default , meaning column values will not be escaped. Accepted values: [\"true\", \"false\"] fieldNames This command allows you to define aliases for the CSV columns. The accepted value is a list of labels separated by any character. You can use any separator character, such as a comma, a tab or a semicolon. For example, if you have a CSV with three columns and you want to assign the labels \"Date\" , \"Currency\" , and \"Amount\" to them, you can provide a comma-separated list like '\"Date\", \"Currency\", \"Amount\"' . Another example, let's say you have a CSV file with four columns and you want to assign the labels Name , ID , City , and Country to them. In this case, you can provide a list of these labels separated by a semicolon, such as \"Name;ID;City;Country\" . In the mapping, instead of using column numbers as selectors, these labels can be used instead. You can enable or disable this behavior by using the SETUP command addFieldNames , as described below. addFieldNames Enable/disable to include or not the column names in an output CSV header line. The utilization of this command requires the presence of the SETUP command fieldNames . If the fieldNames command is not present, then this command is bypassed. It is false by default , meaning no header row is generated in the output CSV. Accepted values: [\"true\", \"false\"] MX target format specific commands mxType Allow to indicate the specific MX type in conversions from/into MX Accepted values: [\"pacs.008.001.08\", \"camt.003.001.04\", \"sese.001.001.02\", ..., any ISO20022 valid mx type] appHdrType Allow to indicate the specific MX type in conversions into MX Accepted values: [\"LEGACY\", \"BAH_V1\", \"BAH_V2\", \"BAH_V3\"] MT target format specific commands mtType Allow to indicate the specific MT type in conversions into MT Accepted values: [\"103\", \"MT103\", \"202\", \"MT530\", ..., any valid MT type] FIXLEN target format specific commands addRow Allow to create a valid the empty template of your target fixed-length message, by adding empty slots that will be set at rule processing time. This is useful when the CSV structure contains multiple lines, such as a first row for a header, multiple rows converted from repetitive elements in the source message, and a trailer row.","title":"Setup commands"},{"location":"integrator/myformat/myformat-sql-table/","text":"SQL table structure This section describe the table structure to be used when the mapping configuration is loaded dynamically from a SQL database, as an alternative to the mapping from Excel spreadsheets or the programmatic mapping. Notice this is not to load data to translate, but the mapping configuration itself. It is static information with the definitions for the translation process. The below SQL snippets can be used to create the table in different database engines. MySQL create table pw_mapping_rule ( id bigint not null auto_increment , pw_conf_name varchar ( 50 ) not null , pw_order integer not null , pw_source varchar ( 255 ) not null , pw_transformation varchar ( 255 ), pw_target varchar ( 100 ) not null , pw_mode varchar ( 20 ), primary key ( id ) ); SQLServer create table pw_mapping_rule ( id numeric ( 19 , 0 ) identity not null , pw_conf_name varchar ( 50 ) not null , pw_order int not null , pw_source varchar ( 255 ) not null , pw_transformation varchar ( 255 ), pw_target varchar ( 100 ) not null , pw_mode varchar ( 20 ), primary key ( id ) ); Oracle create table pw_mapping_rule ( id number ( 19 , 0 ) not null , pw_conf_name varchar ( 50 ) not null , pw_order number ( 10 , 0 ) not null , pw_source varchar ( 255 ) not null , pw_transformation varchar ( 255 ), pw_target varchar ( 100 ) not null , pw_mode varchar ( 20 ), primary key ( id ) ); Derby create table pw_mapping_rule ( id bigint generated by default as identity , pw_conf_name varchar ( 50 ) not null , pw_order integer not null , pw_source varchar ( 255 ) not null , pw_transformation varchar ( 255 ), pw_target varchar ( 100 ) not null , pw_mode varchar ( 20 ), primary key ( id ) ); When using Prowide Integrator to develop an external component that interacts with Prowide Enterprise, it might be a good idea to store the actual mappings in Prowide Enterprise, and access them programmatically from the external component. Since the Prowide Enterprise tables are different from the expected table for the Integrator database loader, the following VIEW can be used. By creating this VIEW in the Prowide Enterprise database, the Integrator database loader will be able to load any mapping with the default options. The two configuration tables in the Enterprise are flattened to the single table expected by the Integrator. CREATE VIEW pw_mapping_rule AS SELECT FM . id AS 'id' , FC . name AS 'pw_conf_name' , FM . order_key AS 'pw_order' , CASE WHEN FM . read_mode = 'LITERAL' THEN concat ( 'literal(' , FM . source_selector , ')' ) WHEN FM . read_mode = 'FOREACH' THEN concat ( 'foreach(' , FM . source_selector , ')' ) WHEN FM . read_mode = 'CONCAT' THEN concat ( 'concat(' , FM . source_selector , ')' ) ELSE FM . source_selector END AS 'pw_source' , FM . transformations AS 'pw_transformation' , FM . target_selector AS 'pw_target' , FM . write_mode AS 'pw_mode' FROM my_format_configuration FC INNER JOIN my_format_mapping FM ON FC . id = FM . conf_id","title":"SQL table structure"},{"location":"integrator/myformat/myformat-sql-table/#sql-table-structure","text":"This section describe the table structure to be used when the mapping configuration is loaded dynamically from a SQL database, as an alternative to the mapping from Excel spreadsheets or the programmatic mapping. Notice this is not to load data to translate, but the mapping configuration itself. It is static information with the definitions for the translation process. The below SQL snippets can be used to create the table in different database engines.","title":"SQL table structure"},{"location":"integrator/myformat/myformat-sql-table/#mysql","text":"create table pw_mapping_rule ( id bigint not null auto_increment , pw_conf_name varchar ( 50 ) not null , pw_order integer not null , pw_source varchar ( 255 ) not null , pw_transformation varchar ( 255 ), pw_target varchar ( 100 ) not null , pw_mode varchar ( 20 ), primary key ( id ) );","title":"MySQL"},{"location":"integrator/myformat/myformat-sql-table/#sqlserver","text":"create table pw_mapping_rule ( id numeric ( 19 , 0 ) identity not null , pw_conf_name varchar ( 50 ) not null , pw_order int not null , pw_source varchar ( 255 ) not null , pw_transformation varchar ( 255 ), pw_target varchar ( 100 ) not null , pw_mode varchar ( 20 ), primary key ( id ) );","title":"SQLServer"},{"location":"integrator/myformat/myformat-sql-table/#oracle","text":"create table pw_mapping_rule ( id number ( 19 , 0 ) not null , pw_conf_name varchar ( 50 ) not null , pw_order number ( 10 , 0 ) not null , pw_source varchar ( 255 ) not null , pw_transformation varchar ( 255 ), pw_target varchar ( 100 ) not null , pw_mode varchar ( 20 ), primary key ( id ) );","title":"Oracle"},{"location":"integrator/myformat/myformat-sql-table/#derby","text":"create table pw_mapping_rule ( id bigint generated by default as identity , pw_conf_name varchar ( 50 ) not null , pw_order integer not null , pw_source varchar ( 255 ) not null , pw_transformation varchar ( 255 ), pw_target varchar ( 100 ) not null , pw_mode varchar ( 20 ), primary key ( id ) ); When using Prowide Integrator to develop an external component that interacts with Prowide Enterprise, it might be a good idea to store the actual mappings in Prowide Enterprise, and access them programmatically from the external component. Since the Prowide Enterprise tables are different from the expected table for the Integrator database loader, the following VIEW can be used. By creating this VIEW in the Prowide Enterprise database, the Integrator database loader will be able to load any mapping with the default options. The two configuration tables in the Enterprise are flattened to the single table expected by the Integrator. CREATE VIEW pw_mapping_rule AS SELECT FM . id AS 'id' , FC . name AS 'pw_conf_name' , FM . order_key AS 'pw_order' , CASE WHEN FM . read_mode = 'LITERAL' THEN concat ( 'literal(' , FM . source_selector , ')' ) WHEN FM . read_mode = 'FOREACH' THEN concat ( 'foreach(' , FM . source_selector , ')' ) WHEN FM . read_mode = 'CONCAT' THEN concat ( 'concat(' , FM . source_selector , ')' ) ELSE FM . source_selector END AS 'pw_source' , FM . transformations AS 'pw_transformation' , FM . target_selector AS 'pw_target' , FM . write_mode AS 'pw_mode' FROM my_format_configuration FC INNER JOIN my_format_mapping FM ON FC . id = FM . conf_id","title":"Derby"},{"location":"integrator/myformat/myformat-transformations/","text":"Transformation functions The following table lists all available functions for the transformation in mapping rules. Text generation These are transformations that generate values rather than transform input ones. For these special cases, you'd want to use a dummy source selector (i.e. \"-\"). Text generation now() Returns the current date-time from the system clock in the local time-zone, formatted as yyyy-MM-dd'T'HH:mm:ss.SSSZ (ISO 8601) . now(utcOffset) Returns the current date-time from the system clock at the specified UTC Offset or ZoneId, formatted as yyyy-MM-dd'T'HH:mm:ss.SSSZ (ISO 8601) . uetr() Generates a new random UETR Text manipulation Text manipulation abbreviate(maxWidth) Abbreviates a String using ellipses. This will turn \"A long sentence that must be abbreviated\"\" into \"A long sentence...\". append(suffix) Appends the suffix to the end of the input. appendIfMissing(suffix) Appends the suffix to the end of the input if the input does not already end with the suffix. appendIfMissingIgnoreCase(suffix) Appends the suffix to the end of the input if the input does not already end, case-insensitive, with the suffix. capitalize() Capitalizes the input, changing the first letter to title case. No other letters are changed. chop() Remove the last character from the input. defaultString(default) If the input is null, empty or blank, returns the value indicated as default, otherwise returns the input unaltered. fixed(default) Returns the fixed value provided by the parameter, regardless of the input content. This transformation is useful to generate fixed content based on source elements being present or not. If a source selector finds content, even if the content is empty or blank, then the rule is executed, and this fixed content is added to the output message. However, if the source selector returns null, because the source content is not present, then fixed content will not be added to the output message. Notice that to force creation of fixed content regardless of an input selector, transformations are not required because plain literal values can be provided directly as source selectors. formatDateTime(sourceFormat, targetFormat) Formats a date or datetime input given its source and target formats. The format definition must be compliant to Java SimpleDateFormat. Returns the formatted date or the input unaltered if it cannot be formatted. formatMTDecimal() Formats a number in decimal notation (with dot as decimal separator) into a SWIFT MT amount. SWIFT amounts in MT messages are expressed with no thousand's separator, with mandatory comma as decimal separator and with the decimal part optional. Returns the formatted amount or input unaltered if it cannot format as decimal. formatDecimal() Formats a number into decimal notation (with dot as decimal separator and without thousands separator). Returns the formatted amount or input unaltered if it cannot format as decimal. The decimal part is always present in the result, initialized with .0 if the source number does not have decimals. This is aimed to convert MT numbers with commas as decimal separators into big decimal compatible values. So if the input has a comma, the comma is interpreted as a decimal separator and the dot (if present) will be dropped. Meaning 1.234,56 is converted into 1234.56. The transformation also handles MT numbers with missing decimal digits, such as 123, that is converted into 123.0. formatDecimal(format) Formats a number into decimal notation given the expected output format. The format definition must be compliant to Java DecimalFormat. This is similar to the formatDecimal without a parameter, in the sense that a comma in the input is parsed as a decimal separator. This transformation is useful when converting from MT amounts into big decimal compatible values. For example, if you want to have all converted numbers with at least 3 decimal digits, you would pass as parameter the format \"0.000####\". Returns the formatted amount or input unaltered if it cannot format as decimal. ifElse(regex, resultIfTrue, resultIfFalse) Checks if the input string matches the regex. If matches, the resultIfTrue is returned, else resultIfFalse. ifMatches(regex) If the input matches the regex, the input is forwarded as the transformation result. If it does not match, the transformation returns null (meaning content in the target selector will not be written). ifNotMatches(regex) If the input does not match the regex, the input is forwarded as the transformation result. If it does match, the transformation returns null (meaning content in the target selector will not be written). indexOf(searchString) Finds the first index within a String. If not found, returns null. indexOfIgnoreCase(searchString) Finds the first index within a String ignoring the case. If not found, returns null. lastIndexOf(searchString) Finds the last index within a String. If not found, returns null. lastIndexOfIgnoreCase(searchString) Finds the last index within a String ignoring the case. If not found, returns null. left(len:int) Returns the leftmost len characters of the input. leftPad(size:int) Left pad of the input with spaces (' '). leftPad(size:int, padString) Left pad of the input with a specified String. lowerCase() Converts the input to lowercase. map(key, value, key, value, ...) Replaces the input with a mapped value. The mapping tuples are passed as a simple list of parameters that will be interpreted in pairs. The number of parameters must be even. For example, the list of parameters P, PROC, F, FULL will transform an input string \"F\" into the string \"FULL\". To map simple values, check replace and replaceIfEquals . If the value is not found in the map, it is returned as is. normalizeSpace() Returns the input with whitespace normalized by using trim(String) to remove leading and trailing whitespace, and then replacing sequences of whitespace characters by a single space. prepend(prefix) Prepends the prefix to the start of the input. prependIfMissing(prefix) Prepends the prefix to the start of the input if the input does not already start with the prefix. prependIfMissingIgnoreCase(prefix) Prepends the prefix to the start of the input if the input does not already start, case-insensitive, with the prefix. remove(remove) Removes all occurrences of a substring from within the input. removeAll(regex) Removes each substring of the text String that matches the given regular expression. removeFirst(regex) Removes the first substring of the text string that matches the given regular expression. removeStart(remove) Removes a substring only if it is at the beginning of the input, otherwise returns the input unaltered. removeStartIgnoreCase(remove) Case insensitive removal of a substring if it is at the beginning of the input, otherwise returns the input unaltered. removeEnd(remove) Removes a substring only if it is at the end of the input, otherwise returns the input unaltered. removeEndIgnoreCase(remove) Case insensitive removal of a substring if it is at the end of the input, otherwise returns the input unaltered. removeWhitespace() Deletes all whitespaces from the input. replace(searchString, replacement) Replaces all occurrences of searchString within the input with the replacement. replace(searchString) Replaces all occurrences of searchString within the input with empty, therefore deleting the searchString from the input. replaceAll(regex, replacement) Replaces each substring of the text String that matches the given regular expression with the given replacement. This is similar to the replacePattern(regex, replacement) but without the DOTALL in the regex. replaceFirst(regex, replacement) Replaces the first substring of the text string that matches the given regular expression with the given replacement. replaceIfEquals(searchString, replacementIfEquals, replacementIfNotEquals) Compares the input with searchString; if equals, replacementIfEquals is returned, otherwise replacementIfNotEquals is returned. replaceOnce(searchString, replacement) Replaces the first occurrence of searchString within the input with the replacement. replaceOnce(searchString) Replaces the first occurrence of searchString within the input with an empty, therefore deleting the first occurrence of searchString from the input. replacePattern(regex, replacement) Replaces each substring of the source String that matches the given regular expression with the given replacement. This is similar to the replaceAll(regex, replacement) but using the DOTALL in the regex. right(len:int) Returns the rightmost len characters of the input. rightPad(size:int) Right pad of the input with spaces (' '). rightPad(size:int, padString) Right pad of the input with a specified String. stripToNull() Strips whitespace from the start and end of the input, returning null if the String is empty (\"\") after the strip. stripToEmpty() Strips whitespace from the start and end of the input, returning an empty String if null input. strip(stripChars) Strips any of a set of characters from the start and end of the input. Notice this removes any of the indicated characters, to strip all occurrences of a String use remove(searchString). stripStart() Strips whitespaces from the start of the input. stripStart(stripChars) Strips any of a set of characters from the start of the input. Notice this removes any of the indicated characters, to strip a complete String use removeStart(searchString). stripEnd() Strips whitespaces from the end of the input. stripEnd(stripChars) Strips any of a set of characters from the end of the input. Notice this removes any of the indicated characters, to strip a complete String use removeEnd(searchString). substring(start:int) Gets a substring of the input starting at the position indicated as start. substring(start:int, end:int) Gets a substring of the input between the indicated start and end position. substringAfter(separator) Gets the substring after the first occurrence of a separator. The separator is not returned. substringAfterLast(separator) Gets the substring after the last occurrence of a separator. The separator is not returned. substringBefore(separator) Gets the substring before the first occurrence of a separator. The separator is not returned. substringBeforeLast(separator) Gets the substring before the last occurrence of a separator. The separator is not returned. substringBetween(tag) Gets the String that is nested in between two instances of the indicated String. substringBetween(open, close) Gets the String that is nested in between two Strings. Only the first match is returned. swapCase() Swaps the case of the input, changing upper and title case to lowercase, and lowercase to uppercase. toTimeZone(dateTimeFormat, targetUtcOffset) Gets the formatted input date-time and converts it to the target UTC timezone or ZoneId toTimeZone(dateTimeFormat, sourceUtcOffset, targetUtcOffset) Gets the formatted input date-time at source UTC timezone or ZoneId, and converts it to the target UTC timezone or ZoneId unwrap(wrapToken) Unwraps a given string from the input, meaning it removes the given wrapToken from the beginning and/or ending of the input. This is the opposite operation of the wrap(wrapWith). Notice, if the input is not quoted with the wrapping token at both the beginning and end of the string, the input is returned unaltered. Meaning, wrap is removed only when present at both beginning and end of the input string. upperCase() Converts the input to uppercase. wrap(wrapWith) Wraps the input with a character or string, adding the character before and after the input. wrapLines(lineLength) Wraps a single line of text, identifying words by ' '. Long words (such as URLs) will be wrapped. wrapLinesPrepend(lineLength, prefix) Similar to wrapLines, but it will also add the given prefix at the beginning of each resulting line. The lineLength parameter should be the maximum line length including the prefix. This function is particularly useful when generating MT narrative fields where lines must be preceded by a double slash. wrapLinesPreserve(lineLength) Similar to wrapLines(lineLength) but if the input is already split into lines, the original LF are preserved while doing the wrap. If an original line contains less than the length limit, that line is copied as is to the output. Only lines exceeding the length are wrapped. wrapLinesPreservePrepend(lineLength, prefix) Similar to wrapLinesPrepend(lineLength, prefix) but if the input is already split into lines, the original LF are preserved while doing the wrap. If an original line contains less than the length limit, that line is copied as is to the output. Only lines exceeding the length are wrapped. Math Operations Math Operations add(added:int) Converts the input to an integer value and adds the parameter integer. Returns the result of the mathematical add operation, or null if the input is not an integer value. addDecimal(added:decimal) Converts the input to a decimal value and adds the parameter decimal. Returns the result of the mathematical add operation or null if the input is not a decimal value (with dot as decimal separator and no thousands separators, ex: 123.4). subtract(subtracted:int) Converts the input to an integer value and subtracts the parameter integer. Returns the result of the mathematical subtract operation, or null if the input is not an integer value. subtractDecimal(subtracted:decimal) Converts the input to a decimal value and subtracts the parameter decimal. Returns the result of the mathematical subtract operation or null if the input is not a decimal value (with dot as decimal separator and no thousands separators, ex: 123.4). divide(divisor:int) Converts the input to a decimal value and divides it to the parameter integer. Returns the result of the mathematical division operation, or null if the input is not a valid number. The result is rounded to two decimal parts. divide(divisor:int, decimals:int) Converts the input to a decimal value and divides it to the parameter decimal. Returns the result of the mathematical division operation, or null if the input is not a valid number. The result is rounded to specified decimal parts. divideDecimal(divisor:decimal) Converts the input to a decimal value and divides it to the parameter decimal. Returns the result of the mathematical division operation, or null if the input is not a valid number. The result is rounded to two decimal parts. divideDecimal(divisor:decimal, decimals:int) Converts the input to a decimal value and divides it to the parameter decimal. Returns the result of the mathematical division operation, or null if the input is not a valid number. The result is rounded to the indicated decimal parts. round(decimals:int) Converts the input to a decimal value and rounds it to the indicated decimal parts. Returns the rounded value or null if the input is not a valid number. BIC operations BIC operations bic8(address) Takes a BIC or logical terminal address and returns the BIC8 part. bic11(address) Takes a BIC or logical terminal address and returns the BIC11 part. bicBranch(address) Takes a BIC or logical terminal address and returns the branch (or XXX if branch is not defined). bicCountry(address) Takes a BIC or logical terminal address and returns the country code. bicInstitution(address) Takes a BIC or logical terminal address and returns the institution part (first 4 characters). Custom Additional functions are added to the module on a regular basis and distributed with the product within maintenance updates. You can also add your own transformation functions in a regular Java class by implementing the Transformer interface. Fixed-Length For translation from or to fixed-length files, some special transformation functions are provided: filler, fromPIC, toPIC. Fixed-Length operations filler(format \u2026 ) This transformation takes multiple PIC formats as input and generates a single output value that complies with the PIC formats. For example: filler(\"HDR\", \"X(4)\", \"9(8)\") will generate the string \"HDR 00000000\" where the input will be ignored. It is especially suited to initialize records in a target fixed-length file. fromPIC(format) This transformation reads the input string according to the received PIC format. It is especially suited to read content from a fixed-length file. For example, fromPIC(\"9(6)V99\") applied to the value \"00123456\" will return \"1234.56\". toPIC(format) This transformation takes the input string and processes it to generate a string compliant with the parameter PIC format. It is especially suited to write content in a fixed-length file. For example: toPIC(\"9(6)V99\") applied to the value \"1234.56\" will return \"00123456\". These functions are a subset of the legacy COBOL PIC Formats (PICTURE clause). This transformation is especially suited to convert to/from fixed length strings to normal strings, but could be helpful for other message formats. A few letters are reserved values for PIC formats (described in the following table). Any other character will be considered to appear as is in the input/output string. Letter Description X Indicates any character can be present (see the section on Character Set, below). A Same as A. While in COBOL these codes have different usage, in our implementation they are the same. 9 Indicates a decimal digit can be present. V Indicates an implied virtual decimal separator. It is common in Fixed Len formats to store digits without the decimal separator (ex: 123.45 can be stored as 012345 using a PIC of 9999V99, note how an extra leading zero is added). . (decimal dot) Indicates a dot as decimal separator. It is rarely used in Fixed Len formats (usually, the V is used). , (comma) Indicates a comma as decimal separator. It is rarely used in Fixed Len formats (usually, the V is used) S Indicates a sign for a numeric value. It can be in the front or in the back of the value (ex: S9999 or 9999S). When used, a \"+\" or \" \" implies positive, a \"-\" implies negative Z Indicates left padding blanks * Indicates the asterisk character is used for left padding Only the characters \"9\", \"X\" and \"A\" can be repeated. Whenever repetitions are needed, they can be replaced with a reduced version, by putting the number of repetitions between parentheses. Example \"99\" can be indicated as \"9(2)\", \" 999999V99\" can be indicated as \"9(6)V99\" and \"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\" can be indicated as \"X(40)\". When these reserved characters (A, X, Z, etc\u2026) are used in the PIC definition, they must be escaped with a backward slash. Some examples of different PICs are: Source PIC Format Description Result \"12345.67\" 9(6)V99 Number with implied decimal point \"01234567\" \"2125553344\" 999.999.9999 Telephone number with dots between components \"212.555.3344\" \"20180415\" 9999-99-99 A date \"2018-04-15\" \"C1234AAB\" \"X 9999 XXX\" An Argentinian Postal Code \"C 1234 AAB\" \"0876543210-\" \"9(7)V999S\" A negative number with 3 decimals (note the leading and trailing zeros are removed) \"-876543.21\" \"1234567\" \"S9(9)\" A signed 9 digits integer \"+001234567\" \"-12.34\" \"9(6)V99S\" A signed 8 digits number, with sign as suffix and decimal separator \"00001234-\" \"12345.6\" \"ZZ9(5).9\" A number with decimal separator a left padded with blank \" 12345.6\" \"20190506170339\" \"9999-99-99T99:99:99\" A formatted date and time \"2019-05-06T17:03:39\" fromPIC This transformation takes the input string and processes it according to the received PIC format (see below), returning a new string. Examples: Transformation Input Output fromPIC(\"9(6)V99\") \"00123456\" \"1234.56\" fromPIC(\"9(3).99S\") \"000.01-\" \"-0.01\" fromPIC(\"S9(3).99\") \"+765.43\" \"765.43\" fromPIC(\"S9(3).99\") \" 765.43\" \"765.43\" fromPIC(\"X(10)\") \"Test! \" \"Test!\" toPIC This transformation takes the input string and processes it to generate a string compliant with the received PIC format (see below), returning a new string. Examples: Transformation Input Output toPIC(\"9(6)V99\") \"1234.56\" \"00123456\" toPIC(\"9(3).99S\") \"-0.01\" \"000.01-\" toPIC(\"S9(3).99\") \"+765.43\" \"+765.43\" toPIC(\"S9(3).99\") \"765.43\" \"+765.43\" toPIC(\"X(10)\") \"Test!\" \"Test! \"","title":"Transformations"},{"location":"integrator/myformat/myformat-transformations/#transformation-functions","text":"The following table lists all available functions for the transformation in mapping rules.","title":"Transformation functions"},{"location":"integrator/myformat/myformat-transformations/#text-generation","text":"These are transformations that generate values rather than transform input ones. For these special cases, you'd want to use a dummy source selector (i.e. \"-\"). Text generation now() Returns the current date-time from the system clock in the local time-zone, formatted as yyyy-MM-dd'T'HH:mm:ss.SSSZ (ISO 8601) . now(utcOffset) Returns the current date-time from the system clock at the specified UTC Offset or ZoneId, formatted as yyyy-MM-dd'T'HH:mm:ss.SSSZ (ISO 8601) . uetr() Generates a new random UETR","title":"Text generation"},{"location":"integrator/myformat/myformat-transformations/#text-manipulation","text":"Text manipulation abbreviate(maxWidth) Abbreviates a String using ellipses. This will turn \"A long sentence that must be abbreviated\"\" into \"A long sentence...\". append(suffix) Appends the suffix to the end of the input. appendIfMissing(suffix) Appends the suffix to the end of the input if the input does not already end with the suffix. appendIfMissingIgnoreCase(suffix) Appends the suffix to the end of the input if the input does not already end, case-insensitive, with the suffix. capitalize() Capitalizes the input, changing the first letter to title case. No other letters are changed. chop() Remove the last character from the input. defaultString(default) If the input is null, empty or blank, returns the value indicated as default, otherwise returns the input unaltered. fixed(default) Returns the fixed value provided by the parameter, regardless of the input content. This transformation is useful to generate fixed content based on source elements being present or not. If a source selector finds content, even if the content is empty or blank, then the rule is executed, and this fixed content is added to the output message. However, if the source selector returns null, because the source content is not present, then fixed content will not be added to the output message. Notice that to force creation of fixed content regardless of an input selector, transformations are not required because plain literal values can be provided directly as source selectors. formatDateTime(sourceFormat, targetFormat) Formats a date or datetime input given its source and target formats. The format definition must be compliant to Java SimpleDateFormat. Returns the formatted date or the input unaltered if it cannot be formatted. formatMTDecimal() Formats a number in decimal notation (with dot as decimal separator) into a SWIFT MT amount. SWIFT amounts in MT messages are expressed with no thousand's separator, with mandatory comma as decimal separator and with the decimal part optional. Returns the formatted amount or input unaltered if it cannot format as decimal. formatDecimal() Formats a number into decimal notation (with dot as decimal separator and without thousands separator). Returns the formatted amount or input unaltered if it cannot format as decimal. The decimal part is always present in the result, initialized with .0 if the source number does not have decimals. This is aimed to convert MT numbers with commas as decimal separators into big decimal compatible values. So if the input has a comma, the comma is interpreted as a decimal separator and the dot (if present) will be dropped. Meaning 1.234,56 is converted into 1234.56. The transformation also handles MT numbers with missing decimal digits, such as 123, that is converted into 123.0. formatDecimal(format) Formats a number into decimal notation given the expected output format. The format definition must be compliant to Java DecimalFormat. This is similar to the formatDecimal without a parameter, in the sense that a comma in the input is parsed as a decimal separator. This transformation is useful when converting from MT amounts into big decimal compatible values. For example, if you want to have all converted numbers with at least 3 decimal digits, you would pass as parameter the format \"0.000####\". Returns the formatted amount or input unaltered if it cannot format as decimal. ifElse(regex, resultIfTrue, resultIfFalse) Checks if the input string matches the regex. If matches, the resultIfTrue is returned, else resultIfFalse. ifMatches(regex) If the input matches the regex, the input is forwarded as the transformation result. If it does not match, the transformation returns null (meaning content in the target selector will not be written). ifNotMatches(regex) If the input does not match the regex, the input is forwarded as the transformation result. If it does match, the transformation returns null (meaning content in the target selector will not be written). indexOf(searchString) Finds the first index within a String. If not found, returns null. indexOfIgnoreCase(searchString) Finds the first index within a String ignoring the case. If not found, returns null. lastIndexOf(searchString) Finds the last index within a String. If not found, returns null. lastIndexOfIgnoreCase(searchString) Finds the last index within a String ignoring the case. If not found, returns null. left(len:int) Returns the leftmost len characters of the input. leftPad(size:int) Left pad of the input with spaces (' '). leftPad(size:int, padString) Left pad of the input with a specified String. lowerCase() Converts the input to lowercase. map(key, value, key, value, ...) Replaces the input with a mapped value. The mapping tuples are passed as a simple list of parameters that will be interpreted in pairs. The number of parameters must be even. For example, the list of parameters P, PROC, F, FULL will transform an input string \"F\" into the string \"FULL\". To map simple values, check replace and replaceIfEquals . If the value is not found in the map, it is returned as is. normalizeSpace() Returns the input with whitespace normalized by using trim(String) to remove leading and trailing whitespace, and then replacing sequences of whitespace characters by a single space. prepend(prefix) Prepends the prefix to the start of the input. prependIfMissing(prefix) Prepends the prefix to the start of the input if the input does not already start with the prefix. prependIfMissingIgnoreCase(prefix) Prepends the prefix to the start of the input if the input does not already start, case-insensitive, with the prefix. remove(remove) Removes all occurrences of a substring from within the input. removeAll(regex) Removes each substring of the text String that matches the given regular expression. removeFirst(regex) Removes the first substring of the text string that matches the given regular expression. removeStart(remove) Removes a substring only if it is at the beginning of the input, otherwise returns the input unaltered. removeStartIgnoreCase(remove) Case insensitive removal of a substring if it is at the beginning of the input, otherwise returns the input unaltered. removeEnd(remove) Removes a substring only if it is at the end of the input, otherwise returns the input unaltered. removeEndIgnoreCase(remove) Case insensitive removal of a substring if it is at the end of the input, otherwise returns the input unaltered. removeWhitespace() Deletes all whitespaces from the input. replace(searchString, replacement) Replaces all occurrences of searchString within the input with the replacement. replace(searchString) Replaces all occurrences of searchString within the input with empty, therefore deleting the searchString from the input. replaceAll(regex, replacement) Replaces each substring of the text String that matches the given regular expression with the given replacement. This is similar to the replacePattern(regex, replacement) but without the DOTALL in the regex. replaceFirst(regex, replacement) Replaces the first substring of the text string that matches the given regular expression with the given replacement. replaceIfEquals(searchString, replacementIfEquals, replacementIfNotEquals) Compares the input with searchString; if equals, replacementIfEquals is returned, otherwise replacementIfNotEquals is returned. replaceOnce(searchString, replacement) Replaces the first occurrence of searchString within the input with the replacement. replaceOnce(searchString) Replaces the first occurrence of searchString within the input with an empty, therefore deleting the first occurrence of searchString from the input. replacePattern(regex, replacement) Replaces each substring of the source String that matches the given regular expression with the given replacement. This is similar to the replaceAll(regex, replacement) but using the DOTALL in the regex. right(len:int) Returns the rightmost len characters of the input. rightPad(size:int) Right pad of the input with spaces (' '). rightPad(size:int, padString) Right pad of the input with a specified String. stripToNull() Strips whitespace from the start and end of the input, returning null if the String is empty (\"\") after the strip. stripToEmpty() Strips whitespace from the start and end of the input, returning an empty String if null input. strip(stripChars) Strips any of a set of characters from the start and end of the input. Notice this removes any of the indicated characters, to strip all occurrences of a String use remove(searchString). stripStart() Strips whitespaces from the start of the input. stripStart(stripChars) Strips any of a set of characters from the start of the input. Notice this removes any of the indicated characters, to strip a complete String use removeStart(searchString). stripEnd() Strips whitespaces from the end of the input. stripEnd(stripChars) Strips any of a set of characters from the end of the input. Notice this removes any of the indicated characters, to strip a complete String use removeEnd(searchString). substring(start:int) Gets a substring of the input starting at the position indicated as start. substring(start:int, end:int) Gets a substring of the input between the indicated start and end position. substringAfter(separator) Gets the substring after the first occurrence of a separator. The separator is not returned. substringAfterLast(separator) Gets the substring after the last occurrence of a separator. The separator is not returned. substringBefore(separator) Gets the substring before the first occurrence of a separator. The separator is not returned. substringBeforeLast(separator) Gets the substring before the last occurrence of a separator. The separator is not returned. substringBetween(tag) Gets the String that is nested in between two instances of the indicated String. substringBetween(open, close) Gets the String that is nested in between two Strings. Only the first match is returned. swapCase() Swaps the case of the input, changing upper and title case to lowercase, and lowercase to uppercase. toTimeZone(dateTimeFormat, targetUtcOffset) Gets the formatted input date-time and converts it to the target UTC timezone or ZoneId toTimeZone(dateTimeFormat, sourceUtcOffset, targetUtcOffset) Gets the formatted input date-time at source UTC timezone or ZoneId, and converts it to the target UTC timezone or ZoneId unwrap(wrapToken) Unwraps a given string from the input, meaning it removes the given wrapToken from the beginning and/or ending of the input. This is the opposite operation of the wrap(wrapWith). Notice, if the input is not quoted with the wrapping token at both the beginning and end of the string, the input is returned unaltered. Meaning, wrap is removed only when present at both beginning and end of the input string. upperCase() Converts the input to uppercase. wrap(wrapWith) Wraps the input with a character or string, adding the character before and after the input. wrapLines(lineLength) Wraps a single line of text, identifying words by ' '. Long words (such as URLs) will be wrapped. wrapLinesPrepend(lineLength, prefix) Similar to wrapLines, but it will also add the given prefix at the beginning of each resulting line. The lineLength parameter should be the maximum line length including the prefix. This function is particularly useful when generating MT narrative fields where lines must be preceded by a double slash. wrapLinesPreserve(lineLength) Similar to wrapLines(lineLength) but if the input is already split into lines, the original LF are preserved while doing the wrap. If an original line contains less than the length limit, that line is copied as is to the output. Only lines exceeding the length are wrapped. wrapLinesPreservePrepend(lineLength, prefix) Similar to wrapLinesPrepend(lineLength, prefix) but if the input is already split into lines, the original LF are preserved while doing the wrap. If an original line contains less than the length limit, that line is copied as is to the output. Only lines exceeding the length are wrapped.","title":"Text manipulation"},{"location":"integrator/myformat/myformat-transformations/#math-operations","text":"Math Operations add(added:int) Converts the input to an integer value and adds the parameter integer. Returns the result of the mathematical add operation, or null if the input is not an integer value. addDecimal(added:decimal) Converts the input to a decimal value and adds the parameter decimal. Returns the result of the mathematical add operation or null if the input is not a decimal value (with dot as decimal separator and no thousands separators, ex: 123.4). subtract(subtracted:int) Converts the input to an integer value and subtracts the parameter integer. Returns the result of the mathematical subtract operation, or null if the input is not an integer value. subtractDecimal(subtracted:decimal) Converts the input to a decimal value and subtracts the parameter decimal. Returns the result of the mathematical subtract operation or null if the input is not a decimal value (with dot as decimal separator and no thousands separators, ex: 123.4). divide(divisor:int) Converts the input to a decimal value and divides it to the parameter integer. Returns the result of the mathematical division operation, or null if the input is not a valid number. The result is rounded to two decimal parts. divide(divisor:int, decimals:int) Converts the input to a decimal value and divides it to the parameter decimal. Returns the result of the mathematical division operation, or null if the input is not a valid number. The result is rounded to specified decimal parts. divideDecimal(divisor:decimal) Converts the input to a decimal value and divides it to the parameter decimal. Returns the result of the mathematical division operation, or null if the input is not a valid number. The result is rounded to two decimal parts. divideDecimal(divisor:decimal, decimals:int) Converts the input to a decimal value and divides it to the parameter decimal. Returns the result of the mathematical division operation, or null if the input is not a valid number. The result is rounded to the indicated decimal parts. round(decimals:int) Converts the input to a decimal value and rounds it to the indicated decimal parts. Returns the rounded value or null if the input is not a valid number.","title":"Math Operations"},{"location":"integrator/myformat/myformat-transformations/#bic-operations","text":"BIC operations bic8(address) Takes a BIC or logical terminal address and returns the BIC8 part. bic11(address) Takes a BIC or logical terminal address and returns the BIC11 part. bicBranch(address) Takes a BIC or logical terminal address and returns the branch (or XXX if branch is not defined). bicCountry(address) Takes a BIC or logical terminal address and returns the country code. bicInstitution(address) Takes a BIC or logical terminal address and returns the institution part (first 4 characters).","title":"BIC operations"},{"location":"integrator/myformat/myformat-transformations/#custom","text":"Additional functions are added to the module on a regular basis and distributed with the product within maintenance updates. You can also add your own transformation functions in a regular Java class by implementing the Transformer interface.","title":"Custom"},{"location":"integrator/myformat/myformat-transformations/#fixed-length","text":"For translation from or to fixed-length files, some special transformation functions are provided: filler, fromPIC, toPIC. Fixed-Length operations filler(format \u2026 ) This transformation takes multiple PIC formats as input and generates a single output value that complies with the PIC formats. For example: filler(\"HDR\", \"X(4)\", \"9(8)\") will generate the string \"HDR 00000000\" where the input will be ignored. It is especially suited to initialize records in a target fixed-length file. fromPIC(format) This transformation reads the input string according to the received PIC format. It is especially suited to read content from a fixed-length file. For example, fromPIC(\"9(6)V99\") applied to the value \"00123456\" will return \"1234.56\". toPIC(format) This transformation takes the input string and processes it to generate a string compliant with the parameter PIC format. It is especially suited to write content in a fixed-length file. For example: toPIC(\"9(6)V99\") applied to the value \"1234.56\" will return \"00123456\". These functions are a subset of the legacy COBOL PIC Formats (PICTURE clause). This transformation is especially suited to convert to/from fixed length strings to normal strings, but could be helpful for other message formats. A few letters are reserved values for PIC formats (described in the following table). Any other character will be considered to appear as is in the input/output string. Letter Description X Indicates any character can be present (see the section on Character Set, below). A Same as A. While in COBOL these codes have different usage, in our implementation they are the same. 9 Indicates a decimal digit can be present. V Indicates an implied virtual decimal separator. It is common in Fixed Len formats to store digits without the decimal separator (ex: 123.45 can be stored as 012345 using a PIC of 9999V99, note how an extra leading zero is added). . (decimal dot) Indicates a dot as decimal separator. It is rarely used in Fixed Len formats (usually, the V is used). , (comma) Indicates a comma as decimal separator. It is rarely used in Fixed Len formats (usually, the V is used) S Indicates a sign for a numeric value. It can be in the front or in the back of the value (ex: S9999 or 9999S). When used, a \"+\" or \" \" implies positive, a \"-\" implies negative Z Indicates left padding blanks * Indicates the asterisk character is used for left padding Only the characters \"9\", \"X\" and \"A\" can be repeated. Whenever repetitions are needed, they can be replaced with a reduced version, by putting the number of repetitions between parentheses. Example \"99\" can be indicated as \"9(2)\", \" 999999V99\" can be indicated as \"9(6)V99\" and \"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\" can be indicated as \"X(40)\". When these reserved characters (A, X, Z, etc\u2026) are used in the PIC definition, they must be escaped with a backward slash. Some examples of different PICs are: Source PIC Format Description Result \"12345.67\" 9(6)V99 Number with implied decimal point \"01234567\" \"2125553344\" 999.999.9999 Telephone number with dots between components \"212.555.3344\" \"20180415\" 9999-99-99 A date \"2018-04-15\" \"C1234AAB\" \"X 9999 XXX\" An Argentinian Postal Code \"C 1234 AAB\" \"0876543210-\" \"9(7)V999S\" A negative number with 3 decimals (note the leading and trailing zeros are removed) \"-876543.21\" \"1234567\" \"S9(9)\" A signed 9 digits integer \"+001234567\" \"-12.34\" \"9(6)V99S\" A signed 8 digits number, with sign as suffix and decimal separator \"00001234-\" \"12345.6\" \"ZZ9(5).9\" A number with decimal separator a left padded with blank \" 12345.6\" \"20190506170339\" \"9999-99-99T99:99:99\" A formatted date and time \"2019-05-06T17:03:39\"","title":"Fixed-Length"},{"location":"integrator/myformat/myformat-transformations/#frompic","text":"This transformation takes the input string and processes it according to the received PIC format (see below), returning a new string. Examples: Transformation Input Output fromPIC(\"9(6)V99\") \"00123456\" \"1234.56\" fromPIC(\"9(3).99S\") \"000.01-\" \"-0.01\" fromPIC(\"S9(3).99\") \"+765.43\" \"765.43\" fromPIC(\"S9(3).99\") \" 765.43\" \"765.43\" fromPIC(\"X(10)\") \"Test! \" \"Test!\"","title":"fromPIC"},{"location":"integrator/myformat/myformat-transformations/#topic","text":"This transformation takes the input string and processes it to generate a string compliant with the received PIC format (see below), returning a new string. Examples: Transformation Input Output toPIC(\"9(6)V99\") \"1234.56\" \"00123456\" toPIC(\"9(3).99S\") \"-0.01\" \"000.01-\" toPIC(\"S9(3).99\") \"+765.43\" \"+765.43\" toPIC(\"S9(3).99\") \"765.43\" \"+765.43\" toPIC(\"X(10)\") \"Test!\" \"Test! \"","title":"toPIC"},{"location":"integrator/myformat/myformat-xml/","text":"Format > XML and MX XML files can be used as source or target for a translation. Translations for XML and MX (ISO 20022) share a similar implementation and thus offer similar features. The main difference is that for XML the structure can be anything, while for MX the XML structure must be compliant with the specific MX message type. XML Selector If the message is an XML (including MX messages), the selector uses XPath expressions. All the common syntax for XPath expressions can be used, including simple predicates and attributes in the elements. The paths must always be absolute, though. For example: /Document/SttlmInstrDtls/SttlmDtTm/DtTm selects the value of the element DtTm /Document/PmtDtls/SttlmAmt/@Ccy selects the value of the attribute Ccy in the element SttlmAmt /Document/PmtDtls/Debtor/PstlAddr/AddrLine[1] selects the value of the first occurrence of element AddrLine within PstlAddr /Document/PmtDtls/Debtor/PstlAddr/AddrLine[3] selects the value of the third occurrence of element AddrLine within PstlAddr When the source message in the translation is an XML or MX message, the selector indicates which element text or attribute must be read. For example, a rule having /Document/PmtDtls/SttlmAmt/@Ccy in the source selector will get the value of the currency attribute, and pass that as content for the translation. Analogously, when the target message in the translation is an XML o MX, the selector indicates what element or attribute must be written in the target message. For exampl,e a target selector having /Document/SttlmInstrDtls/SttlmDtTm/DtTm will take the translation content and create in the target XML an element DtTm. All elements in the path parent structure will be created automatically. Predicates The XPath supports predicates to indicate repetition indexes. The predicates can be in any segment of the path. For example, /Document/CstmrCdtTrfInitn/PmtInf[2]/CdtTrfTxInf[3]/CdtrAgt selects the CdtrAgt element in the third repetition of CdtTrfTxInf within the second repetition of PmtInf . In the above examples, all predicates have numbers, meaning they reference a specific instance of the repetitive elements. When the selector is used in rule processing multiple elements, the number can be replaced by a variable name. For example the source selector /Document/CstmrCdtTrfInitn/PmtInf[{m}]/CdtTrfTxInf[{n}]/CdtrAgt will read all instances of the element CdtrAgt , and will propagate a variable named m with the repetition index of PmtInf and a variable n with the repetition of CdtTrfTxInf . Repetition in a foreach is 1 based, meaning the first read PmtInf will have n=1 . These repetition variables can then be used in the target selector, to map each repetitive 22F to a specific repetitive element in the target message. Prefilled target message When translating into XML or MX, sometimes it is necessary to apply a translation into existing content. This can be accomplished easily, passing your own instances of the reader and writer to the engine. // Mapping definition MappingTable t = new MappingTable ( FileFormat . MT , FileFormat . MX ); rules . add ( new MappingRule ( \"/Document/Foo/Amount\" , \"/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/Amt/EqvtAmt/Amt\" , WriteMode . CREATE )); // existing MX message MxPain00100103 mx = new MxPain00100103 (); mx . setBusinessHeader ( new BusinessHeader ()); mx . getBusinessHeader (). setBusinessApplicationHeader ( new BusinessApplicationHeaderV01 ()); mx . getBusinessHeader (). getBusinessApplicationHeader (). setBizMsgIdr ( \"1234\" ); mx . setCstmrCdtTrfInitn ( new CustomerCreditTransferInitiationV03 ()); mx . getCstmrCdtTrfInitn (). setGrpHdr ( new GroupHeader32 ()); mx . getCstmrCdtTrfInitn (). getGrpHdr (). setMsgId ( \"5678\" ); // writer initialized with the MX message MxWriter preFilledWriter = new MxWriter ( mx ); // sample source message MT103 mt = new MT103 (); mt . append ( new Field20 ( \"XXX\" )); mt . append ( new Field32A ( \"151019USD1234,5\" )); MtReader mtReader = new MtReader ( mt ); // translation call passing a pre-filled MX writer instance MyFormatEngine . translate ( mtReader , preFilledWriter , t . rules ); MX to MX case When translating from MX to MX, the source and target messages must be of the same message type. Then the mxType for output message and path validation should be setup like below: MappingTable t = new MappingTable ( FileFormat . MX , FileFormat . MX ); t . add ( new MappingRule ( MxTypePacs . pacs_008_001_08 . mxId (). id (), SetupCommand . mxType . name (), WriteMode . SETUP )); t . add ( new MappingRule ( \"/Document/CstmrCdtTrfInitn/GrpHdr/MsgId\" , \"/Document/FIToFICstmrCdtTrf/GrpHdr/MsgId\" )); t . add ( new MappingRule ( \"FOREACH(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf, ../DbtrAcct/Id/IBAN)\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf[1]/PmtId/TxId\" , WriteMode . APPEND )); RulePathValidator rulePathValidator = new RulePathValidator () . withSourceSchemaProvider ( MxTypePain . pain_001_001_03 ) . withTargetSchemaProvider ( MxTypePacs . pacs_008_001_08 ); List < String > validate = MappingValidator . validate ( t . getRules (), t , rulePathValidator );","title":"Format > XML and MX"},{"location":"integrator/myformat/myformat-xml/#format-xml-and-mx","text":"XML files can be used as source or target for a translation. Translations for XML and MX (ISO 20022) share a similar implementation and thus offer similar features. The main difference is that for XML the structure can be anything, while for MX the XML structure must be compliant with the specific MX message type.","title":"Format > XML and MX"},{"location":"integrator/myformat/myformat-xml/#xml-selector","text":"If the message is an XML (including MX messages), the selector uses XPath expressions. All the common syntax for XPath expressions can be used, including simple predicates and attributes in the elements. The paths must always be absolute, though. For example: /Document/SttlmInstrDtls/SttlmDtTm/DtTm selects the value of the element DtTm /Document/PmtDtls/SttlmAmt/@Ccy selects the value of the attribute Ccy in the element SttlmAmt /Document/PmtDtls/Debtor/PstlAddr/AddrLine[1] selects the value of the first occurrence of element AddrLine within PstlAddr /Document/PmtDtls/Debtor/PstlAddr/AddrLine[3] selects the value of the third occurrence of element AddrLine within PstlAddr When the source message in the translation is an XML or MX message, the selector indicates which element text or attribute must be read. For example, a rule having /Document/PmtDtls/SttlmAmt/@Ccy in the source selector will get the value of the currency attribute, and pass that as content for the translation. Analogously, when the target message in the translation is an XML o MX, the selector indicates what element or attribute must be written in the target message. For exampl,e a target selector having /Document/SttlmInstrDtls/SttlmDtTm/DtTm will take the translation content and create in the target XML an element DtTm. All elements in the path parent structure will be created automatically.","title":"XML Selector"},{"location":"integrator/myformat/myformat-xml/#predicates","text":"The XPath supports predicates to indicate repetition indexes. The predicates can be in any segment of the path. For example, /Document/CstmrCdtTrfInitn/PmtInf[2]/CdtTrfTxInf[3]/CdtrAgt selects the CdtrAgt element in the third repetition of CdtTrfTxInf within the second repetition of PmtInf . In the above examples, all predicates have numbers, meaning they reference a specific instance of the repetitive elements. When the selector is used in rule processing multiple elements, the number can be replaced by a variable name. For example the source selector /Document/CstmrCdtTrfInitn/PmtInf[{m}]/CdtTrfTxInf[{n}]/CdtrAgt will read all instances of the element CdtrAgt , and will propagate a variable named m with the repetition index of PmtInf and a variable n with the repetition of CdtTrfTxInf . Repetition in a foreach is 1 based, meaning the first read PmtInf will have n=1 . These repetition variables can then be used in the target selector, to map each repetitive 22F to a specific repetitive element in the target message.","title":"Predicates"},{"location":"integrator/myformat/myformat-xml/#prefilled-target-message","text":"When translating into XML or MX, sometimes it is necessary to apply a translation into existing content. This can be accomplished easily, passing your own instances of the reader and writer to the engine. // Mapping definition MappingTable t = new MappingTable ( FileFormat . MT , FileFormat . MX ); rules . add ( new MappingRule ( \"/Document/Foo/Amount\" , \"/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf/Amt/EqvtAmt/Amt\" , WriteMode . CREATE )); // existing MX message MxPain00100103 mx = new MxPain00100103 (); mx . setBusinessHeader ( new BusinessHeader ()); mx . getBusinessHeader (). setBusinessApplicationHeader ( new BusinessApplicationHeaderV01 ()); mx . getBusinessHeader (). getBusinessApplicationHeader (). setBizMsgIdr ( \"1234\" ); mx . setCstmrCdtTrfInitn ( new CustomerCreditTransferInitiationV03 ()); mx . getCstmrCdtTrfInitn (). setGrpHdr ( new GroupHeader32 ()); mx . getCstmrCdtTrfInitn (). getGrpHdr (). setMsgId ( \"5678\" ); // writer initialized with the MX message MxWriter preFilledWriter = new MxWriter ( mx ); // sample source message MT103 mt = new MT103 (); mt . append ( new Field20 ( \"XXX\" )); mt . append ( new Field32A ( \"151019USD1234,5\" )); MtReader mtReader = new MtReader ( mt ); // translation call passing a pre-filled MX writer instance MyFormatEngine . translate ( mtReader , preFilledWriter , t . rules );","title":"Prefilled target message"},{"location":"integrator/myformat/myformat-xml/#mx-to-mx-case","text":"When translating from MX to MX, the source and target messages must be of the same message type. Then the mxType for output message and path validation should be setup like below: MappingTable t = new MappingTable ( FileFormat . MX , FileFormat . MX ); t . add ( new MappingRule ( MxTypePacs . pacs_008_001_08 . mxId (). id (), SetupCommand . mxType . name (), WriteMode . SETUP )); t . add ( new MappingRule ( \"/Document/CstmrCdtTrfInitn/GrpHdr/MsgId\" , \"/Document/FIToFICstmrCdtTrf/GrpHdr/MsgId\" )); t . add ( new MappingRule ( \"FOREACH(/Document/CstmrCdtTrfInitn/PmtInf/CdtTrfTxInf, ../DbtrAcct/Id/IBAN)\" , \"/Document/FIToFICstmrCdtTrf/CdtTrfTxInf[1]/PmtId/TxId\" , WriteMode . APPEND )); RulePathValidator rulePathValidator = new RulePathValidator () . withSourceSchemaProvider ( MxTypePain . pain_001_001_03 ) . withTargetSchemaProvider ( MxTypePacs . pacs_008_001_08 ); List < String > validate = MappingValidator . validate ( t . getRules (), t , rulePathValidator );","title":"MX to MX case"},{"location":"integrator/sdk/","text":"Prowide Integrator SDK - Overview The Prowide Integrator SDK is the cornerstone library for the Prowide Integrator suite. It provides a set of handy APIs to handle MT messages and interact with SWIFT networks and services, such as SWIFT Alliance Access (SAA). The key features provided by the SDK are: API to create and parse the DataPDU (SAA XML v2 message envelope) LAU signing and verification for SAA integration Multipurpose BIC Dictionary Customizable TXT and HTML expanded printout for MT messages MtPath to simplify content selection in MT (FIN) messages Javadoc Online javadoc Prowide Integrator SDK Javadoc SRU2023-9.4.x","title":"Prowide Integrator SDK - Overview"},{"location":"integrator/sdk/#prowide-integrator-sdk-overview","text":"The Prowide Integrator SDK is the cornerstone library for the Prowide Integrator suite. It provides a set of handy APIs to handle MT messages and interact with SWIFT networks and services, such as SWIFT Alliance Access (SAA). The key features provided by the SDK are: API to create and parse the DataPDU (SAA XML v2 message envelope) LAU signing and verification for SAA integration Multipurpose BIC Dictionary Customizable TXT and HTML expanded printout for MT messages MtPath to simplify content selection in MT (FIN) messages","title":"Prowide Integrator SDK - Overview"},{"location":"integrator/sdk/#javadoc","text":"Online javadoc Prowide Integrator SDK Javadoc SRU2023-9.4.x","title":"Javadoc"},{"location":"integrator/sdk/sdk-bicdirectory/","text":"BIC Directory (import and query) In order to perform multiple processes, it is required to access some BIC directory that contains a complete BIC codes database. This information is mainly used by the validation module to perform BIC code validation, but it is also available for any suitable use to the applications by means of Java API. The data is distributed as an independent jar file named pw-integrator-data-1.X.X.jar . The jar contains the BIC directory in binary form, packaged into an embedded Derby database. The main entry point to access and query the directory is the class: http://api.prowidesoftware.com/javadoc/SRU2023-9/module-sdk/com/prowidesoftware/swift/BICDirectory.html/ IMPORTANT : The data jar provided with the package is just an example to get started. Since the BIC codes are monthly updated by SWIFT, the information in the pw-integrator-data-1.X.X.jar file should be updated often, by replacing the file with a fresher one. It is under the customer responsibility of keeping the directory updated to the latest version of BIC reference information distributed by swift. Updating the BIC Directory The tool to update the BIC directory is the BICImporter process. This process will create a new BIC directory jar file by reading the BIC data from an input file. This item is enclosed in the SDK jar file, and should be executed, by command line, as follows: java -cp CLASSPATH com.prowidesoftware.swift.app.BICImporter TXT_FILE Where CLASSPATH is the SDK jar and dependencies. In this case: * pw-swift-integrator-sdk * commons-lang3 * derby Note that if you downloaded Integrator from a download link, just use \"*;lib/*\" as CLASSPATH. Any other case just include the 3 jar's paths (i.e. \"pw-swift-integrator-sdk-SRU2022-9.3.13.jar;lib/commons-lang3-3.12.0.jar;lib/derby-10.12.1.1.jar\" ) And TXT_FILE is the path to the BIC directory file to import (i.e. FI_201806.txt ). Please see the Supported data files for further details. After the import run, a new pw-swift-integrator-data-1.X.X.jar will be created at ./ and should be used to replace the old one from your project setup. Run example and expected output: $ java -cp \"*;lib/*\" com.prowidesoftware.swift.app.BICImporter FI_201806.txt BICImporter: starting FI_201806.txt file import... BICImporter: detected file format BIC DIRECTORY 2018 BICImporter: initializing a new database BICImporter: starting import process BICImporter: processed 100 so far BICImporter: processed 200 so far ... ... BICImporter: processed 5005 so far Shutdown result: Derby system shutdown. BICImporter: 4999 records imported, 6 records ignored, in 16122ms Where the 4999 count is for the records marked with add (A), modification (M) or update (U) in the imported file, and the 6 count is for the records marked with delete (D) in the imported file. Since we create a fresh new directory each time, there is no need to delete pre-existing data and the deletion indication is just ignored. For the BIC Plus the non-operational records in the file will also be counted as ignored. Please notice that these BIC upgrades are available online at swiftrefdata.com to the BIC directory online subscribers. The data file is included with your Integrator download just for convenience, but you need to keep the information up to date, downloading and importing the new BIC information monthly published by SWIFT to subscribers. Supported data files The BIC Directory and in particular the BICImporter tool seamlessly support data files from any of these sources: Legacy BIC Directory: FI_YYYYMM.txt BIC Directory 2018: BICDIR2018_V1_FULL_YYYYMMDD.txt BIC Plus: BICPLUS_V1_FULL_YYYYMMDD.txt The catalog database is generated from scratch on each import run, so the full (no delta) files are required. Regarding the new BIC Plus support, since the Prowide Integrator BIC directory is used for BICs lookup and validation, when importing BIC codes from the extended BIC Plus files, only the operationally active records are loaded. The data files can be downloaded from https://www.swiftrefdata.com/ upon subscription to the SWIFT Ref services from SWIFT. Using a custom database The IBICDirectory interface can be implemented to provide a custom BIC directory. The default implementation is the BICDirectory class , which uses the embedded Derby database included in the pw-swift-integrator-data-1.X.X.jar file. To use your own BIC database, you can implement the IBICDirectory interface and provide your own implementation to the BICDirectory class. For example, to use a MySQL database. The custom implementation then can be injected as needed in the relevant features. For example, to use the custom implementation in the expanded printout, you can pass the custom implementation to the PrintoutWriter constructor. Then to use a custom BIC directory in the validation module, you can set your own instance to the ValidationConfiguration in the ValidationEngine . Validating the generated pw-integrator-data-1.X.X.jar Once the update process is complete, is it possible to verify the result. For that purpose a tool called BICQuery is provided. It can be used as indicated below: $ java -cp \"*;lib/*\" com.prowidesoftware.swift.app.BICQuery 'AFABAFKA' row,code,branch,branchInformation,cityHeading,countryName,extraInformation,institutionName,location,physicalAddressPart1,physicalAddressPart2,physicalAddressPart3,physicalAddressPart4,POBCountryName,POBLocation,POBNumber,subtypeIndication,tagIdentifier,valueAddedServices 1, AFABAFKA, XXX, , KABUL, AFGHANISTAN, CK, ARIAN BANK, 5810 KABUL, HOUSE NO.2, HANZALA MOSQUE ROAD, QALAI FATH, , , , , , SUPE, FIN Alternatively, there are some options for running this command. Use -short arg for an abbreviated result: $ java -cp \"*;lib/*\" com.prowidesoftware.swift.app.BICQuery '-short' 'AFABAFKA' 1> AFABAFKAXXX Use % arg for a SQL like type query: $ java -cp \"*;lib/*\" com.prowidesoftware.swift.app.BICQuery 'AAA%' row,code,branch,branchInformation,cityHeading,countryName,extraInformation,institutionName,location,physicalAddressPart1,physicalAddressPart2,physicalAddressPart3,physicalAddressPart4,POBCountryName,POBLocation,POBNumber,subtypeIndication,tagIdentifier,valueAddedServices 1, AAAARSBG, XXX, , BEOGRAD, SERBIA, CB, TELENOR BANKA AD, 11070 BEOGRAD, OMLADINSKIH BRIGADA 90V, , , , , , , SUPE, EB+FINTG+ 2, AAACKWKW, XXX, , KUWAIT, KUWAIT, CK, ALMUZAINI EXCHANGE COMPANY KSC (CLOSED), 13022 KUWAIT, OPPOSITE PUBLIC LIBRARY, ALI AL SALEM STREET, MUBARAKIA, SAFAT, , KUWAIT, 13022 KUWAIT, POB 2156, SUPE, FIN 3, AAADFRP1, XXX, , PARIS, FRANCE, NP, ASSET ALLOCATION ADVISORS SA, 75008 PARIS, 3, AVENUE HOCHE, CHEZ NSM, CHEZ NSM, , , , , NSWB, 4, AAAJBG21, XXX, , PLOVDIV, BULGARIA, N2, ARCUS ASSET MANAGEMENT JSC, 4000 PLOVDIV, BUSINESS CENTER LEGIS, 152, 6TH OF SEPTEMBER BLVD., , , , , , NSWB, 5, AAALSARI, ALK, (EASTERN AREA ALKHOBAR), ALKHOBAR, SAUDI ARABIA, BRA CR, SAUDI HOLLANDI BANK, ALKHOBAR, , , , , , , , SUPE, FINTG+ 6, AAASTHB1, XXX, , BANGKOK, THAILAND, NB, ASIA PLUS SECURITIES PUBLIC COMPANY LIMITED, BANGKOK 10120, SATHORN CITY TOWER, 3RD/1 FLOOR, 175 SOUTH SATHORN ROAD, , , , , NSWB, Note: depending on your SQL engine, you would need to use ? for the same purpose.","title":"BIC directory"},{"location":"integrator/sdk/sdk-bicdirectory/#bic-directory-import-and-query","text":"In order to perform multiple processes, it is required to access some BIC directory that contains a complete BIC codes database. This information is mainly used by the validation module to perform BIC code validation, but it is also available for any suitable use to the applications by means of Java API. The data is distributed as an independent jar file named pw-integrator-data-1.X.X.jar . The jar contains the BIC directory in binary form, packaged into an embedded Derby database. The main entry point to access and query the directory is the class: http://api.prowidesoftware.com/javadoc/SRU2023-9/module-sdk/com/prowidesoftware/swift/BICDirectory.html/ IMPORTANT : The data jar provided with the package is just an example to get started. Since the BIC codes are monthly updated by SWIFT, the information in the pw-integrator-data-1.X.X.jar file should be updated often, by replacing the file with a fresher one. It is under the customer responsibility of keeping the directory updated to the latest version of BIC reference information distributed by swift.","title":"BIC Directory (import and query)"},{"location":"integrator/sdk/sdk-bicdirectory/#updating-the-bic-directory","text":"The tool to update the BIC directory is the BICImporter process. This process will create a new BIC directory jar file by reading the BIC data from an input file. This item is enclosed in the SDK jar file, and should be executed, by command line, as follows: java -cp CLASSPATH com.prowidesoftware.swift.app.BICImporter TXT_FILE Where CLASSPATH is the SDK jar and dependencies. In this case: * pw-swift-integrator-sdk * commons-lang3 * derby Note that if you downloaded Integrator from a download link, just use \"*;lib/*\" as CLASSPATH. Any other case just include the 3 jar's paths (i.e. \"pw-swift-integrator-sdk-SRU2022-9.3.13.jar;lib/commons-lang3-3.12.0.jar;lib/derby-10.12.1.1.jar\" ) And TXT_FILE is the path to the BIC directory file to import (i.e. FI_201806.txt ). Please see the Supported data files for further details. After the import run, a new pw-swift-integrator-data-1.X.X.jar will be created at ./ and should be used to replace the old one from your project setup. Run example and expected output: $ java -cp \"*;lib/*\" com.prowidesoftware.swift.app.BICImporter FI_201806.txt BICImporter: starting FI_201806.txt file import... BICImporter: detected file format BIC DIRECTORY 2018 BICImporter: initializing a new database BICImporter: starting import process BICImporter: processed 100 so far BICImporter: processed 200 so far ... ... BICImporter: processed 5005 so far Shutdown result: Derby system shutdown. BICImporter: 4999 records imported, 6 records ignored, in 16122ms Where the 4999 count is for the records marked with add (A), modification (M) or update (U) in the imported file, and the 6 count is for the records marked with delete (D) in the imported file. Since we create a fresh new directory each time, there is no need to delete pre-existing data and the deletion indication is just ignored. For the BIC Plus the non-operational records in the file will also be counted as ignored. Please notice that these BIC upgrades are available online at swiftrefdata.com to the BIC directory online subscribers. The data file is included with your Integrator download just for convenience, but you need to keep the information up to date, downloading and importing the new BIC information monthly published by SWIFT to subscribers.","title":"Updating the BIC Directory"},{"location":"integrator/sdk/sdk-bicdirectory/#supported-data-files","text":"The BIC Directory and in particular the BICImporter tool seamlessly support data files from any of these sources: Legacy BIC Directory: FI_YYYYMM.txt BIC Directory 2018: BICDIR2018_V1_FULL_YYYYMMDD.txt BIC Plus: BICPLUS_V1_FULL_YYYYMMDD.txt The catalog database is generated from scratch on each import run, so the full (no delta) files are required. Regarding the new BIC Plus support, since the Prowide Integrator BIC directory is used for BICs lookup and validation, when importing BIC codes from the extended BIC Plus files, only the operationally active records are loaded. The data files can be downloaded from https://www.swiftrefdata.com/ upon subscription to the SWIFT Ref services from SWIFT.","title":"Supported data files"},{"location":"integrator/sdk/sdk-bicdirectory/#using-a-custom-database","text":"The IBICDirectory interface can be implemented to provide a custom BIC directory. The default implementation is the BICDirectory class , which uses the embedded Derby database included in the pw-swift-integrator-data-1.X.X.jar file. To use your own BIC database, you can implement the IBICDirectory interface and provide your own implementation to the BICDirectory class. For example, to use a MySQL database. The custom implementation then can be injected as needed in the relevant features. For example, to use the custom implementation in the expanded printout, you can pass the custom implementation to the PrintoutWriter constructor. Then to use a custom BIC directory in the validation module, you can set your own instance to the ValidationConfiguration in the ValidationEngine .","title":"Using a custom database"},{"location":"integrator/sdk/sdk-bicdirectory/#validating-the-generated-pw-integrator-data-1xxjar","text":"Once the update process is complete, is it possible to verify the result. For that purpose a tool called BICQuery is provided. It can be used as indicated below: $ java -cp \"*;lib/*\" com.prowidesoftware.swift.app.BICQuery 'AFABAFKA' row,code,branch,branchInformation,cityHeading,countryName,extraInformation,institutionName,location,physicalAddressPart1,physicalAddressPart2,physicalAddressPart3,physicalAddressPart4,POBCountryName,POBLocation,POBNumber,subtypeIndication,tagIdentifier,valueAddedServices 1, AFABAFKA, XXX, , KABUL, AFGHANISTAN, CK, ARIAN BANK, 5810 KABUL, HOUSE NO.2, HANZALA MOSQUE ROAD, QALAI FATH, , , , , , SUPE, FIN Alternatively, there are some options for running this command. Use -short arg for an abbreviated result: $ java -cp \"*;lib/*\" com.prowidesoftware.swift.app.BICQuery '-short' 'AFABAFKA' 1> AFABAFKAXXX Use % arg for a SQL like type query: $ java -cp \"*;lib/*\" com.prowidesoftware.swift.app.BICQuery 'AAA%' row,code,branch,branchInformation,cityHeading,countryName,extraInformation,institutionName,location,physicalAddressPart1,physicalAddressPart2,physicalAddressPart3,physicalAddressPart4,POBCountryName,POBLocation,POBNumber,subtypeIndication,tagIdentifier,valueAddedServices 1, AAAARSBG, XXX, , BEOGRAD, SERBIA, CB, TELENOR BANKA AD, 11070 BEOGRAD, OMLADINSKIH BRIGADA 90V, , , , , , , SUPE, EB+FINTG+ 2, AAACKWKW, XXX, , KUWAIT, KUWAIT, CK, ALMUZAINI EXCHANGE COMPANY KSC (CLOSED), 13022 KUWAIT, OPPOSITE PUBLIC LIBRARY, ALI AL SALEM STREET, MUBARAKIA, SAFAT, , KUWAIT, 13022 KUWAIT, POB 2156, SUPE, FIN 3, AAADFRP1, XXX, , PARIS, FRANCE, NP, ASSET ALLOCATION ADVISORS SA, 75008 PARIS, 3, AVENUE HOCHE, CHEZ NSM, CHEZ NSM, , , , , NSWB, 4, AAAJBG21, XXX, , PLOVDIV, BULGARIA, N2, ARCUS ASSET MANAGEMENT JSC, 4000 PLOVDIV, BUSINESS CENTER LEGIS, 152, 6TH OF SEPTEMBER BLVD., , , , , , NSWB, 5, AAALSARI, ALK, (EASTERN AREA ALKHOBAR), ALKHOBAR, SAUDI ARABIA, BRA CR, SAUDI HOLLANDI BANK, ALKHOBAR, , , , , , , , SUPE, FINTG+ 6, AAASTHB1, XXX, , BANGKOK, THAILAND, NB, ASIA PLUS SECURITIES PUBLIC COMPANY LIMITED, BANGKOK 10120, SATHORN CITY TOWER, 3RD/1 FLOOR, 175 SOUTH SATHORN ROAD, , , , , NSWB, Note: depending on your SQL engine, you would need to use ? for the same purpose.","title":"Validating the generated pw-integrator-data-1.X.X.jar"},{"location":"integrator/sdk/sdk-datapdu/","text":"DataPDU (XML v2) The Protocol Data Units (DataPDU) is an XML wrapper used in transmission between message partners and SWIFT Alliance Access (SAA). It can seamlessly wrap both MT and MX messages. The structure is also known as XML V2. The root element of the XML v2 structure is a DataPDU element, where the children elements are the Revision , the Header and the Body . When the wrapper is built for an MX message, the Body element contains the complete ISO 20022 message with the optional AppHdr and Document . While for MT messages, since MT format is not XML-based, the FIN content is put into the Body element as a plain string base64 encoded. From the XML v2 perspective, the Body is always a SwAny element, not defined in the SAA schema. The same DataPDU is also used for transmission reports (ACK/NAK). There are multiple revisions of the SAA schemas for the DataPDU structure. The library supports several versions, and more can be added on demand. The provided API gives an option to use a default version or a specific one, by using classes in the specific version package. The following sections describe different use cases and the relevant API. Inbound DataPDU To process inbound DataPDU files received from SAA the easiest way is to parse the content with the AbstractDataPDU class: DataPDUContentParser parser = AbstractDataPDU . parse ( xml ); if ( parser . type () == DataPDUType . Message_MX ) { AbstractMX mx = parser . extractMx (); } Since SAA supports multiple revisions of the schemas, the parser above will automatically detect the schema version and the returned object will be a specific instance for the detected revision. The DataPDUContentParser is an interface implemented by all revision models. Thus, you can parse the main elements of the DataPDU and extract the payload message without bothering about the specific revision that is received from SAA. With the parser, you can check the DataPDU type, and extract the MX or MT message. In the above example the mx object will be a specific message type instance, such as MxPacs00800108 with the header and document parsed from the DataPDU. If you don\u2019t care if it is an MT o MX, you can also run a generic extraction like this: DataPDUContentParser parser = AbstractDataPDU . parse ( xml ); AbstractSwiftMessage msg = parser . extractMessage (); Where the extracted message will be either an MX, an MT or even a Service21 message (ACK) id the DataPDU is a Transmission Report. Finally, if more specific elements of the DataPDU structure have to be read, you can cast the generic DataPDUContentParser to a specific implementation instance. In order to do this, you have to know in advance the specific version, or you can use the getRevision to get it. if ( \"2.0.13\" . equals ( parser . getRevision ) { DataPDUParser parserV13 = ( DataPDUParser ) parser ; Priority p = parserV13 . getHeader (). getMessage (). getNetworkInfo (). getPriority (); } Where the DataPDUParser is a class in the specific implementation in the com.prowidesoftware.swift.wrappers.saa.v_2_0_14 package. Similar classes are available for the supported revisions. The AbstractDataPDU parser just checks the enclosed revision in the XML and delegates to the specific implementation. Using a fixed version of the DataPDU If you need to access the DataPDU content, besides extracting the MT/MX payload and you receive many different versions from your interfaces, you could also use the latest revision to parse all of them. So that you avoid casting the model to the different versions. For example, if you are using the latest revision, you can use the following code to parse: DataPDUParser dataPdu = com . prowidesoftware . swift . wrappers . saa . v2_0_14 . DataPDUParser . parse ( xml ); Setting a specific DN to the message There's the possibility that you need to use the DN Id instead of BIC one, in those cases, you can use the following code: MxSwiftMessage mx = new MxSwiftMessage ( xml ); DataPDUWriter dataPDUWriter = new DataPDUWriter ( mx ); dataPDUWriter . getHeader (). getMessage (). getSender (). setDN ( new BIC ( mx . getSender ()). distinguishedName ()); dataPDUWriter . getHeader (). getMessage (). getReceiver (). setDN ( new BIC ( mx . getReceiver ()). distinguishedName ()); final String dataPDU = dataPDUWriter . xml (); Stripping the binary prefix When calling any of the DataPDU parsing options make sure your XML string does not contain the binary prefix. If it does you can remove this prefix from the XML string before calling the parsing methods. For example: DataPDUParser . parse ( XmlV2Utils . stripBinaryPrefix ( xml )); Find more information for the binary prefix below. Outbound DataPDU To create an outbound DataPDU file to be sent to SAA the easiest way is to use the DataPDUWriter class. Since multiple versions of the DataPDU structure exist for SAA, there is a DataPDUWriter for each in the specific version packages, such as com.prowidesoftware.swift.wrappers.saa.v_2_0_14 . Then, multiple constructor options are available, each for a different purpose. For example, to build a DataPDU completely from scratch you can use: DataPDUWriter writer = new DataPDUWriter (); writer . setHeader ( new Header ()); writer . getHeader (). setMessage ( new Message ()); writer . getHeader (). getMessage (). setSenderReference ( \"senderRef123\" ); writer . getHeader (). getMessage (). setFormat ( \"File\" ); As you can see in the above example, you have a comprehensive setters API to build any element of the DataPDU. Then the xml() method can be used on the writer to generate the actual XML content of the DataPDU. When sending MT or MX messages as the payload of a DataPDU envelope, specific constructors are provided, such as: MtSwiftMessage mt = new MtSwiftMessage ( fin ); DataPDUWriter w = new DataPDUWriter ( mt )); final String xml = w . xml (); And the same for Mx. The above will automatically marshall the MT or MX payload into the generated XML. For MY messages, it will encode the message body in base 64. Where for MX, the AppHdr and Document elements will be enclosed into the Body of the DataPDU. Meaning, this constructor will automatically generate the Body element of the DataPDU from the parameter message. If the use case requires creating a new DataPDU by modifying an existing XML, the writer has also constructor options from an XML string and from a DataPDUParser . Thus, you can use the parser to read an existing XML structure, and then create a writer out of it for modifications. DataPDUWriter factory When the writer has to be created from and existing XML in order to do modifications or content enrichment, a factory can be used to create the specific version of the writer automatically for a given XML input: AbstractDataPDU dataPDUWriter = DataPDUWriterFactory . getDataPDUWriter ( xml ); writer . getHeader (). getMessage (). setSenderReference ( \"senderRef123\" ); ... final String dataPDU = dataPDUWriter . xml (); The factory extracts the revision number from the given XML string and returns a specific DataPDUWriter instance (subclass of the AbstractDataPDU ) corresponding to that extracted revision. If the revision number does not match any of the supported versions or the XML is null, it defaults to the latest. MT encoded content When MT messages are wrapped into the XML, the MT content is put in the Body as a single base64 encoded string. This encoded string could have: The complete MT message including headers, text block and trailers. Just the text block (block 4) By default, the writer will write the whole message content in the encoded string when creating the Body element. The API accepts an optional configuration class where you can change this default behavior and indicate whether in your environment the XML for MT should be created with only the block 4 encoded in the Body element. As for the parser, the encoded Body will be autodetected. When the complete MT content is present, that will be parsed into the returned MT instance. And if only the block 4 is encoded in the Body element, the headers and trailer will be recreated by the parser using information from other elements in the XML. MX custom namespaces When constructing an MX message, the DataPDUWriter automatically incorporates the default namespaces for the MX message, specifically h for Header and Doc for Document . However, to override this default behavior, one can specify a desired namespace. Alternatively, setting the namespace to null can exclude it from being included. Check the code below: MxCamt00300105 mxCamt00300105 = MxCamt00300105 . parse ( your_mx ); DataPDUWriter w = new DataPDUWriter ( mxCamt00300105 , \"REF VAL\" , \"FOOZLULL\" , \"FOOZLULL\" ); final XmlV2Configuration conf = new XmlV2Configuration (); MxWriteParams mxHeaderWriteParams = new MxWriteParams (); mxHeaderWriteParams . prefix = \"header\" ; conf . setMxHeaderWriteParams ( mxHeaderWriteParams ); MxWriteParams mxDocumentWriteParams = new MxWriteParams (); mxDocumentWriteParams . prefix = mxCamt00300105 . getBusinessProcess (); conf . setMxDocumentWriteParams ( mxDocumentWriteParams ); final String xml = w . xml ( conf ); This will produce the following XML: 2.0.13 REF VAL camt.003.001.05 MX Input FOOZLULLAXXX FOOZLULLXXXX ... ... 2015-08-27T08:59:00Z ... TransmissionReport The DataPDU is also used by SAA to return transmission reports. For this purpose, the DataPDU/Header structure is a choice that can hold a simple Message but also a Transmission Report and other structures. When the parser is called and the DataPDU/Header/TransmissionReport is found with an embedded MT , the parsed message result will be a FIN ACK/NAK as the following. Meaning a call like this: DataPDUContentParser parser = AbstractDataPDU . parse ( xml ); AbstractSwiftMessage msg = parser . extractMessage (); Will extract into the AbstractSwiftMessage a message payload like this: {1:F21AAAAGHA0AXXX241764}{4:{177:19101921138}{451:0}}{1:F01AAAAGHA0AXXX241764}{2:I103BBBBGHA0XXXXN}{3:{121:8a0c1649-efa9-42a6-8dcf-8df8c9b2c99f}}{4: :20:REFERENCE123 :23B:CRED :26T:123 :32A:191019EUR1, :50A:/1234456 AAAAGHA0 :59:/234455 Foo :71A:OUR -} Where you have the service message (21) with the date time and ACK fields, followed by the original message. You can then use the original message to do the internal matching in your application to reconcile the ACK and the original sent message. A similar Transmission Report is generated by SAA to acknowledge MX messages. In this case, the result of the parser is still a FIN service 21 message like this: {1:F21SPXAINJJAA05151}{4:{177:1102111528}{451:0}{108:PPTEI00000001013}} Which is just a service message (21) without any attached original message. Since the original message was an MX. In this scenario, if the MUR is present in the XML v2, you will find it in the field 108, and you can use it to match the original MX sent. The original MX message is not present in the result because there is no equivalence in ISO 20022 for the FIN service messages service type 21. For MT acknowledges, we can, because FIN defines such a structure where you have a service message plus an original message attached. But there is no message model to hold an ACK along an original MX, that structure is the actual DataPDU. Therefore, if you have to process ACK/NAK for MX, and you need the original message parsed because the MUR is not enough for the reconciliation, you can still accomplish that with the API like this: DataPDUParser parser = AbstractDataPDU . parse ( xml ); parser . getHeader (). getTransmissionReport (). getMessage (). getBody (); More info on ACK https://dev.prowidesoftware.com/latest/open-source/core/mt-ack/ DataPDU binary prefix (XmlV2Utils) The DataPDU is a regular UTF-8 encoded XML, but it can be preceded by a binary prefix with a digital signature. The Xmlv2Utils class is the main entry point to handle this binary prefix for the DataPDU XMLs. This prefix is actually obsolete in SAA, but only supported for backward compatibility. When reading an XML the XmlV2Utils class will strip the prefix if present. And when writing an XML a parameter is available to indicate whether the prefix must be generated or not. For inbound messages, to convert an XML into a message, you just need to call: AbstractSwiftMessage message = XmlV2Utils . readMessage ( xml ); The message variable will contain as result the embedded MT or MX message. The implementation will just strip the prefix if present, and will call the DataPDU parsing API to extract the enclosed message. For outbound messages, the XmlV2Utils class provides additional methods to select the usage of the binary prefix. Notice however when the flag to generate the binary prefix is true, this prefix will be generated with just the message size, but the signature will be filled with nulls. If you need to send outbound messages to SAA with a valid computed signature in the binary prefix, check the section describing LAU.","title":"DataPDU"},{"location":"integrator/sdk/sdk-datapdu/#datapdu-xml-v2","text":"The Protocol Data Units (DataPDU) is an XML wrapper used in transmission between message partners and SWIFT Alliance Access (SAA). It can seamlessly wrap both MT and MX messages. The structure is also known as XML V2. The root element of the XML v2 structure is a DataPDU element, where the children elements are the Revision , the Header and the Body . When the wrapper is built for an MX message, the Body element contains the complete ISO 20022 message with the optional AppHdr and Document . While for MT messages, since MT format is not XML-based, the FIN content is put into the Body element as a plain string base64 encoded. From the XML v2 perspective, the Body is always a SwAny element, not defined in the SAA schema. The same DataPDU is also used for transmission reports (ACK/NAK). There are multiple revisions of the SAA schemas for the DataPDU structure. The library supports several versions, and more can be added on demand. The provided API gives an option to use a default version or a specific one, by using classes in the specific version package. The following sections describe different use cases and the relevant API.","title":"DataPDU (XML v2)"},{"location":"integrator/sdk/sdk-datapdu/#inbound-datapdu","text":"To process inbound DataPDU files received from SAA the easiest way is to parse the content with the AbstractDataPDU class: DataPDUContentParser parser = AbstractDataPDU . parse ( xml ); if ( parser . type () == DataPDUType . Message_MX ) { AbstractMX mx = parser . extractMx (); } Since SAA supports multiple revisions of the schemas, the parser above will automatically detect the schema version and the returned object will be a specific instance for the detected revision. The DataPDUContentParser is an interface implemented by all revision models. Thus, you can parse the main elements of the DataPDU and extract the payload message without bothering about the specific revision that is received from SAA. With the parser, you can check the DataPDU type, and extract the MX or MT message. In the above example the mx object will be a specific message type instance, such as MxPacs00800108 with the header and document parsed from the DataPDU. If you don\u2019t care if it is an MT o MX, you can also run a generic extraction like this: DataPDUContentParser parser = AbstractDataPDU . parse ( xml ); AbstractSwiftMessage msg = parser . extractMessage (); Where the extracted message will be either an MX, an MT or even a Service21 message (ACK) id the DataPDU is a Transmission Report. Finally, if more specific elements of the DataPDU structure have to be read, you can cast the generic DataPDUContentParser to a specific implementation instance. In order to do this, you have to know in advance the specific version, or you can use the getRevision to get it. if ( \"2.0.13\" . equals ( parser . getRevision ) { DataPDUParser parserV13 = ( DataPDUParser ) parser ; Priority p = parserV13 . getHeader (). getMessage (). getNetworkInfo (). getPriority (); } Where the DataPDUParser is a class in the specific implementation in the com.prowidesoftware.swift.wrappers.saa.v_2_0_14 package. Similar classes are available for the supported revisions. The AbstractDataPDU parser just checks the enclosed revision in the XML and delegates to the specific implementation.","title":"Inbound DataPDU"},{"location":"integrator/sdk/sdk-datapdu/#using-a-fixed-version-of-the-datapdu","text":"If you need to access the DataPDU content, besides extracting the MT/MX payload and you receive many different versions from your interfaces, you could also use the latest revision to parse all of them. So that you avoid casting the model to the different versions. For example, if you are using the latest revision, you can use the following code to parse: DataPDUParser dataPdu = com . prowidesoftware . swift . wrappers . saa . v2_0_14 . DataPDUParser . parse ( xml );","title":"Using a fixed version of the DataPDU"},{"location":"integrator/sdk/sdk-datapdu/#setting-a-specific-dn-to-the-message","text":"There's the possibility that you need to use the DN Id instead of BIC one, in those cases, you can use the following code: MxSwiftMessage mx = new MxSwiftMessage ( xml ); DataPDUWriter dataPDUWriter = new DataPDUWriter ( mx ); dataPDUWriter . getHeader (). getMessage (). getSender (). setDN ( new BIC ( mx . getSender ()). distinguishedName ()); dataPDUWriter . getHeader (). getMessage (). getReceiver (). setDN ( new BIC ( mx . getReceiver ()). distinguishedName ()); final String dataPDU = dataPDUWriter . xml ();","title":"Setting a specific DN to the message"},{"location":"integrator/sdk/sdk-datapdu/#stripping-the-binary-prefix","text":"When calling any of the DataPDU parsing options make sure your XML string does not contain the binary prefix. If it does you can remove this prefix from the XML string before calling the parsing methods. For example: DataPDUParser . parse ( XmlV2Utils . stripBinaryPrefix ( xml )); Find more information for the binary prefix below.","title":"Stripping the binary prefix"},{"location":"integrator/sdk/sdk-datapdu/#outbound-datapdu","text":"To create an outbound DataPDU file to be sent to SAA the easiest way is to use the DataPDUWriter class. Since multiple versions of the DataPDU structure exist for SAA, there is a DataPDUWriter for each in the specific version packages, such as com.prowidesoftware.swift.wrappers.saa.v_2_0_14 . Then, multiple constructor options are available, each for a different purpose. For example, to build a DataPDU completely from scratch you can use: DataPDUWriter writer = new DataPDUWriter (); writer . setHeader ( new Header ()); writer . getHeader (). setMessage ( new Message ()); writer . getHeader (). getMessage (). setSenderReference ( \"senderRef123\" ); writer . getHeader (). getMessage (). setFormat ( \"File\" ); As you can see in the above example, you have a comprehensive setters API to build any element of the DataPDU. Then the xml() method can be used on the writer to generate the actual XML content of the DataPDU. When sending MT or MX messages as the payload of a DataPDU envelope, specific constructors are provided, such as: MtSwiftMessage mt = new MtSwiftMessage ( fin ); DataPDUWriter w = new DataPDUWriter ( mt )); final String xml = w . xml (); And the same for Mx. The above will automatically marshall the MT or MX payload into the generated XML. For MY messages, it will encode the message body in base 64. Where for MX, the AppHdr and Document elements will be enclosed into the Body of the DataPDU. Meaning, this constructor will automatically generate the Body element of the DataPDU from the parameter message. If the use case requires creating a new DataPDU by modifying an existing XML, the writer has also constructor options from an XML string and from a DataPDUParser . Thus, you can use the parser to read an existing XML structure, and then create a writer out of it for modifications.","title":"Outbound DataPDU"},{"location":"integrator/sdk/sdk-datapdu/#datapduwriter-factory","text":"When the writer has to be created from and existing XML in order to do modifications or content enrichment, a factory can be used to create the specific version of the writer automatically for a given XML input: AbstractDataPDU dataPDUWriter = DataPDUWriterFactory . getDataPDUWriter ( xml ); writer . getHeader (). getMessage (). setSenderReference ( \"senderRef123\" ); ... final String dataPDU = dataPDUWriter . xml (); The factory extracts the revision number from the given XML string and returns a specific DataPDUWriter instance (subclass of the AbstractDataPDU ) corresponding to that extracted revision. If the revision number does not match any of the supported versions or the XML is null, it defaults to the latest.","title":"DataPDUWriter factory"},{"location":"integrator/sdk/sdk-datapdu/#mt-encoded-content","text":"When MT messages are wrapped into the XML, the MT content is put in the Body as a single base64 encoded string. This encoded string could have: The complete MT message including headers, text block and trailers. Just the text block (block 4) By default, the writer will write the whole message content in the encoded string when creating the Body element. The API accepts an optional configuration class where you can change this default behavior and indicate whether in your environment the XML for MT should be created with only the block 4 encoded in the Body element. As for the parser, the encoded Body will be autodetected. When the complete MT content is present, that will be parsed into the returned MT instance. And if only the block 4 is encoded in the Body element, the headers and trailer will be recreated by the parser using information from other elements in the XML.","title":"MT encoded content"},{"location":"integrator/sdk/sdk-datapdu/#mx-custom-namespaces","text":"When constructing an MX message, the DataPDUWriter automatically incorporates the default namespaces for the MX message, specifically h for Header and Doc for Document . However, to override this default behavior, one can specify a desired namespace. Alternatively, setting the namespace to null can exclude it from being included. Check the code below: MxCamt00300105 mxCamt00300105 = MxCamt00300105 . parse ( your_mx ); DataPDUWriter w = new DataPDUWriter ( mxCamt00300105 , \"REF VAL\" , \"FOOZLULL\" , \"FOOZLULL\" ); final XmlV2Configuration conf = new XmlV2Configuration (); MxWriteParams mxHeaderWriteParams = new MxWriteParams (); mxHeaderWriteParams . prefix = \"header\" ; conf . setMxHeaderWriteParams ( mxHeaderWriteParams ); MxWriteParams mxDocumentWriteParams = new MxWriteParams (); mxDocumentWriteParams . prefix = mxCamt00300105 . getBusinessProcess (); conf . setMxDocumentWriteParams ( mxDocumentWriteParams ); final String xml = w . xml ( conf ); This will produce the following XML: 2.0.13 REF VAL camt.003.001.05 MX Input FOOZLULLAXXX FOOZLULLXXXX ... ... 2015-08-27T08:59:00Z ... ","title":"MX custom namespaces"},{"location":"integrator/sdk/sdk-datapdu/#transmissionreport","text":"The DataPDU is also used by SAA to return transmission reports. For this purpose, the DataPDU/Header structure is a choice that can hold a simple Message but also a Transmission Report and other structures. When the parser is called and the DataPDU/Header/TransmissionReport is found with an embedded MT , the parsed message result will be a FIN ACK/NAK as the following. Meaning a call like this: DataPDUContentParser parser = AbstractDataPDU . parse ( xml ); AbstractSwiftMessage msg = parser . extractMessage (); Will extract into the AbstractSwiftMessage a message payload like this: {1:F21AAAAGHA0AXXX241764}{4:{177:19101921138}{451:0}}{1:F01AAAAGHA0AXXX241764}{2:I103BBBBGHA0XXXXN}{3:{121:8a0c1649-efa9-42a6-8dcf-8df8c9b2c99f}}{4: :20:REFERENCE123 :23B:CRED :26T:123 :32A:191019EUR1, :50A:/1234456 AAAAGHA0 :59:/234455 Foo :71A:OUR -} Where you have the service message (21) with the date time and ACK fields, followed by the original message. You can then use the original message to do the internal matching in your application to reconcile the ACK and the original sent message. A similar Transmission Report is generated by SAA to acknowledge MX messages. In this case, the result of the parser is still a FIN service 21 message like this: {1:F21SPXAINJJAA05151}{4:{177:1102111528}{451:0}{108:PPTEI00000001013}} Which is just a service message (21) without any attached original message. Since the original message was an MX. In this scenario, if the MUR is present in the XML v2, you will find it in the field 108, and you can use it to match the original MX sent. The original MX message is not present in the result because there is no equivalence in ISO 20022 for the FIN service messages service type 21. For MT acknowledges, we can, because FIN defines such a structure where you have a service message plus an original message attached. But there is no message model to hold an ACK along an original MX, that structure is the actual DataPDU. Therefore, if you have to process ACK/NAK for MX, and you need the original message parsed because the MUR is not enough for the reconciliation, you can still accomplish that with the API like this: DataPDUParser parser = AbstractDataPDU . parse ( xml ); parser . getHeader (). getTransmissionReport (). getMessage (). getBody (); More info on ACK https://dev.prowidesoftware.com/latest/open-source/core/mt-ack/","title":"TransmissionReport"},{"location":"integrator/sdk/sdk-datapdu/#datapdu-binary-prefix-xmlv2utils","text":"The DataPDU is a regular UTF-8 encoded XML, but it can be preceded by a binary prefix with a digital signature. The Xmlv2Utils class is the main entry point to handle this binary prefix for the DataPDU XMLs. This prefix is actually obsolete in SAA, but only supported for backward compatibility. When reading an XML the XmlV2Utils class will strip the prefix if present. And when writing an XML a parameter is available to indicate whether the prefix must be generated or not. For inbound messages, to convert an XML into a message, you just need to call: AbstractSwiftMessage message = XmlV2Utils . readMessage ( xml ); The message variable will contain as result the embedded MT or MX message. The implementation will just strip the prefix if present, and will call the DataPDU parsing API to extract the enclosed message. For outbound messages, the XmlV2Utils class provides additional methods to select the usage of the binary prefix. Notice however when the flag to generate the binary prefix is true, this prefix will be generated with just the message size, but the signature will be filled with nulls. If you need to send outbound messages to SAA with a valid computed signature in the binary prefix, check the section describing LAU.","title":"DataPDU binary prefix (XmlV2Utils)"},{"location":"integrator/sdk/sdk-lau/","text":"LAU The SDK provide API for Local Authentication (LAU) to ensure incoming and outgoing messages are not tempered between the back-office applications and the SWIFT Alliance Access , increasing overall infrastructure security. LAU is based on the industry standard algorithm HMAC-SHA256, and is the only authentication method supported by SAA for transmission of message files to SWIFT. The LAU authentication consists of adding a digital signature calculated using the message body and a pair of shared keys that are uniquely defined for each back-office. In the SAA the keys and the LAU are enabled per Message Partner configuration. The LAU key consists of 32 printable characters entered as two 16 character strings. This allows users to have dual control over the maintenance of these keys. SWIFT has also defined complexity rules which must be followed while creating the key. The entry point for the LAU API is the LAU class. This class provides methods to sing an outgoing message, adding the signature in the security trailer block, and also methods to verify the signature of an incoming message. The LAU signature can be located in two places: As the MDG field in an MT trailer block In the XML v2 (DataPDU) envelop While the trailer block is exclusive for MT messages, the XML v2 (DataPDU) envelop can be used as a wrapper for both MT and MX payloads, and also as a companion file to sign or verify a FileAct exchange. http://api.prowidesoftware.com/integrator/com/prowidesoftware/swift/lau/LAU.html/ Outbound flow When a message is created in the back-office application, the signature should be added. Signing an AbstractMT (computing the MDG trailer) The API receives the message instance and the pair of keys to use, and will compute and add to the message a trailer block \"S\" with the MDG tag containing the calculated signature. String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); LAU lau = new LAU (); lau . sign ( mt , authParams ); After the above call, the mt parameter will contain a trailer like this: {S:{MDG:FA926417A34D0D9235080413FC03B9052B68FD7F3AC41B0C8EADD68FF89064CC}} This is the simplest LAU usage scenario, only available for MT interfaces, with no XML involved. Signing an XML v2 (DataPDU) This section explains how to create the LAU structure, when signing an outbound payload. The API receives the plain XML structure as a String , computes the digest and the signature, and returns a new XML containing the LAU section. The XML v2 in this use case is a wrapper with an MT or MX payload. String signedXml = lau . signXmlV2 ( unsignedXml , new AuthParameters ( leftKey , rightKey )); You can create the parameter unsignedXml with ease from the MtSwiftMessage or MxSwiftMessage using the XmlV2Utils class like this: String unsignedXml = XmlV2Utils . write ( message ); This XmlV2Utils class is used to add or strip this binary prefix from the XML v2 envelop. Notice the XML v2 envelop contains inside a DataPDU XML structure. For details on this structure see the DataPDU documentation. Signing an XML v2 companion file for FileAct LAU signing is also provided for the companion file of FileAct exchanges. In FileAct the actual payload is a file with any format. The payload could be an MX message or any other things. The signing API takes a DataPDU xml for the companion file (you must create and provide this XML) and the content in bytes of the payload file. The API will first compute the payload digest and add it to the companion XML. Then the whole XML digest is calculated and signed. Path path = Paths . get ( \"payload.txt\" ); byte [] data = Files . readAllBytes ( path ); String signedCompanionXml = lau . signFileActXmlV2 ( unsignedCompanionXml , data , new AuthParameters ( leftKey , rightKey )); You then send both the payload.txt file and the created signedCompanionXml files to SAA. If the companion file must also contain the binary prefix, you can further apply the binary prefix computation to that companion file ( Computing the binary prefix for XML v2 ) As for the structure of the companion file, the required content will depend on the type of payload you have to exchange and the configuration in SAA. You can use the DataPDUWriter API to create that file easily. As a reference, the code below will create a companion file when the payload file is an MX: MxPain00100103 mx = MxPain00100103 . parse ( Lib . readResource ( \"Pain001_Message.xml\" )); DataPDUWriter pdu = new DataPDUWriter (); Message pduMessage = new Message (); pdu . getDataPDU (). getHeader (). setMessage ( pduMessage ); pduMessage . setSenderReference ( mx . getCstmrCdtTrfInitn (). getGrpHdr (). getMsgId ()); pduMessage . setMessageIdentifier ( mx . getMxId (). id ()); pduMessage . setFormat ( \"File\" ); pduMessage . setSubFormat ( SubFormat . INPUT ); String senderBIC = mx . getCstmrCdtTrfInitn (). getGrpHdr (). getInitgPty (). getId (). getOrgId (). getBICOrBEI (); LogicalTerminalAddress senderLT = new LogicalTerminalAddress ( senderBIC ); pduMessage . setSender ( new AddressInfo ()); pduMessage . getSender (). setBIC12 ( senderLT . getSenderLogicalTerminalAddress ()); String receiverBIC = mx . getCstmrCdtTrfInitn (). getPmtInf (). get ( 0 ). getDbtrAgt (). getFinInstnId (). getBIC (); LogicalTerminalAddress receiverLT = new LogicalTerminalAddress ( receiverBIC ); pduMessage . setReceiver ( new AddressInfo ()); pduMessage . getReceiver (). setBIC12 ( receiverLT . getReceiverLogicalTerminalAddress ()); pduMessage . setInterfaceInfo ( new InterfaceInfo ()); pduMessage . getInterfaceInfo (). setUserReference ( mx . getCstmrCdtTrfInitn (). getPmtInf (). get ( 0 ). getPmtInfId ()); pduMessage . setNetworkInfo ( new NetworkInfo ()); pduMessage . getNetworkInfo (). setService ( \"swift.corp.fa!p\" ); pduMessage . setFileLogicalName ( \"Pain001_Message.xml\" ); String unsignedCompanionXML = pdu . xml (); Computing the binary prefix for XML v2 Depending on how the SAA is configured, it might be also expecting the binary prefix signature for XML v2. This prefix adds another layer of security to the XML v2 exchanges by computing an HMAC on the transmitted file. This additional signature is added as a binary prefix, before the XML declaration. In this usage scenario you have to do the signing in two steps: First you create the internal LAU structure. String signedXml = lau . signXmlV2 ( xml , authParams ); Then you add the binary prefix signature on top String binPrefixed = lau . signBinaryPrefix ( xml , authParams2 ); The binPrefixed string result will contain both the LAU signature segment inside the DataPDU, and the whole XML prefixed with the binary signature (it contains the 0x1f, etc). Inbound Flow When a message is received from SAA it will already contain the MDG tag in the FIN message or the LAU signature elements in the XML v2 if you receive content from SAA as XML v2 wrappers. In order to ensure the message has not been tampered, the back-office application must verify the signature. Verifying an AbstractMT (MDG trailer) When you receive an MT message containing the MDG trailer, you can verify that the message has not been tampered with: String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); LAU lau = new LAU (); boolean result = lau . verify ( mt , authParams ); If the result of the verification is false, the back-office application should reject the message and follow proper actions to deal with the situation. Verifying an XML v2 (DataPDU) This verification will check the LAU structure in the XML content. The verification involves computing the digest on a canonicalized XML, and computing the signature for the digest. Both the digest and the computed signature should match with the content in the LAU structure to consider the message authenticated. String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); LAU lau = new LAU (); boolean result = lau . verifyXmlV2 ( signedXml , authParams ); If the result of the verification is false, the back-office application should reject the message and follow proper actions to deal with the situation. Once the XML is verified, you can parse its content into an MtSwiftMessage or MxSwiftMessage with ease using the XmlV2Utils class like this: AbstractSwiftMessage message = XmlV2Utils . readMessage ( signedXml ); For more details regarding the above API v2 check the XML v2 section in this guide. Verifying an XML v2 companion file for FileAct This verification is used when you receive from SAA two messages, the actual payload file, and an XML v2 companion file with the signature. In FileAct the actual payload is a file with any format. The payload could be an MX message or any other things. The verification API takes the DataPDU xml for the companion file containing the signature and the content in bytes of the payload file. String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); LAU lau = new LAU (); Path path = Paths . get ( \"payload.txt\" ); byte [] data = Files . readAllBytes ( path ); boolean result = lau . verifyFileActXmlV2 ( signedCompanionXml , data , authParams ); If the result of the verification is false, the back-office application should reject the message and follow proper actions to deal with the situation. Verifying a binary prefix Depending on how the SAA is configured, you might receive the XML v2 messages with a binary prefix. This prefix adds another layer of security to the XML v2 exchanges by computing an HMAC on the transmitted file, and it is independent of the internal LAU structure in the XML. LAU lau = new LAU (); // verify the binary prefix String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); if ( ! lau . verifyBinaryPrefix ( binPrefix , authParams )) { // message not valid } String xml = XmlV2Utils . stripBinaryPrefix ( binPrefix ); // verify the xml signature String rightKey2 = \"Abcd1234abcd1234B\" ; String leftKey2 = \"Abcd1234abcd1234B\" ; AuthParameters authParams2 = new AuthParameters ( rightKey , leftKey ); if ( ! lau . verifyXmlV2 ( xml , authParams2 )) { // message not valid } The snipped above will first check the binary prefix. If that is valid, the prefix is removed from the file content and the LAU structure is verified. When both steps pass the verification, you can rest assured the message has not been tampered. Processing Options for DataPDU The LAU verification (and also the signing) involves first computing a digest, then applying the specific signing algorithm to the computed digest. While the algorithm part is normally explicit and clear, the digest computation is very sensitive to any small change in the payload or in the way to do the canonicalization of the payload. To cape with this, some processing parameters can be adjusted in the LAU object. Like this: // configure LAU for Alliance Lite LAU lau = new LAU(); lau.getProcessingParameters().setIncludeLAUInDigest(true).setSignatureNamespacePrefix(\"dsig\"); // the keys AuthParameters authParams = new AuthParameters(\"Abcd1234abcd1234A\", \"Abcd1234abcd1234A\"); // try to verify message and payload boolean verify = lau.verifyXmlV2(payload, authParams); In the above example the processing parameters is instructed to use an empty element in the digest computation and also to use the \"dssig\" prefix instead of the \"ds\" default. The default processing parameters are kept in sync with what is normally required for SWIFT Alliance Access, while the configuration in the example above is needed when exchanging messages with recent versions of SWIFT Alliance Lite. LAUSigner The LAUSigner is a helper class containing the LAU utility instance along with the pair of keys. It can be thought of as a cache for the keys. To follow the four-eyes principle, the back-office application is expected to distribute each pair of the keys to a different supervisor user so that in order to release a message, both keys are entered in the system. The application can then control whether to ask for the keys for each message or per batch of messages. This class can be used then to hold the provided keys entered by the users in a detached flow than the actual signing and verification. A scenario for this could be to create a LAUSigner instance object and store it in the Spring Context, letting the application just look for the signer and sign messages, while a background thread could deal with key setup and renewal if necessary. The LAUSigner API is straightforward to use. It is created with the AuthParameters and then provides simple methods to sign and verify the messages. http://api.prowidesoftware.com/integrator/com/prowidesoftware/swift/lau/LAUSigner.html/ Non-compliant messages The signature computation is sensitive to the message character encoding. The default API requires the message to be compliant with LAU specification. This means that there are no user defined blocks (except perhaps a Block S), that the FIN representation of the message is composed exclusively of ASCII characters and that the end of lines uses CRLF. When transmitting a message to or from SAA you must ensure the encoding is not altered. In the scenario where a message with non ASCII characters must be signed or verified, for example when working on an alternative (non-SWIFT) network, additional parameters can be passed to the API. The additional parameter ProcessingParameters can be passed to indicate the specific Charset to use in the signature computation, or to indicate the original Charset used to calculate the signature when verifying a received message.","title":"LAU"},{"location":"integrator/sdk/sdk-lau/#lau","text":"The SDK provide API for Local Authentication (LAU) to ensure incoming and outgoing messages are not tempered between the back-office applications and the SWIFT Alliance Access , increasing overall infrastructure security. LAU is based on the industry standard algorithm HMAC-SHA256, and is the only authentication method supported by SAA for transmission of message files to SWIFT. The LAU authentication consists of adding a digital signature calculated using the message body and a pair of shared keys that are uniquely defined for each back-office. In the SAA the keys and the LAU are enabled per Message Partner configuration. The LAU key consists of 32 printable characters entered as two 16 character strings. This allows users to have dual control over the maintenance of these keys. SWIFT has also defined complexity rules which must be followed while creating the key. The entry point for the LAU API is the LAU class. This class provides methods to sing an outgoing message, adding the signature in the security trailer block, and also methods to verify the signature of an incoming message. The LAU signature can be located in two places: As the MDG field in an MT trailer block In the XML v2 (DataPDU) envelop While the trailer block is exclusive for MT messages, the XML v2 (DataPDU) envelop can be used as a wrapper for both MT and MX payloads, and also as a companion file to sign or verify a FileAct exchange. http://api.prowidesoftware.com/integrator/com/prowidesoftware/swift/lau/LAU.html/","title":"LAU"},{"location":"integrator/sdk/sdk-lau/#outbound-flow","text":"When a message is created in the back-office application, the signature should be added.","title":"Outbound flow"},{"location":"integrator/sdk/sdk-lau/#signing-an-abstractmt-computing-the-mdg-trailer","text":"The API receives the message instance and the pair of keys to use, and will compute and add to the message a trailer block \"S\" with the MDG tag containing the calculated signature. String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); LAU lau = new LAU (); lau . sign ( mt , authParams ); After the above call, the mt parameter will contain a trailer like this: {S:{MDG:FA926417A34D0D9235080413FC03B9052B68FD7F3AC41B0C8EADD68FF89064CC}} This is the simplest LAU usage scenario, only available for MT interfaces, with no XML involved.","title":"Signing an AbstractMT (computing the MDG trailer)"},{"location":"integrator/sdk/sdk-lau/#signing-an-xml-v2-datapdu","text":"This section explains how to create the LAU structure, when signing an outbound payload. The API receives the plain XML structure as a String , computes the digest and the signature, and returns a new XML containing the LAU section. The XML v2 in this use case is a wrapper with an MT or MX payload. String signedXml = lau . signXmlV2 ( unsignedXml , new AuthParameters ( leftKey , rightKey )); You can create the parameter unsignedXml with ease from the MtSwiftMessage or MxSwiftMessage using the XmlV2Utils class like this: String unsignedXml = XmlV2Utils . write ( message ); This XmlV2Utils class is used to add or strip this binary prefix from the XML v2 envelop. Notice the XML v2 envelop contains inside a DataPDU XML structure. For details on this structure see the DataPDU documentation.","title":"Signing an XML v2 (DataPDU)"},{"location":"integrator/sdk/sdk-lau/#signing-an-xml-v2-companion-file-for-fileact","text":"LAU signing is also provided for the companion file of FileAct exchanges. In FileAct the actual payload is a file with any format. The payload could be an MX message or any other things. The signing API takes a DataPDU xml for the companion file (you must create and provide this XML) and the content in bytes of the payload file. The API will first compute the payload digest and add it to the companion XML. Then the whole XML digest is calculated and signed. Path path = Paths . get ( \"payload.txt\" ); byte [] data = Files . readAllBytes ( path ); String signedCompanionXml = lau . signFileActXmlV2 ( unsignedCompanionXml , data , new AuthParameters ( leftKey , rightKey )); You then send both the payload.txt file and the created signedCompanionXml files to SAA. If the companion file must also contain the binary prefix, you can further apply the binary prefix computation to that companion file ( Computing the binary prefix for XML v2 ) As for the structure of the companion file, the required content will depend on the type of payload you have to exchange and the configuration in SAA. You can use the DataPDUWriter API to create that file easily. As a reference, the code below will create a companion file when the payload file is an MX: MxPain00100103 mx = MxPain00100103 . parse ( Lib . readResource ( \"Pain001_Message.xml\" )); DataPDUWriter pdu = new DataPDUWriter (); Message pduMessage = new Message (); pdu . getDataPDU (). getHeader (). setMessage ( pduMessage ); pduMessage . setSenderReference ( mx . getCstmrCdtTrfInitn (). getGrpHdr (). getMsgId ()); pduMessage . setMessageIdentifier ( mx . getMxId (). id ()); pduMessage . setFormat ( \"File\" ); pduMessage . setSubFormat ( SubFormat . INPUT ); String senderBIC = mx . getCstmrCdtTrfInitn (). getGrpHdr (). getInitgPty (). getId (). getOrgId (). getBICOrBEI (); LogicalTerminalAddress senderLT = new LogicalTerminalAddress ( senderBIC ); pduMessage . setSender ( new AddressInfo ()); pduMessage . getSender (). setBIC12 ( senderLT . getSenderLogicalTerminalAddress ()); String receiverBIC = mx . getCstmrCdtTrfInitn (). getPmtInf (). get ( 0 ). getDbtrAgt (). getFinInstnId (). getBIC (); LogicalTerminalAddress receiverLT = new LogicalTerminalAddress ( receiverBIC ); pduMessage . setReceiver ( new AddressInfo ()); pduMessage . getReceiver (). setBIC12 ( receiverLT . getReceiverLogicalTerminalAddress ()); pduMessage . setInterfaceInfo ( new InterfaceInfo ()); pduMessage . getInterfaceInfo (). setUserReference ( mx . getCstmrCdtTrfInitn (). getPmtInf (). get ( 0 ). getPmtInfId ()); pduMessage . setNetworkInfo ( new NetworkInfo ()); pduMessage . getNetworkInfo (). setService ( \"swift.corp.fa!p\" ); pduMessage . setFileLogicalName ( \"Pain001_Message.xml\" ); String unsignedCompanionXML = pdu . xml ();","title":"Signing an XML v2 companion file for FileAct"},{"location":"integrator/sdk/sdk-lau/#computing-the-binary-prefix-for-xml-v2","text":"Depending on how the SAA is configured, it might be also expecting the binary prefix signature for XML v2. This prefix adds another layer of security to the XML v2 exchanges by computing an HMAC on the transmitted file. This additional signature is added as a binary prefix, before the XML declaration. In this usage scenario you have to do the signing in two steps: First you create the internal LAU structure. String signedXml = lau . signXmlV2 ( xml , authParams ); Then you add the binary prefix signature on top String binPrefixed = lau . signBinaryPrefix ( xml , authParams2 ); The binPrefixed string result will contain both the LAU signature segment inside the DataPDU, and the whole XML prefixed with the binary signature (it contains the 0x1f, etc).","title":"Computing the binary prefix for XML v2"},{"location":"integrator/sdk/sdk-lau/#inbound-flow","text":"When a message is received from SAA it will already contain the MDG tag in the FIN message or the LAU signature elements in the XML v2 if you receive content from SAA as XML v2 wrappers. In order to ensure the message has not been tampered, the back-office application must verify the signature.","title":"Inbound Flow"},{"location":"integrator/sdk/sdk-lau/#verifying-an-abstractmt-mdg-trailer","text":"When you receive an MT message containing the MDG trailer, you can verify that the message has not been tampered with: String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); LAU lau = new LAU (); boolean result = lau . verify ( mt , authParams ); If the result of the verification is false, the back-office application should reject the message and follow proper actions to deal with the situation.","title":"Verifying an AbstractMT (MDG trailer)"},{"location":"integrator/sdk/sdk-lau/#verifying-an-xml-v2-datapdu","text":"This verification will check the LAU structure in the XML content. The verification involves computing the digest on a canonicalized XML, and computing the signature for the digest. Both the digest and the computed signature should match with the content in the LAU structure to consider the message authenticated. String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); LAU lau = new LAU (); boolean result = lau . verifyXmlV2 ( signedXml , authParams ); If the result of the verification is false, the back-office application should reject the message and follow proper actions to deal with the situation. Once the XML is verified, you can parse its content into an MtSwiftMessage or MxSwiftMessage with ease using the XmlV2Utils class like this: AbstractSwiftMessage message = XmlV2Utils . readMessage ( signedXml ); For more details regarding the above API v2 check the XML v2 section in this guide.","title":"Verifying an XML v2 (DataPDU)"},{"location":"integrator/sdk/sdk-lau/#verifying-an-xml-v2-companion-file-for-fileact","text":"This verification is used when you receive from SAA two messages, the actual payload file, and an XML v2 companion file with the signature. In FileAct the actual payload is a file with any format. The payload could be an MX message or any other things. The verification API takes the DataPDU xml for the companion file containing the signature and the content in bytes of the payload file. String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); LAU lau = new LAU (); Path path = Paths . get ( \"payload.txt\" ); byte [] data = Files . readAllBytes ( path ); boolean result = lau . verifyFileActXmlV2 ( signedCompanionXml , data , authParams ); If the result of the verification is false, the back-office application should reject the message and follow proper actions to deal with the situation.","title":"Verifying an XML v2 companion file for FileAct"},{"location":"integrator/sdk/sdk-lau/#verifying-a-binary-prefix","text":"Depending on how the SAA is configured, you might receive the XML v2 messages with a binary prefix. This prefix adds another layer of security to the XML v2 exchanges by computing an HMAC on the transmitted file, and it is independent of the internal LAU structure in the XML. LAU lau = new LAU (); // verify the binary prefix String rightKey = \"Abcd1234abcd1234A\" ; String leftKey = \"Abcd1234abcd1234A\" ; AuthParameters authParams = new AuthParameters ( rightKey , leftKey ); if ( ! lau . verifyBinaryPrefix ( binPrefix , authParams )) { // message not valid } String xml = XmlV2Utils . stripBinaryPrefix ( binPrefix ); // verify the xml signature String rightKey2 = \"Abcd1234abcd1234B\" ; String leftKey2 = \"Abcd1234abcd1234B\" ; AuthParameters authParams2 = new AuthParameters ( rightKey , leftKey ); if ( ! lau . verifyXmlV2 ( xml , authParams2 )) { // message not valid } The snipped above will first check the binary prefix. If that is valid, the prefix is removed from the file content and the LAU structure is verified. When both steps pass the verification, you can rest assured the message has not been tampered.","title":"Verifying a binary prefix"},{"location":"integrator/sdk/sdk-lau/#processing-options-for-datapdu","text":"The LAU verification (and also the signing) involves first computing a digest, then applying the specific signing algorithm to the computed digest. While the algorithm part is normally explicit and clear, the digest computation is very sensitive to any small change in the payload or in the way to do the canonicalization of the payload. To cape with this, some processing parameters can be adjusted in the LAU object. Like this: // configure LAU for Alliance Lite LAU lau = new LAU(); lau.getProcessingParameters().setIncludeLAUInDigest(true).setSignatureNamespacePrefix(\"dsig\"); // the keys AuthParameters authParams = new AuthParameters(\"Abcd1234abcd1234A\", \"Abcd1234abcd1234A\"); // try to verify message and payload boolean verify = lau.verifyXmlV2(payload, authParams); In the above example the processing parameters is instructed to use an empty element in the digest computation and also to use the \"dssig\" prefix instead of the \"ds\" default. The default processing parameters are kept in sync with what is normally required for SWIFT Alliance Access, while the configuration in the example above is needed when exchanging messages with recent versions of SWIFT Alliance Lite.","title":"Processing Options for DataPDU"},{"location":"integrator/sdk/sdk-lau/#lausigner","text":"The LAUSigner is a helper class containing the LAU utility instance along with the pair of keys. It can be thought of as a cache for the keys. To follow the four-eyes principle, the back-office application is expected to distribute each pair of the keys to a different supervisor user so that in order to release a message, both keys are entered in the system. The application can then control whether to ask for the keys for each message or per batch of messages. This class can be used then to hold the provided keys entered by the users in a detached flow than the actual signing and verification. A scenario for this could be to create a LAUSigner instance object and store it in the Spring Context, letting the application just look for the signer and sign messages, while a background thread could deal with key setup and renewal if necessary. The LAUSigner API is straightforward to use. It is created with the AuthParameters and then provides simple methods to sign and verify the messages. http://api.prowidesoftware.com/integrator/com/prowidesoftware/swift/lau/LAUSigner.html/","title":"LAUSigner"},{"location":"integrator/sdk/sdk-lau/#non-compliant-messages","text":"The signature computation is sensitive to the message character encoding. The default API requires the message to be compliant with LAU specification. This means that there are no user defined blocks (except perhaps a Block S), that the FIN representation of the message is composed exclusively of ASCII characters and that the end of lines uses CRLF. When transmitting a message to or from SAA you must ensure the encoding is not altered. In the scenario where a message with non ASCII characters must be signed or verified, for example when working on an alternative (non-SWIFT) network, additional parameters can be passed to the API. The additional parameter ProcessingParameters can be passed to indicate the specific Charset to use in the signature computation, or to indicate the original Charset used to calculate the signature when verifying a received message.","title":"Non-compliant messages"},{"location":"integrator/sdk/sdk-mtpath/","text":"MT Path This unique feature of the SDK gives the possibility to query MT messages content by means of path expressions ( analogous to XML XPath). The syntax and semantics of this path expression is proprietary and particularly designed for MT messages, based on the understanding that besides being a plain list of fields, the underlying structure of MT messages can be processed like a tree conformed by blocks, sequences, subsequences, and fields. A path is then composed by the following steps: BLOCK / SEQUENCE[*] / FIELD / QUALIFIER / (COMPONENT | COMPONENT_NAME) / LINE Where at least a field or a sequence must be present, while all other items are optional. Depending on the path expression, the target element to find may be a set of fields or a set of sequences. Query for fields Example of path expressions referencing fields , and fields components: b3/108 gets the value of field 108 at block header 3. A/20C/SEME gets value of generic field 20C, with qualifier SEME at sequence A B1[2]/98A/2 gets component 2, of field 98A in the second instance of sequence B1 50K/NameAndAddress selects the \"NameAndAddress\" component, of field 50K 93a gets value of fields 93, for any letter option found b1/LogicalTerminal gets the logical terminal field of header block 1 Notice from the above examples that path may refer to fields in the text block (block 4) but also in the header blocks. The field is mandatory when the expected target is a field, but the rest of elements (sequence, qualifier, component, line) are optional. Also notice that the component name must comply the Camel Case format. Examples of compliant component names are: FINCopyServiceCode TypeOfAgreement NumberOfAmendment The Line indication can be used within field path expressions to retrieve a specific line within the field's value. 59/Line[2] gets the second line of component 59, with the name & address information. Notice that this will perform a semantic line retrieval based on the field components definition, so this is not the same as just splitting the value in lines and getting one of the lines with an index. If the field defines the first line components as optional and those components are not present in the particular field instance, then Line[1] will return null because according to the field definition the first line is not present. The Line step can be particularly useful combined with a component indication. For example, for field 70E the narrative content starts from the second component. So the following examples show how to get specific lines of the field\u2019s narrative text. 70E/2/Line[1] gets the first line of the narrative, notice the component 2 is the narrative and is used as an offset for the line selector 70E/2/Line[*] gets all text of the narrative, notice the * is used to select all lines, and the component indication offset, so the lines are gathered starting from the narrative component. The examples above can be also expressed using the component name instead of the component number. The result will be exactly the same: 70E/Narrative/Line[1] 70E/Narrative/Line[*] Query for sequences When the target element is a sequence, the path has a similar syntax but the field, component, qualifier, and line elements are not present. Example of path expressions referencing sequences , and fields components: A1 gets all sequences A1. A1a[2] gets the second instance of sequence A1 for the indicated second instance of A1a Sequence steps include additional capacities. First, the path can contain more than one sequence step, giving the capacity to chain several sequences and subsequences indications to define a very specific portion of the message tree structure. Second, it supports axes. Sequence axis Unlike axis in strict XML XPath, where the axis defines a node-set relative to the current node; in MtPath the implementation of axis support is limited to parent and child , and only admitted in sequence steps. Parent The parent axis is used to get the parent sequence in any sequence step. A[1]/A1[2]/A1a gets all sequences A1a within the second instance of A1, within the first instance of A. parent::A1a[2] gets the container sequence A1 for the indicated second instance of A1a All this can be combined to define more complex paths, for example: A/parent::A1b[3]/95P/ACOW/3 gets component 3, of all fields 95P in the parent sequence of each third instance of a subsequence A1b The parent axis is particularly useful in situations where you would use the unsupported double dot (\"..\") to traverse up in the sequence tree. For example, if you have an MtPathResult with a sequence, and you want to query a field in the parent sequence of that current position. You would then create a path using the parent axis, running the evaluation with the current MtPathResult as starting point (current node). Child The child axis is used to indicate that the field, component or line to retrieve must be a direct child of the contained sequence. E/98A gets all fields 98A in either E or further subsequences such as E1 or E2. While this: child::E/98A gets all fields 98A that are direct children of sequence E, meaning it will not return 98A occurrences in subsequences such as E1 or E2. Notice by default all MtPath expressions result in any sequence descendant. So, in situations where the queried field can be present on the target sequence but also on subsequences, this axis is useful to clearly determine if the query will be on direct elements or on any descendant. In strict XML XPath the double slash (\"//\") is used when the search must be in any descendant of a step. Also, worth mentioning the child axis only makes sense in the last sequence step. A query with child:E/E1 will return no results because sequences E1 will be removed from the result set then the child:E step is processed. Sample code The following example shows how to perform a simple path query on an MT message. It gets second component of field 20C with qualifier SEME: MT535 mt = MT535 . parse (...); List < MtPathResult > found = MtPath . evaluate ( \"20C/SEME/2\" , mt ); System . out . println ( found . get ( 0 ). getComponent ()); The result of the query is always a List and these result objects are hybrid containers for sequences, fields, or components. The following sample is equivalent to the one above, but using the component name instead of the component number: MT535 mt = MT535 . parse (...); List < MtPathResult > found = MtPath . evaluate ( \"20C/SEME/Reference\" , mt ); System . out . println ( found . get ( 0 ). getComponent ()); This other example shows how to search for all instances of field 93, any letter option, in any instance of sequence B; printing out the value of each found field. Notice in this example we gather the actual fields from the result, while in the previous one we\u2019ve printed the component. found = MtPath . evaluate ( \"B[*]/93a\" , mt ); for ( MtPathResult f : found ) { System . out . println ( f . getField (). getValue ()); } The result will be properly populated with the found content according to the processed path expression. For example, if the expression references a sequence with no field information, the MtPathResult object will contain the found sequences while the field and component attributes will be left null. If the path references a field, then the MtPathResult will contain each found field along with its containing sequence. And finally if the path references a component, the result will contain the found component value, but also the field where the component was found, and the container sequence of such a field. In other terms, when searching for components we are also searching for fields, and when searching for fields we are also searching for sequences. Check the javadoc for more API options. Queries can also be nested, providing an MtPathResult as \"current node\" for the expression evaluation. This is particularly useful if you have a query to retrieve sequences, and then you iterate the sequences running more queries to get fields within the current sequence in the loop. ACK content selection The service 21 messages (ACK and NAK) have a different structure for block 4. Instead of fields in multiple lines, all fields are contained in inner blocks. From the MtPath expression, this difference in the structure is the same, and you can retrieve the content with the same expressions as for any other message type. For example: String fin = \"{1:F21BBBBARB1A0B20509002124}{4:{177:2011140437}{451:0}}\" ; AbstractMT mt = AbstractMT . parse ( fin ); List < MtPathResult > found = MtPath . evaluate ( \"451\" , mt ); System . out . println ( found . get ( 0 ). value ()); The result of the query will be the value \"0\" from the ACK block 4. Then, if the ACK/NAK contains the original sent message attached as a suffix after the service 21 message, a special keyword @attach can be used to select content from the original message. For example: String fin = \"{1:F21BBBBARB1A0B20509002124}{4:{177:2011140437}{451:0}}\" + \"{1:F01AAAAARB1A0B20509002124}{2:I999ADRBNL21XXXXN}{4:\\n\" + \":20:REFERENCE123\\n\" + \":21:REPORT ABC NAN\\n\" + \":79:TEST FOO BAR\\n\" + \"-}\" ; AbstractMT mt = AbstractMT . parse ( fin ); List < MtPathResult > found = MtPath . evaluate ( \"@attach/20\" , mt ); System . out . println ( found . get ( 0 ). value ()); The result of the query will be the value \"REFERENCE123\" from the block 4 of the original sent message, present after the ACK content. The @attach can be combined with any type of path expressions, such as: @attach/b1/LogicalTerminal @attach/b2 @attach/59/Line[2] @attach/32A/2 @attach/90B/AmountTypeCode Alternatively, the @main keyword can be used to retrieve content from the original message attached to an ACK/NAK The @main can be used as follows: * @main/b1/LogicalTerminal * @main/b4 More path expression examples can be found at https://github.com/prowide/ MtPath to build messages The MtPath expressions can also be used to build messages, leveraging the MtWriter component from the MyFormat library. The MtWriter exposes a method write that takes an MtPath expression and a value to write in the target message, and internally creates the necessary sequences and fields to write the content. Check the MyFormat documentation for more details on how to use the MtWriter to build messages.","title":"MT Path"},{"location":"integrator/sdk/sdk-mtpath/#mt-path","text":"This unique feature of the SDK gives the possibility to query MT messages content by means of path expressions ( analogous to XML XPath). The syntax and semantics of this path expression is proprietary and particularly designed for MT messages, based on the understanding that besides being a plain list of fields, the underlying structure of MT messages can be processed like a tree conformed by blocks, sequences, subsequences, and fields. A path is then composed by the following steps: BLOCK / SEQUENCE[*] / FIELD / QUALIFIER / (COMPONENT | COMPONENT_NAME) / LINE Where at least a field or a sequence must be present, while all other items are optional. Depending on the path expression, the target element to find may be a set of fields or a set of sequences.","title":"MT Path"},{"location":"integrator/sdk/sdk-mtpath/#query-for-fields","text":"Example of path expressions referencing fields , and fields components: b3/108 gets the value of field 108 at block header 3. A/20C/SEME gets value of generic field 20C, with qualifier SEME at sequence A B1[2]/98A/2 gets component 2, of field 98A in the second instance of sequence B1 50K/NameAndAddress selects the \"NameAndAddress\" component, of field 50K 93a gets value of fields 93, for any letter option found b1/LogicalTerminal gets the logical terminal field of header block 1 Notice from the above examples that path may refer to fields in the text block (block 4) but also in the header blocks. The field is mandatory when the expected target is a field, but the rest of elements (sequence, qualifier, component, line) are optional. Also notice that the component name must comply the Camel Case format. Examples of compliant component names are: FINCopyServiceCode TypeOfAgreement NumberOfAmendment The Line indication can be used within field path expressions to retrieve a specific line within the field's value. 59/Line[2] gets the second line of component 59, with the name & address information. Notice that this will perform a semantic line retrieval based on the field components definition, so this is not the same as just splitting the value in lines and getting one of the lines with an index. If the field defines the first line components as optional and those components are not present in the particular field instance, then Line[1] will return null because according to the field definition the first line is not present. The Line step can be particularly useful combined with a component indication. For example, for field 70E the narrative content starts from the second component. So the following examples show how to get specific lines of the field\u2019s narrative text. 70E/2/Line[1] gets the first line of the narrative, notice the component 2 is the narrative and is used as an offset for the line selector 70E/2/Line[*] gets all text of the narrative, notice the * is used to select all lines, and the component indication offset, so the lines are gathered starting from the narrative component. The examples above can be also expressed using the component name instead of the component number. The result will be exactly the same: 70E/Narrative/Line[1] 70E/Narrative/Line[*]","title":"Query for fields"},{"location":"integrator/sdk/sdk-mtpath/#query-for-sequences","text":"When the target element is a sequence, the path has a similar syntax but the field, component, qualifier, and line elements are not present. Example of path expressions referencing sequences , and fields components: A1 gets all sequences A1. A1a[2] gets the second instance of sequence A1 for the indicated second instance of A1a Sequence steps include additional capacities. First, the path can contain more than one sequence step, giving the capacity to chain several sequences and subsequences indications to define a very specific portion of the message tree structure. Second, it supports axes.","title":"Query for sequences"},{"location":"integrator/sdk/sdk-mtpath/#sequence-axis","text":"Unlike axis in strict XML XPath, where the axis defines a node-set relative to the current node; in MtPath the implementation of axis support is limited to parent and child , and only admitted in sequence steps. Parent The parent axis is used to get the parent sequence in any sequence step. A[1]/A1[2]/A1a gets all sequences A1a within the second instance of A1, within the first instance of A. parent::A1a[2] gets the container sequence A1 for the indicated second instance of A1a All this can be combined to define more complex paths, for example: A/parent::A1b[3]/95P/ACOW/3 gets component 3, of all fields 95P in the parent sequence of each third instance of a subsequence A1b The parent axis is particularly useful in situations where you would use the unsupported double dot (\"..\") to traverse up in the sequence tree. For example, if you have an MtPathResult with a sequence, and you want to query a field in the parent sequence of that current position. You would then create a path using the parent axis, running the evaluation with the current MtPathResult as starting point (current node). Child The child axis is used to indicate that the field, component or line to retrieve must be a direct child of the contained sequence. E/98A gets all fields 98A in either E or further subsequences such as E1 or E2. While this: child::E/98A gets all fields 98A that are direct children of sequence E, meaning it will not return 98A occurrences in subsequences such as E1 or E2. Notice by default all MtPath expressions result in any sequence descendant. So, in situations where the queried field can be present on the target sequence but also on subsequences, this axis is useful to clearly determine if the query will be on direct elements or on any descendant. In strict XML XPath the double slash (\"//\") is used when the search must be in any descendant of a step. Also, worth mentioning the child axis only makes sense in the last sequence step. A query with child:E/E1 will return no results because sequences E1 will be removed from the result set then the child:E step is processed.","title":"Sequence axis"},{"location":"integrator/sdk/sdk-mtpath/#sample-code","text":"The following example shows how to perform a simple path query on an MT message. It gets second component of field 20C with qualifier SEME: MT535 mt = MT535 . parse (...); List < MtPathResult > found = MtPath . evaluate ( \"20C/SEME/2\" , mt ); System . out . println ( found . get ( 0 ). getComponent ()); The result of the query is always a List and these result objects are hybrid containers for sequences, fields, or components. The following sample is equivalent to the one above, but using the component name instead of the component number: MT535 mt = MT535 . parse (...); List < MtPathResult > found = MtPath . evaluate ( \"20C/SEME/Reference\" , mt ); System . out . println ( found . get ( 0 ). getComponent ()); This other example shows how to search for all instances of field 93, any letter option, in any instance of sequence B; printing out the value of each found field. Notice in this example we gather the actual fields from the result, while in the previous one we\u2019ve printed the component. found = MtPath . evaluate ( \"B[*]/93a\" , mt ); for ( MtPathResult f : found ) { System . out . println ( f . getField (). getValue ()); } The result will be properly populated with the found content according to the processed path expression. For example, if the expression references a sequence with no field information, the MtPathResult object will contain the found sequences while the field and component attributes will be left null. If the path references a field, then the MtPathResult will contain each found field along with its containing sequence. And finally if the path references a component, the result will contain the found component value, but also the field where the component was found, and the container sequence of such a field. In other terms, when searching for components we are also searching for fields, and when searching for fields we are also searching for sequences. Check the javadoc for more API options. Queries can also be nested, providing an MtPathResult as \"current node\" for the expression evaluation. This is particularly useful if you have a query to retrieve sequences, and then you iterate the sequences running more queries to get fields within the current sequence in the loop.","title":"Sample code"},{"location":"integrator/sdk/sdk-mtpath/#ack-content-selection","text":"The service 21 messages (ACK and NAK) have a different structure for block 4. Instead of fields in multiple lines, all fields are contained in inner blocks. From the MtPath expression, this difference in the structure is the same, and you can retrieve the content with the same expressions as for any other message type. For example: String fin = \"{1:F21BBBBARB1A0B20509002124}{4:{177:2011140437}{451:0}}\" ; AbstractMT mt = AbstractMT . parse ( fin ); List < MtPathResult > found = MtPath . evaluate ( \"451\" , mt ); System . out . println ( found . get ( 0 ). value ()); The result of the query will be the value \"0\" from the ACK block 4. Then, if the ACK/NAK contains the original sent message attached as a suffix after the service 21 message, a special keyword @attach can be used to select content from the original message. For example: String fin = \"{1:F21BBBBARB1A0B20509002124}{4:{177:2011140437}{451:0}}\" + \"{1:F01AAAAARB1A0B20509002124}{2:I999ADRBNL21XXXXN}{4:\\n\" + \":20:REFERENCE123\\n\" + \":21:REPORT ABC NAN\\n\" + \":79:TEST FOO BAR\\n\" + \"-}\" ; AbstractMT mt = AbstractMT . parse ( fin ); List < MtPathResult > found = MtPath . evaluate ( \"@attach/20\" , mt ); System . out . println ( found . get ( 0 ). value ()); The result of the query will be the value \"REFERENCE123\" from the block 4 of the original sent message, present after the ACK content. The @attach can be combined with any type of path expressions, such as: @attach/b1/LogicalTerminal @attach/b2 @attach/59/Line[2] @attach/32A/2 @attach/90B/AmountTypeCode Alternatively, the @main keyword can be used to retrieve content from the original message attached to an ACK/NAK The @main can be used as follows: * @main/b1/LogicalTerminal * @main/b4 More path expression examples can be found at https://github.com/prowide/","title":"ACK content selection"},{"location":"integrator/sdk/sdk-mtpath/#mtpath-to-build-messages","text":"The MtPath expressions can also be used to build messages, leveraging the MtWriter component from the MyFormat library. The MtWriter exposes a method write that takes an MtPath expression and a value to write in the target message, and internally creates the necessary sequences and fields to write the content. Check the MyFormat documentation for more details on how to use the MtWriter to build messages.","title":"MtPath to build messages"},{"location":"integrator/sdk/sdk-printout/","text":"Expanded printout The expanded printout generates a human-friendly representation of a message content, including: Comprehensive labels for sequences, fields, and components Expanded BIC information with the institution name and location Formatted dates and amounts The implementation is generic and can be applied to any MT or MX (ISO 20022) message. MT Printout The main entry point for the feature is the PrintoutWriter class and the print methods. The printout can be done directly into a String object, or an OutputStream can be passed as argument. The following example illustrates the default printout in TXT format for an MT103: ------------------------- Instance Type and Transmission ------------------------- Copy sent to SWIFT Priority/Delivery : Urgent/Delivery Notification ------------------------- Message Header ----------------------------------------- Swift : FIN 103 Single Customer Credit Transfer Sender : XBDSJPJTBXXX - FOO CAPITAL MARKETS (JAPAN) LTD., TOKYO (JAPAN) Receiver : XOJPJPJTXMF1 - BANK OF FOOBAR - (FOR FOOOBAR'S RESERVES USE ONLY) (JAPAN) MUR : FOOB3926BE868XXX ------------------------- Message Text ------------------------------------------- 20: Sender's Reference Reference: 11111111 23B: Bank Operation Code Type: CRED 32A: Value Date/Currency/Interbank Settled Amount Date: Feb 4, 2013 Currency: EUR Amount: 1,234,567.89 33B: Currency/Instructed Amount Currency: USD Amount: 89,431.4 50A: Ordering Customer Account: 12345678901234567890 BIC: AAAAUS33XXX - FOOBAR AND CO. INC. () 59: Beneficiary Customer Account: 12345678901234567890 Name And Address: JOE DOE Name And Address 2: MyStreet 1234 71A: Details of Charges Code: OUR ------------------------- Message Trailer ----------------------------------------- CHK: 3916EF336FF7 Sequences, fields and components are printed with label. BICs are expanded with the institution name and location. Dates and amounts are formatted. Please check the sample below about how to create a printout similar to the one listed above. SwiftMessage m = SwiftMessage . parse ( \"{1:F01XBDSJPJTBXXX0000000000}{2:I103XOJPJPJTXMF1U2}{3:{108:FOOB3926BE868XXX}}{4:\\n\" + \":20:11111111\\n\" + \":23B:CRED\\n\" + \":32A:130204EUR1234567,89\\n\" + \":33B:USD89431,40\\n\" + \":50A:/12345678901234567890\\n\" + \"AAAAUS33XXX\\n\" + \":59:/12345678901234567890\\n\" + \"JOE DOE\\n\" + \"MyStreet 1234\\n\" + \":71A:OUR\\n\" + \"-}\" ); final String text = new PrintoutWriter (). print ( m ); System . out . println ( text ); Localization The default output prints labels using the default locale, however a specific locale can be passed in the constructor. Current supported languages are English, Spanish, Russian, French, German, and Italian . If a different locale is configured or passed as an argument, or if a particular label is not found in the specific locale, the printing falls back to English as default. MT Info The MTInfo is a helper class to retrieve message information (label, descriptions) from resource bundles and to print formatted field values. It is used by the printout feature, but can be used independently as well. The resource bundles include translations for English, Spanish, Russian, French, German, and Italian . These labels are provided in the pw_mt_info.properties files. The object is instantiated provided a Locale and a specific MT message object. Then API is provided to retrieve fields and sequence labels for the particular MT. MX Printout A similar printout can be generated for MX messages using the MxPrintoutWriter . The output is slightly different. The following example illustrates the default printout in TXT format for an pacs.009: ------------------------- Instance Type and Transmission ------------------------- Copy sent to SWIFT Priority : Normal ------------------------- Message Header ----------------------------------------- Message Type : pacs.009.001.08 - Financial Institution Credit Transfer V08 Sender : AAAAFRPBTGT - FOO BANK OF CANADA, PARIS BRANCH - (TARGET) (FRANCE) Receiver : BBBBDEFFXXX - FOOBAR BANK AG (GERMANY) Reference : FOOJUNE01234 Service Name : swift.cbprplus.02 Creation : 2022-11-11T11:11:11Z ----------------------------- Document ------------------------------------------- Group Header Message Identification : NONREF Creation Date Time : 2022-06-02T20:04:35-04:00 Number Of Transactions : 1 Settlement Information Settlement Method : CLRG Clearing System Code : TGT Credit Transfer Transaction Information Payment Identification Instruction Identification : FOO TEST 5 End To End Identification : FOOJUNE0222T5 UETR : 145c2054-dc14-4b95-93a3-f8e99a712345 Interbank Settlement Amount : EUR 567 Interbank Settlement Date : 2022-11-11 Instructing Agent Financial Institution Identification BICFI : AAAAFRPBTGT - FOO BANK OF CANADA, PARIS BRANCH - (TARGET) (FRANCE) Instructed Agent Financial Institution Identification BICFI : BBBBDEFFXXX - FOOBAR BANK AG (GERMANY) Debtor Financial Institution Identification BICFI : CCCCFRPBTGT - FOO BANK OF CANADA, PARIS BRANCH - (TARGET) (FRANCE) Creditor Financial Institution Identification BICFI : DDDDDEFFXXX - FOOBAR BANK AG (GERMANY) The nested structure of the actual XML is printed with nested indentation. Then BIC information is expanded with the institution name and location, and dates and amounts are formatted. Please check the sample below about how to obtain a printout similar to the one listed above. String xmlInput = \"\\n\" + \"\\n\" + \"\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" AAAAFRPBTGT\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" BBBBDEFFXXX\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" FOOJUNE01234\\n\" + \" pacs.009.001.08\\n\" + \" swift.cbprplus.02\\n\" + \" Normal\\n\" + \" 2022-11-11T11:11:11Z\\n\" + \"\\n\" + \"\\n\" + \" \\n\" + \" \\n\" + \" NONREF\\n\" + \" 2022-06-02T20:04:35-04:00\\n\" + \" 1\\n\" + \" \\n\" + \" CLRG\\n\" + \" \\n\" + \" TGT\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" FOO TEST 5\\n\" + \" FOOJUNE0222T5\\n\" + \" 145c2054-dc14-4b95-93a3-f8e99a712345\\n\" + \" \\n\" + \" 567\\n\" + \" 2022-11-11\\n\" + \" \\n\" + \" \\n\" + \" AAAAFRPBTGT\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" BBBBDEFFXXX\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" CCCCFRPBTGT\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" DDDDDEFFXXX\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \"\\n\" + \"\" ; MxSwiftMessage m = MxSwiftMessage . parse ( xmlInput ); m . setDirection ( MessageIOType . outgoing ); MxPrintoutWriter mxPrintoutWriter = new MxPrintoutWriter ( Locale . ENGLISH , new MxTxtPrintoutVisitor ()); System . out . println ( mxPrintoutWriter . print ( m )); MX Info The MXInfo is a helper class to retrieve ISO 20022 labels for message elements. This classe is created after an ISO 20022 enriched schema, containing documentation annotations. On creation, the XSD is traversed and the labels are stored in a map. MxLabelInfo labelInfo = new MxLabelInfo(MxType.pacs_008_001_10.schema()); Then given a path to a specific element in the specific MX, a similar complete path is returned with the segments as human-friendly labels. For example given the path; /Document/FIToFICstmrCdtTrf/CdtTrfTxInf/InstgAgt/FinInstnId/PstlAdr/DstrctNm the method returns: /Document/FIToFICustomerCreditTransferV10/CreditTransferTransactionInformation/InstructingAgent/FinancialInstitutionIdentification/PostalAddress/DistrictName This is what the MxPrintoutWriter uses to print the MX messages. Customization All aspects of the printout can be customized by providing an implementation of the PrintoutVisitor interface. The methods in this interface are called in a specific order, passing a portion of data retrieved from the message and expecting the output in return. Default implementations for the interface are provided for TXT and HTML formats. As an alternative to implementing the interface from scratch, the default implementations for TXT and HTML can be extended in order to provide an alternative implementation just for specific methods. The interface could be use even to generate a JSON version of the message content, with labels. BIC data A BIC directory is used to print the institution name along with the BIC. By default, the printout uses the default implementation of IBICDirectory from the BICDirectory class. This class uses an Apache Derby DB contained in the pw-swift-integrator-data-1.X.X.jar file. This DB contains the BIC data from the SWIFT BIC directory, and can be updated by you. If you already have a BIC data source and want to use it, you can implement the IBICDirectory interface and pass it to the printout writer constructor. If you do not need the BIC data and want to avoid adding the data jar as dependency, you can pass null to the printout writer constructor like this: PrintoutWriter printoutWriter = new PrintoutWriter ( Locale . ENGLISH , new TxtPrintoutVisitor (), null ); final String text = printoutWriter . print ( m ); Then whenever a BIC is found in the message, it will be printed as is, without the institution name.","title":"Expanded printout"},{"location":"integrator/sdk/sdk-printout/#expanded-printout","text":"The expanded printout generates a human-friendly representation of a message content, including: Comprehensive labels for sequences, fields, and components Expanded BIC information with the institution name and location Formatted dates and amounts The implementation is generic and can be applied to any MT or MX (ISO 20022) message.","title":"Expanded printout"},{"location":"integrator/sdk/sdk-printout/#mt-printout","text":"The main entry point for the feature is the PrintoutWriter class and the print methods. The printout can be done directly into a String object, or an OutputStream can be passed as argument. The following example illustrates the default printout in TXT format for an MT103: ------------------------- Instance Type and Transmission ------------------------- Copy sent to SWIFT Priority/Delivery : Urgent/Delivery Notification ------------------------- Message Header ----------------------------------------- Swift : FIN 103 Single Customer Credit Transfer Sender : XBDSJPJTBXXX - FOO CAPITAL MARKETS (JAPAN) LTD., TOKYO (JAPAN) Receiver : XOJPJPJTXMF1 - BANK OF FOOBAR - (FOR FOOOBAR'S RESERVES USE ONLY) (JAPAN) MUR : FOOB3926BE868XXX ------------------------- Message Text ------------------------------------------- 20: Sender's Reference Reference: 11111111 23B: Bank Operation Code Type: CRED 32A: Value Date/Currency/Interbank Settled Amount Date: Feb 4, 2013 Currency: EUR Amount: 1,234,567.89 33B: Currency/Instructed Amount Currency: USD Amount: 89,431.4 50A: Ordering Customer Account: 12345678901234567890 BIC: AAAAUS33XXX - FOOBAR AND CO. INC. () 59: Beneficiary Customer Account: 12345678901234567890 Name And Address: JOE DOE Name And Address 2: MyStreet 1234 71A: Details of Charges Code: OUR ------------------------- Message Trailer ----------------------------------------- CHK: 3916EF336FF7 Sequences, fields and components are printed with label. BICs are expanded with the institution name and location. Dates and amounts are formatted. Please check the sample below about how to create a printout similar to the one listed above. SwiftMessage m = SwiftMessage . parse ( \"{1:F01XBDSJPJTBXXX0000000000}{2:I103XOJPJPJTXMF1U2}{3:{108:FOOB3926BE868XXX}}{4:\\n\" + \":20:11111111\\n\" + \":23B:CRED\\n\" + \":32A:130204EUR1234567,89\\n\" + \":33B:USD89431,40\\n\" + \":50A:/12345678901234567890\\n\" + \"AAAAUS33XXX\\n\" + \":59:/12345678901234567890\\n\" + \"JOE DOE\\n\" + \"MyStreet 1234\\n\" + \":71A:OUR\\n\" + \"-}\" ); final String text = new PrintoutWriter (). print ( m ); System . out . println ( text );","title":"MT Printout"},{"location":"integrator/sdk/sdk-printout/#localization","text":"The default output prints labels using the default locale, however a specific locale can be passed in the constructor. Current supported languages are English, Spanish, Russian, French, German, and Italian . If a different locale is configured or passed as an argument, or if a particular label is not found in the specific locale, the printing falls back to English as default.","title":"Localization"},{"location":"integrator/sdk/sdk-printout/#mt-info","text":"The MTInfo is a helper class to retrieve message information (label, descriptions) from resource bundles and to print formatted field values. It is used by the printout feature, but can be used independently as well. The resource bundles include translations for English, Spanish, Russian, French, German, and Italian . These labels are provided in the pw_mt_info.properties files. The object is instantiated provided a Locale and a specific MT message object. Then API is provided to retrieve fields and sequence labels for the particular MT.","title":"MT Info"},{"location":"integrator/sdk/sdk-printout/#mx-printout","text":"A similar printout can be generated for MX messages using the MxPrintoutWriter . The output is slightly different. The following example illustrates the default printout in TXT format for an pacs.009: ------------------------- Instance Type and Transmission ------------------------- Copy sent to SWIFT Priority : Normal ------------------------- Message Header ----------------------------------------- Message Type : pacs.009.001.08 - Financial Institution Credit Transfer V08 Sender : AAAAFRPBTGT - FOO BANK OF CANADA, PARIS BRANCH - (TARGET) (FRANCE) Receiver : BBBBDEFFXXX - FOOBAR BANK AG (GERMANY) Reference : FOOJUNE01234 Service Name : swift.cbprplus.02 Creation : 2022-11-11T11:11:11Z ----------------------------- Document ------------------------------------------- Group Header Message Identification : NONREF Creation Date Time : 2022-06-02T20:04:35-04:00 Number Of Transactions : 1 Settlement Information Settlement Method : CLRG Clearing System Code : TGT Credit Transfer Transaction Information Payment Identification Instruction Identification : FOO TEST 5 End To End Identification : FOOJUNE0222T5 UETR : 145c2054-dc14-4b95-93a3-f8e99a712345 Interbank Settlement Amount : EUR 567 Interbank Settlement Date : 2022-11-11 Instructing Agent Financial Institution Identification BICFI : AAAAFRPBTGT - FOO BANK OF CANADA, PARIS BRANCH - (TARGET) (FRANCE) Instructed Agent Financial Institution Identification BICFI : BBBBDEFFXXX - FOOBAR BANK AG (GERMANY) Debtor Financial Institution Identification BICFI : CCCCFRPBTGT - FOO BANK OF CANADA, PARIS BRANCH - (TARGET) (FRANCE) Creditor Financial Institution Identification BICFI : DDDDDEFFXXX - FOOBAR BANK AG (GERMANY) The nested structure of the actual XML is printed with nested indentation. Then BIC information is expanded with the institution name and location, and dates and amounts are formatted. Please check the sample below about how to obtain a printout similar to the one listed above. String xmlInput = \"\\n\" + \"\\n\" + \"\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" AAAAFRPBTGT\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" BBBBDEFFXXX\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" FOOJUNE01234\\n\" + \" pacs.009.001.08\\n\" + \" swift.cbprplus.02\\n\" + \" Normal\\n\" + \" 2022-11-11T11:11:11Z\\n\" + \"\\n\" + \"\\n\" + \" \\n\" + \" \\n\" + \" NONREF\\n\" + \" 2022-06-02T20:04:35-04:00\\n\" + \" 1\\n\" + \" \\n\" + \" CLRG\\n\" + \" \\n\" + \" TGT\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" FOO TEST 5\\n\" + \" FOOJUNE0222T5\\n\" + \" 145c2054-dc14-4b95-93a3-f8e99a712345\\n\" + \" \\n\" + \" 567\\n\" + \" 2022-11-11\\n\" + \" \\n\" + \" \\n\" + \" AAAAFRPBTGT\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" BBBBDEFFXXX\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" CCCCFRPBTGT\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" DDDDDEFFXXX\\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \" \\n\" + \"\\n\" + \"\" ; MxSwiftMessage m = MxSwiftMessage . parse ( xmlInput ); m . setDirection ( MessageIOType . outgoing ); MxPrintoutWriter mxPrintoutWriter = new MxPrintoutWriter ( Locale . ENGLISH , new MxTxtPrintoutVisitor ()); System . out . println ( mxPrintoutWriter . print ( m ));","title":"MX Printout"},{"location":"integrator/sdk/sdk-printout/#mx-info","text":"The MXInfo is a helper class to retrieve ISO 20022 labels for message elements. This classe is created after an ISO 20022 enriched schema, containing documentation annotations. On creation, the XSD is traversed and the labels are stored in a map. MxLabelInfo labelInfo = new MxLabelInfo(MxType.pacs_008_001_10.schema()); Then given a path to a specific element in the specific MX, a similar complete path is returned with the segments as human-friendly labels. For example given the path; /Document/FIToFICstmrCdtTrf/CdtTrfTxInf/InstgAgt/FinInstnId/PstlAdr/DstrctNm the method returns: /Document/FIToFICustomerCreditTransferV10/CreditTransferTransactionInformation/InstructingAgent/FinancialInstitutionIdentification/PostalAddress/DistrictName This is what the MxPrintoutWriter uses to print the MX messages.","title":"MX Info"},{"location":"integrator/sdk/sdk-printout/#customization","text":"All aspects of the printout can be customized by providing an implementation of the PrintoutVisitor interface. The methods in this interface are called in a specific order, passing a portion of data retrieved from the message and expecting the output in return. Default implementations for the interface are provided for TXT and HTML formats. As an alternative to implementing the interface from scratch, the default implementations for TXT and HTML can be extended in order to provide an alternative implementation just for specific methods. The interface could be use even to generate a JSON version of the message content, with labels.","title":"Customization"},{"location":"integrator/sdk/sdk-printout/#bic-data","text":"A BIC directory is used to print the institution name along with the BIC. By default, the printout uses the default implementation of IBICDirectory from the BICDirectory class. This class uses an Apache Derby DB contained in the pw-swift-integrator-data-1.X.X.jar file. This DB contains the BIC data from the SWIFT BIC directory, and can be updated by you. If you already have a BIC data source and want to use it, you can implement the IBICDirectory interface and pass it to the printout writer constructor. If you do not need the BIC data and want to avoid adding the data jar as dependency, you can pass null to the printout writer constructor like this: PrintoutWriter printoutWriter = new PrintoutWriter ( Locale . ENGLISH , new TxtPrintoutVisitor (), null ); final String text = printoutWriter . print ( m ); Then whenever a BIC is found in the message, it will be printed as is, without the institution name.","title":"BIC data"},{"location":"integrator/sdk/sdk-schemes/","text":"MT messages structure schemes in XML Message schemes are a central and powerful part of the component. Message structure schemes are mainly used by the message validator module, but they may be suitable for multiple purposes in a SWIFT message management application. For example, they can be the base information source of a message creation user interface. The schemes are defined by means of an XML, and provided as a Java model in the library. The structure is statically defined in a SchemeNNN class. The following examples serve to quickly understand the content and general structure of these XML schemas: Example 1: Simple message with two inner sequences. Example 2: with two level sequences. (...) Loading schemes To access the out-of-the-box schemes, the MtType enumeration can be used. This enumeration is updated yearly and contains all types available for the current SRU. For example, MtType.MT103.scheme() will return a Scheme object with the specific message schema for MT103. Semantics of XML elements and attributes scheme : Mandatory container tag and root element of every scheme. It identifies the MT being structured. Attributes: name : mandatory identifier of the scheme, usually related to an MT name, as mentioned in the SWIFT Handbook . description : Optional description of message scheme. sequence : All message fields must be part of a specific sequence. At least one main sequence is required, even if the standard does not mention it. Sequences can be nested, conforming to the blocks and subblocks of the message as needed. Attributes: name : Optional name for the sequence, can be a letter based name as used through the SWIFT handbook or any functional name related to the contents of the sequence. minRepetitions : Mandatory attribute accepting an integer number to indicate the minimum repetitions expected of the sequence. A value of \"0\" means that the sequence will be optional, a value of \"1\" means that the sequence is mandatory, and a value of \"n\" (being n an integer number greater than 1) means that the sequence is mandatory and at least n sequences must be filled for a message to be valid according to this scheme definition. maxRepetitions : Mandatory attribute accepting a positive integer number greater or equal to 1 to indicate the maximum allowed repetitions of the sequence. A value of \"1\" means that the sequence can have up to one repetition and a value of \"n\" (being n an integer number greater than 1) means that the sequence is mandatory and at most n sequences can be filled for a message to be valid according to this scheme definition. To allow an unlimited number of repetitions, the literal \"UNLIMITED\" can be used. field : This element defines a SWIFT field. Represents a set of zero or more fields of the sequence. Repetition attributes must be present, as well as \"id\". The letterOption attribute is optional, and the literal \"NONE\" is supported. A letter option indicating \"A, B, NONE\" on a field with id \"50\" for example, means that the field can be 50A, 50B or 50 with no letter option. It accepts the same tag attributes as the sequence element, plus: id : Mandatory attribute to indicate the field numeric identifier without the letter options. letterOptions : Optional attribute to indicate the letter options admitted for the field. The letter option must be ppercase, and it admits a single letter or a comma separated list of letters. The literal \"NONE\" can also be used to indicate that the field admits an empty letter option (Notice that a \"NONE\" value is the default for the element, meaning that if the letterOption attribute is not present, the field will not accept letter options. The literal is useful for particular fields where it is valid to a letter option \"A\" for example as well as no letter option at all). qualifiers : Optional attribute to specify fixed values for the field. The attribute value supports complex combination from a simple fixed literal to a combination of qualifiers per letter option and field\u2019s components. For example, a simple value of \"GENL\" means that the field is expected to have the literal GENL as value. Multiple values can be indicated with a comma/whitespace separated list, for example: \"SECU, SEGU, OTHR\" meaning that the field can have any of the mentioned literals. If the field supports several letter options, the literal qualifiers can be indicated for particular letter options for example: \"SECU, A.SEGU, B.OTHR\" means that literal SEGU is expected for any letter option, SEGU is expected for letter option A, and OTHR for letter option B. By default the qualifier is validated against the first component of the field. If a specific field\u2019s component is expected to have the qualifier, a letter, and component number combination can be expressed. For example, the qualifier J.5.ACCU means that for letter option J, field\u2019s component 5 is expected to have the literal ACCU as value. Fieldsets This section describes some advanced features of the XML schemes that may be useful to tune up validations on specific scenarios. All messages for category 5, as well as some messages for category 3 have an extensive structure definition. These definitions are performed with the same XML described above, but including two special features: fieldsets and evaluations. A fieldset is a definition of a message field that has several consecutive and unordered instances. All fields in the fieldset share the field number, but may accept different letter options and different qualifiers. For example, the following definition will accept up to three instances of field 20C with the qualifiers CORP, SEME and COAF, with two of them mandatory and one optional:
            The validation of this structure is well covered by the SWIFT Handbook . Please notice that a fieldset is different from a field with repetitions because it can have different qualifiers, letter options, and expected repetitions of each item. It also is different from a sequence because the items can appear in the message in any order. Semantic of the fieldset XML definition and attributes: fieldset : Mandatory container tag and root element of every fieldset. Attributes: id : Mandatory identifier field's number defined by the fieldset. All inner items will share this field number. letterOption : Optional identification of the letter option. If this attribute is defined on the fieldset tag, all inner items will share the same expected letter options. minRepetitions : Optional attribute accepting an integer number to indicate the minimum repetitions expected of all inner items of this fieldset. If this attribute is defined on the fieldset tag, all inner items will share the same expected minimum repetition. maxRepetitions : Optional attribute accepting a positive integer number greater or equal to 1 to indicate the maximum allowed repetitions of all inner items of this fieldset. If this attribute is defined on the fieldset tag, all inner items will share the same expected maximum repetition. item : Definition of each possible field instance into the container fieldset. Attributes: letterOption : Optional identification of the letter option. This value can be overwritten if the letter option is defined at the container fieldset. minRepetitions : Definition of the minimum repetitions expected for the field instance. This value can be overwritten if the letter option is defined at the container fieldset. If the attribute is not defined for the fieldset, it is mandatory to define it in the item. maxRepetitions : Definition of the maximum repetitions expected for the field instance. This value can be overwritten if the letter option is defined at the container fieldset. If the attribute is not defined for the fieldset, it is mandatory to define it in the item. qualifiers : Optional attribute to specify fixed values for the field. Qualifier validation evaluations Qualifier validation elements are used to indicate the allowed field qualifiers and conditional qualifiers within field, fieldset and item elements. Notice for simple cases where the field or item expects certain qualifiers, the direct qualifiers attribute described above suffices. However, for some message types the logic to determine the expected qualifier is more complex and has to be defined conditionally. The qualifierValidation element might contain several attributes. Some attributes are used as a conditional , to determine if the actual validation applies. Plus the attributes to define the actual constraint . For example, the following definition will match fields 94B, with qualifiers PRIC or RATS, and if the DSS (data source definition) of the field is not set, then the conditional qualifier (component 3) must be LMAR, FIND, THEO or VEND.
            In the above example, the notDssCondition is the conditional and the conditionalQualifiers is the actual constraint. The available attributes for the conditional part are: notDssCondition : boolean value, when true, means the field\u2019s DSS (data source definition) should not be present for the qualifier validation to apply. letterCondition : string value with the field instance letter option (admits a csv list), the qualifier validation will be applied only if the field matches the letter. qualifierCondition : a specific qualifier that the field must match in order for the conditional qualifier validation to apply. The available attributes for the constraint are: qualifiers(list) : function that evaluates to true if the field main qualifier has any of the given values. The list parameter is a string value with one or many qualifiers, separated with a comma. Each qualifier may be prefixed with an integer to specify the component that will be checked (by default, the component checked is the component 1). conditionalQualifiers(list) : function that evaluates to true if the field conditional qualifier has any of the given values. The component used as a \"conditional qualifier\" is the third component. For example, when the field defines a data source scheme as the second component (for example 22F), or the second component if the field does not define a data source scheme (for example 12C). The conditional qualifier function is intended only for generic fields (Field that implements the interface GenericField ). For all other fields, the verifyQualifier function should be used. Then when defining the actual qualifiers or conditional qualifiers list in the constraint, a couple of fixed literal expressions are supported. These are needed just for two particular cases. These expressions are interpreted as literals, thus these specific strings are the only ones supported: [3!n_NOT_ZERO] : string value that can be used in a qualifier list parameter and will evaluate to true if the component value is composed of three numbers and not 000. [4!n_NOT_ZERO] : string value that can be used in a qualifier list parameter and will evaluate to true if the component value is composed of four numbers and not 000. Several examples of qualifierValidation can be found in the included XML schemes of the package. For example: During the validation, the attributes in the qualifierValidation element are evaluated in order to determine if the input is valid or not. The validation engine will match the field/item only if all the attributes are evaluated as true. If an evaluation is false, the field may be reported as an unexpected field.","title":"MT schemes"},{"location":"integrator/sdk/sdk-schemes/#mt-messages-structure-schemes-in-xml","text":"Message schemes are a central and powerful part of the component. Message structure schemes are mainly used by the message validator module, but they may be suitable for multiple purposes in a SWIFT message management application. For example, they can be the base information source of a message creation user interface. The schemes are defined by means of an XML, and provided as a Java model in the library. The structure is statically defined in a SchemeNNN class. The following examples serve to quickly understand the content and general structure of these XML schemas: Example 1: Simple message with two inner sequences. Example 2: with two level sequences. (...) ","title":"MT messages structure schemes in XML"},{"location":"integrator/sdk/sdk-schemes/#loading-schemes","text":"To access the out-of-the-box schemes, the MtType enumeration can be used. This enumeration is updated yearly and contains all types available for the current SRU. For example, MtType.MT103.scheme() will return a Scheme object with the specific message schema for MT103.","title":"Loading schemes"},{"location":"integrator/sdk/sdk-schemes/#semantics-of-xml-elements-and-attributes","text":"scheme : Mandatory container tag and root element of every scheme. It identifies the MT being structured. Attributes: name : mandatory identifier of the scheme, usually related to an MT name, as mentioned in the SWIFT Handbook . description : Optional description of message scheme. sequence : All message fields must be part of a specific sequence. At least one main sequence is required, even if the standard does not mention it. Sequences can be nested, conforming to the blocks and subblocks of the message as needed. Attributes: name : Optional name for the sequence, can be a letter based name as used through the SWIFT handbook or any functional name related to the contents of the sequence. minRepetitions : Mandatory attribute accepting an integer number to indicate the minimum repetitions expected of the sequence. A value of \"0\" means that the sequence will be optional, a value of \"1\" means that the sequence is mandatory, and a value of \"n\" (being n an integer number greater than 1) means that the sequence is mandatory and at least n sequences must be filled for a message to be valid according to this scheme definition. maxRepetitions : Mandatory attribute accepting a positive integer number greater or equal to 1 to indicate the maximum allowed repetitions of the sequence. A value of \"1\" means that the sequence can have up to one repetition and a value of \"n\" (being n an integer number greater than 1) means that the sequence is mandatory and at most n sequences can be filled for a message to be valid according to this scheme definition. To allow an unlimited number of repetitions, the literal \"UNLIMITED\" can be used. field : This element defines a SWIFT field. Represents a set of zero or more fields of the sequence. Repetition attributes must be present, as well as \"id\". The letterOption attribute is optional, and the literal \"NONE\" is supported. A letter option indicating \"A, B, NONE\" on a field with id \"50\" for example, means that the field can be 50A, 50B or 50 with no letter option. It accepts the same tag attributes as the sequence element, plus: id : Mandatory attribute to indicate the field numeric identifier without the letter options. letterOptions : Optional attribute to indicate the letter options admitted for the field. The letter option must be ppercase, and it admits a single letter or a comma separated list of letters. The literal \"NONE\" can also be used to indicate that the field admits an empty letter option (Notice that a \"NONE\" value is the default for the element, meaning that if the letterOption attribute is not present, the field will not accept letter options. The literal is useful for particular fields where it is valid to a letter option \"A\" for example as well as no letter option at all). qualifiers : Optional attribute to specify fixed values for the field. The attribute value supports complex combination from a simple fixed literal to a combination of qualifiers per letter option and field\u2019s components. For example, a simple value of \"GENL\" means that the field is expected to have the literal GENL as value. Multiple values can be indicated with a comma/whitespace separated list, for example: \"SECU, SEGU, OTHR\" meaning that the field can have any of the mentioned literals. If the field supports several letter options, the literal qualifiers can be indicated for particular letter options for example: \"SECU, A.SEGU, B.OTHR\" means that literal SEGU is expected for any letter option, SEGU is expected for letter option A, and OTHR for letter option B. By default the qualifier is validated against the first component of the field. If a specific field\u2019s component is expected to have the qualifier, a letter, and component number combination can be expressed. For example, the qualifier J.5.ACCU means that for letter option J, field\u2019s component 5 is expected to have the literal ACCU as value.","title":"Semantics of XML elements and attributes"},{"location":"integrator/sdk/sdk-schemes/#fieldsets","text":"This section describes some advanced features of the XML schemes that may be useful to tune up validations on specific scenarios. All messages for category 5, as well as some messages for category 3 have an extensive structure definition. These definitions are performed with the same XML described above, but including two special features: fieldsets and evaluations. A fieldset is a definition of a message field that has several consecutive and unordered instances. All fields in the fieldset share the field number, but may accept different letter options and different qualifiers. For example, the following definition will accept up to three instances of field 20C with the qualifiers CORP, SEME and COAF, with two of them mandatory and one optional:
            The validation of this structure is well covered by the SWIFT Handbook . Please notice that a fieldset is different from a field with repetitions because it can have different qualifiers, letter options, and expected repetitions of each item. It also is different from a sequence because the items can appear in the message in any order. Semantic of the fieldset XML definition and attributes: fieldset : Mandatory container tag and root element of every fieldset. Attributes: id : Mandatory identifier field's number defined by the fieldset. All inner items will share this field number. letterOption : Optional identification of the letter option. If this attribute is defined on the fieldset tag, all inner items will share the same expected letter options. minRepetitions : Optional attribute accepting an integer number to indicate the minimum repetitions expected of all inner items of this fieldset. If this attribute is defined on the fieldset tag, all inner items will share the same expected minimum repetition. maxRepetitions : Optional attribute accepting a positive integer number greater or equal to 1 to indicate the maximum allowed repetitions of all inner items of this fieldset. If this attribute is defined on the fieldset tag, all inner items will share the same expected maximum repetition. item : Definition of each possible field instance into the container fieldset. Attributes: letterOption : Optional identification of the letter option. This value can be overwritten if the letter option is defined at the container fieldset. minRepetitions : Definition of the minimum repetitions expected for the field instance. This value can be overwritten if the letter option is defined at the container fieldset. If the attribute is not defined for the fieldset, it is mandatory to define it in the item. maxRepetitions : Definition of the maximum repetitions expected for the field instance. This value can be overwritten if the letter option is defined at the container fieldset. If the attribute is not defined for the fieldset, it is mandatory to define it in the item. qualifiers : Optional attribute to specify fixed values for the field.","title":"Fieldsets"},{"location":"integrator/sdk/sdk-schemes/#qualifier-validation-evaluations","text":"Qualifier validation elements are used to indicate the allowed field qualifiers and conditional qualifiers within field, fieldset and item elements. Notice for simple cases where the field or item expects certain qualifiers, the direct qualifiers attribute described above suffices. However, for some message types the logic to determine the expected qualifier is more complex and has to be defined conditionally. The qualifierValidation element might contain several attributes. Some attributes are used as a conditional , to determine if the actual validation applies. Plus the attributes to define the actual constraint . For example, the following definition will match fields 94B, with qualifiers PRIC or RATS, and if the DSS (data source definition) of the field is not set, then the conditional qualifier (component 3) must be LMAR, FIND, THEO or VEND.
            In the above example, the notDssCondition is the conditional and the conditionalQualifiers is the actual constraint. The available attributes for the conditional part are: notDssCondition : boolean value, when true, means the field\u2019s DSS (data source definition) should not be present for the qualifier validation to apply. letterCondition : string value with the field instance letter option (admits a csv list), the qualifier validation will be applied only if the field matches the letter. qualifierCondition : a specific qualifier that the field must match in order for the conditional qualifier validation to apply. The available attributes for the constraint are: qualifiers(list) : function that evaluates to true if the field main qualifier has any of the given values. The list parameter is a string value with one or many qualifiers, separated with a comma. Each qualifier may be prefixed with an integer to specify the component that will be checked (by default, the component checked is the component 1). conditionalQualifiers(list) : function that evaluates to true if the field conditional qualifier has any of the given values. The component used as a \"conditional qualifier\" is the third component. For example, when the field defines a data source scheme as the second component (for example 22F), or the second component if the field does not define a data source scheme (for example 12C). The conditional qualifier function is intended only for generic fields (Field that implements the interface GenericField ). For all other fields, the verifyQualifier function should be used. Then when defining the actual qualifiers or conditional qualifiers list in the constraint, a couple of fixed literal expressions are supported. These are needed just for two particular cases. These expressions are interpreted as literals, thus these specific strings are the only ones supported: [3!n_NOT_ZERO] : string value that can be used in a qualifier list parameter and will evaluate to true if the component value is composed of three numbers and not 000. [4!n_NOT_ZERO] : string value that can be used in a qualifier list parameter and will evaluate to true if the component value is composed of four numbers and not 000. Several examples of qualifierValidation can be found in the included XML schemes of the package. For example: During the validation, the attributes in the qualifierValidation element are evaluated in order to determine if the input is valid or not. The validation engine will match the field/item only if all the attributes are evaluated as true. If an evaluation is false, the field may be reported as an unexpected field.","title":"Qualifier validation evaluations"},{"location":"integrator/translations/","text":"Prowide Integrator Translations - Overview The Translations library provides out-of-the-box conversions between MT and ISO 20022 messages. The library is used in runtime, as a regular dependency, to convert messages on the fly. The conversion process is based on a set of rules that are embedded in the implementation and are maintained by Prowide as the standards change. The translation is built on top of the Prowide Core and Prowide ISO 20022 message model. Therefore, the same API and classes used for parsing or building the messages are used as parameters and return values of the translation. Automatic message conversion is also possible by means of a Factory that given a source message in either MT or MX format can autodetect the message type and find a suitable translator implementation for its equivalent in the other standard. Javadoc Online javadoc Prowide Integrator Translations Javadoc SRU2023-9.4.x","title":"Prowide Integrator Translations - Overview"},{"location":"integrator/translations/#prowide-integrator-translations-overview","text":"The Translations library provides out-of-the-box conversions between MT and ISO 20022 messages. The library is used in runtime, as a regular dependency, to convert messages on the fly. The conversion process is based on a set of rules that are embedded in the implementation and are maintained by Prowide as the standards change. The translation is built on top of the Prowide Core and Prowide ISO 20022 message model. Therefore, the same API and classes used for parsing or building the messages are used as parameters and return values of the translation. Automatic message conversion is also possible by means of a Factory that given a source message in either MT or MX format can autodetect the message type and find a suitable translator implementation for its equivalent in the other standard.","title":"Prowide Integrator Translations - Overview"},{"location":"integrator/translations/#javadoc","text":"Online javadoc Prowide Integrator Translations Javadoc SRU2023-9.4.x","title":"Javadoc"},{"location":"integrator/translations/translations-avail/","text":"Available Translations The following table contains all out-of-the-box translations. The provided implementations within its internal mapping logic are based on the equivalence tables defined by SWIFT. Notice there is no linear correlation between the source and target of the available translation, meaning that if A can be translated to B, the reverse is not always true. The tables below are only a general reference. New translations are added on a regular basis. For a most accurate and up-to-date list, please check the actual classes available in the com.prowidesoftware.swift.translations package of your distribution, and in the restricted ISO 20022 version subpackages such as com.prowidesoftware.swift.translations.cbpr and com.prowidesoftware.swift.translations.sic . MT to MX ISO Source Target 101 pain.001.001.03 101 pain.001.001.08 101 pain.001.001.09 102 pacs.008.001.08 102 pacs.008.001.09 102 pacs.008.001.10 103 pacs.002.001.10 103 pacs.004.001.09 103 pacs.004.001.10 103 pacs.008.001.02 103 pacs.008.001.06 103 pacs.008.001.07 103 pacs.008.001.08 103 pacs.008.001.09 103 pacs.008.001.10 103.REMIT pacs.008.001.02 103.REMIT pacs.008.001.06 103.REMIT pacs.008.001.07 103.REMIT pacs.008.001.08 103.REMIT pacs.008.001.09 103.REMIT pacs.008.001.10 103.STP pacs.008.001.02 103.STP pacs.008.001.06 103.STP pacs.008.001.07 103.STP pacs.008.001.08 103.STP pacs.008.001.09 104 pacs.003.001.08 104 pacs.003.001.09 104 pacs.003.001.10 104 pain.008.001.08 107 pacs.003.001.08 107 pacs.003.001.09 107 pacs.003.001.10 110 camt.107.001.01 111 camt.108.001.01 112 camt.109.001.01 192 camt.056.001.08 192 camt.056.001.10 192 camt.058.001.08 196 camt.029.001.09 196 camt.029.001.11 199 pacs.002.001.10 200 camt.050.001.05 200 pacs.009.001.08 200 pacs.009.001.09 200 pacs.009.001.10 202 pacs.002.001.10 202 pacs.004.001.09 202 pacs.004.001.10 202 pacs.009.001.02 202 pacs.009.001.06 202 pacs.009.001.07 202 pacs.009.001.08 202 pacs.009.001.09 202 pacs.009.001.10 202.COV pacs.002.001.10 202.COV pacs.009.001.02 202.COV pacs.009.001.06 202.COV pacs.009.001.07 202.COV pacs.009.001.08 202.COV pacs.009.001.09 202.COV pacs.009.001.10 204 pacs.010.001.03 205 pacs.002.001.10 205 pacs.004.001.09 205 pacs.004.001.10 205 pacs.009.001.08 205 pacs.009.001.09 205.COV pacs.002.001.10 205.COV pacs.009.001.08 205.COV pacs.009.001.09 210 camt.057.001.06 292 camt.056.001.08 292 camt.056.001.10 292 camt.058.001.08 296 camt.029.001.09 296 camt.029.001.11 299 pacs.002.001.10 300 fxtr.014.001.03 502 setr.004.002.01 502 setr.010.002.01 508 semt.015.002.01 508 semt.020.002.01 509 setr.016.001.04 509 setr.016.002.01 509 setr.017.001.04 515 setr.006.001.04 515 setr.006.002.01 515 setr.012.001.04 515 setr.012.002.01 524 semt.013.002.01 524 sese.020.002.01 530 sese.030.001.08 530 sese.030.002.01 535 semt.002.001.11 535 semt.002.002.03 535 semt.003.002.03 535 semt.020.002.01 536 semt.017.001.12 536 semt.020.002.01 537 semt.018.001.13 537 semt.018.002.01 537 semt.020.002.01 538 semt.016.002.01 538 semt.020.002.01 540 sese.020.001.06 540 sese.020.001.07 540 sese.020.002.01 540 sese.023.001.09 540 sese.023.001.11 540 sese.023.002.01 540 sese.033.002.01 540 sese.036.002.01 541 sese.020.001.06 541 sese.020.001.07 541 sese.020.002.01 541 sese.023.001.09 541 sese.023.001.11 541 sese.023.002.01 541 sese.033.002.01 541 sese.036.002.01 542 sese.020.001.06 542 sese.020.001.07 542 sese.020.002.01 542 sese.023.001.09 542 sese.023.001.11 542 sese.023.002.01 542 sese.033.002.01 542 sese.036.002.01 543 sese.020.001.06 543 sese.020.001.07 543 sese.020.002.01 543 sese.023.001.09 543 sese.023.001.11 543 sese.023.002.01 543 sese.033.002.01 543 sese.036.002.01 544 semt.020.002.01 544 sese.025.001.09 544 sese.025.001.11 544 sese.025.002.01 544 sese.026.001.10 544 sese.026.002.01 544 sese.035.002.01 545 semt.020.002.01 545 sese.025.001.09 545 sese.025.001.11 545 sese.025.002.01 545 sese.026.001.10 545 sese.026.002.01 545 sese.035.002.01 546 semt.020.002.01 546 sese.025.001.09 546 sese.025.001.11 546 sese.025.002.01 546 sese.026.001.10 546 sese.026.002.01 546 sese.035.002.01 547 semt.020.002.01 547 sese.025.001.09 547 sese.025.001.11 547 sese.025.002.01 547 sese.026.001.10 547 sese.026.002.01 547 sese.035.002.01 548 semt.014.002.01 548 sese.022.002.01 548 sese.024.001.10 548 sese.024.001.11 548 sese.024.001.12 548 sese.024.002.01 548 sese.027.001.05 548 sese.027.002.01 548 sese.031.001.08 548 sese.031.002.01 548 sese.032.002.01 548 sese.034.002.01 549 semt.021.002.01 549 sese.021.002.01 564 seev.031.001.10 564 seev.031.001.11 564 seev.031.002.02 564 seev.031.002.06 564 seev.031.002.12 564 seev.031.002.13 564 seev.035.001.12 564 seev.035.002.02 564 seev.035.002.12 564 seev.039.002.02 564 seev.039.002.06 564 seev.039.002.11 564 seev.044.001.10 564 seev.044.002.02 564 seev.044.002.10 565 seev.033.002.02 565 seev.033.002.12 565 seev.040.002.02 565 seev.040.002.11 566 seev.036.001.12 566 seev.036.002.02 566 seev.036.002.06 566 seev.036.002.07 566 seev.036.002.08 566 seev.036.002.09 566 seev.036.002.12 566 seev.037.001.12 566 seev.037.002.02 566 seev.037.002.06 566 seev.037.002.07 566 seev.037.002.08 566 seev.037.002.09 566 seev.037.002.12 567 seev.032.002.02 567 seev.032.002.08 567 seev.034.002.02 567 seev.034.002.13 567 seev.041.001.10 567 seev.041.002.12 568 seev.031.001.10 568 seev.031.001.11 568 seev.031.002.02 568 seev.031.002.06 568 seev.031.002.12 568 seev.031.002.13 568 seev.038.002.02 568 seev.038.002.07 578 semt.020.001.07 578 semt.020.002.01 578 sese.028.001.08 578 sese.028.002.01 578 sese.029.002.01 586 semt.019.002.01 586 semt.020.002.01 586 sese.037.002.01 900 camt.054.001.02 900 camt.054.001.06 900 camt.054.001.07 900 camt.054.001.08 900 camt.054.001.09 910 camt.054.001.02 910 camt.054.001.06 910 camt.054.001.07 910 camt.054.001.08 910 camt.054.001.09 920 camt.060.001.05 920 camt.060.001.06 940 camt.053.001.02 940 camt.053.001.06 940 camt.053.001.07 940 camt.053.001.08 940 camt.053.001.09 940 camt.053.001.10 940 camt.053.001.11 941 camt.052.001.02 941 camt.052.001.06 941 camt.052.001.07 941 camt.052.001.08 941 camt.052.001.09 942 camt.052.001.02 942 camt.052.001.06 942 camt.052.001.07 942 camt.052.001.08 942 camt.052.001.09 950 camt.053.001.02 950 camt.053.001.06 950 camt.053.001.07 950 camt.053.001.08 950 camt.053.001.09 950 camt.053.001.10 950 camt.053.001.11 CBPR Source Target 101 pain.001.001.09 102 pacs.008.001.08 102.STP pacs.008.001.08.STP 103 pacs.002.001.10 103 pacs.004.001.09 103 pacs.008.001.08 103.STP pacs.008.001.08.STP 104 pacs.003.001.08 104 pain.008.001.08 107 pacs.003.001.08 110 camt.107.001.01 111 camt.108.001.01 112 camt.109.001.01 192 camt.055.001.08 192 camt.056.001.08 196 camt.029.001.09 199 pacs.002.001.10 200 pacs.009.001.08 201 pacs.009.001.08 202 pacs.002.001.10 202 pacs.004.001.09 202 pacs.009.001.08 202 pacs.009.001.08.ADV 202.COV pacs.002.001.10 202.COV pacs.009.001.08.COV 203 pacs.009.001.08 204 pacs.010.001.03 205 pacs.002.001.10 205 pacs.004.001.09 205 pacs.009.001.08 205.COV pacs.002.001.10 205.COV pacs.009.001.08.COV 210 camt.057.001.06 292 camt.056.001.08 292 camt.058.001.08 296 camt.029.001.09 299 pacs.002.001.10 900 camt.054.001.08 910 camt.054.001.08 920 camt.060.001.05 940 camt.053.001.08 941 camt.052.001.08 942 camt.052.001.08 950 camt.053.001.08 CHATS Source Target 103 pacs.008.001.08 192 camt.056.001.08 202 pacs.009.001.08 202.COV pacs.009.001.08 292 camt.056.001.08 LYNX Source Target 103 pacs.004.001.09 103 pacs.008.001.08 202 pacs.004.001.09 202 pacs.009.001.08 202.COV pacs.009.001.08 205 pacs.004.001.09 205 pacs.009.001.08 RITS Source Target 103 pacs.008.001.09 202 pacs.009.001.09 202.COV pacs.009.001.09 SCRIPS Source Target 103 pacs.008.001.08 202 pacs.009.001.08 202.COV pacs.009.001.08 SIC_v4_10 Source Target 103 pacs.008.001.08.Ch02 202 pacs.009.001.08.Ch03 202.COV pacs.009.001.08.Ch03 SWIFTGO Source Target 103 pacs.008.001.08 199 trck.001.001.02 199 trck.002.001.01 T2 Source Target 103 pacs.004.001.09 103 pacs.008.001.08 202 pacs.004.001.09 202 pacs.009.001.08 205 pacs.004.001.09 205 pacs.009.001.08 MX to MT ISO Source Target camt.029.001.09 196 camt.029.001.09 296 camt.029.001.11 196 camt.029.001.11 296 camt.050.001.05 200 camt.052.001.06 941 camt.052.001.06 942 camt.052.001.07 941 camt.052.001.07 942 camt.052.001.08 941 camt.052.001.08 942 camt.052.001.09 941 camt.052.001.09 942 camt.053.001.02 940 camt.053.001.06 940 camt.053.001.06 950 camt.053.001.07 940 camt.053.001.07 950 camt.053.001.08 940 camt.053.001.08 950 camt.053.001.09 940 camt.053.001.09 950 camt.053.001.10 940 camt.053.001.10 950 camt.053.001.11 940 camt.053.001.11 950 camt.054.001.06 900 camt.054.001.06 910 camt.054.001.07 900 camt.054.001.07 910 camt.054.001.08 900 camt.054.001.08 910 camt.054.001.09 900 camt.054.001.09 910 camt.056.001.08 192 camt.056.001.08 292 camt.056.001.10 192 camt.056.001.10 292 camt.057.001.06 210 camt.060.001.05 920 camt.060.001.06 920 camt.107.001.01 110 camt.108.001.01 111 camt.109.001.01 112 pacs.002.001.10 199 pacs.002.001.10 299 pacs.003.001.08 104 pacs.003.001.08 107 pacs.003.001.09 104 pacs.003.001.09 107 pacs.003.001.10 104 pacs.003.001.10 107 pacs.004.001.02 103 pacs.004.001.09 103 pacs.004.001.09 202 pacs.004.001.09 205 pacs.004.001.10 103 pacs.004.001.10 202 pacs.004.001.10 205 pacs.008.001.02 103 pacs.008.001.06 103 pacs.008.001.07 103 pacs.008.001.08 102 pacs.008.001.08 103 pacs.008.001.08 103.REMIT pacs.008.001.09 102 pacs.008.001.09 103 pacs.008.001.10 102 pacs.008.001.10 103 pacs.009.001.02 202 pacs.009.001.02 202.COV pacs.009.001.06 202 pacs.009.001.06 202.COV pacs.009.001.07 202 pacs.009.001.07 202.COV pacs.009.001.08 200 pacs.009.001.08 202 pacs.009.001.08 202.COV pacs.009.001.08 205 pacs.009.001.08 205.COV pacs.009.001.09 200 pacs.009.001.09 202 pacs.009.001.09 202.COV pacs.009.001.09 205 pacs.009.001.10 200 pacs.009.001.10 202 pacs.009.001.10 202.COV pacs.009.001.10 205 pacs.010.001.03 204 pain.001.001.03 101 pain.001.001.08 101 pain.001.001.09 101 pain.001.001.09 103 seev.001.001.10 564 seev.002.001.09 564 seev.003.001.09 564 seev.004.001.09 565 seev.005.001.09 565 seev.006.001.09 567 seev.007.001.09 567 seev.008.001.08 568 seev.031.001.03 564 seev.031.001.03 568 seev.031.001.09 564 seev.031.001.10 564 seev.031.001.10 568 seev.031.001.11 564 seev.031.001.11 568 seev.031.001.12 564 seev.031.001.12 568 seev.031.001.13 564 seev.031.001.13 568 seev.031.002.02 564 seev.031.002.02 568 seev.031.002.12 564 seev.031.002.12 568 seev.031.002.13 564 seev.031.002.13 568 seev.032.002.02 567 seev.032.002.08 567 seev.033.002.02 565 seev.033.002.12 565 seev.034.002.02 567 seev.034.002.13 567 seev.035.001.03 564 seev.035.001.10 564 seev.035.001.11 564 seev.035.001.12 564 seev.035.001.13 564 seev.035.001.14 564 seev.035.002.02 564 seev.035.002.12 564 seev.036.001.11 566 seev.036.001.12 566 seev.036.001.13 566 seev.036.001.14 566 seev.036.002.02 566 seev.036.002.06 566 seev.036.002.07 566 seev.036.002.08 566 seev.036.002.09 566 seev.036.002.12 566 seev.037.001.11 566 seev.037.001.12 566 seev.037.001.13 566 seev.037.001.14 566 seev.037.002.02 566 seev.037.002.06 566 seev.037.002.07 566 seev.037.002.08 566 seev.037.002.09 566 seev.037.002.12 566 seev.038.001.03 568 seev.038.002.02 568 seev.038.002.07 568 seev.039.001.03 564 seev.039.001.10 564 seev.039.001.11 564 seev.039.001.12 564 seev.039.002.02 564 seev.039.002.11 564 seev.040.002.02 565 seev.040.002.11 565 seev.041.002.12 567 seev.044.001.03 564 seev.044.001.10 564 seev.044.001.11 564 seev.044.001.12 564 seev.044.002.02 564 seev.044.002.10 564 semt.002.001.10 535 semt.002.001.11 535 semt.002.002.03 535 semt.003.002.03 535 semt.013.002.01 524 semt.014.002.01 548 semt.015.002.01 508 semt.016.002.01 538 semt.017.001.12 536 semt.017.002.01 536 semt.018.001.13 537 semt.018.002.01 537 semt.019.002.01 586 semt.020.001.05 578 semt.020.001.07 578 semt.020.002.01 508 semt.020.002.01 535 semt.020.002.01 536 semt.020.002.01 537 semt.020.002.01 538 semt.020.002.01 544 semt.020.002.01 545 semt.020.002.01 546 semt.020.002.01 547 semt.020.002.01 578 semt.020.002.01 586 semt.021.002.01 549 sese.020.001.06 540 sese.020.001.06 541 sese.020.001.06 542 sese.020.001.06 543 sese.020.001.07 540 sese.020.001.07 541 sese.020.001.07 542 sese.020.001.07 543 sese.020.002.01 524 sese.020.002.01 540 sese.020.002.01 541 sese.020.002.01 542 sese.020.002.01 543 sese.021.002.01 549 sese.022.002.01 548 sese.023.001.09 540 sese.023.001.09 541 sese.023.001.09 542 sese.023.001.09 543 sese.023.001.11 540 sese.023.001.11 541 sese.023.001.11 542 sese.023.001.11 543 sese.023.002.01 540 sese.023.002.01 541 sese.023.002.01 542 sese.023.002.01 543 sese.024.001.09 548 sese.024.001.10 548 sese.024.001.11 548 sese.024.001.12 548 sese.024.002.01 548 sese.025.001.09 544 sese.025.001.09 545 sese.025.001.09 546 sese.025.001.09 547 sese.025.001.11 544 sese.025.001.11 545 sese.025.001.11 546 sese.025.001.11 547 sese.025.002.01 544 sese.025.002.01 545 sese.025.002.01 546 sese.025.002.01 547 sese.026.001.10 544 sese.026.001.10 545 sese.026.001.10 546 sese.026.001.10 547 sese.026.002.01 544 sese.026.002.01 545 sese.026.002.01 546 sese.026.002.01 547 sese.027.001.05 548 sese.027.002.01 548 sese.028.001.08 578 sese.028.001.09 578 sese.028.001.10 578 sese.028.002.01 578 sese.029.001.04 578 sese.029.002.01 578 sese.030.001.08 530 sese.030.002.01 530 sese.031.001.08 548 sese.031.002.01 548 sese.032.002.01 548 sese.033.002.01 540 sese.033.002.01 541 sese.033.002.01 542 sese.033.002.01 543 sese.034.002.01 548 sese.035.002.01 544 sese.035.002.01 545 sese.035.002.01 546 sese.035.002.01 547 sese.036.002.01 540 sese.036.002.01 541 sese.036.002.01 542 sese.036.002.01 543 sese.037.002.01 586 setr.004.001.04 502 setr.004.002.01 502 setr.006.001.04 515 setr.006.002.01 515 setr.010.001.04 502 setr.010.002.01 502 setr.012.001.04 515 setr.012.002.01 515 setr.015.001.04 515.Redemption setr.015.001.04 515.Subscription setr.016.001.04 509 setr.016.002.01 509 setr.017.001.04 509 CBPR Source Target camt.029.001.09 196 camt.029.001.09 296 camt.052.001.08 941 camt.052.001.08 942 camt.053.001.08 940 camt.053.001.08 950 camt.054.001.08 900 camt.054.001.08 910 camt.055.001.08 192 camt.056.001.08 192 camt.056.001.08 292 camt.057.001.06 210 camt.058.001.08 292 camt.060.001.05 920 camt.107.001.01 110 camt.108.001.01 111 camt.109.001.01 112 pacs.002.001.10 199 pacs.002.001.10 299 pacs.003.001.08 104 pacs.003.001.08 107 pacs.004.001.09 103 pacs.004.001.09 202 pacs.004.001.09 205 pacs.008.001.08 102 pacs.008.001.08 103 pacs.008.001.08 103.REMIT pacs.008.001.08STP 102STP pacs.008.001.08STP 103STP pacs.009.001.08 200 pacs.009.001.08 202 pacs.009.001.08 205 pacs.009.001.08.ADV 202 pacs.009.001.08.COV 202.COV pacs.009.001.08.COV 205.COV pacs.010.001.03 204 pain.001.001.09 101 pain.008.001.08 104 SIC_v4_10 Source Target pacs.004.001.09.Ch02 103 pacs.008.001.08.Ch02 103 pacs.009.001.08.Ch03 202 pacs.009.001.08.Ch03 202.COV SWIFTGO Source Target pacs.008.001.08 103 trck.001.001.02 199 trck.002.001.01 199","title":"Available Translations"},{"location":"integrator/translations/translations-avail/#available-translations","text":"The following table contains all out-of-the-box translations. The provided implementations within its internal mapping logic are based on the equivalence tables defined by SWIFT. Notice there is no linear correlation between the source and target of the available translation, meaning that if A can be translated to B, the reverse is not always true. The tables below are only a general reference. New translations are added on a regular basis. For a most accurate and up-to-date list, please check the actual classes available in the com.prowidesoftware.swift.translations package of your distribution, and in the restricted ISO 20022 version subpackages such as com.prowidesoftware.swift.translations.cbpr and com.prowidesoftware.swift.translations.sic .","title":"Available Translations"},{"location":"integrator/translations/translations-avail/#mt-to-mx","text":"","title":"MT to MX"},{"location":"integrator/translations/translations-avail/#iso","text":"Source Target 101 pain.001.001.03 101 pain.001.001.08 101 pain.001.001.09 102 pacs.008.001.08 102 pacs.008.001.09 102 pacs.008.001.10 103 pacs.002.001.10 103 pacs.004.001.09 103 pacs.004.001.10 103 pacs.008.001.02 103 pacs.008.001.06 103 pacs.008.001.07 103 pacs.008.001.08 103 pacs.008.001.09 103 pacs.008.001.10 103.REMIT pacs.008.001.02 103.REMIT pacs.008.001.06 103.REMIT pacs.008.001.07 103.REMIT pacs.008.001.08 103.REMIT pacs.008.001.09 103.REMIT pacs.008.001.10 103.STP pacs.008.001.02 103.STP pacs.008.001.06 103.STP pacs.008.001.07 103.STP pacs.008.001.08 103.STP pacs.008.001.09 104 pacs.003.001.08 104 pacs.003.001.09 104 pacs.003.001.10 104 pain.008.001.08 107 pacs.003.001.08 107 pacs.003.001.09 107 pacs.003.001.10 110 camt.107.001.01 111 camt.108.001.01 112 camt.109.001.01 192 camt.056.001.08 192 camt.056.001.10 192 camt.058.001.08 196 camt.029.001.09 196 camt.029.001.11 199 pacs.002.001.10 200 camt.050.001.05 200 pacs.009.001.08 200 pacs.009.001.09 200 pacs.009.001.10 202 pacs.002.001.10 202 pacs.004.001.09 202 pacs.004.001.10 202 pacs.009.001.02 202 pacs.009.001.06 202 pacs.009.001.07 202 pacs.009.001.08 202 pacs.009.001.09 202 pacs.009.001.10 202.COV pacs.002.001.10 202.COV pacs.009.001.02 202.COV pacs.009.001.06 202.COV pacs.009.001.07 202.COV pacs.009.001.08 202.COV pacs.009.001.09 202.COV pacs.009.001.10 204 pacs.010.001.03 205 pacs.002.001.10 205 pacs.004.001.09 205 pacs.004.001.10 205 pacs.009.001.08 205 pacs.009.001.09 205.COV pacs.002.001.10 205.COV pacs.009.001.08 205.COV pacs.009.001.09 210 camt.057.001.06 292 camt.056.001.08 292 camt.056.001.10 292 camt.058.001.08 296 camt.029.001.09 296 camt.029.001.11 299 pacs.002.001.10 300 fxtr.014.001.03 502 setr.004.002.01 502 setr.010.002.01 508 semt.015.002.01 508 semt.020.002.01 509 setr.016.001.04 509 setr.016.002.01 509 setr.017.001.04 515 setr.006.001.04 515 setr.006.002.01 515 setr.012.001.04 515 setr.012.002.01 524 semt.013.002.01 524 sese.020.002.01 530 sese.030.001.08 530 sese.030.002.01 535 semt.002.001.11 535 semt.002.002.03 535 semt.003.002.03 535 semt.020.002.01 536 semt.017.001.12 536 semt.020.002.01 537 semt.018.001.13 537 semt.018.002.01 537 semt.020.002.01 538 semt.016.002.01 538 semt.020.002.01 540 sese.020.001.06 540 sese.020.001.07 540 sese.020.002.01 540 sese.023.001.09 540 sese.023.001.11 540 sese.023.002.01 540 sese.033.002.01 540 sese.036.002.01 541 sese.020.001.06 541 sese.020.001.07 541 sese.020.002.01 541 sese.023.001.09 541 sese.023.001.11 541 sese.023.002.01 541 sese.033.002.01 541 sese.036.002.01 542 sese.020.001.06 542 sese.020.001.07 542 sese.020.002.01 542 sese.023.001.09 542 sese.023.001.11 542 sese.023.002.01 542 sese.033.002.01 542 sese.036.002.01 543 sese.020.001.06 543 sese.020.001.07 543 sese.020.002.01 543 sese.023.001.09 543 sese.023.001.11 543 sese.023.002.01 543 sese.033.002.01 543 sese.036.002.01 544 semt.020.002.01 544 sese.025.001.09 544 sese.025.001.11 544 sese.025.002.01 544 sese.026.001.10 544 sese.026.002.01 544 sese.035.002.01 545 semt.020.002.01 545 sese.025.001.09 545 sese.025.001.11 545 sese.025.002.01 545 sese.026.001.10 545 sese.026.002.01 545 sese.035.002.01 546 semt.020.002.01 546 sese.025.001.09 546 sese.025.001.11 546 sese.025.002.01 546 sese.026.001.10 546 sese.026.002.01 546 sese.035.002.01 547 semt.020.002.01 547 sese.025.001.09 547 sese.025.001.11 547 sese.025.002.01 547 sese.026.001.10 547 sese.026.002.01 547 sese.035.002.01 548 semt.014.002.01 548 sese.022.002.01 548 sese.024.001.10 548 sese.024.001.11 548 sese.024.001.12 548 sese.024.002.01 548 sese.027.001.05 548 sese.027.002.01 548 sese.031.001.08 548 sese.031.002.01 548 sese.032.002.01 548 sese.034.002.01 549 semt.021.002.01 549 sese.021.002.01 564 seev.031.001.10 564 seev.031.001.11 564 seev.031.002.02 564 seev.031.002.06 564 seev.031.002.12 564 seev.031.002.13 564 seev.035.001.12 564 seev.035.002.02 564 seev.035.002.12 564 seev.039.002.02 564 seev.039.002.06 564 seev.039.002.11 564 seev.044.001.10 564 seev.044.002.02 564 seev.044.002.10 565 seev.033.002.02 565 seev.033.002.12 565 seev.040.002.02 565 seev.040.002.11 566 seev.036.001.12 566 seev.036.002.02 566 seev.036.002.06 566 seev.036.002.07 566 seev.036.002.08 566 seev.036.002.09 566 seev.036.002.12 566 seev.037.001.12 566 seev.037.002.02 566 seev.037.002.06 566 seev.037.002.07 566 seev.037.002.08 566 seev.037.002.09 566 seev.037.002.12 567 seev.032.002.02 567 seev.032.002.08 567 seev.034.002.02 567 seev.034.002.13 567 seev.041.001.10 567 seev.041.002.12 568 seev.031.001.10 568 seev.031.001.11 568 seev.031.002.02 568 seev.031.002.06 568 seev.031.002.12 568 seev.031.002.13 568 seev.038.002.02 568 seev.038.002.07 578 semt.020.001.07 578 semt.020.002.01 578 sese.028.001.08 578 sese.028.002.01 578 sese.029.002.01 586 semt.019.002.01 586 semt.020.002.01 586 sese.037.002.01 900 camt.054.001.02 900 camt.054.001.06 900 camt.054.001.07 900 camt.054.001.08 900 camt.054.001.09 910 camt.054.001.02 910 camt.054.001.06 910 camt.054.001.07 910 camt.054.001.08 910 camt.054.001.09 920 camt.060.001.05 920 camt.060.001.06 940 camt.053.001.02 940 camt.053.001.06 940 camt.053.001.07 940 camt.053.001.08 940 camt.053.001.09 940 camt.053.001.10 940 camt.053.001.11 941 camt.052.001.02 941 camt.052.001.06 941 camt.052.001.07 941 camt.052.001.08 941 camt.052.001.09 942 camt.052.001.02 942 camt.052.001.06 942 camt.052.001.07 942 camt.052.001.08 942 camt.052.001.09 950 camt.053.001.02 950 camt.053.001.06 950 camt.053.001.07 950 camt.053.001.08 950 camt.053.001.09 950 camt.053.001.10 950 camt.053.001.11","title":"ISO"},{"location":"integrator/translations/translations-avail/#cbpr","text":"Source Target 101 pain.001.001.09 102 pacs.008.001.08 102.STP pacs.008.001.08.STP 103 pacs.002.001.10 103 pacs.004.001.09 103 pacs.008.001.08 103.STP pacs.008.001.08.STP 104 pacs.003.001.08 104 pain.008.001.08 107 pacs.003.001.08 110 camt.107.001.01 111 camt.108.001.01 112 camt.109.001.01 192 camt.055.001.08 192 camt.056.001.08 196 camt.029.001.09 199 pacs.002.001.10 200 pacs.009.001.08 201 pacs.009.001.08 202 pacs.002.001.10 202 pacs.004.001.09 202 pacs.009.001.08 202 pacs.009.001.08.ADV 202.COV pacs.002.001.10 202.COV pacs.009.001.08.COV 203 pacs.009.001.08 204 pacs.010.001.03 205 pacs.002.001.10 205 pacs.004.001.09 205 pacs.009.001.08 205.COV pacs.002.001.10 205.COV pacs.009.001.08.COV 210 camt.057.001.06 292 camt.056.001.08 292 camt.058.001.08 296 camt.029.001.09 299 pacs.002.001.10 900 camt.054.001.08 910 camt.054.001.08 920 camt.060.001.05 940 camt.053.001.08 941 camt.052.001.08 942 camt.052.001.08 950 camt.053.001.08","title":"CBPR"},{"location":"integrator/translations/translations-avail/#chats","text":"Source Target 103 pacs.008.001.08 192 camt.056.001.08 202 pacs.009.001.08 202.COV pacs.009.001.08 292 camt.056.001.08","title":"CHATS"},{"location":"integrator/translations/translations-avail/#lynx","text":"Source Target 103 pacs.004.001.09 103 pacs.008.001.08 202 pacs.004.001.09 202 pacs.009.001.08 202.COV pacs.009.001.08 205 pacs.004.001.09 205 pacs.009.001.08","title":"LYNX"},{"location":"integrator/translations/translations-avail/#rits","text":"Source Target 103 pacs.008.001.09 202 pacs.009.001.09 202.COV pacs.009.001.09","title":"RITS"},{"location":"integrator/translations/translations-avail/#scrips","text":"Source Target 103 pacs.008.001.08 202 pacs.009.001.08 202.COV pacs.009.001.08","title":"SCRIPS"},{"location":"integrator/translations/translations-avail/#sic_v4_10","text":"Source Target 103 pacs.008.001.08.Ch02 202 pacs.009.001.08.Ch03 202.COV pacs.009.001.08.Ch03","title":"SIC_v4_10"},{"location":"integrator/translations/translations-avail/#swiftgo","text":"Source Target 103 pacs.008.001.08 199 trck.001.001.02 199 trck.002.001.01","title":"SWIFTGO"},{"location":"integrator/translations/translations-avail/#t2","text":"Source Target 103 pacs.004.001.09 103 pacs.008.001.08 202 pacs.004.001.09 202 pacs.009.001.08 205 pacs.004.001.09 205 pacs.009.001.08","title":"T2"},{"location":"integrator/translations/translations-avail/#mx-to-mt","text":"","title":"MX to MT"},{"location":"integrator/translations/translations-avail/#iso_1","text":"Source Target camt.029.001.09 196 camt.029.001.09 296 camt.029.001.11 196 camt.029.001.11 296 camt.050.001.05 200 camt.052.001.06 941 camt.052.001.06 942 camt.052.001.07 941 camt.052.001.07 942 camt.052.001.08 941 camt.052.001.08 942 camt.052.001.09 941 camt.052.001.09 942 camt.053.001.02 940 camt.053.001.06 940 camt.053.001.06 950 camt.053.001.07 940 camt.053.001.07 950 camt.053.001.08 940 camt.053.001.08 950 camt.053.001.09 940 camt.053.001.09 950 camt.053.001.10 940 camt.053.001.10 950 camt.053.001.11 940 camt.053.001.11 950 camt.054.001.06 900 camt.054.001.06 910 camt.054.001.07 900 camt.054.001.07 910 camt.054.001.08 900 camt.054.001.08 910 camt.054.001.09 900 camt.054.001.09 910 camt.056.001.08 192 camt.056.001.08 292 camt.056.001.10 192 camt.056.001.10 292 camt.057.001.06 210 camt.060.001.05 920 camt.060.001.06 920 camt.107.001.01 110 camt.108.001.01 111 camt.109.001.01 112 pacs.002.001.10 199 pacs.002.001.10 299 pacs.003.001.08 104 pacs.003.001.08 107 pacs.003.001.09 104 pacs.003.001.09 107 pacs.003.001.10 104 pacs.003.001.10 107 pacs.004.001.02 103 pacs.004.001.09 103 pacs.004.001.09 202 pacs.004.001.09 205 pacs.004.001.10 103 pacs.004.001.10 202 pacs.004.001.10 205 pacs.008.001.02 103 pacs.008.001.06 103 pacs.008.001.07 103 pacs.008.001.08 102 pacs.008.001.08 103 pacs.008.001.08 103.REMIT pacs.008.001.09 102 pacs.008.001.09 103 pacs.008.001.10 102 pacs.008.001.10 103 pacs.009.001.02 202 pacs.009.001.02 202.COV pacs.009.001.06 202 pacs.009.001.06 202.COV pacs.009.001.07 202 pacs.009.001.07 202.COV pacs.009.001.08 200 pacs.009.001.08 202 pacs.009.001.08 202.COV pacs.009.001.08 205 pacs.009.001.08 205.COV pacs.009.001.09 200 pacs.009.001.09 202 pacs.009.001.09 202.COV pacs.009.001.09 205 pacs.009.001.10 200 pacs.009.001.10 202 pacs.009.001.10 202.COV pacs.009.001.10 205 pacs.010.001.03 204 pain.001.001.03 101 pain.001.001.08 101 pain.001.001.09 101 pain.001.001.09 103 seev.001.001.10 564 seev.002.001.09 564 seev.003.001.09 564 seev.004.001.09 565 seev.005.001.09 565 seev.006.001.09 567 seev.007.001.09 567 seev.008.001.08 568 seev.031.001.03 564 seev.031.001.03 568 seev.031.001.09 564 seev.031.001.10 564 seev.031.001.10 568 seev.031.001.11 564 seev.031.001.11 568 seev.031.001.12 564 seev.031.001.12 568 seev.031.001.13 564 seev.031.001.13 568 seev.031.002.02 564 seev.031.002.02 568 seev.031.002.12 564 seev.031.002.12 568 seev.031.002.13 564 seev.031.002.13 568 seev.032.002.02 567 seev.032.002.08 567 seev.033.002.02 565 seev.033.002.12 565 seev.034.002.02 567 seev.034.002.13 567 seev.035.001.03 564 seev.035.001.10 564 seev.035.001.11 564 seev.035.001.12 564 seev.035.001.13 564 seev.035.001.14 564 seev.035.002.02 564 seev.035.002.12 564 seev.036.001.11 566 seev.036.001.12 566 seev.036.001.13 566 seev.036.001.14 566 seev.036.002.02 566 seev.036.002.06 566 seev.036.002.07 566 seev.036.002.08 566 seev.036.002.09 566 seev.036.002.12 566 seev.037.001.11 566 seev.037.001.12 566 seev.037.001.13 566 seev.037.001.14 566 seev.037.002.02 566 seev.037.002.06 566 seev.037.002.07 566 seev.037.002.08 566 seev.037.002.09 566 seev.037.002.12 566 seev.038.001.03 568 seev.038.002.02 568 seev.038.002.07 568 seev.039.001.03 564 seev.039.001.10 564 seev.039.001.11 564 seev.039.001.12 564 seev.039.002.02 564 seev.039.002.11 564 seev.040.002.02 565 seev.040.002.11 565 seev.041.002.12 567 seev.044.001.03 564 seev.044.001.10 564 seev.044.001.11 564 seev.044.001.12 564 seev.044.002.02 564 seev.044.002.10 564 semt.002.001.10 535 semt.002.001.11 535 semt.002.002.03 535 semt.003.002.03 535 semt.013.002.01 524 semt.014.002.01 548 semt.015.002.01 508 semt.016.002.01 538 semt.017.001.12 536 semt.017.002.01 536 semt.018.001.13 537 semt.018.002.01 537 semt.019.002.01 586 semt.020.001.05 578 semt.020.001.07 578 semt.020.002.01 508 semt.020.002.01 535 semt.020.002.01 536 semt.020.002.01 537 semt.020.002.01 538 semt.020.002.01 544 semt.020.002.01 545 semt.020.002.01 546 semt.020.002.01 547 semt.020.002.01 578 semt.020.002.01 586 semt.021.002.01 549 sese.020.001.06 540 sese.020.001.06 541 sese.020.001.06 542 sese.020.001.06 543 sese.020.001.07 540 sese.020.001.07 541 sese.020.001.07 542 sese.020.001.07 543 sese.020.002.01 524 sese.020.002.01 540 sese.020.002.01 541 sese.020.002.01 542 sese.020.002.01 543 sese.021.002.01 549 sese.022.002.01 548 sese.023.001.09 540 sese.023.001.09 541 sese.023.001.09 542 sese.023.001.09 543 sese.023.001.11 540 sese.023.001.11 541 sese.023.001.11 542 sese.023.001.11 543 sese.023.002.01 540 sese.023.002.01 541 sese.023.002.01 542 sese.023.002.01 543 sese.024.001.09 548 sese.024.001.10 548 sese.024.001.11 548 sese.024.001.12 548 sese.024.002.01 548 sese.025.001.09 544 sese.025.001.09 545 sese.025.001.09 546 sese.025.001.09 547 sese.025.001.11 544 sese.025.001.11 545 sese.025.001.11 546 sese.025.001.11 547 sese.025.002.01 544 sese.025.002.01 545 sese.025.002.01 546 sese.025.002.01 547 sese.026.001.10 544 sese.026.001.10 545 sese.026.001.10 546 sese.026.001.10 547 sese.026.002.01 544 sese.026.002.01 545 sese.026.002.01 546 sese.026.002.01 547 sese.027.001.05 548 sese.027.002.01 548 sese.028.001.08 578 sese.028.001.09 578 sese.028.001.10 578 sese.028.002.01 578 sese.029.001.04 578 sese.029.002.01 578 sese.030.001.08 530 sese.030.002.01 530 sese.031.001.08 548 sese.031.002.01 548 sese.032.002.01 548 sese.033.002.01 540 sese.033.002.01 541 sese.033.002.01 542 sese.033.002.01 543 sese.034.002.01 548 sese.035.002.01 544 sese.035.002.01 545 sese.035.002.01 546 sese.035.002.01 547 sese.036.002.01 540 sese.036.002.01 541 sese.036.002.01 542 sese.036.002.01 543 sese.037.002.01 586 setr.004.001.04 502 setr.004.002.01 502 setr.006.001.04 515 setr.006.002.01 515 setr.010.001.04 502 setr.010.002.01 502 setr.012.001.04 515 setr.012.002.01 515 setr.015.001.04 515.Redemption setr.015.001.04 515.Subscription setr.016.001.04 509 setr.016.002.01 509 setr.017.001.04 509","title":"ISO"},{"location":"integrator/translations/translations-avail/#cbpr_1","text":"Source Target camt.029.001.09 196 camt.029.001.09 296 camt.052.001.08 941 camt.052.001.08 942 camt.053.001.08 940 camt.053.001.08 950 camt.054.001.08 900 camt.054.001.08 910 camt.055.001.08 192 camt.056.001.08 192 camt.056.001.08 292 camt.057.001.06 210 camt.058.001.08 292 camt.060.001.05 920 camt.107.001.01 110 camt.108.001.01 111 camt.109.001.01 112 pacs.002.001.10 199 pacs.002.001.10 299 pacs.003.001.08 104 pacs.003.001.08 107 pacs.004.001.09 103 pacs.004.001.09 202 pacs.004.001.09 205 pacs.008.001.08 102 pacs.008.001.08 103 pacs.008.001.08 103.REMIT pacs.008.001.08STP 102STP pacs.008.001.08STP 103STP pacs.009.001.08 200 pacs.009.001.08 202 pacs.009.001.08 205 pacs.009.001.08.ADV 202 pacs.009.001.08.COV 202.COV pacs.009.001.08.COV 205.COV pacs.010.001.03 204 pain.001.001.09 101 pain.008.001.08 104","title":"CBPR"},{"location":"integrator/translations/translations-avail/#sic_v4_11","text":"Source Target pacs.004.001.09.Ch02 103 pacs.008.001.08.Ch02 103 pacs.009.001.08.Ch03 202 pacs.009.001.08.Ch03 202.COV","title":"SIC_v4_10"},{"location":"integrator/translations/translations-avail/#swiftgo_1","text":"Source Target pacs.008.001.08 103 trck.001.001.02 199 trck.002.001.01 199","title":"SWIFTGO"},{"location":"integrator/translations/translations-factory/","text":"Translator factory Generic translation Generic translation calls, without knowing in advance the source message type, can be done in two ways. Using the Translator interface or using the TranslatorFactory . This is particularly useful when translating and inbound queue of receiving a variety of unknown message types. Translator interface All MT and MX translation classes implement the common translation interface Translator . This interface is helpful in situations where generic translation must be implemented, consolidating the translation of several message types in a single processing unit. The following method uses this interface to translate any MT receiving the translation implementation and specific source message as parameters: private static AbstractMX doTranslation ( final Translator translator , final AbstractMT msg ){ AbstractMX mx = null ; try { mx = translator . translate ( msg ); } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } catch ( final TranslationPreconditionException e2 ) { System . out . println ( \"precondition exception: \" + e2 . getMessage ()); } return mx ; } The reverse from MX to MT can be seamlessly achieve. Translator factory In order to get a proper translator instance automatically, a TranslatorFactory is also provided. The factory accepts an MT or MX message instance as a parameter and returns the available matching translator for the message. Translator t = TranslatorFactory . getTranslator ( msg ); The above method, for example, when an MT103 is passed, would return an instance of the MT103_MxPacs00800110_Translation translation implementation. And when the parameter is an MxPacs00800110 message the returned translator will be MxPacs00800110_MT103_Translation . Meaning the same factory is used to either MT to MX or MX to MT translations. Notice the MX version may be different from the example, depending on the latest version available. When converting from MT to MX several translator implementations might be available, to create different versions of the same output MX message type. In this situation, by default, the factory will return the translator for the latest version available. Internally the factory applies different methods in cascade to narrow the available options and to finally select the specific translator instance to return: 1. Existing translation implementation for the specific source message type 2. Logical message criteria applied to the source message type 3. Optional, preconditions check applied to the source message type 4. Optional, preferred specific target message type In any of the steps above if the options are reduced to a single candidate, that translator is returned. Otherwise, the factory returns null. Factory selection criteria The main logic to pickup one translation over another one is by applying the logical message criteria on the source message. These criteria are implemented when the equivalence is not 1 to 1. Most of the available translations are a 1 to one equivalence, but in some exceptional cases, you might have in particular some MT that can be used for multiple functions while in the MX standard there are specific types for each use case. This logic is implemented in each translator classe and is used by the factory to determine which translator instance to create. As a result, the getTranslator call for an MT502 could return either MT502_MxSetr01000201_Translation , MT502_MxSetr00400201_Translation or null depending on the function of the MT message. And by function we refer to the source message content. Thus, the criteria check involves inspecting the source message content. The javadoc for the translator implementations describes the specific criteria for each translator. Complete example: https://github.com/prowide/prowide-integrator-examples/blob/master/src/main/java/com/prowidesoftware/swift/samples/integrator/translations/MtMxTranslationExample3.java Factory preconditions check Besides the logical message criteria, the factory can also check the preconditions (when available for the translator). This check is skipped by default because despite the logical message criteria, a source message could be translated even if it does not meet the preconditions. The host application can always retrieve the translator from the factory, and then check the preconditions itself to handle any errors. When this is not the preferred option, the factory can be configured to use also the precondition check for the translator selection like this: TranslatorFactory . getTranslator ( msg , new TranslatorFactoryConfiguration (). setEvaluatePreconditions ( true )); While this reduces logic in the calling application, the drawback is that the factory might return null when there is no selectable translator instance and the application will not know if the issue comes from a failed logical message criteria or by a failed precondition. The precondition check main goal is to ensure that the translated message will be valid. Preferred specific version The factory accepts a also a parameter to indicate the specific target message type. For example: Translator t = TranslatorFactory . getTranslator ( mt , \"pacs.008.001.08\" ); In the above example, given an MT103 as parameter the translator instance will be the MT103_MxPacs00800108_Translation translation implementation. It is important to notice that the target message type must be a valid equivalence and with a translation implementation available in the library, otherwise the factory will return null. This way of customizing the factoru might be useful for instance in situations where the expected output message type is received as parameter from the user or exported service. On the contrary, it does not make much sense to use this parameter hard-coded in the application, since in that case where the versions are fixed and known, it is better to create the specific translator instance directly. Preferred equivalences As an alternative to the above, there is a much powerful option to customize the overall criteria for the factory using a parameter in the TranslatorFactoryConfiguration like this: TranslatorFactory . getTranslator ( new MT103 (), new TranslatorFactoryConfiguration () . withTranslationMappings ( Collections . singletonList ( \"MT103:pacs.008.001.08\" )); In this example, when translating from an MT103 message, the factory will pick up the 08 version of the MX instead of using the latest available version as default. Or: TranslatorFactory . getTranslator ( new MxPacs00900108 (), new TranslatorFactoryConfiguration () . withTranslationMappings ( Collections . singletonList ( \"pacs.009.001.08:MT200.*\" )); In this other example, when translating from a pacs.009.001.08 the factory will pick up the MT200 as target message type instead of the default MT202 . The TranslationMappings parameter is the key feature to configure the factory criteria in a flexible way. Each entry in this List is a String that defines a mapping from a source message type to one or more target message types. The general format is \"SOURCE : TARGET1, TARGET2,...,TARGETN\". Example: MT103: pacs.008.001.02, pacs.008.002.08 : This mapping indicates that the source message type MT103 is primarily translated to pacs.008.001.02 . If this target is not available, the system attempts to translate to pacs.008.002.08 , and if this too is unavailable, it will resort to any other available target. Flexibility with Wildcards: Wildcards ( * ) are particularly useful in specifying a range of message types. For instance, using * with an MtId or MXid allows the system to select any message type within the specified range, prioritizing the most recent version available. Examples include camt.* to match any camt message, pacs.008.001.* to match any version of pacs.008.001 , and pain.*.*.03 to match any pain message with the version 03 regardless of its business process or functionality. Overall, when a very strict set of versions is required, it is recommended that you implement your own factory logic, and creating the specific instance of Translator needed for each source MT. In the MX to MT case, the situation is simpler since normally there is a single target MT type for any given MX . Thus, the factory can normally be used in most situations. Custom Translator Factory In certain scenarios it might make sense to create your own translator factory. This allows you to dynamically choose the right translation implementation for a given message. A translator factory is basically any class that receives a source message and returns a Translator instance. So there are no restrictions on how to implement it. However, here's an example of how to create a simple translator factory leveraging the translatable method of the translator to apply the logical criteria and preconditions check: public Translator getTranslator ( AbstractMX source , boolean checkPreconditions ) { final String identifier = source . getMxId (). id (); switch ( identifier ) { case \"pacs.004.001.09\" : { MxPacs00400109Ch02_MT103_Translation t = new MxPacs00400109Ch02_MT103_Translation (); if ( t . translatable (( MxPacs00400109Ch02 ) source , checkPreconditions )) { return t ; } break ; } case \"pacs.008.001.08\" : { MxPacs00800108Ch02_MT103_Translation t = new MxPacs00800108Ch02_MT103_Translation (); if ( t . translatable (( MxPacs00800108Ch02 ) source , checkPreconditions )) { return t ; } break ; } case \"pacs.009.001.08\" : { MxPacs00900108Ch03 mx = ( MxPacs00900108Ch03 ) source ; MxPacs00900108Ch03_MT202COV_Translation tCOV = new MxPacs00900108Ch03_MT202COV_Translation (); if ( tCOV . translatable ( mx , checkPreconditions )) { return tCOV ; } MxPacs00900108Ch03_MT202_Translation t = new MxPacs00900108Ch03_MT202_Translation (); if ( t . translatable ( mx , checkPreconditions )) { return t ; } break ; } } return null ; } In this example, the CustomTranslatorFactory class defines a getTranslator method that takes the source MX message and a boolean flag to indicate whether preconditions should be checked. Inside the method, you can use a switch statement or any logic you prefer to select the appropriate translation class based on the message identifier ( identifier ). The translatable method is called for each potential translation class to check if it's suitable for the given source message. In situations such as dealing with pacs.009 messages, where there may be multiple target options, you may want to test each of them to determine the appropriate translation. Additionally, there are cases where multiple target options are available, and the logical criteria check does not provide a clear choice. In such cases, you'll need to make a decision based on your specific requirements. Creating a custom translator factory allows you to dynamically select the most suitable translator class for a given source message, enhancing the adaptability of your translation process. Using the Custom Translator Factory To use the custom translator factory, you can call its getTranslator method when you need to perform a translation: CustomTranslatorFactory factory = new CustomTranslatorFactory (); AbstractMX sourceMessage = // Initialize your source MX message here boolean checkPreconditions = true ; // Set to true if you want to check preconditions Translator translator = factory . getTranslator ( sourceMessage , checkPreconditions ); if ( translator != null ) { // Perform the translation using the selected translator // ... } else { // Handle the case when no suitable translator is found // ... } This approach gives you the flexibility to dynamically choose the appropriate translation class based on the source message type, making your translation process more adaptable to different scenarios. Factories per market type All the topics above apply to the general ISO 20022 translator factory and also for the complementary factories provided by the library for the restricted ISO 20022 standards: such as CBPR+, SIC, CHATS, etc... Those factories can be accessed directly from the specific marget type package, and provide the same API as the general ISO 20022 translator factory. And also by means of the TranslatorFactoryProvider . For more details check the ISO 20022 restricted standards section.","title":"Translator factory"},{"location":"integrator/translations/translations-factory/#translator-factory","text":"","title":"Translator factory"},{"location":"integrator/translations/translations-factory/#generic-translation","text":"Generic translation calls, without knowing in advance the source message type, can be done in two ways. Using the Translator interface or using the TranslatorFactory . This is particularly useful when translating and inbound queue of receiving a variety of unknown message types.","title":"Generic translation"},{"location":"integrator/translations/translations-factory/#translator-interface","text":"All MT and MX translation classes implement the common translation interface Translator . This interface is helpful in situations where generic translation must be implemented, consolidating the translation of several message types in a single processing unit. The following method uses this interface to translate any MT receiving the translation implementation and specific source message as parameters: private static AbstractMX doTranslation ( final Translator translator , final AbstractMT msg ){ AbstractMX mx = null ; try { mx = translator . translate ( msg ); } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } catch ( final TranslationPreconditionException e2 ) { System . out . println ( \"precondition exception: \" + e2 . getMessage ()); } return mx ; } The reverse from MX to MT can be seamlessly achieve.","title":"Translator interface"},{"location":"integrator/translations/translations-factory/#translator-factory_1","text":"In order to get a proper translator instance automatically, a TranslatorFactory is also provided. The factory accepts an MT or MX message instance as a parameter and returns the available matching translator for the message. Translator t = TranslatorFactory . getTranslator ( msg ); The above method, for example, when an MT103 is passed, would return an instance of the MT103_MxPacs00800110_Translation translation implementation. And when the parameter is an MxPacs00800110 message the returned translator will be MxPacs00800110_MT103_Translation . Meaning the same factory is used to either MT to MX or MX to MT translations. Notice the MX version may be different from the example, depending on the latest version available. When converting from MT to MX several translator implementations might be available, to create different versions of the same output MX message type. In this situation, by default, the factory will return the translator for the latest version available. Internally the factory applies different methods in cascade to narrow the available options and to finally select the specific translator instance to return: 1. Existing translation implementation for the specific source message type 2. Logical message criteria applied to the source message type 3. Optional, preconditions check applied to the source message type 4. Optional, preferred specific target message type In any of the steps above if the options are reduced to a single candidate, that translator is returned. Otherwise, the factory returns null.","title":"Translator factory"},{"location":"integrator/translations/translations-factory/#factory-selection-criteria","text":"The main logic to pickup one translation over another one is by applying the logical message criteria on the source message. These criteria are implemented when the equivalence is not 1 to 1. Most of the available translations are a 1 to one equivalence, but in some exceptional cases, you might have in particular some MT that can be used for multiple functions while in the MX standard there are specific types for each use case. This logic is implemented in each translator classe and is used by the factory to determine which translator instance to create. As a result, the getTranslator call for an MT502 could return either MT502_MxSetr01000201_Translation , MT502_MxSetr00400201_Translation or null depending on the function of the MT message. And by function we refer to the source message content. Thus, the criteria check involves inspecting the source message content. The javadoc for the translator implementations describes the specific criteria for each translator. Complete example: https://github.com/prowide/prowide-integrator-examples/blob/master/src/main/java/com/prowidesoftware/swift/samples/integrator/translations/MtMxTranslationExample3.java","title":"Factory selection criteria"},{"location":"integrator/translations/translations-factory/#factory-preconditions-check","text":"Besides the logical message criteria, the factory can also check the preconditions (when available for the translator). This check is skipped by default because despite the logical message criteria, a source message could be translated even if it does not meet the preconditions. The host application can always retrieve the translator from the factory, and then check the preconditions itself to handle any errors. When this is not the preferred option, the factory can be configured to use also the precondition check for the translator selection like this: TranslatorFactory . getTranslator ( msg , new TranslatorFactoryConfiguration (). setEvaluatePreconditions ( true )); While this reduces logic in the calling application, the drawback is that the factory might return null when there is no selectable translator instance and the application will not know if the issue comes from a failed logical message criteria or by a failed precondition. The precondition check main goal is to ensure that the translated message will be valid.","title":"Factory preconditions check"},{"location":"integrator/translations/translations-factory/#preferred-specific-version","text":"The factory accepts a also a parameter to indicate the specific target message type. For example: Translator t = TranslatorFactory . getTranslator ( mt , \"pacs.008.001.08\" ); In the above example, given an MT103 as parameter the translator instance will be the MT103_MxPacs00800108_Translation translation implementation. It is important to notice that the target message type must be a valid equivalence and with a translation implementation available in the library, otherwise the factory will return null. This way of customizing the factoru might be useful for instance in situations where the expected output message type is received as parameter from the user or exported service. On the contrary, it does not make much sense to use this parameter hard-coded in the application, since in that case where the versions are fixed and known, it is better to create the specific translator instance directly.","title":"Preferred specific version"},{"location":"integrator/translations/translations-factory/#preferred-equivalences","text":"As an alternative to the above, there is a much powerful option to customize the overall criteria for the factory using a parameter in the TranslatorFactoryConfiguration like this: TranslatorFactory . getTranslator ( new MT103 (), new TranslatorFactoryConfiguration () . withTranslationMappings ( Collections . singletonList ( \"MT103:pacs.008.001.08\" )); In this example, when translating from an MT103 message, the factory will pick up the 08 version of the MX instead of using the latest available version as default. Or: TranslatorFactory . getTranslator ( new MxPacs00900108 (), new TranslatorFactoryConfiguration () . withTranslationMappings ( Collections . singletonList ( \"pacs.009.001.08:MT200.*\" )); In this other example, when translating from a pacs.009.001.08 the factory will pick up the MT200 as target message type instead of the default MT202 . The TranslationMappings parameter is the key feature to configure the factory criteria in a flexible way. Each entry in this List is a String that defines a mapping from a source message type to one or more target message types. The general format is \"SOURCE : TARGET1, TARGET2,...,TARGETN\". Example: MT103: pacs.008.001.02, pacs.008.002.08 : This mapping indicates that the source message type MT103 is primarily translated to pacs.008.001.02 . If this target is not available, the system attempts to translate to pacs.008.002.08 , and if this too is unavailable, it will resort to any other available target. Flexibility with Wildcards: Wildcards ( * ) are particularly useful in specifying a range of message types. For instance, using * with an MtId or MXid allows the system to select any message type within the specified range, prioritizing the most recent version available. Examples include camt.* to match any camt message, pacs.008.001.* to match any version of pacs.008.001 , and pain.*.*.03 to match any pain message with the version 03 regardless of its business process or functionality. Overall, when a very strict set of versions is required, it is recommended that you implement your own factory logic, and creating the specific instance of Translator needed for each source MT. In the MX to MT case, the situation is simpler since normally there is a single target MT type for any given MX . Thus, the factory can normally be used in most situations.","title":"Preferred equivalences"},{"location":"integrator/translations/translations-factory/#custom-translator-factory","text":"In certain scenarios it might make sense to create your own translator factory. This allows you to dynamically choose the right translation implementation for a given message. A translator factory is basically any class that receives a source message and returns a Translator instance. So there are no restrictions on how to implement it. However, here's an example of how to create a simple translator factory leveraging the translatable method of the translator to apply the logical criteria and preconditions check: public Translator getTranslator ( AbstractMX source , boolean checkPreconditions ) { final String identifier = source . getMxId (). id (); switch ( identifier ) { case \"pacs.004.001.09\" : { MxPacs00400109Ch02_MT103_Translation t = new MxPacs00400109Ch02_MT103_Translation (); if ( t . translatable (( MxPacs00400109Ch02 ) source , checkPreconditions )) { return t ; } break ; } case \"pacs.008.001.08\" : { MxPacs00800108Ch02_MT103_Translation t = new MxPacs00800108Ch02_MT103_Translation (); if ( t . translatable (( MxPacs00800108Ch02 ) source , checkPreconditions )) { return t ; } break ; } case \"pacs.009.001.08\" : { MxPacs00900108Ch03 mx = ( MxPacs00900108Ch03 ) source ; MxPacs00900108Ch03_MT202COV_Translation tCOV = new MxPacs00900108Ch03_MT202COV_Translation (); if ( tCOV . translatable ( mx , checkPreconditions )) { return tCOV ; } MxPacs00900108Ch03_MT202_Translation t = new MxPacs00900108Ch03_MT202_Translation (); if ( t . translatable ( mx , checkPreconditions )) { return t ; } break ; } } return null ; } In this example, the CustomTranslatorFactory class defines a getTranslator method that takes the source MX message and a boolean flag to indicate whether preconditions should be checked. Inside the method, you can use a switch statement or any logic you prefer to select the appropriate translation class based on the message identifier ( identifier ). The translatable method is called for each potential translation class to check if it's suitable for the given source message. In situations such as dealing with pacs.009 messages, where there may be multiple target options, you may want to test each of them to determine the appropriate translation. Additionally, there are cases where multiple target options are available, and the logical criteria check does not provide a clear choice. In such cases, you'll need to make a decision based on your specific requirements. Creating a custom translator factory allows you to dynamically select the most suitable translator class for a given source message, enhancing the adaptability of your translation process.","title":"Custom Translator Factory"},{"location":"integrator/translations/translations-factory/#using-the-custom-translator-factory","text":"To use the custom translator factory, you can call its getTranslator method when you need to perform a translation: CustomTranslatorFactory factory = new CustomTranslatorFactory (); AbstractMX sourceMessage = // Initialize your source MX message here boolean checkPreconditions = true ; // Set to true if you want to check preconditions Translator translator = factory . getTranslator ( sourceMessage , checkPreconditions ); if ( translator != null ) { // Perform the translation using the selected translator // ... } else { // Handle the case when no suitable translator is found // ... } This approach gives you the flexibility to dynamically choose the appropriate translation class based on the source message type, making your translation process more adaptable to different scenarios.","title":"Using the Custom Translator Factory"},{"location":"integrator/translations/translations-factory/#factories-per-market-type","text":"All the topics above apply to the general ISO 20022 translator factory and also for the complementary factories provided by the library for the restricted ISO 20022 standards: such as CBPR+, SIC, CHATS, etc... Those factories can be accessed directly from the specific marget type package, and provide the same API as the general ISO 20022 translator factory. And also by means of the TranslatorFactoryProvider . For more details check the ISO 20022 restricted standards section.","title":"Factories per market type"},{"location":"integrator/translations/translations-general/","text":"General Concepts Translation classes Translations are normally one to one , from a source message into a target message. Each available translation implementation, given a source message type and a target message type, is implemented in a specific class. The message types are explicit in the class names and also in the class parameters for the translation call. For example: Class name Source message type Target message type MT103_STP_MxPacs00800102_Translation MT 103 STP pacs.008.001.02 MxPacs00900102_MT202COV_Translation pacs.009.001.02 MT 202 COV In the most simple use case scenario the translation is called like this: MT103 mt = MT103 . parse ( fin ); try { MxPacs00800108_MT103_Translation t = new MxPacs00800108_MT103_Translation (); MxPacs00800108 mx = t . translate ( mt ); } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } catch ( final TranslationPreconditionException e2 ) { System . out . println ( \"precondition exception: \" + e2 . getMessage ()); } In the code above, we create an instance of the specific translation, and we call the translate method passing the source message as parameter. The result is the target message. And the revers from MX to an MT analogously. Notice translation classes are not thread safe , so a new instance must be created for each translation. The precondition and logical criteria checks are explained in the following sections, but that is basically a way to check if the source message is suitable for the specific translation, and if the target message will be valid after the translation. Logical message criteria The logical message criteria is a condition evaluated on the source message, to know if it is selectable for the specific translation. In most cases, there is only a single available equivalence for the translation. This is mostly the case when converting from MX to MT. However, in some cases, a single message can be translated to more than one target option. This is due to the fact that in the MT standard, there are many message types that can be used for different functions. While in the MX standard, there are specific message types for each function. For example, an MT502 could be a Redemption Order or a Subscription Order, meaning the same MT structure can be used for two different functions. While its MX equivalences have two specific message types for the Redemption and Subscription, setr.004.002.01 or setr.010.002.01. This criteria evaluation is checked automatically when the translation is run. It can be switched off by configuration, and optionally called by the application before the translation. Manual criteria check All translation classes have a translatable method that is used to check the logical criteria. This method checks the content of the source message and returns true or false if it is suitable for the specific translation. MT545 for example could be translated to a sese.025, sese.020, sese.026 or sese.035. Since in the MX standard, there are specific types for each use case, while in the MT all functions are covered by the same message type 545. If you call the translatable method for all possible translations using the same MT source for example: MT545 mt = MT545 . parse ( fin ); MT545_MxSese02500109_Translation t1 = new MT545_MxSese02500109_Translation (); MT545_MxSemt02000201_Translation t2 = new MT545_MxSemt02000201_Translation (); MT545_MxSese02600201_Translation t3 = new MT545_MxSese02600201_Translation (); MT545_MxSese03500201_Translation t4 = new MT545_MxSese03500201_Translation (); t1 . translatable ( mt , true )); t2 . translatable ( mt , true )); t3 . translatable ( mt , true )); t4 . translatable ( mt , true )); Then, for a given valid MT, only one of the options should return true while the others should return false. You can do the above manually, in a sequence of IF/ELSE conditions. Or you can just use the translator factory. The translator factory does exactly that, it checks given a source message what output is translatable. Although, notice there are a few situations where the same input could be translated seamlessly to more than one output. In such cases the translator factory returns a default. Preconditions Each specific translation may implement its own preconditions . This is a condition evaluated on the source message, to make sure the created target message will be valid. It is mainly used when the target message has some mandatory content that is optional in the source message. These preconditions are checked automatically when the translation is run. They can be switched off by configuration, and optionally called by the application before the translation. Manual precondition check Preconditions on the source message can be checked explicitly before attempting the translation, or can be caught from an exception calling the translation method in a try block. The following method will check all the message preconditions and will return a list of precondition errors. final MT564_MxSeev03900202_Translation translator = new MT564_MxSeev03900202_Translation (); final MT564 source = MT564 . parse ( sample ); try { // The precondition being check is: // IF ((B2[*]\\97a Account\\SAFE\\97C\\Account Code ContainsString 'GENR') And ((B2[*]\\95a Party\\ACOW IsPresent) Or ((B2[*]\\94a Place\\SAFE IsPresent) Or (B2[*]\\93a Balance IsPresent)))) // this pseudo-code is available in the translator javadoc List < PreconditionError > p = translator . preconditionsCheck ( source ); if ( p . isEmpty ()) { // Call the translation process final MxSeev03900202 mx = translator . translate ( source ); // Print content from the translated message System . out . println ( \"Cancellation Reason Code: \" + mx . getCorpActnCxlAdvc (). getCxlAdvcGnlInf (). getCxlRsnCd (). name ()); System . out . println ( \"Processing Completness: \" + mx . getCorpActnCxlAdvc (). getCxlAdvcGnlInf (). getPrcgSts (). getEvtSts (). getEvtCmpltnsSts (). name ()); System . out . println ( \"Corporate Action Id: \" + mx . getCorpActnCxlAdvc (). getCorpActnGnlInf (). getCorpActnEvtId ()); System . out . println ( \"Event Type Code: \" + mx . getCorpActnCxlAdvc (). getCorpActnGnlInf (). getEvtTp (). getCd (). name ()); System . out . println ( \"Underlying Security ISIN: \" + mx . getCorpActnCxlAdvc (). getCorpActnGnlInf (). getUndrlygSctyId (). getISIN ()); } else { // Print precondition errors for ( PreconditionError e : p ) { System . out . println ( \"precondition error: \" + e . getCode () + \" \" + e . getDescription ()); } } } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } In the above example the translator is any instance of a Translator implementation. When the translation is from MT to MX the expected parameter is the MT. When the translation is from MX to MT the expected parameter is the MX. If the returned list is empty, the source message satisfies all preconditions. If not, each element in the list will contain a code and a description of the condition that is not satisfied. Compliance In order for the target message to be valid, these premises should be satisfied: The source message should be valid. Notice the translation module will not run full compliance message validation, neither on source nor target messages. However, the Prowide Integrator Validation module can be used for this purpose. The logical message criteria check should pass: meaning the source message should be selectable for the specific translation applied. The preconditions on the source message should pass. Regardless of this contract, since the translation is sensitive to the data, if the translated message is going to be sent through the network it is recommended that as the last step of the process the validation is run on the created message. Headers Regardless of the specific translation mappings, the target message header is always filled with data from the source or with derived content as follows: Translation Source element Target element MT to MX Block 1 Sender Block 2 Receiver Fixed from target message identifier Current date and time Main message reference Trailer PDE AppHdr From AppHdr To AppHdr Message Definition AppHdr Creation Date and Time AppHdr Business Message Identifier AppHdr Possible Duplicate Emission (By default the ISO Business Header is created, not the legacy Application Header) MX to MT AppHdr From * AppHdr To * AppHdr Possible Duplicate Emission Fixed from target message identifier (both ISO Business Header and legacy Application Header are supported) Block 1 Sender Block 2 Receiver Trailer PDE Block 2 message type (Direction is Input by default. The rest of the MT headers data is filled with proper defaults) * If the AppHdr is not present, the translation attempts to use the parties BIC codes in the Group Header element within the MX Document. If none is found, then the MT is populated with default BIC codes. Also, both BIC and DN structures are supported, when the DN is used the BIC is extracted and filled with the default branch code. This default mapping can be overridden by configuration. In the TranslationConfiguration class that can be optionally passed to the translator call, a fixed specific sender and/or receiver can be set. The configuration will take precedence on any other default or mapped value. For example: MT103 mt = translator . translate ( mx , new TranslationConfiguration (). setSender ( new BIC ( \"ABCDARXX\" ))); Message direction In MT messages, the direction is explicit in the message structure because the headers are mandatory and there is one specific header for outgoing messages and another specific header for incoming messages. So when you have an MT payload, you know the direction. This is not true for MX, where the direction is not in the payload (AppHdr + Document), but in the transmission wrapper, and that is dependent on the specific interface. When the message is converted from MX to MT, there is no longer an explicit direction, so by default all translators from MX to MT will generate an input message. An Input message means the message is going to be sent to SWIFT. If in the MX to MT translation process, in your host application, you know the generated MTs should be Output because you have received the original MX from SWIFT then you can use a configuration to switch the direction. This is done passing the optional TranslationConfiguration to the translation call. For example: MT103 mt = translator . translate ( mx , new TranslationConfiguration (). setDirection ( MessageDirection . Output )); The MT content will be the same, but in the headers the sender and receiver will be reconfigured as Output (received) message. Truncation When the source element value does not fit in the target message field, the translation will truncate the content. This could happen specially when translating from MX to MT, where the MT fields are shorter than the MX elements. By default, the truncation is done with evidence, meaning in the translated messages the truncated content will contain an explicit '+' symbol at the end of the field. This is done to indicate that the content has been truncated. Along that, the translation class stores the original and truncated content so that a report can be generated with the truncated elements. This report can be generated by calling the getTruncatedContent() method in the translator. Coverage For MX to MT translations, a coverage report can be generated by calling the getCoverageReport() method in the translator. This report will show the elements of the source MX elements that have been mapped into the target MT. Notice in most situations the coverage report will not be 100% because there are many elements in the source MX that cannot be mapped into the target MT. The idea of the coverage report is to analyse if for certain use cases the key elements in the MX have been mapped. Restricted ISO 20022 versions Depending on the user group, central bank, clearing system, or market infrastructure, different translation implementations might be available for the same pair of message types. This is the case when a restricted version of ISO 20022 is used with custom mappings; for example: CBPR+, ESMIG, SIC, etc\u2026 When these alternative translations are available, the variant or group will be explicit in the translation file name. Support for these restricted versions is a work in progress and will be added as needed. Current restricted versions available: Comprehensive coverage for all CBPR+ (Cross Border Payments) messages Partial translation for SIC (Swiss RGTS) messages Partial translation for RITS (Australian RGTS) messages Partial translation for CHATS (Hong Kong RGTS) messages Partial translation for SCRIPS (MEPS+, Singapore RGTS) messages Partial translations for T2S (TARGET2) messages Partial translations for LYNX (Canadian RGTS) messages Partial translations for SWIFTGO (SWIFT GPI) messages Note here we refer to providing specific translation implementations for the restricted versions. However, since all restricted standards are based on ISO, by default the general ISO 20022 can be used. MX to MT: the general ISO 20022 translation should be OK in most situations since from the output perspective, the MT message is undistinguished. Meaning an MT2103 created from a generic pacs.008 or a T2 pacs.008 will be the same. MT to MX: the general ISO 20022 translation could be use in most cases, and then the created MX output can be tweaked to match the specific requirements of the restricted version. For example, the MT2103 could be translated to a generic pacs.008 and then the specific T2 pacs.008 can be created by adding the missing elements or removing the ones not allowed. When available these translations are available in specific packages. Thus, instead of the translator implementation being located in the com.prowidesoftware.swift.translations package, it will be located in a package with the name of com.prowidesoftware.swift.translations.cbrp , com.prowidesoftware.swift.translations.sic , etc... To facilitate access to these alternative translators, each package contains it own TranslatorFactory class. For example, to get a translator for the CBPR+ pacs.008 to MT103 translation, instead of using the general TranslatorFactory.getTranslator(mx) method, you can use the specific CbprTranslatorFactory.getTranslator(mx) method. Moreover, to implementa a system that automatically translate messages for multiple target markets, there is also a TranslatorFactoryProvider class that will return the specific factory for a given target market. For example: TranslatorFactory factory = TranslatorFactoryProvider . getTranslatorFactory ( MarketType . RITS ); Translator translator = factory . getTranslator ( mt ); The code above with create an instance of the RITS specific translator factory, and from it, will attempt to find a suitable translator for the given MT message. M to N translations Although translation implementations are always one to one , there are some use cases where a single MX message can contain data corresponding to multiple MT messages. In other words, where a business operation, report, or transaction in an MX message cannot be mapped into a single MT because of the limitations of the MT standard. setr.015 to MT515 The switch order confirmation in an MX setr.015 can contain multiple switch operations, and for each it can contain multiple redemption and subscription legs. Thus, the translation to achieve should receive a single setr.015 and convert that into multiple MT515 messages. To keep the translation API simple and consistent, in these situations more than one translation implementation is made available for the given source and target message types. IN the swift order confirmation example, this is achieved by two translators: Class name Source message type Target message type MxSetr01500104_MT515_Redemption_Translation setr.015.001.04 MT 515 MxSetr01500104_MT515_Subscription_Translation setr.015.001.04 MT 515 Where the first translation implementation will convert the redemption leg data from the MX into an MT515 with the instrument sell, and the second translator will convert the subscription leg data from the MX into another MT515 with the instrument buy. The host application or the process running the translation is expected to use both translators, passing as parameters the same source MX message. The first call will create the redemption, while the second call, with the same source MX parameter, will create the subscription. pain.001 to MT101 The payment initiation in a pain.001 can contain multiple payment information elements, each having multiple credit transfers. The default 1 to 1 translation implemented in the MxPain00100103_MT101_Translation class will use as source content only the first payment information element. Each credit transfer in this source element will be mapped into a repetitive sequence B in the target MT. But a single MT will be created. A special 1 to many implementations for this use case is provided in the MxPain00100103_MT101_BulkTranslation class. The translation methods in this class return a List instead of a single instance. This implementation uses internally the one to one mapping, but will process all the available payment information elements in the source MX. For each payment information in the MX a single MT101 is created. As for the credit transfer repetitions within each payment information element, multiple sequences B are created in the corresponding MT101 instance. The 1 to 1 translation implemented in the MxPain00100103_MT101_Translation can be considered a special case of the MxPain00100103_MT101_BulkTranslation where the result will be a list with a single element. The drawback of the special bulk translation is that it cannot implement the generic translator API, thus it will not be recognized by the Translators Factory.","title":"General concepts"},{"location":"integrator/translations/translations-general/#general-concepts","text":"","title":"General Concepts"},{"location":"integrator/translations/translations-general/#translation-classes","text":"Translations are normally one to one , from a source message into a target message. Each available translation implementation, given a source message type and a target message type, is implemented in a specific class. The message types are explicit in the class names and also in the class parameters for the translation call. For example: Class name Source message type Target message type MT103_STP_MxPacs00800102_Translation MT 103 STP pacs.008.001.02 MxPacs00900102_MT202COV_Translation pacs.009.001.02 MT 202 COV In the most simple use case scenario the translation is called like this: MT103 mt = MT103 . parse ( fin ); try { MxPacs00800108_MT103_Translation t = new MxPacs00800108_MT103_Translation (); MxPacs00800108 mx = t . translate ( mt ); } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } catch ( final TranslationPreconditionException e2 ) { System . out . println ( \"precondition exception: \" + e2 . getMessage ()); } In the code above, we create an instance of the specific translation, and we call the translate method passing the source message as parameter. The result is the target message. And the revers from MX to an MT analogously. Notice translation classes are not thread safe , so a new instance must be created for each translation. The precondition and logical criteria checks are explained in the following sections, but that is basically a way to check if the source message is suitable for the specific translation, and if the target message will be valid after the translation.","title":"Translation classes"},{"location":"integrator/translations/translations-general/#logical-message-criteria","text":"The logical message criteria is a condition evaluated on the source message, to know if it is selectable for the specific translation. In most cases, there is only a single available equivalence for the translation. This is mostly the case when converting from MX to MT. However, in some cases, a single message can be translated to more than one target option. This is due to the fact that in the MT standard, there are many message types that can be used for different functions. While in the MX standard, there are specific message types for each function. For example, an MT502 could be a Redemption Order or a Subscription Order, meaning the same MT structure can be used for two different functions. While its MX equivalences have two specific message types for the Redemption and Subscription, setr.004.002.01 or setr.010.002.01. This criteria evaluation is checked automatically when the translation is run. It can be switched off by configuration, and optionally called by the application before the translation.","title":"Logical message criteria"},{"location":"integrator/translations/translations-general/#manual-criteria-check","text":"All translation classes have a translatable method that is used to check the logical criteria. This method checks the content of the source message and returns true or false if it is suitable for the specific translation. MT545 for example could be translated to a sese.025, sese.020, sese.026 or sese.035. Since in the MX standard, there are specific types for each use case, while in the MT all functions are covered by the same message type 545. If you call the translatable method for all possible translations using the same MT source for example: MT545 mt = MT545 . parse ( fin ); MT545_MxSese02500109_Translation t1 = new MT545_MxSese02500109_Translation (); MT545_MxSemt02000201_Translation t2 = new MT545_MxSemt02000201_Translation (); MT545_MxSese02600201_Translation t3 = new MT545_MxSese02600201_Translation (); MT545_MxSese03500201_Translation t4 = new MT545_MxSese03500201_Translation (); t1 . translatable ( mt , true )); t2 . translatable ( mt , true )); t3 . translatable ( mt , true )); t4 . translatable ( mt , true )); Then, for a given valid MT, only one of the options should return true while the others should return false. You can do the above manually, in a sequence of IF/ELSE conditions. Or you can just use the translator factory. The translator factory does exactly that, it checks given a source message what output is translatable. Although, notice there are a few situations where the same input could be translated seamlessly to more than one output. In such cases the translator factory returns a default.","title":"Manual criteria check"},{"location":"integrator/translations/translations-general/#preconditions","text":"Each specific translation may implement its own preconditions . This is a condition evaluated on the source message, to make sure the created target message will be valid. It is mainly used when the target message has some mandatory content that is optional in the source message. These preconditions are checked automatically when the translation is run. They can be switched off by configuration, and optionally called by the application before the translation.","title":"Preconditions"},{"location":"integrator/translations/translations-general/#manual-precondition-check","text":"Preconditions on the source message can be checked explicitly before attempting the translation, or can be caught from an exception calling the translation method in a try block. The following method will check all the message preconditions and will return a list of precondition errors. final MT564_MxSeev03900202_Translation translator = new MT564_MxSeev03900202_Translation (); final MT564 source = MT564 . parse ( sample ); try { // The precondition being check is: // IF ((B2[*]\\97a Account\\SAFE\\97C\\Account Code ContainsString 'GENR') And ((B2[*]\\95a Party\\ACOW IsPresent) Or ((B2[*]\\94a Place\\SAFE IsPresent) Or (B2[*]\\93a Balance IsPresent)))) // this pseudo-code is available in the translator javadoc List < PreconditionError > p = translator . preconditionsCheck ( source ); if ( p . isEmpty ()) { // Call the translation process final MxSeev03900202 mx = translator . translate ( source ); // Print content from the translated message System . out . println ( \"Cancellation Reason Code: \" + mx . getCorpActnCxlAdvc (). getCxlAdvcGnlInf (). getCxlRsnCd (). name ()); System . out . println ( \"Processing Completness: \" + mx . getCorpActnCxlAdvc (). getCxlAdvcGnlInf (). getPrcgSts (). getEvtSts (). getEvtCmpltnsSts (). name ()); System . out . println ( \"Corporate Action Id: \" + mx . getCorpActnCxlAdvc (). getCorpActnGnlInf (). getCorpActnEvtId ()); System . out . println ( \"Event Type Code: \" + mx . getCorpActnCxlAdvc (). getCorpActnGnlInf (). getEvtTp (). getCd (). name ()); System . out . println ( \"Underlying Security ISIN: \" + mx . getCorpActnCxlAdvc (). getCorpActnGnlInf (). getUndrlygSctyId (). getISIN ()); } else { // Print precondition errors for ( PreconditionError e : p ) { System . out . println ( \"precondition error: \" + e . getCode () + \" \" + e . getDescription ()); } } } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } In the above example the translator is any instance of a Translator implementation. When the translation is from MT to MX the expected parameter is the MT. When the translation is from MX to MT the expected parameter is the MX. If the returned list is empty, the source message satisfies all preconditions. If not, each element in the list will contain a code and a description of the condition that is not satisfied.","title":"Manual precondition check"},{"location":"integrator/translations/translations-general/#compliance","text":"In order for the target message to be valid, these premises should be satisfied: The source message should be valid. Notice the translation module will not run full compliance message validation, neither on source nor target messages. However, the Prowide Integrator Validation module can be used for this purpose. The logical message criteria check should pass: meaning the source message should be selectable for the specific translation applied. The preconditions on the source message should pass. Regardless of this contract, since the translation is sensitive to the data, if the translated message is going to be sent through the network it is recommended that as the last step of the process the validation is run on the created message.","title":"Compliance"},{"location":"integrator/translations/translations-general/#headers","text":"Regardless of the specific translation mappings, the target message header is always filled with data from the source or with derived content as follows: Translation Source element Target element MT to MX Block 1 Sender Block 2 Receiver Fixed from target message identifier Current date and time Main message reference Trailer PDE AppHdr From AppHdr To AppHdr Message Definition AppHdr Creation Date and Time AppHdr Business Message Identifier AppHdr Possible Duplicate Emission (By default the ISO Business Header is created, not the legacy Application Header) MX to MT AppHdr From * AppHdr To * AppHdr Possible Duplicate Emission Fixed from target message identifier (both ISO Business Header and legacy Application Header are supported) Block 1 Sender Block 2 Receiver Trailer PDE Block 2 message type (Direction is Input by default. The rest of the MT headers data is filled with proper defaults) * If the AppHdr is not present, the translation attempts to use the parties BIC codes in the Group Header element within the MX Document. If none is found, then the MT is populated with default BIC codes. Also, both BIC and DN structures are supported, when the DN is used the BIC is extracted and filled with the default branch code. This default mapping can be overridden by configuration. In the TranslationConfiguration class that can be optionally passed to the translator call, a fixed specific sender and/or receiver can be set. The configuration will take precedence on any other default or mapped value. For example: MT103 mt = translator . translate ( mx , new TranslationConfiguration (). setSender ( new BIC ( \"ABCDARXX\" )));","title":"Headers"},{"location":"integrator/translations/translations-general/#message-direction","text":"In MT messages, the direction is explicit in the message structure because the headers are mandatory and there is one specific header for outgoing messages and another specific header for incoming messages. So when you have an MT payload, you know the direction. This is not true for MX, where the direction is not in the payload (AppHdr + Document), but in the transmission wrapper, and that is dependent on the specific interface. When the message is converted from MX to MT, there is no longer an explicit direction, so by default all translators from MX to MT will generate an input message. An Input message means the message is going to be sent to SWIFT. If in the MX to MT translation process, in your host application, you know the generated MTs should be Output because you have received the original MX from SWIFT then you can use a configuration to switch the direction. This is done passing the optional TranslationConfiguration to the translation call. For example: MT103 mt = translator . translate ( mx , new TranslationConfiguration (). setDirection ( MessageDirection . Output )); The MT content will be the same, but in the headers the sender and receiver will be reconfigured as Output (received) message.","title":"Message direction"},{"location":"integrator/translations/translations-general/#truncation","text":"When the source element value does not fit in the target message field, the translation will truncate the content. This could happen specially when translating from MX to MT, where the MT fields are shorter than the MX elements. By default, the truncation is done with evidence, meaning in the translated messages the truncated content will contain an explicit '+' symbol at the end of the field. This is done to indicate that the content has been truncated. Along that, the translation class stores the original and truncated content so that a report can be generated with the truncated elements. This report can be generated by calling the getTruncatedContent() method in the translator.","title":"Truncation"},{"location":"integrator/translations/translations-general/#coverage","text":"For MX to MT translations, a coverage report can be generated by calling the getCoverageReport() method in the translator. This report will show the elements of the source MX elements that have been mapped into the target MT. Notice in most situations the coverage report will not be 100% because there are many elements in the source MX that cannot be mapped into the target MT. The idea of the coverage report is to analyse if for certain use cases the key elements in the MX have been mapped.","title":"Coverage"},{"location":"integrator/translations/translations-general/#restricted-iso-20022-versions","text":"Depending on the user group, central bank, clearing system, or market infrastructure, different translation implementations might be available for the same pair of message types. This is the case when a restricted version of ISO 20022 is used with custom mappings; for example: CBPR+, ESMIG, SIC, etc\u2026 When these alternative translations are available, the variant or group will be explicit in the translation file name. Support for these restricted versions is a work in progress and will be added as needed. Current restricted versions available: Comprehensive coverage for all CBPR+ (Cross Border Payments) messages Partial translation for SIC (Swiss RGTS) messages Partial translation for RITS (Australian RGTS) messages Partial translation for CHATS (Hong Kong RGTS) messages Partial translation for SCRIPS (MEPS+, Singapore RGTS) messages Partial translations for T2S (TARGET2) messages Partial translations for LYNX (Canadian RGTS) messages Partial translations for SWIFTGO (SWIFT GPI) messages Note here we refer to providing specific translation implementations for the restricted versions. However, since all restricted standards are based on ISO, by default the general ISO 20022 can be used. MX to MT: the general ISO 20022 translation should be OK in most situations since from the output perspective, the MT message is undistinguished. Meaning an MT2103 created from a generic pacs.008 or a T2 pacs.008 will be the same. MT to MX: the general ISO 20022 translation could be use in most cases, and then the created MX output can be tweaked to match the specific requirements of the restricted version. For example, the MT2103 could be translated to a generic pacs.008 and then the specific T2 pacs.008 can be created by adding the missing elements or removing the ones not allowed. When available these translations are available in specific packages. Thus, instead of the translator implementation being located in the com.prowidesoftware.swift.translations package, it will be located in a package with the name of com.prowidesoftware.swift.translations.cbrp , com.prowidesoftware.swift.translations.sic , etc... To facilitate access to these alternative translators, each package contains it own TranslatorFactory class. For example, to get a translator for the CBPR+ pacs.008 to MT103 translation, instead of using the general TranslatorFactory.getTranslator(mx) method, you can use the specific CbprTranslatorFactory.getTranslator(mx) method. Moreover, to implementa a system that automatically translate messages for multiple target markets, there is also a TranslatorFactoryProvider class that will return the specific factory for a given target market. For example: TranslatorFactory factory = TranslatorFactoryProvider . getTranslatorFactory ( MarketType . RITS ); Translator translator = factory . getTranslator ( mt ); The code above with create an instance of the RITS specific translator factory, and from it, will attempt to find a suitable translator for the given MT message.","title":"Restricted ISO 20022 versions"},{"location":"integrator/translations/translations-general/#m-to-n-translations","text":"Although translation implementations are always one to one , there are some use cases where a single MX message can contain data corresponding to multiple MT messages. In other words, where a business operation, report, or transaction in an MX message cannot be mapped into a single MT because of the limitations of the MT standard.","title":"M to N translations"},{"location":"integrator/translations/translations-general/#setr015-to-mt515","text":"The switch order confirmation in an MX setr.015 can contain multiple switch operations, and for each it can contain multiple redemption and subscription legs. Thus, the translation to achieve should receive a single setr.015 and convert that into multiple MT515 messages. To keep the translation API simple and consistent, in these situations more than one translation implementation is made available for the given source and target message types. IN the swift order confirmation example, this is achieved by two translators: Class name Source message type Target message type MxSetr01500104_MT515_Redemption_Translation setr.015.001.04 MT 515 MxSetr01500104_MT515_Subscription_Translation setr.015.001.04 MT 515 Where the first translation implementation will convert the redemption leg data from the MX into an MT515 with the instrument sell, and the second translator will convert the subscription leg data from the MX into another MT515 with the instrument buy. The host application or the process running the translation is expected to use both translators, passing as parameters the same source MX message. The first call will create the redemption, while the second call, with the same source MX parameter, will create the subscription.","title":"setr.015 to MT515"},{"location":"integrator/translations/translations-general/#pain001-to-mt101","text":"The payment initiation in a pain.001 can contain multiple payment information elements, each having multiple credit transfers. The default 1 to 1 translation implemented in the MxPain00100103_MT101_Translation class will use as source content only the first payment information element. Each credit transfer in this source element will be mapped into a repetitive sequence B in the target MT. But a single MT will be created. A special 1 to many implementations for this use case is provided in the MxPain00100103_MT101_BulkTranslation class. The translation methods in this class return a List instead of a single instance. This implementation uses internally the one to one mapping, but will process all the available payment information elements in the source MX. For each payment information in the MX a single MT101 is created. As for the credit transfer repetitions within each payment information element, multiple sequences B are created in the corresponding MT101 instance. The 1 to 1 translation implemented in the MxPain00100103_MT101_Translation can be considered a special case of the MxPain00100103_MT101_BulkTranslation where the result will be a list with a single element. The drawback of the special bulk translation is that it cannot implement the generic translator API, thus it will not be recognized by the Translators Factory.","title":"pain.001 to MT101"},{"location":"integrator/translations/translations-mt2mx/","text":"MT to MX Translation from MT messages to its MX equivalent is done using the specific classes name MTnnn_Mxmmm_Translation , where nnn corresponds to a specific translatable MT and mmm to its available MX representation. Class selection The first step to perform a message translation is to select the proper translation to use. The specific translation class depends mainly on the message type, but in several cases also on the message content. MT103 for example, has two flavors (STP and not STP) for the source message, while the target MX is the same for both, so the available translation are: MT103_STP_MxPacs00800102_Translation MT103_MxPacs00800102_Translation A different example can be seen for MT564, where the same message type can be translated to several Mx messages depending on the message functionality (deductible from content): MT564_MxSeev03100202_Translation MT564_MxSeev03500202_Translation MT564_MxSeev03900202_Translation MT564_MxSeev04400202_Translation While the selection of a proper translation combination to apply is a responsibility of the calling application, the correctness of the call is checked at several points: First by the translation classes. You cannot invoke an MT103_MxPacs00800102_Translation passing and MT202 as parameters. Also, you cannot assign the result of that translation to an invalid Mx. Second, by the message logical criteria checks. These checks are performed internally by the translation process, and a runtime LogicalMessageCriteriaException is thrown if the criteria is not satisfied. For example in the MT564 example, these criteria checks are mainly based on the function of the corporate action message, defined in field 23G, so that a \"cancellation\" won't be translated into a \"confirmation\". Third, by the message preconditions. When all the above is correct, numerous content preconditions are checked to ensure that the source message can be effectively translated to the target message. Translation call The translation procedure is invoked with the translation method of the specific translation class. The following example shows how to translate an MT 564 into its corresponding MX seev.039.002.02: The MT is parsed into an MT564 object using any of the providing parsing methods: final MT564 source = MT564 . parse ( sample ); A proper instance of translation is created: MT564_MxSeev03900202_Translation translator = new MT564_MxSeev03900202_Translation (); And finally, the translation method is invoked in a try to catch the logical message criteria and preconditions exceptions. try { final MxSeev03900202 mx = ( MxSeev03900202 ) translator . translate ( source ); } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } catch ( final TranslationPreconditionException e2 ) { System . out . println ( \"precondition exception: \" + e2 . getMessage ()); } If the MT564 satisfies all preconditions, the mx variable will contain the resulting MX message. Then all the MX API can be used to retrieve content from the converted message, or it can be serialized to its XML representation. System . out . println ( \"Cancellation Reason Code:\" + mx . getCorpActnCxlAdvc (). getCxlAdvcGnlInf (). getCxlRsnCd (). name ()); System . out . println ( mx . message ()); 4 Business Header Depending on the source MT, some fields might be mapped to the target MX business header, which is optional. To check the created header in XML: In the created MX object, the message() or document() calls will serialize just the Document portion of the MX, while header() will serialize the header if it is present. Alternatively, you can call message(String, boolean) which will generate both header (if present) and document in a single XML under the indicated wrapper element. To check header in Java model: The getBusinessHeader() will return the model representation with the header. Complete example: https://github.com/prowide/prowide-integrator-examples/blob/master/src/main/java/com/prowidesoftware/swift/samples/integrator/translations/MtMxTranslationExample1.java","title":"MT to MX"},{"location":"integrator/translations/translations-mt2mx/#mt-to-mx","text":"Translation from MT messages to its MX equivalent is done using the specific classes name MTnnn_Mxmmm_Translation , where nnn corresponds to a specific translatable MT and mmm to its available MX representation.","title":"MT to MX"},{"location":"integrator/translations/translations-mt2mx/#class-selection","text":"The first step to perform a message translation is to select the proper translation to use. The specific translation class depends mainly on the message type, but in several cases also on the message content. MT103 for example, has two flavors (STP and not STP) for the source message, while the target MX is the same for both, so the available translation are: MT103_STP_MxPacs00800102_Translation MT103_MxPacs00800102_Translation A different example can be seen for MT564, where the same message type can be translated to several Mx messages depending on the message functionality (deductible from content): MT564_MxSeev03100202_Translation MT564_MxSeev03500202_Translation MT564_MxSeev03900202_Translation MT564_MxSeev04400202_Translation While the selection of a proper translation combination to apply is a responsibility of the calling application, the correctness of the call is checked at several points: First by the translation classes. You cannot invoke an MT103_MxPacs00800102_Translation passing and MT202 as parameters. Also, you cannot assign the result of that translation to an invalid Mx. Second, by the message logical criteria checks. These checks are performed internally by the translation process, and a runtime LogicalMessageCriteriaException is thrown if the criteria is not satisfied. For example in the MT564 example, these criteria checks are mainly based on the function of the corporate action message, defined in field 23G, so that a \"cancellation\" won't be translated into a \"confirmation\". Third, by the message preconditions. When all the above is correct, numerous content preconditions are checked to ensure that the source message can be effectively translated to the target message.","title":"Class selection"},{"location":"integrator/translations/translations-mt2mx/#translation-call","text":"The translation procedure is invoked with the translation method of the specific translation class. The following example shows how to translate an MT 564 into its corresponding MX seev.039.002.02: The MT is parsed into an MT564 object using any of the providing parsing methods: final MT564 source = MT564 . parse ( sample ); A proper instance of translation is created: MT564_MxSeev03900202_Translation translator = new MT564_MxSeev03900202_Translation (); And finally, the translation method is invoked in a try to catch the logical message criteria and preconditions exceptions. try { final MxSeev03900202 mx = ( MxSeev03900202 ) translator . translate ( source ); } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } catch ( final TranslationPreconditionException e2 ) { System . out . println ( \"precondition exception: \" + e2 . getMessage ()); } If the MT564 satisfies all preconditions, the mx variable will contain the resulting MX message. Then all the MX API can be used to retrieve content from the converted message, or it can be serialized to its XML representation. System . out . println ( \"Cancellation Reason Code:\" + mx . getCorpActnCxlAdvc (). getCxlAdvcGnlInf (). getCxlRsnCd (). name ()); System . out . println ( mx . message ()); 4","title":"Translation call"},{"location":"integrator/translations/translations-mt2mx/#business-header","text":"Depending on the source MT, some fields might be mapped to the target MX business header, which is optional. To check the created header in XML: In the created MX object, the message() or document() calls will serialize just the Document portion of the MX, while header() will serialize the header if it is present. Alternatively, you can call message(String, boolean) which will generate both header (if present) and document in a single XML under the indicated wrapper element. To check header in Java model: The getBusinessHeader() will return the model representation with the header. Complete example: https://github.com/prowide/prowide-integrator-examples/blob/master/src/main/java/com/prowidesoftware/swift/samples/integrator/translations/MtMxTranslationExample1.java","title":"Business Header"},{"location":"integrator/translations/translations-mx2mt/","text":"MX to MT Translation from MX messages to its MT equivalent is done using the specific classes name Mxmmm_MTnnn_Translation , where mmmm corresponds to a specific translatable MX and nn to its available MT representation. Class selection The first step to perform a message translation is to select the proper translation to use. The specific translation class depends mainly on the message type, but in several cases also on the message content. MxPacs00800102 for example can only be translated into an MT103. However, MxPacs00900102 can be used to create MT202 in both flavors; STP and not STP, so the available translation are: MxPacs00800102_MT103_Translation MxPacs00900102_MT202_Translation MxPacs00900102_MT202COV_Translation In the above example, a different set of preconditions apply to create the MT202 for STP or not. A different example can be seen for MxSeev03100202, where the same message type can be translated to several target MT messages: MxSeev03100202_MT564_Translation MxSeev03100202_MT568_Translation While the selection of a proper translation combination to apply is a responsibility of the calling application, the correctness of the call is checked at several points: First by the translation classes. You cannot invoke an MxSeev03100202_MT564_Translation passing anything different from a MxSeev03100202 as source message parameter. Also, you cannot assign the result of that translation to an invalid MT. Second, by the message logical criteria checks. These checks are performed internally by the translation process, and a runtime LogicalMessageCriteriaException is thrown if the criteria is not satisfied. Third, by the message preconditions. When all the above is correct, many content preconditions are checked to ensure that the source message can be effectively translated to the target message. Translation call The translation procedure is invoked with the translation method of the specific translation class. The following example shows how to translate a MxSeev03400202 into its corresponding MT 567: The source message can be created using the MX API or parsing its content from an XML file or string. MxSeev03400202 mx = new MxSeev03400202 (); mx . setBusinessHeader ( new BusinessHeader ( new BusinessApplicationHeaderV01 ())); mx . getBusinessHeader (). getBusinessApplicationHeader (). setBizMsgIdr ( \"MYID\" ); mx . setCorpActnInstrStsAdvc ( new CorporateActionInstructionStatusAdviceV02Subset ()); mx . getCorpActnInstrStsAdvc (). setCorpActnGnlInf ( new CorporateActionGeneralInformation13 ()); mx . getCorpActnInstrStsAdvc (). getCorpActnGnlInf (). setCorpActnEvtId ( \"777\" ); A proper instance of translation is created: MxSeev03400202_MT567_Translation translator = new MxSeev03400202_MT567_Translation (); And finally, the translation method is invoked in a try to catch the logical message criteria and preconditions exceptions. try { final MT567 mt = ( MT567 ) translator . translate ( mx ); } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } catch ( final TranslationPreconditionException e2 ) { System . out . println ( \"precondition exception: \" + e2 . getMessage ()); } If the MX satisfies all preconditions, the mt variable will contain the resulting MT message. Then all the MT API can be used to retrieve content from the converted message, or it can be serialized to its SWIFT FIN representation. System . out . println ( mt . message ()); Complete example: https://github.com/prowide/prowide-integrator-examples/blob/master/src/main/java/com/prowidesoftware/swift/samples/integrator/translations/MxMtTranslationExample1.java Truncation For situations where the element in the target message is limited to a certain size and the content read from the source message is larger, truncation is produced. Whenever truncation occurs during the translation process, the translator class collects the original and the truncated content in the object. The truncated content list can be retrieved by API: MxSeev03400202_MT567_Translation translator = new MxSeev03400202_MT567_Translation (); final MT567 mt = ( MT567 ) translator . translate ( mx ); for ( Truncation truncation : translator . getTruncatedContent ()) { System . out . println ( truncation . getOriginal () + \u201c -> \u201c + truncation . getTruncated ()); } When there is no truncation, the truncated content list in the translator class will be empty. Along with this internal report, the truncation is made explicit in the target message by adding a '+' symbol at the end of the truncated content. For example, this MX element with a long text: Lorem ipsum dolor sit amet, ut has choro rationibus. Cum denique consequat et. Est reque meliore platonem te. Te vim commodo ornatus delicatissimi. Pri eu graeco theophrastus intellegebat, inani vivendo suscipit sit id. Might be mapped into this truncated narrative in the target MT: :70D::REAS//Lorem ipsum dolor sit amet, ut has choro rationibus. Cum denique conse quat et. Est reque meliore platonem te. Te vim commodo ornatus delicat issimi. Pri eu graeco theophrastus intellegebat, inani vivendo suscip+ Where the text was wrapped into the available lines of 35 characters length, and the last character of the last line contains the '+' symbol to evidence that content was truncated. Notice, the '+' symbol will only be added if the target element supports the symbol in its character set. If the element for example only allows alphanumeric characters, then the '+' will not be used and the content will be just trimmed without explicit evidence. This evidence behavior can also be switched off as a flag in the optional TranslatorConfiguration that can be passed to the translation call. The internal truncation report will always be available, regardless of the evidence symbol being used or not in the content of the target message. Meaning if the symbol is not used because the element does not allow it or because the evidence has been switched off, in the truncation report you will still have the complete list of original and truncated content. Here is an example of the truncation behavior: public void testTruncateReferenceMxToMt () { String xml = \"\" + \"\" //... + \" \" + \" \" + \" VeryLargeReferenceInTheSource\" + \" \" //... + \" \" + \" Uhrengrosshandel Buxtehude Very Large Name\" + \" \" //... + \"\" ; MxPacs00800102 mxPacs00800102 = MxPacs00800102 . parse ( xml ); final MT103 mt103 = new MxPacs00800102_MT103_Translation (). translate ( mxPacs00800102 ); List < Truncation > truncatedContent = new MxPacs00800102_MT103_Translation (). getTruncatedContent (); //Original values assertEquals ( \"VeryLargeRefere+\" , mt103 . getField20 (). getValue ()); assertEquals ( \" Buxtehude Very La+\" , mt103 . getField50K (). getComponent2 ()); //Truncated Content 1 Truncation t1 = truncatedContent . get ( 0 ); assertEquals ( \"VeryLargeReferenceInTheSource\" , t1 . getOriginal ()); assertEquals ( \"nceInTheSource\" , t1 . getTruncated ()); //Truncated Content 2 Truncation t2 = truncatedContent . get ( 1 ); assertEquals ( \"Uhrengrosshandel Buxtehude Very Large Name\" , t2 . getOriginal ()); assertEquals ( \"rge Name\" , t2 . getTruncated ()); assertFalse ( t2 . isReference ()); } The translator configuration parameter must be adjusted to enable or disable truncation with evidence using the + symbol. For those fields that are reference ones, the Truncation object will have the isReference() method returning true. While returning false for those fields that are not reference ones. This is important to know because the truncation will have more impact in the first field types. To disable the truncation evidence, use the setTruncationEvidenceEnabled(false) method in the configuration object. new MxPacs00800102_MT103_Translation (). translate ( mxPacs00800102 , new TranslatorConfiguration (). setTruncateWithEvidence ( false )); Same example but with truncation evidence disabled, note that + symbol is not present in the result and the truncation slightly changed by one character. public void testTruncateReferenceMxToMt () { String xml = \"\" + \"\" //... + \" \" + \" \" + \" VeryLargeReferenceInTheSource\" + \" \" //... + \" \" + \" Uhrengrosshandel Buxtehude Very Large Name\" + \" \" //... + \"\" ; MxPacs00800102 mxPacs00800102 = MxPacs00800102 . parse ( xml ); //THIS IS THE IMPORTANT PART final MT103 mt103 = new MxPacs00800102_MT103_Translation (). translate ( mxPacs00800102 , new TranslatorConfiguration (). setTruncateWithEvidence ( false )); List < Truncation > truncatedContent = new MxPacs00800102_MT103_Translation (). getTruncatedContent (); //Original values assertEquals ( \"VeryLargeReferen\" , mt103 . getField20 (). getValue ()); assertEquals ( \" Buxtehude Very Lar\" , mt103 . getField50K (). getComponent2 ()); //Truncated Content 1 NO PLUS SIGN BUT CHAR Truncation t1 = truncatedContent . get ( 0 ); assertEquals ( \"VeryLargeReferenceInTheSource\" , t1 . getOriginal ()); assertEquals ( \"ceInTheSource\" , t1 . getTruncated ()); //Truncated Content 2 ONE CHAR SHORTER Truncation t2 = truncatedContent . get ( 1 ); assertEquals ( \"Uhrengrosshandel Buxtehude Very Large Name\" , t2 . getOriginal ()); assertEquals ( \"ge Name\" , t2 . getTruncated ()); assertFalse ( t2 . isReference ()); } For MX to MT translations, the translator class can provide a coverage report. During the translation process the accessed elements in the source XML are flagged as read, thus after the translation the covered and not covered elements can be queries. This flagging and the resulting report is available by default, but can be switched off with the TranslatorConfiguration parameter if needed for performance reasons. The report is encapsulated in a class with several methods that basically indicate if the header elements were covered, if the document elements were covered, and the list of elements including the path and value for each group. For example: MxSeev03400202 mx = MxSeev03400202 . parse ( xml ); MxSeev03400202_MT567_Translation translator = new MxSeev03400202_MT567_Translation (); MT567 mt = translator . translate ( mx ); MxCoverageReport report = translator . getCoverageReport (); if ( ! report . isDocumentCovered ()) { System . out . println ( \"Document not covered elements\" ); for ( MxCoverageReportElement element : report . getDocumentNotCovered ()) { System . out . println ( element . getPath () + \" = \" + element . getValue ()); } } Producing and output such as: Document not covered elements: /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/ApldOptnInd = false /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/CshMvmntDtls/RateAndAmtDtls/EarlySlctnFeeRate/Amt = 2345 /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/CshMvmntDtls/RateAndAmtDtls/EarlySlctnFeeRate/Amt/Ccy = USD /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/RateAndAmtDtls/NetDvddRate/RateTpAndAmtAndRateSts/Amt = 23423 /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/RateAndAmtDtls/NetDvddRate/RateTpAndAmtAndRateSts/Amt/Ccy = USD /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/RateAndAmtDtls/NetDvddRate/RateTpAndAmtAndRateSts/RateSts/Cd = ACTU /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/RateAndAmtDtls/NetDvddRate/RateTpAndAmtAndRateSts/RateTp/Cd = FLFR /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/SctiesQty/MaxQtyToInst/Unit = 234234 /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/SctiesQty/MinMltplQtyToInst/Unit = 23423 /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/SctiesQty/MinQtyToInst/Unit = 23423 With the key value pair of elements in the source MX that has not been read during the translation. Notice covered elements do not strictly mean the content will appear in the target MT, but its element value was read as part of the translation process. Depending on the specific mappings, the translation process is not just moving data from one place to the other, in many cases decisions are made based on the source content and for this coverage report those elements are considered read. Notice as well, due to the richness of the ISO 20022 standard compared to the MT, full coverage is an exceptional case to achieve and not the normal case. IN most scenarios, you will find elements in the MX that have no equivalent in the MT or that are not processed as part of the translation logic. Sanitize After translating from MX to MT, the translator will sanitize the content of the source MX to ensure the resulting MT is valid. This is done by removing invalid characters and replacing them with a valid character. The default character is the '.' (dot) character, and the invalida characters are '&' (ampersand), '\"' (double quote), '<' (less than symbol) and '>' (greater than symbol). Furthermore, in multiline fields, any ':' (colon) or '-' (hyphen) character found at the beginning of each line starting from the second line will be substituted with a '.' (dot). However, if a line begins with multiple consecutive hyphen or colon characters, only the first one will be replaced. Finally, the translator will verify if specific fields have a mandatory component and assign a default value in case they are missing it. This function is particularly useful for fields containing a party identifier that does not include the name and address. The sanitization process is done by default, but can be switched off with the TranslatorConfiguration parameter if needed. MxPacs00800102_MT103_Translation translator = new MxPacs00800102_MT103_Translation (); final MT103 mt = translator . translate ( source , new TranslatorConfiguration (). setMxToMtCharsetConversionEnabled ( false )); All the process described above is done by using the MtSanitizer class. This class is a helper to manipulate and fix fields in an MT messages. So it can be used to sanitize any MT message, not just the ones translated by the library.","title":"MX to MT"},{"location":"integrator/translations/translations-mx2mt/#mx-to-mt","text":"Translation from MX messages to its MT equivalent is done using the specific classes name Mxmmm_MTnnn_Translation , where mmmm corresponds to a specific translatable MX and nn to its available MT representation.","title":"MX to MT"},{"location":"integrator/translations/translations-mx2mt/#class-selection","text":"The first step to perform a message translation is to select the proper translation to use. The specific translation class depends mainly on the message type, but in several cases also on the message content. MxPacs00800102 for example can only be translated into an MT103. However, MxPacs00900102 can be used to create MT202 in both flavors; STP and not STP, so the available translation are: MxPacs00800102_MT103_Translation MxPacs00900102_MT202_Translation MxPacs00900102_MT202COV_Translation In the above example, a different set of preconditions apply to create the MT202 for STP or not. A different example can be seen for MxSeev03100202, where the same message type can be translated to several target MT messages: MxSeev03100202_MT564_Translation MxSeev03100202_MT568_Translation While the selection of a proper translation combination to apply is a responsibility of the calling application, the correctness of the call is checked at several points: First by the translation classes. You cannot invoke an MxSeev03100202_MT564_Translation passing anything different from a MxSeev03100202 as source message parameter. Also, you cannot assign the result of that translation to an invalid MT. Second, by the message logical criteria checks. These checks are performed internally by the translation process, and a runtime LogicalMessageCriteriaException is thrown if the criteria is not satisfied. Third, by the message preconditions. When all the above is correct, many content preconditions are checked to ensure that the source message can be effectively translated to the target message.","title":"Class selection"},{"location":"integrator/translations/translations-mx2mt/#translation-call","text":"The translation procedure is invoked with the translation method of the specific translation class. The following example shows how to translate a MxSeev03400202 into its corresponding MT 567: The source message can be created using the MX API or parsing its content from an XML file or string. MxSeev03400202 mx = new MxSeev03400202 (); mx . setBusinessHeader ( new BusinessHeader ( new BusinessApplicationHeaderV01 ())); mx . getBusinessHeader (). getBusinessApplicationHeader (). setBizMsgIdr ( \"MYID\" ); mx . setCorpActnInstrStsAdvc ( new CorporateActionInstructionStatusAdviceV02Subset ()); mx . getCorpActnInstrStsAdvc (). setCorpActnGnlInf ( new CorporateActionGeneralInformation13 ()); mx . getCorpActnInstrStsAdvc (). getCorpActnGnlInf (). setCorpActnEvtId ( \"777\" ); A proper instance of translation is created: MxSeev03400202_MT567_Translation translator = new MxSeev03400202_MT567_Translation (); And finally, the translation method is invoked in a try to catch the logical message criteria and preconditions exceptions. try { final MT567 mt = ( MT567 ) translator . translate ( mx ); } catch ( final LogicalMessageCriteriaException e1 ) { System . out . println ( \"logical message criteria exception: \" + e1 . getMessage ()); } catch ( final TranslationPreconditionException e2 ) { System . out . println ( \"precondition exception: \" + e2 . getMessage ()); } If the MX satisfies all preconditions, the mt variable will contain the resulting MT message. Then all the MT API can be used to retrieve content from the converted message, or it can be serialized to its SWIFT FIN representation. System . out . println ( mt . message ()); Complete example: https://github.com/prowide/prowide-integrator-examples/blob/master/src/main/java/com/prowidesoftware/swift/samples/integrator/translations/MxMtTranslationExample1.java","title":"Translation call"},{"location":"integrator/translations/translations-mx2mt/#truncation","text":"For situations where the element in the target message is limited to a certain size and the content read from the source message is larger, truncation is produced. Whenever truncation occurs during the translation process, the translator class collects the original and the truncated content in the object. The truncated content list can be retrieved by API: MxSeev03400202_MT567_Translation translator = new MxSeev03400202_MT567_Translation (); final MT567 mt = ( MT567 ) translator . translate ( mx ); for ( Truncation truncation : translator . getTruncatedContent ()) { System . out . println ( truncation . getOriginal () + \u201c -> \u201c + truncation . getTruncated ()); } When there is no truncation, the truncated content list in the translator class will be empty. Along with this internal report, the truncation is made explicit in the target message by adding a '+' symbol at the end of the truncated content. For example, this MX element with a long text: Lorem ipsum dolor sit amet, ut has choro rationibus. Cum denique consequat et. Est reque meliore platonem te. Te vim commodo ornatus delicatissimi. Pri eu graeco theophrastus intellegebat, inani vivendo suscipit sit id. Might be mapped into this truncated narrative in the target MT: :70D::REAS//Lorem ipsum dolor sit amet, ut has choro rationibus. Cum denique conse quat et. Est reque meliore platonem te. Te vim commodo ornatus delicat issimi. Pri eu graeco theophrastus intellegebat, inani vivendo suscip+ Where the text was wrapped into the available lines of 35 characters length, and the last character of the last line contains the '+' symbol to evidence that content was truncated. Notice, the '+' symbol will only be added if the target element supports the symbol in its character set. If the element for example only allows alphanumeric characters, then the '+' will not be used and the content will be just trimmed without explicit evidence. This evidence behavior can also be switched off as a flag in the optional TranslatorConfiguration that can be passed to the translation call. The internal truncation report will always be available, regardless of the evidence symbol being used or not in the content of the target message. Meaning if the symbol is not used because the element does not allow it or because the evidence has been switched off, in the truncation report you will still have the complete list of original and truncated content. Here is an example of the truncation behavior: public void testTruncateReferenceMxToMt () { String xml = \"\" + \"\" //... + \" \" + \" \" + \" VeryLargeReferenceInTheSource\" + \" \" //... + \" \" + \" Uhrengrosshandel Buxtehude Very Large Name\" + \" \" //... + \"\" ; MxPacs00800102 mxPacs00800102 = MxPacs00800102 . parse ( xml ); final MT103 mt103 = new MxPacs00800102_MT103_Translation (). translate ( mxPacs00800102 ); List < Truncation > truncatedContent = new MxPacs00800102_MT103_Translation (). getTruncatedContent (); //Original values assertEquals ( \"VeryLargeRefere+\" , mt103 . getField20 (). getValue ()); assertEquals ( \" Buxtehude Very La+\" , mt103 . getField50K (). getComponent2 ()); //Truncated Content 1 Truncation t1 = truncatedContent . get ( 0 ); assertEquals ( \"VeryLargeReferenceInTheSource\" , t1 . getOriginal ()); assertEquals ( \"nceInTheSource\" , t1 . getTruncated ()); //Truncated Content 2 Truncation t2 = truncatedContent . get ( 1 ); assertEquals ( \"Uhrengrosshandel Buxtehude Very Large Name\" , t2 . getOriginal ()); assertEquals ( \"rge Name\" , t2 . getTruncated ()); assertFalse ( t2 . isReference ()); } The translator configuration parameter must be adjusted to enable or disable truncation with evidence using the + symbol. For those fields that are reference ones, the Truncation object will have the isReference() method returning true. While returning false for those fields that are not reference ones. This is important to know because the truncation will have more impact in the first field types. To disable the truncation evidence, use the setTruncationEvidenceEnabled(false) method in the configuration object. new MxPacs00800102_MT103_Translation (). translate ( mxPacs00800102 , new TranslatorConfiguration (). setTruncateWithEvidence ( false )); Same example but with truncation evidence disabled, note that + symbol is not present in the result and the truncation slightly changed by one character. public void testTruncateReferenceMxToMt () { String xml = \"\" + \"\" //... + \" \" + \" \" + \" VeryLargeReferenceInTheSource\" + \" \" //... + \" \" + \" Uhrengrosshandel Buxtehude Very Large Name\" + \" \" //... + \"\" ; MxPacs00800102 mxPacs00800102 = MxPacs00800102 . parse ( xml ); //THIS IS THE IMPORTANT PART final MT103 mt103 = new MxPacs00800102_MT103_Translation (). translate ( mxPacs00800102 , new TranslatorConfiguration (). setTruncateWithEvidence ( false )); List < Truncation > truncatedContent = new MxPacs00800102_MT103_Translation (). getTruncatedContent (); //Original values assertEquals ( \"VeryLargeReferen\" , mt103 . getField20 (). getValue ()); assertEquals ( \" Buxtehude Very Lar\" , mt103 . getField50K (). getComponent2 ()); //Truncated Content 1 NO PLUS SIGN BUT CHAR Truncation t1 = truncatedContent . get ( 0 ); assertEquals ( \"VeryLargeReferenceInTheSource\" , t1 . getOriginal ()); assertEquals ( \"ceInTheSource\" , t1 . getTruncated ()); //Truncated Content 2 ONE CHAR SHORTER Truncation t2 = truncatedContent . get ( 1 ); assertEquals ( \"Uhrengrosshandel Buxtehude Very Large Name\" , t2 . getOriginal ()); assertEquals ( \"ge Name\" , t2 . getTruncated ()); assertFalse ( t2 . isReference ()); } For MX to MT translations, the translator class can provide a coverage report. During the translation process the accessed elements in the source XML are flagged as read, thus after the translation the covered and not covered elements can be queries. This flagging and the resulting report is available by default, but can be switched off with the TranslatorConfiguration parameter if needed for performance reasons. The report is encapsulated in a class with several methods that basically indicate if the header elements were covered, if the document elements were covered, and the list of elements including the path and value for each group. For example: MxSeev03400202 mx = MxSeev03400202 . parse ( xml ); MxSeev03400202_MT567_Translation translator = new MxSeev03400202_MT567_Translation (); MT567 mt = translator . translate ( mx ); MxCoverageReport report = translator . getCoverageReport (); if ( ! report . isDocumentCovered ()) { System . out . println ( \"Document not covered elements\" ); for ( MxCoverageReportElement element : report . getDocumentNotCovered ()) { System . out . println ( element . getPath () + \" = \" + element . getValue ()); } } Producing and output such as: Document not covered elements: /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/ApldOptnInd = false /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/CshMvmntDtls/RateAndAmtDtls/EarlySlctnFeeRate/Amt = 2345 /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/CshMvmntDtls/RateAndAmtDtls/EarlySlctnFeeRate/Amt/Ccy = USD /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/RateAndAmtDtls/NetDvddRate/RateTpAndAmtAndRateSts/Amt = 23423 /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/RateAndAmtDtls/NetDvddRate/RateTpAndAmtAndRateSts/Amt/Ccy = USD /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/RateAndAmtDtls/NetDvddRate/RateTpAndAmtAndRateSts/RateSts/Cd = ACTU /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/RateAndAmtDtls/NetDvddRate/RateTpAndAmtAndRateSts/RateTp/Cd = FLFR /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/SctiesQty/MaxQtyToInst/Unit = 234234 /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/SctiesQty/MinMltplQtyToInst/Unit = 23423 /Document/CorpActnMvmntPrlimryAdvc/CorpActnMvmntDtls/SctiesQty/MinQtyToInst/Unit = 23423 With the key value pair of elements in the source MX that has not been read during the translation. Notice covered elements do not strictly mean the content will appear in the target MT, but its element value was read as part of the translation process. Depending on the specific mappings, the translation process is not just moving data from one place to the other, in many cases decisions are made based on the source content and for this coverage report those elements are considered read. Notice as well, due to the richness of the ISO 20022 standard compared to the MT, full coverage is an exceptional case to achieve and not the normal case. IN most scenarios, you will find elements in the MX that have no equivalent in the MT or that are not processed as part of the translation logic.","title":"Truncation"},{"location":"integrator/translations/translations-mx2mt/#sanitize","text":"After translating from MX to MT, the translator will sanitize the content of the source MX to ensure the resulting MT is valid. This is done by removing invalid characters and replacing them with a valid character. The default character is the '.' (dot) character, and the invalida characters are '&' (ampersand), '\"' (double quote), '<' (less than symbol) and '>' (greater than symbol). Furthermore, in multiline fields, any ':' (colon) or '-' (hyphen) character found at the beginning of each line starting from the second line will be substituted with a '.' (dot). However, if a line begins with multiple consecutive hyphen or colon characters, only the first one will be replaced. Finally, the translator will verify if specific fields have a mandatory component and assign a default value in case they are missing it. This function is particularly useful for fields containing a party identifier that does not include the name and address. The sanitization process is done by default, but can be switched off with the TranslatorConfiguration parameter if needed. MxPacs00800102_MT103_Translation translator = new MxPacs00800102_MT103_Translation (); final MT103 mt = translator . translate ( source , new TranslatorConfiguration (). setMxToMtCharsetConversionEnabled ( false )); All the process described above is done by using the MtSanitizer class. This class is a helper to manipulate and fix fields in an MT messages. So it can be used to sanitize any MT message, not just the ones translated by the library.","title":"Sanitize"},{"location":"integrator/validation/","text":"Prowide Integrator Validation - Overview The Validation library provides a set of APIs to validate SWIFT messages (MT and ISO 20022) against the standard rules. By making sure the messages are valid, the library helps to avoid sending messages that will be rejected by the SWIFT network, or the counter-party applications; preventing NAKs. For MT messages, all SWIFT format validations are implemented, including: Structure : mandatory sequences and fields, sequence and fields ordering, sequence and fields repetitions. Fields : fields mandatory components, components length, character sets, specific codeword qualifiers. Semantic validations (network rules). BIC codes against directory, ISO country and currency codes, IBAN numbers, custom rules. For MX messages (ISO 20022), the library validates: Message structure using the XSD schema . ISO external code sets . Cross-element rules, for a subset of messages types. BIC codes against directory, ISO country and currency codes, IBAN numbers, custom rules. The different steps of the validation process can be tuned up, for example, using specific message schema definitions, adding or removing validation rules, and filtering the resulting problem list. Custom rules can also be added to the validation process, to implement specific validations for a given message type. Javadoc Online javadoc Prowide Integrator Validation Javadoc SRU2023-9.4.x","title":"Prowide Integrator Validation - Overview"},{"location":"integrator/validation/#prowide-integrator-validation-overview","text":"The Validation library provides a set of APIs to validate SWIFT messages (MT and ISO 20022) against the standard rules. By making sure the messages are valid, the library helps to avoid sending messages that will be rejected by the SWIFT network, or the counter-party applications; preventing NAKs. For MT messages, all SWIFT format validations are implemented, including: Structure : mandatory sequences and fields, sequence and fields ordering, sequence and fields repetitions. Fields : fields mandatory components, components length, character sets, specific codeword qualifiers. Semantic validations (network rules). BIC codes against directory, ISO country and currency codes, IBAN numbers, custom rules. For MX messages (ISO 20022), the library validates: Message structure using the XSD schema . ISO external code sets . Cross-element rules, for a subset of messages types. BIC codes against directory, ISO country and currency codes, IBAN numbers, custom rules. The different steps of the validation process can be tuned up, for example, using specific message schema definitions, adding or removing validation rules, and filtering the resulting problem list. Custom rules can also be added to the validation process, to implement specific validations for a given message type.","title":"Prowide Integrator Validation - Overview"},{"location":"integrator/validation/#javadoc","text":"Online javadoc Prowide Integrator Validation Javadoc SRU2023-9.4.x","title":"Javadoc"},{"location":"integrator/validation/validation-bic/","text":"BIC validation To avoid false positives when validating BIC codes due to a possible un-updated BIC dictionary, this validation is turned off by default. If this is set to true, when validating a BIC code, the internal database will be used and validation will pass only if the exact BIC exists in the internal catalog, checking the full BIC code including institution code, location and branch. If left false, the BIC validation will just check that the code has 8 or 11 characters. To turn this validation on, the Configuration object in the Validation Engine can be used: engine . getConfig (). setBicDatabaseEnabled ( true ); By default the BIC directory that is used, is the Derby embedded database included in the pw-swift-integrator-data-1.X.X.jar file that can be added as a regular dependency to the project. A custom BIC directory can be provided by implementing the IBICDirectory interface and providing an instance to the SdkConfiguration class: SdkConfiguration . setCustomIBICDirectory ( customInstance ); Country and currency validation As for the elements containing country and currency codes, the validation engine will use the internal list of valid codes. This list is initialized with values from the underlying Java library, but can be extended with custom values using the IsoUtils class.","title":"BIC validation"},{"location":"integrator/validation/validation-bic/#bic-validation","text":"To avoid false positives when validating BIC codes due to a possible un-updated BIC dictionary, this validation is turned off by default. If this is set to true, when validating a BIC code, the internal database will be used and validation will pass only if the exact BIC exists in the internal catalog, checking the full BIC code including institution code, location and branch. If left false, the BIC validation will just check that the code has 8 or 11 characters. To turn this validation on, the Configuration object in the Validation Engine can be used: engine . getConfig (). setBicDatabaseEnabled ( true ); By default the BIC directory that is used, is the Derby embedded database included in the pw-swift-integrator-data-1.X.X.jar file that can be added as a regular dependency to the project. A custom BIC directory can be provided by implementing the IBICDirectory interface and providing an instance to the SdkConfiguration class: SdkConfiguration . setCustomIBICDirectory ( customInstance );","title":"BIC validation"},{"location":"integrator/validation/validation-bic/#country-and-currency-validation","text":"As for the elements containing country and currency codes, the validation engine will use the internal list of valid codes. This list is initialized with values from the underlying Java library, but can be extended with custom values using the IsoUtils class.","title":"Country and currency validation"},{"location":"integrator/validation/validation-mt/","text":"MT message validation MT message structure validation Message structure validation is the first step in the MT validation process, and it's almost the most important for MT messages. The structure validation rules validate the overall message structure. They check that the message has the mandatory and optional blocks and that the blocks are in correct order. For block 4, they validate each field and each defined sequence of fields checking presence if it is mandatory, allowed repetitions and ordering. The structure is done by a heuristic of field matching against a defined message scheme. The structure of a message is defined in a proprietary XML scheme. The library includes schemes for all SWIFT MT messages, and any of them can be customized. For detailed information regarding schemes, please check the SDK developer guide . During the validation process the engine can automatically detect a suitable scheme to apply, but the user may overwrite this indicating a specific scheme to use by API. As a general use case the scheme to use will map the mt number of the message as indicated at block 2 plus the optional message variant (STP, COV, REMIT) indicated in block 3. The following example is similar to the previous one, but a specific scheme is indicated in the validation call. ValidationEngine engine = new ValidationEngine (); engine . initialize (); Scheme scheme = SRU2016MtType . MT103_REMIT . sheme (); List < ValidationProblem > r = engine . validateMessage ( msg , scheme ); engine . dispose (); The scheme parameter is optional. There are two situations where indicating a specific scheme becomes handy: When the Scheme object has been dynamically modified to achieve custom validations. To achieve maximum performance, releasing the engine from the auto-detection and loading of corresponding schemes. Ignoring structure problems On occasions, messages may be written on purpose with invalid values or received from internal back-office applications with local information not suitable for SWIFT. One common use case of this is the usage given to the Logical Terminal (LT) identifier in the header block. According to SWIFT the LT identifier is used when the institution runs more than one terminal, and in that case letters A, B or C are used, while X is explicitly forbidden (X's padding should be only used for the branch). Nevertheless, an institution may be using \u2018X\u2019 on testing or load balancing environments and may need to bypass such validation to prevent processes abortion due to validation error. Another common use case is the session and sequence number generated with invalid data. Therefore, this feature is a quick way to bypass message structure validations by means of API, using the ValidationConfiguration . For the example above, the following code will indicate the engine to ignore the validation of the LT identifier at the header block (block 1): engine . getConfig (). addIgnoreValidatorProblemKey ( StructureProblem . H10 ); All problems in StructureProblem that start with BLOCK1_ and BLOCK2_ may be added to the ignore list. Attempts to add other problem types will be ignored, issuing just a log message. More validation examples can be found at https://github.com/prowide/ MT message field validation The field validation rules check the internal component structure of each field in a message. For each combination of field number and letter option, the compliance to specific validation pattern is verified, checking: Presence of mandatory components. Components length and charset Specific format subfunctions, for example DATE2, DATE4, TIME2, AMOUNT15, CUR, etc.. The number and size of lines (including not allowed characters starting a line). Since version 7.8 this validation rules are implemented into a single processing unit, in the FieldValidationRule class. For information regarding the allowed pattern and internal components of each field, please refer to the javadoc for each FieldNN implementation. MT message semantic and network rules validation The semantic (a.k.a. network rules) rules are validation constraints that usually involve more than a field in a message. There are hundreds of semantic validations defined by SWIFT and implemented by the validation module. This semantic checks are defined per message type and can involve among other things: Validating conditional presence of fields and sequences based on other fields or sequences. Validating conditional presence of fields and sequences based on fields qualifiers. Validating conditional allowed qualifiers between fields. Validating cross-referenced dates. Validating currencies' consistency. Validating sum of amounts between transactions and fields with totes. There are 300 semantic validations checks. The relation between a specific message type and the semantica validation that are applied is defined in the message Scheme. ERI (Euro Related Info) validation On top of the default generic format, some fields are validated against the ERI constraints when the ERI data is present. ERI refers to the original currency in the transaction. If no specific fields are available to specify the original currency and amount, ERI data may be added in a free text field with the codewords: OCMT and CHGS . By default, the ERI is validated in fields 72, field 77A (MTs 416, 455 and 456), field 79 (MT 986) and fields 86 and 61 (MTs 940 and 942). ERI validation is reported with standard error codes such as T47, T52 and T40. Since the specification of ERI is always optional, this special constraint checks can be easily switched off with a parameter in the validation engine configuration: engine . getConfig (). setEriValidationEnabled ( false ); This switch is the recommended way to disable all ERI related checks if the constraints must not be checked in your business context. IBAN validation Multiple MT fields could contain an account number, such as the first component in field 59. The default validation for these account numbers is just based on the allowed characters and total length, which in general for account numbers is 34x. When these account components are used with IBAN numbers, an additional constraint can be enforced so that the full IBAN number validation is applied. In the validation configuration, you need to first enable IBAN validation in general with the flag: engine . getConfig (). setIBANValidationEnabled ( true ); Then you need to explicitly identify the specific field components where the IBAN validation should apply. These are configured using MtPath expressions like this: engine . getConfig (). addMtIbanPath ( MtPathExpression . parse ( \"50K/1\" )); engine . getConfig (). addMtIbanPath ( MtPathExpression . parse ( \"59/1\" )); For information on the MtPath expressions syntax and capabilities, please check the SDK developer guide. Custom MT validation The validation engine supports three different ways to customize the validation. These together allow you to define any custom constraint over the standard. Structure validations can be modified by means of the scheme structure definition, and other types of rules can be added or removed from the validation process. Customizing schemes To change mandatory and optional fields, supported letter options, field and sequences repetitions, and expected qualifiers, a modified scheme can be used in the validation call. ValidationEngine .validateMessage can accept just the SwiftMessage object to validate, or the message object plus a specific Scheme object if the default behaviour is being overwritten. The custom scheme can be created in Java, from scratch, or by modifying one of the out-of-the-box default Scheme classes provided. Schemes can also be defined in XML and read as Scheme objects using the SchemeXmlReader . The scheme object defines the overall structure of a message, including its nested sequences (if any) and all the fields and letter options combination that the message accepts. By means of a custom scheme, you can for example restrict several letter options on specific fields, or reduce or extend the expected qualifiers for any field. Most common use cases demanding some kind of custom validation can be entirely covered by customizing schemes. For more information on schemes, please check the SDK Developer Guide. Adding a custom rule Custom rules can be injected in the validation to perform any additional check not covered by the standard validation. Being implemented as Java classes, this custom rules can do anything you need. Custom rules will be evaluated after all standard rules, and are implemented in your own application as normal Java classes meeting the following simple requisites: Extend ValidationRule directly or indirectly. Override implementation of the method eval(SwiftMessage, String) to perform any check on the message without limitations. The method must return the list of validation problems found or an empty list if the message satisfies the validation. Example 1: Custom rule to check the reference prefix The following example implements a rule to check that the message reference is prefixed \"MYREF\", so if the message reference is not present or not prefixed with \"MYREF\" this rule will report a validation problem: public class MyRule extends ValidationRule { @Override protected List < ValidationProblem > eval ( SwiftMessage msg , String mt ) { List < ValidationProblem > result = new ArrayList < ValidationProblem > (); if ( msg . getBlock4 () != null ) { Tag reference = msg . getBlock4 (). getTagByName ( \"20\" ); if ( reference == null || ! StringUtils . startsWith ( reference . getValue (), \"MYREF\" )) { result . add ( new ValidationProblem ( \"BAD_REFERENCE\" , \"the reference must start with MYREF\" )); } } return result ; } } Example 2: Custom rule to check the presence of the trailer block The example below demonstrates a rule for verifying the presence of the trailer block in the message. According to the standard, Block 5, if included, must always contain the CHK tag. However, the checksum calculation algorithm is proprietary and not disclosed by SWIFT. Therefore, without a method for users to compute the checksum, adding validation for it is not feasible. For that reason it is a good practice to check the presence of the trailer block and the CHK tag in a custom rule. public class TrailerCHKValidationRule extends ValidationRule { @Override protected List < ValidationProblem > eval ( SwiftMessage msg , String mt ) { List < ValidationProblem > result = new ArrayList <> (); SwiftBlock5 block5 = msg . getBlock5 (); if ( block5 != null && ! block5 . getTags (). isEmpty ()) { Tag chk = block5 . getTagByName ( \"CHK\" ); if ( chk == null ) { result . add ( new ValidationProblem ( StructureProblem . Z04 ). setBundleKey ( \"Z04.missing\" )); } } return result ; } } All found errors should be returned as ValidationProblem objects, and it is a good practice that custom rules create custom validation problems, since the standard ValidationProblem class is not intended to be a general purpose class. Custom validation problems may be created by extending the ValidationProblem or can be generated dynamically in your own rule just by creating a generic ValidationProblem instance, providing a custom error key and error message. Once the validation rule is implemented, it must be injected in the engine configuration. All rules are associated with messages by scheme names (where scheme names by default is a composition of the message type and the message variant). If the same rule should be applied to more than one message type, it must explicitly be added into the custom rules map for each corresponding message type. The following example adds the above rules to an engine instance for messages MT103 REMIT and MT 202: engine . getConfig (). addCustomRule ( \"103_REMIT\" , new MyRule ()); engine . getConfig (). addCustomRule ( \"202\" , new TrailerCHKValidationRule ()); Notice in the example, we use the MT types enumeration to provide valid scheme names. The plain string with the message type number can also be used for this purpose if you don\u2019t use specific message variants. Elaborated examples can be found at https://github.com/prowide/prowide-integrator-examples/blob/master/src/com/prowidesoftware/swift/samples/integrator/validation/MessageValidationWithCustomRulesExample.java Ignoring specific validation rules When instead of adding a new constraint over the standard, there is a need to be more flexible, reducing the constraint already implemented, you can indicate that some validation problems should be ignored. This is done by a dynamic setting in the validation engine configuration instance, where you can mark as many problems as you need. Validation problems are uniquely identified by its error keys, so the available enumerations are used to clearly identify the problem to ignore. The following example shows how to mark several types of validation problems for ignore, including general, structure, field, and semantic checks. In a real use case scenario, this is used to filter just a few specific constraints depending on the nature of the messages being validation and the need for some flexibility over the default standard constraints. engine . getConfig (). addIgnoredValidationProblem ( GeneralProblem . EXTRA_DATA_IN_MESSAGE ); engine . getConfig (). addIgnoredValidationProblem ( StructureProblem . INVALID_FIELD_QUALIFIER ); engine . getConfig (). addIgnoredValidationProblem ( StructureProblem . BLOCK1_APPLICATION_ID ); engine . getConfig (). addIgnoredValidationProblem ( FieldProblem . COMPONENT_BAD_SIZE ); engine . getConfig (). addIgnoredValidationProblem ( FieldProblem . BAD_CURRENCY ); engine . getConfig (). addIgnoredValidationProblem ( FieldProblem . COMPONENT_NOT_BIC ); engine . getConfig (). addIgnoredValidationProblem ( SemanticProblem . D75 ); Notice some special problems are blocking for the validation and cannot be ignored; the ones related to the license ( UNLICENSED_BIC, UNLICENSED_MT, LICENSE_PROBLEM) and the major blocking issues (UNSUPPORTED_MESSAGE, UNRECOGNIZED, MISSING_BLOCK1, MISSING_BLOCK2, MISSING_BLOCK4). A complete example can be found at https://github.com/prowide/prowide-integrator-examples/blob/master/src/com/prowidesoftware/swift/samples/integrator/validation/MessageValidationIgnoringCustomExample.java","title":"MT message validation"},{"location":"integrator/validation/validation-mt/#mt-message-validation","text":"","title":"MT message validation"},{"location":"integrator/validation/validation-mt/#mt-message-structure-validation","text":"Message structure validation is the first step in the MT validation process, and it's almost the most important for MT messages. The structure validation rules validate the overall message structure. They check that the message has the mandatory and optional blocks and that the blocks are in correct order. For block 4, they validate each field and each defined sequence of fields checking presence if it is mandatory, allowed repetitions and ordering. The structure is done by a heuristic of field matching against a defined message scheme. The structure of a message is defined in a proprietary XML scheme. The library includes schemes for all SWIFT MT messages, and any of them can be customized. For detailed information regarding schemes, please check the SDK developer guide . During the validation process the engine can automatically detect a suitable scheme to apply, but the user may overwrite this indicating a specific scheme to use by API. As a general use case the scheme to use will map the mt number of the message as indicated at block 2 plus the optional message variant (STP, COV, REMIT) indicated in block 3. The following example is similar to the previous one, but a specific scheme is indicated in the validation call. ValidationEngine engine = new ValidationEngine (); engine . initialize (); Scheme scheme = SRU2016MtType . MT103_REMIT . sheme (); List < ValidationProblem > r = engine . validateMessage ( msg , scheme ); engine . dispose (); The scheme parameter is optional. There are two situations where indicating a specific scheme becomes handy: When the Scheme object has been dynamically modified to achieve custom validations. To achieve maximum performance, releasing the engine from the auto-detection and loading of corresponding schemes.","title":"MT message structure validation"},{"location":"integrator/validation/validation-mt/#ignoring-structure-problems","text":"On occasions, messages may be written on purpose with invalid values or received from internal back-office applications with local information not suitable for SWIFT. One common use case of this is the usage given to the Logical Terminal (LT) identifier in the header block. According to SWIFT the LT identifier is used when the institution runs more than one terminal, and in that case letters A, B or C are used, while X is explicitly forbidden (X's padding should be only used for the branch). Nevertheless, an institution may be using \u2018X\u2019 on testing or load balancing environments and may need to bypass such validation to prevent processes abortion due to validation error. Another common use case is the session and sequence number generated with invalid data. Therefore, this feature is a quick way to bypass message structure validations by means of API, using the ValidationConfiguration . For the example above, the following code will indicate the engine to ignore the validation of the LT identifier at the header block (block 1): engine . getConfig (). addIgnoreValidatorProblemKey ( StructureProblem . H10 ); All problems in StructureProblem that start with BLOCK1_ and BLOCK2_ may be added to the ignore list. Attempts to add other problem types will be ignored, issuing just a log message. More validation examples can be found at https://github.com/prowide/","title":"Ignoring structure problems"},{"location":"integrator/validation/validation-mt/#mt-message-field-validation","text":"The field validation rules check the internal component structure of each field in a message. For each combination of field number and letter option, the compliance to specific validation pattern is verified, checking: Presence of mandatory components. Components length and charset Specific format subfunctions, for example DATE2, DATE4, TIME2, AMOUNT15, CUR, etc.. The number and size of lines (including not allowed characters starting a line). Since version 7.8 this validation rules are implemented into a single processing unit, in the FieldValidationRule class. For information regarding the allowed pattern and internal components of each field, please refer to the javadoc for each FieldNN implementation.","title":"MT message field validation"},{"location":"integrator/validation/validation-mt/#mt-message-semantic-and-network-rules-validation","text":"The semantic (a.k.a. network rules) rules are validation constraints that usually involve more than a field in a message. There are hundreds of semantic validations defined by SWIFT and implemented by the validation module. This semantic checks are defined per message type and can involve among other things: Validating conditional presence of fields and sequences based on other fields or sequences. Validating conditional presence of fields and sequences based on fields qualifiers. Validating conditional allowed qualifiers between fields. Validating cross-referenced dates. Validating currencies' consistency. Validating sum of amounts between transactions and fields with totes. There are 300 semantic validations checks. The relation between a specific message type and the semantica validation that are applied is defined in the message Scheme.","title":"MT message semantic and network rules validation"},{"location":"integrator/validation/validation-mt/#eri-euro-related-info-validation","text":"On top of the default generic format, some fields are validated against the ERI constraints when the ERI data is present. ERI refers to the original currency in the transaction. If no specific fields are available to specify the original currency and amount, ERI data may be added in a free text field with the codewords: OCMT and CHGS . By default, the ERI is validated in fields 72, field 77A (MTs 416, 455 and 456), field 79 (MT 986) and fields 86 and 61 (MTs 940 and 942). ERI validation is reported with standard error codes such as T47, T52 and T40. Since the specification of ERI is always optional, this special constraint checks can be easily switched off with a parameter in the validation engine configuration: engine . getConfig (). setEriValidationEnabled ( false ); This switch is the recommended way to disable all ERI related checks if the constraints must not be checked in your business context.","title":"ERI (Euro Related Info) validation"},{"location":"integrator/validation/validation-mt/#iban-validation","text":"Multiple MT fields could contain an account number, such as the first component in field 59. The default validation for these account numbers is just based on the allowed characters and total length, which in general for account numbers is 34x. When these account components are used with IBAN numbers, an additional constraint can be enforced so that the full IBAN number validation is applied. In the validation configuration, you need to first enable IBAN validation in general with the flag: engine . getConfig (). setIBANValidationEnabled ( true ); Then you need to explicitly identify the specific field components where the IBAN validation should apply. These are configured using MtPath expressions like this: engine . getConfig (). addMtIbanPath ( MtPathExpression . parse ( \"50K/1\" )); engine . getConfig (). addMtIbanPath ( MtPathExpression . parse ( \"59/1\" )); For information on the MtPath expressions syntax and capabilities, please check the SDK developer guide.","title":"IBAN validation"},{"location":"integrator/validation/validation-mt/#custom-mt-validation","text":"The validation engine supports three different ways to customize the validation. These together allow you to define any custom constraint over the standard. Structure validations can be modified by means of the scheme structure definition, and other types of rules can be added or removed from the validation process.","title":"Custom MT validation"},{"location":"integrator/validation/validation-mt/#customizing-schemes","text":"To change mandatory and optional fields, supported letter options, field and sequences repetitions, and expected qualifiers, a modified scheme can be used in the validation call. ValidationEngine .validateMessage can accept just the SwiftMessage object to validate, or the message object plus a specific Scheme object if the default behaviour is being overwritten. The custom scheme can be created in Java, from scratch, or by modifying one of the out-of-the-box default Scheme classes provided. Schemes can also be defined in XML and read as Scheme objects using the SchemeXmlReader . The scheme object defines the overall structure of a message, including its nested sequences (if any) and all the fields and letter options combination that the message accepts. By means of a custom scheme, you can for example restrict several letter options on specific fields, or reduce or extend the expected qualifiers for any field. Most common use cases demanding some kind of custom validation can be entirely covered by customizing schemes. For more information on schemes, please check the SDK Developer Guide.","title":"Customizing schemes"},{"location":"integrator/validation/validation-mt/#adding-a-custom-rule","text":"Custom rules can be injected in the validation to perform any additional check not covered by the standard validation. Being implemented as Java classes, this custom rules can do anything you need. Custom rules will be evaluated after all standard rules, and are implemented in your own application as normal Java classes meeting the following simple requisites: Extend ValidationRule directly or indirectly. Override implementation of the method eval(SwiftMessage, String) to perform any check on the message without limitations. The method must return the list of validation problems found or an empty list if the message satisfies the validation. Example 1: Custom rule to check the reference prefix The following example implements a rule to check that the message reference is prefixed \"MYREF\", so if the message reference is not present or not prefixed with \"MYREF\" this rule will report a validation problem: public class MyRule extends ValidationRule { @Override protected List < ValidationProblem > eval ( SwiftMessage msg , String mt ) { List < ValidationProblem > result = new ArrayList < ValidationProblem > (); if ( msg . getBlock4 () != null ) { Tag reference = msg . getBlock4 (). getTagByName ( \"20\" ); if ( reference == null || ! StringUtils . startsWith ( reference . getValue (), \"MYREF\" )) { result . add ( new ValidationProblem ( \"BAD_REFERENCE\" , \"the reference must start with MYREF\" )); } } return result ; } } Example 2: Custom rule to check the presence of the trailer block The example below demonstrates a rule for verifying the presence of the trailer block in the message. According to the standard, Block 5, if included, must always contain the CHK tag. However, the checksum calculation algorithm is proprietary and not disclosed by SWIFT. Therefore, without a method for users to compute the checksum, adding validation for it is not feasible. For that reason it is a good practice to check the presence of the trailer block and the CHK tag in a custom rule. public class TrailerCHKValidationRule extends ValidationRule { @Override protected List < ValidationProblem > eval ( SwiftMessage msg , String mt ) { List < ValidationProblem > result = new ArrayList <> (); SwiftBlock5 block5 = msg . getBlock5 (); if ( block5 != null && ! block5 . getTags (). isEmpty ()) { Tag chk = block5 . getTagByName ( \"CHK\" ); if ( chk == null ) { result . add ( new ValidationProblem ( StructureProblem . Z04 ). setBundleKey ( \"Z04.missing\" )); } } return result ; } } All found errors should be returned as ValidationProblem objects, and it is a good practice that custom rules create custom validation problems, since the standard ValidationProblem class is not intended to be a general purpose class. Custom validation problems may be created by extending the ValidationProblem or can be generated dynamically in your own rule just by creating a generic ValidationProblem instance, providing a custom error key and error message. Once the validation rule is implemented, it must be injected in the engine configuration. All rules are associated with messages by scheme names (where scheme names by default is a composition of the message type and the message variant). If the same rule should be applied to more than one message type, it must explicitly be added into the custom rules map for each corresponding message type. The following example adds the above rules to an engine instance for messages MT103 REMIT and MT 202: engine . getConfig (). addCustomRule ( \"103_REMIT\" , new MyRule ()); engine . getConfig (). addCustomRule ( \"202\" , new TrailerCHKValidationRule ()); Notice in the example, we use the MT types enumeration to provide valid scheme names. The plain string with the message type number can also be used for this purpose if you don\u2019t use specific message variants. Elaborated examples can be found at https://github.com/prowide/prowide-integrator-examples/blob/master/src/com/prowidesoftware/swift/samples/integrator/validation/MessageValidationWithCustomRulesExample.java","title":"Adding a custom rule"},{"location":"integrator/validation/validation-mt/#ignoring-specific-validation-rules","text":"When instead of adding a new constraint over the standard, there is a need to be more flexible, reducing the constraint already implemented, you can indicate that some validation problems should be ignored. This is done by a dynamic setting in the validation engine configuration instance, where you can mark as many problems as you need. Validation problems are uniquely identified by its error keys, so the available enumerations are used to clearly identify the problem to ignore. The following example shows how to mark several types of validation problems for ignore, including general, structure, field, and semantic checks. In a real use case scenario, this is used to filter just a few specific constraints depending on the nature of the messages being validation and the need for some flexibility over the default standard constraints. engine . getConfig (). addIgnoredValidationProblem ( GeneralProblem . EXTRA_DATA_IN_MESSAGE ); engine . getConfig (). addIgnoredValidationProblem ( StructureProblem . INVALID_FIELD_QUALIFIER ); engine . getConfig (). addIgnoredValidationProblem ( StructureProblem . BLOCK1_APPLICATION_ID ); engine . getConfig (). addIgnoredValidationProblem ( FieldProblem . COMPONENT_BAD_SIZE ); engine . getConfig (). addIgnoredValidationProblem ( FieldProblem . BAD_CURRENCY ); engine . getConfig (). addIgnoredValidationProblem ( FieldProblem . COMPONENT_NOT_BIC ); engine . getConfig (). addIgnoredValidationProblem ( SemanticProblem . D75 ); Notice some special problems are blocking for the validation and cannot be ignored; the ones related to the license ( UNLICENSED_BIC, UNLICENSED_MT, LICENSE_PROBLEM) and the major blocking issues (UNSUPPORTED_MESSAGE, UNRECOGNIZED, MISSING_BLOCK1, MISSING_BLOCK2, MISSING_BLOCK4). A complete example can be found at https://github.com/prowide/prowide-integrator-examples/blob/master/src/com/prowidesoftware/swift/samples/integrator/validation/MessageValidationIgnoringCustomExample.java","title":"Ignoring specific validation rules"},{"location":"integrator/validation/validation-mx/","text":"MX message validation Analogously to MT message validation, for MX messages the validation check is handled through the validation engine. The validation is performed on the XML representation of the message against the corresponding XSD schemas. On top of the schema constraints, the validation can check the BIC codes, currency, and country codes against the internal catalog. The message can contain any of the given structure combinations: Single Document element Single Document element within envelope/wrapper elements Single AppHdr element Single AppHdr element within any envelope/wrapper elements Both AppHdr and Document elements within any root element Both AppHdr and Document elements within any envelope/wrapper element In any case, the validation will strip the Document and the optional AppHdr and will run the validation for that segment of the parameter XML. The envelope/wrapper elements, if present, will be silently ignored. If the parameter for the validation is already in XML because it was read from a String or File, the validation is run directly over the given text. Otherwise, if the validation is called on an MX model object, it is serialized into its XML representation and then the constraints are verified on the resulting XML text. The result of the validation process is a list of ValidationProblem objects that, in case of error, include a specific indication of the invalid or missing content and the xpath within the XML where the problem is found. The following example initializes the validation engine and calls the validation process. The first one assumes the message is being created with a model object, and the second one has the MX message already in xml format. Validation methods The validation engine exports several methods to validate a message, accepting different parameters. Validating from XML or File This is always the preferred entry point for validation. The specific MX type will be automatically detected and the XML content will be checked against the corresponding schema. The following example validates a message from a String with its XML content. A similar method is provided to validate the message from a File . String xml = \"\" ; ValidationEngine engine = new ValidationEngine (); engine . initialize (); List < ValidationProblem > r = engine . validateMxMessage ( xml ); engine . dispose (); This validation will first detect and report malformed XML messages. If the message is well-formed as an XML, the specific message type is detected from the Document namespace. If an AppHdr is also present in the message, it will be validated as well, against the corresponding header schema. For convenience, specific methods are provided in the validation engine to validate the header in its two versions: ISO business application header and legacy swift application header. If the message payload (header and document) are surrounded by an envelope, the elements in the envelope will be silently ignored. Notice when both header and document elements are present in a message, these elements are siblings, so they must be encapsulated under a common wrapper element. This wrapper or envelope in MX is network specific, so it cannot be validated by the library. This is handy when you need to validate Mx messages received from different (even unknown) sources where the header and document content is embedded under non-standard envelopes. Validating from MX objects For messages created using the builder API, meaning the MX objects and the MX business dictionary objects, a specific validation method is provided. This validation will serialize the Document and optional header into XML and will apply the schema for the specific MX passed to the validation. MxAcmt00100103 mx = new MxAcmt00100103 (); mx . setAcctOpngInstr ( new AccountOpeningInstructionV03 ()); ValidationEngine engine = new ValidationEngine (); engine . initialize (); List < ValidationProblem > r = engine . validateMxMessage ( mx ); engine . dispose (); If the MX message object or the XML contains the optional business application header (AppHdr), the found header will also be validated. IMPORTANT : When validated messages from XML, do not parse them into the MX object to call validation because the parser will drop invalid content from the source XML, therefore some errors may not be reported. If the message to validate is already in XML or read from a File , the validation from String and File should be used. ISO 20022 external code set validation Some ISO 20022 messages use external code sets which are not included in the default message schema, thus the code is not validated by default. In the group header of a pacs.008 for example, the Cd element could be any uppercase 4 letters string such as ABCD: INDA MyIdentifier ABCD However, if you apply the external code set validation, the Cd element for this particular message type can only contain BBAN , CUID , AIIN , UPIC , such as: INDA MyIdentifier BBAN The listed codes can be used in specific elements of the messages as indicated in the documents published at: https://www.iso20022.org/catalogue-messages/additional-content-messages/external-code-sets The purpose of externalizing these codes is to be able to update the code sets (for example, add new codes) without impacting the messages themselves and, hence, without requiring the development of a new version of the messages that use these code sets. The external code set validation is not enabled by default, but you can switch it on with a flag in the ValidationConfiguration : engine . getConfig (). setExternalCodeSetValidationEnabled ( true ); The actual external code sets used for the validation are embedded in the jar file as an XSD resource with a fixed name, ExternalCodeSet.xsd. This XSD is the machine-readable file from 18 October 2019 published at the iSO site. The resource will be updated from time to time but if you need to check a specific codeset that is not included in this default XSD, you are expected to override the XSD file as needed. IBAN validation In ISO 20022 messages the IBAN (International Bank Account Number) elements are clearly identified. Thus the IBAN structure format is automatically validated during the process. Custom MX validation The validation engine supports three different ways to customize the validation. These together allows you to define any custom constraint over the standard. A custom XSD schema can be provided for the validation, additional custom rules can be added to the process, and default rules can be removed (marked to be ignored). Customizing XSD schemas By default, the validation will use the default standard ISO schema corresponding to the message type (when validating a Mx object) or XML namespace (when validating XML content). If you need to use a customized version of a schema, instead of the default ISO version, you can pass the XSD schema as parameter for the validation. The easiest way to pass your custom schema to the engine is to include it in the validation call using either of these calls: validateMxMessage ( final String xml , SchemaProvider schemaProvider ) validateMxMessage ( final String xml , StreamSource schema ) It is also posible to load the schema from a xsd file. That could be achieved as follows (in this case for a pacs.008.001.08 MX message): Path filePath = Paths . get ( \"your_path_to_file/pacs.008.001.08.xsd\" ); PathSchemaProvider pathSchemaProvider = new PathSchemaProvider ( filePath ); engine . validateMxMessage ( xml_to_validate , pathSchemaProvider ); Another option, if you need to use many customized schemas, is to implement your own XsdRegistry . This registry has a method to return the schema given the message category, functionality, variant, and version. In order to continue using the default schemas for the message types that you are not overwriting, the easiest way of implementing this is by extending the default registry implementation like this: public class MyRegistry extends XsdRegistryImpl { @Override public StreamSource find ( String category , Integer functionality , Integer variant , Integer version ) { if ( category . equals ( MxBusinessProcess . pain . name ()) && functionality == 1 && variant == 1 && version == 7 ) { return new StreamSource ( new StringReader ( yourXSD ))); } return super . find ( category , functionality , variant , version ); } } In this example, the custom registry provides a custom XSD for pain.001.001.07 while returning all default data for the rest of message types. Once you have the registry implementation, you can inject it to the validation engine using the setXsdRegistry method in the ValidationConfiguration class. Adding a custom rule Custom rules can be injected in the validation to perform any additional check not covered by the standard validation. Being implemented as Java classes, this custom rules can do anything you need. Custom rules will be evaluated after all standard rules, and are implemented in your own application as normal Java classes implementing the MxCustomValidationRule interface. The custom rule must implement the eval(String, MxNode, MxStuctureInfo) to perform any check on the message without limitations. The method must return the list of validation problems found or an empty list if the message satisfies the validation. The parameters for the eval method are redundant for convenience: The first parameter is the raw XML content as it was passed to the validation engine. The second parameter contains the same XML content, but already parsed into a model structure. The MxNode object provides a useful API to get content from the XML using XPath expressions. Finally, the MxStructureInfo provides some metadata from the XML All found errors should be returned as ValidationProblem objects, and it is a good practice that custom rules create custom validation problems, since the standard ValidationProblem class is not intended to be a general purpose class. Custom validation problems may be created by extending the ValidationProblem or can be generated dynamically in your own rule just by creating a generic ValidationProblem instance, providing a custom error key and error message. Once the validation rule is implemented, it must be injected in the engine configuration. A custom rule can be applied to a specific message type such as pain.001.001.03, or you can also associate the rule to all versions of the message type, pain.001.001.* or even to all MX message types. This relation between your custom rule and the message types to which the rule will be applied is defined using MxId objects. The MxId can be created for a specific type providing all its properties (business process, functionality, variant and version) or you can create an MxId and just set the business process, or the business process and the functionality, or any other combination of properties. The attributes in the MxId that are not set, will be used as a wildcard when the engine loads the custom rules to apply to a particular message. The following example adds a rule for all messages in the pacs category, and another rule for the pain.001.002.*: engine . getConfig (). addCustomMxRule ( new MxId (). setBusinessProcess ( MxBusinessProcess . pain ), new MyRule1 ()); engine . getConfig (). addCustomMxRule ( new MxId ( \"pain\" , \"001\" , \"002\" , null ), new MyRule2 ()); Ignoring specific validation rules When instead of adding a new constraint over the standard, there is a need to be more flexible, reducing the constraint already implemented, you can indicate that some validation problems should be ignored. This is done by a dynamic setting in the validation engine configuration instance, where you can mark as many problems as you need. Validation problems are uniquely identified by its error keys, so the available enumerations are used to clearly identify the problem to ignore. The following example shows how to mark the bad currency problems for ignore: engine . getConfig (). addIgnoredValidationProblem ( MxProblem . BAD_CURRENCY ); Cross-element validation The MX standard define for each ISO 20022 message a set of semantic rules that must be satisfied by the message. These rules cannot be specified in the XSD schema because they normally involve more than one element in the XML. For example \"If GrpHdr/InstgAgt is present, then CdtTrfTxInf/InstgAgt is not allowed.\" is a cross-element rule. The error code for this rules is normally prefixed with an \"X\" such as \"X00050\". Since the total variiaty of message types in the comprehensive ISO 20022 set is very large (note that each message type such as pacs.008 could have multiple variants and versions), then the validation engine does not implement all the cross-element rules. The subset of messages for with the cross-element rules are implemented are the ones that are used in the CBPR+ restricted, plus the newer versions of all those mesasge types. This subset is and will be a work in progress and will be extended as needed.","title":"MX message validation"},{"location":"integrator/validation/validation-mx/#mx-message-validation","text":"Analogously to MT message validation, for MX messages the validation check is handled through the validation engine. The validation is performed on the XML representation of the message against the corresponding XSD schemas. On top of the schema constraints, the validation can check the BIC codes, currency, and country codes against the internal catalog. The message can contain any of the given structure combinations: Single Document element Single Document element within envelope/wrapper elements Single AppHdr element Single AppHdr element within any envelope/wrapper elements Both AppHdr and Document elements within any root element Both AppHdr and Document elements within any envelope/wrapper element In any case, the validation will strip the Document and the optional AppHdr and will run the validation for that segment of the parameter XML. The envelope/wrapper elements, if present, will be silently ignored. If the parameter for the validation is already in XML because it was read from a String or File, the validation is run directly over the given text. Otherwise, if the validation is called on an MX model object, it is serialized into its XML representation and then the constraints are verified on the resulting XML text. The result of the validation process is a list of ValidationProblem objects that, in case of error, include a specific indication of the invalid or missing content and the xpath within the XML where the problem is found. The following example initializes the validation engine and calls the validation process. The first one assumes the message is being created with a model object, and the second one has the MX message already in xml format.","title":"MX message validation"},{"location":"integrator/validation/validation-mx/#validation-methods","text":"The validation engine exports several methods to validate a message, accepting different parameters.","title":"Validation methods"},{"location":"integrator/validation/validation-mx/#validating-from-xml-or-file","text":"This is always the preferred entry point for validation. The specific MX type will be automatically detected and the XML content will be checked against the corresponding schema. The following example validates a message from a String with its XML content. A similar method is provided to validate the message from a File . String xml = \"\" ; ValidationEngine engine = new ValidationEngine (); engine . initialize (); List < ValidationProblem > r = engine . validateMxMessage ( xml ); engine . dispose (); This validation will first detect and report malformed XML messages. If the message is well-formed as an XML, the specific message type is detected from the Document namespace. If an AppHdr is also present in the message, it will be validated as well, against the corresponding header schema. For convenience, specific methods are provided in the validation engine to validate the header in its two versions: ISO business application header and legacy swift application header. If the message payload (header and document) are surrounded by an envelope, the elements in the envelope will be silently ignored. Notice when both header and document elements are present in a message, these elements are siblings, so they must be encapsulated under a common wrapper element. This wrapper or envelope in MX is network specific, so it cannot be validated by the library. This is handy when you need to validate Mx messages received from different (even unknown) sources where the header and document content is embedded under non-standard envelopes.","title":"Validating from XML or File"},{"location":"integrator/validation/validation-mx/#validating-from-mx-objects","text":"For messages created using the builder API, meaning the MX objects and the MX business dictionary objects, a specific validation method is provided. This validation will serialize the Document and optional header into XML and will apply the schema for the specific MX passed to the validation. MxAcmt00100103 mx = new MxAcmt00100103 (); mx . setAcctOpngInstr ( new AccountOpeningInstructionV03 ()); ValidationEngine engine = new ValidationEngine (); engine . initialize (); List < ValidationProblem > r = engine . validateMxMessage ( mx ); engine . dispose (); If the MX message object or the XML contains the optional business application header (AppHdr), the found header will also be validated. IMPORTANT : When validated messages from XML, do not parse them into the MX object to call validation because the parser will drop invalid content from the source XML, therefore some errors may not be reported. If the message to validate is already in XML or read from a File , the validation from String and File should be used.","title":"Validating from MX objects"},{"location":"integrator/validation/validation-mx/#iso-20022-external-code-set-validation","text":"Some ISO 20022 messages use external code sets which are not included in the default message schema, thus the code is not validated by default. In the group header of a pacs.008 for example, the Cd element could be any uppercase 4 letters string such as ABCD: INDA MyIdentifier ABCD However, if you apply the external code set validation, the Cd element for this particular message type can only contain BBAN , CUID , AIIN , UPIC , such as: INDA MyIdentifier BBAN The listed codes can be used in specific elements of the messages as indicated in the documents published at: https://www.iso20022.org/catalogue-messages/additional-content-messages/external-code-sets The purpose of externalizing these codes is to be able to update the code sets (for example, add new codes) without impacting the messages themselves and, hence, without requiring the development of a new version of the messages that use these code sets. The external code set validation is not enabled by default, but you can switch it on with a flag in the ValidationConfiguration : engine . getConfig (). setExternalCodeSetValidationEnabled ( true ); The actual external code sets used for the validation are embedded in the jar file as an XSD resource with a fixed name, ExternalCodeSet.xsd. This XSD is the machine-readable file from 18 October 2019 published at the iSO site. The resource will be updated from time to time but if you need to check a specific codeset that is not included in this default XSD, you are expected to override the XSD file as needed.","title":"ISO 20022 external code set validation"},{"location":"integrator/validation/validation-mx/#iban-validation","text":"In ISO 20022 messages the IBAN (International Bank Account Number) elements are clearly identified. Thus the IBAN structure format is automatically validated during the process.","title":"IBAN validation"},{"location":"integrator/validation/validation-mx/#custom-mx-validation","text":"The validation engine supports three different ways to customize the validation. These together allows you to define any custom constraint over the standard. A custom XSD schema can be provided for the validation, additional custom rules can be added to the process, and default rules can be removed (marked to be ignored).","title":"Custom MX validation"},{"location":"integrator/validation/validation-mx/#customizing-xsd-schemas","text":"By default, the validation will use the default standard ISO schema corresponding to the message type (when validating a Mx object) or XML namespace (when validating XML content). If you need to use a customized version of a schema, instead of the default ISO version, you can pass the XSD schema as parameter for the validation. The easiest way to pass your custom schema to the engine is to include it in the validation call using either of these calls: validateMxMessage ( final String xml , SchemaProvider schemaProvider ) validateMxMessage ( final String xml , StreamSource schema ) It is also posible to load the schema from a xsd file. That could be achieved as follows (in this case for a pacs.008.001.08 MX message): Path filePath = Paths . get ( \"your_path_to_file/pacs.008.001.08.xsd\" ); PathSchemaProvider pathSchemaProvider = new PathSchemaProvider ( filePath ); engine . validateMxMessage ( xml_to_validate , pathSchemaProvider ); Another option, if you need to use many customized schemas, is to implement your own XsdRegistry . This registry has a method to return the schema given the message category, functionality, variant, and version. In order to continue using the default schemas for the message types that you are not overwriting, the easiest way of implementing this is by extending the default registry implementation like this: public class MyRegistry extends XsdRegistryImpl { @Override public StreamSource find ( String category , Integer functionality , Integer variant , Integer version ) { if ( category . equals ( MxBusinessProcess . pain . name ()) && functionality == 1 && variant == 1 && version == 7 ) { return new StreamSource ( new StringReader ( yourXSD ))); } return super . find ( category , functionality , variant , version ); } } In this example, the custom registry provides a custom XSD for pain.001.001.07 while returning all default data for the rest of message types. Once you have the registry implementation, you can inject it to the validation engine using the setXsdRegistry method in the ValidationConfiguration class.","title":"Customizing XSD schemas"},{"location":"integrator/validation/validation-mx/#adding-a-custom-rule","text":"Custom rules can be injected in the validation to perform any additional check not covered by the standard validation. Being implemented as Java classes, this custom rules can do anything you need. Custom rules will be evaluated after all standard rules, and are implemented in your own application as normal Java classes implementing the MxCustomValidationRule interface. The custom rule must implement the eval(String, MxNode, MxStuctureInfo) to perform any check on the message without limitations. The method must return the list of validation problems found or an empty list if the message satisfies the validation. The parameters for the eval method are redundant for convenience: The first parameter is the raw XML content as it was passed to the validation engine. The second parameter contains the same XML content, but already parsed into a model structure. The MxNode object provides a useful API to get content from the XML using XPath expressions. Finally, the MxStructureInfo provides some metadata from the XML All found errors should be returned as ValidationProblem objects, and it is a good practice that custom rules create custom validation problems, since the standard ValidationProblem class is not intended to be a general purpose class. Custom validation problems may be created by extending the ValidationProblem or can be generated dynamically in your own rule just by creating a generic ValidationProblem instance, providing a custom error key and error message. Once the validation rule is implemented, it must be injected in the engine configuration. A custom rule can be applied to a specific message type such as pain.001.001.03, or you can also associate the rule to all versions of the message type, pain.001.001.* or even to all MX message types. This relation between your custom rule and the message types to which the rule will be applied is defined using MxId objects. The MxId can be created for a specific type providing all its properties (business process, functionality, variant and version) or you can create an MxId and just set the business process, or the business process and the functionality, or any other combination of properties. The attributes in the MxId that are not set, will be used as a wildcard when the engine loads the custom rules to apply to a particular message. The following example adds a rule for all messages in the pacs category, and another rule for the pain.001.002.*: engine . getConfig (). addCustomMxRule ( new MxId (). setBusinessProcess ( MxBusinessProcess . pain ), new MyRule1 ()); engine . getConfig (). addCustomMxRule ( new MxId ( \"pain\" , \"001\" , \"002\" , null ), new MyRule2 ());","title":"Adding a custom rule"},{"location":"integrator/validation/validation-mx/#ignoring-specific-validation-rules","text":"When instead of adding a new constraint over the standard, there is a need to be more flexible, reducing the constraint already implemented, you can indicate that some validation problems should be ignored. This is done by a dynamic setting in the validation engine configuration instance, where you can mark as many problems as you need. Validation problems are uniquely identified by its error keys, so the available enumerations are used to clearly identify the problem to ignore. The following example shows how to mark the bad currency problems for ignore: engine . getConfig (). addIgnoredValidationProblem ( MxProblem . BAD_CURRENCY );","title":"Ignoring specific validation rules"},{"location":"integrator/validation/validation-mx/#cross-element-validation","text":"The MX standard define for each ISO 20022 message a set of semantic rules that must be satisfied by the message. These rules cannot be specified in the XSD schema because they normally involve more than one element in the XML. For example \"If GrpHdr/InstgAgt is present, then CdtTrfTxInf/InstgAgt is not allowed.\" is a cross-element rule. The error code for this rules is normally prefixed with an \"X\" such as \"X00050\". Since the total variiaty of message types in the comprehensive ISO 20022 set is very large (note that each message type such as pacs.008 could have multiple variants and versions), then the validation engine does not implement all the cross-element rules. The subset of messages for with the cross-element rules are implemented are the ones that are used in the CBPR+ restricted, plus the newer versions of all those mesasge types. This subset is and will be a work in progress and will be extended as needed.","title":"Cross-element validation"},{"location":"integrator/validation/validation-process/","text":"Validation process The validation process can be seen as a pipeline where rules evaluation is performed in the fixed order: structure, fields, semantic and custom. The validation process always perform the following tasks: Loads a proper message scheme definition, based on invocation parameters or using the message type information of the actual message. Evaluates the structure validation rules, matching the message scheme with the actual message content. For each field in the message, evaluate the corresponding field validation rule. Evaluates all semantic rules associated with the validating message type. Evaluates all user defined rules, if any, for the particular message type. The following sections describe each of the validation steps, specifically for MT, where the validation is more fragmented. For MX standard, based on XML, the process has fewer steps and a smaller rule set. Validation Engine The entry point for the validation process is the ValidationEngine . In the simplest scenario the validation involves initiating the engine, passing the message to validate, checking the result and disposing of the engine. The following example performs validation of a message contained in the variable \"msg\": ValidationEngine engine = new ValidationEngine (); engine . initialize (); List < ValidationProblem > r = engine . validateMessage ( msg ); engine . dispose (); This call will initialize the validation engine and will apply the specific validation rule set for the message. If the resulting list is empty, the message is SWIFT standard compliance. Regarding the message parameter, the API supports different options, each for a different use case scenario. In short, there are options to validate messages when the specific message type is unknown, passing the content as String or model; and there are options to validate known messages contained in a model object (for example: MT103). Quick API reference The following table synthesize the API entry point for common use case scenarios: Use Case API validate an message read from String \u2022 validationEngine.validateMtMessage(String) \u2022 validationEngine.validateMxMessage(String) validate a swift message built from API \u2022 validationEngine.validateMessage(MT103) \u2022 validationEngine.validateMessage(SwiftMessage, Scheme) \u2022 validationEngine.validateMessage(MxSecl00100101) Engine configuration Several behaviour of the validation engine can be configured in the enclosed ValidationConfiguration object. This configuration class enables for example to indicate wheater the BIC codes should be validated against a directory, if the IBAN validation should be anabled, if the MT set is GPI or not, and so on. The configuration object is initialized with default values, that can be change at any time before a validation call. ValidationEngine engine = new ValidationEngine (); engine . initialize (); engine . getConfig (). setBicDatabaseEnabled ( true ); List < ValidationProblem > r = engine . validateMessage ( msg ); Engine cache This engine requires initialization and disposal, because it caches several internal structures that are reused acrross validation calls. So it is important when validating large bursts of messages to reuse the engine instance , for example by using a singleton pattern. Since the engine behaviour can be slightly customize with a ValidationConfiguration it could be that different message flows require a different configuration. In this use case scenario multiple instances of the engine can be created, each with its own configuration. But creating a new ValidationEngine per validation call is discouraged, as it will be slower and will consume more memory. Schema cache To enhance the efficiency of the MX validation process, a Schema cache is implemented to significantly reduce the time required for schema creation, which is inherently time-consuming. This cache ensures that schemas are loaded only once and reused throughout the validation operations, leading to faster processing times. To activate this feature, you have to enable the cache in your validation engine instance: ValidationEngine engine = new ValidationEngine (); engine . initialize (); engine . getConfig (). setCache ( new SchemaCacheImpl ()); List < ValidationProblem > r = engine . validateMessage ( msg ); The SchemaCacheImpl is the default implementation of the SchemaCache interface, and it uses a simple Map to store the cached schemas, with no eviction. If you have specific caching requirements, you can tailor the caching behavior by creating your own implementation of the SchemaCache interface. You can for example use a third-party caching library, such as Ehcache, Caffeine or Guava; to provide more advanced caching features. Handling Validation Errors During the validation process a list of validation problems found is created. Note that by default the validation process is not stopped when the first problem is found, but it continues until the end of the validation process. The ValidationProblem object is the container for each validation error found during the evaluation. Its main attributes are: Error Key : A unique validation problem identifier. For MT messages this error code matches the FIN Service alphabetic error codes such as T13, H10, D20. Problem Type : The problem type is coupled to the validation implementation, and provides a classification indication where in the process the issue was found. The available types are: General, Structure, Field, Semantic and Mx. This attribute does not add much value to the final user, it is intended for programmatic error handling. Error Message : An error description suitable for user interface, these messages are fully configured by means of a property file and provided in English, Spanish, Italian, French, and Russian. Specific attributes for MT validation: Field Index: the position of the field with the encountered issue within block 4 (starting with zero at first block 4 field). Specific attributes for MX validation: Line and Column : when the error comes directly from XML parsing Path : Containing the full XPATH where the error is found Examples for MT validation: Problem Type : Structure Problem Key : T13 Error Message : Missing required field: 20 Problem Type : Structure Problem Key : T13 Error Message : Unexpected 99 field found Notice in the above cases, both problems share the same error key, but the description is slightly different. This is because FIN Error codes are very specific in some cases but very wide in others, catching multiple error conditions with a single code. Problem Type : Field Problem Key : T17 Error Message : Field 53A: If the slash ('/') is present, it's following party field information cannot be empty. Problem Type : Semantic Problem Key : E04 Error Message : If field 23B contains one of the code words SPRI, SSTD or SPAY and field 53a is present with option B, then the party identifier (component 1) must be present in that field 53B. Problem Type : Semantic Problem Key : C05 Error Message : The BIC at field 52A must not be a BEI. Problem Type : Semantic Problem Key : D20 Error Message : Field 71A must be present either in sequence A or in each occurrence of sequence B, but it must never be present in both sequences, nor be absent from both sequences. Examples for MX validation: Problem Type : Mx Problem Key : XSD_ERROR Error Message : Invalid content was found starting with element 'TxId'. One of '{\"urn:iso:std:iso:20022:tech:xsd: pacs.008.001.04\":EndToEndId}' is expected. Path : /Document/FIToFICstmrCdtTrf/CdtTrfTxInf/PmtId Line, Column : 29, 11 Validating files versus validating objects It is important to notice the difference when the message to validate comes from a file or from a message object. Where a message from a file means a message that it is already in swift format (fin for MT or xml for MX), for example a message in a String variable (not necessarily a file system file). And a message object is a swift message created with the builder API, populating the swift message object. This is particularly important for MX messages because malformed/incorrect XML messages cannot always fit the java structure. Imagine inserting arbitrary tags in an MX message, there is no Java support for that in the model, since they do not belong to the message definition. So the parser will ignore those tags and the validation of the resulting MX swift object will not detect the errors. Analogously for MT, a not well-formed FIN messages could be although parsed into an MTnnn object, and the validation of the resulting object will not be able to detect some errors, for example unrecognized blocks, wrong CRLFs, incomplete headers. The following code samples illustrate these alternatives: MT message object created with builder API: MT103 mt = new MT103 (); m . addField ( new Field20 ( \"REFERENCE\" )); List < ValidationProblem > r = engine . validateMessage ( mt ); MT message already in FIN format, in a String , delegating parsing to the engine: String mt = \"{1:F01BIC...}\" ; List < ValidationProblem > r = engine . validateMtMessage ( mt ); MT message already in FIN format, in a File , delegating reading and parsing to the engine: File mt = new File \"/tmp/out-103.fin\" ; List < ValidationProblem > r = engine . validateMtMessage ( mt ); MX message created with builder API: MxAcmt00100103 mx = new MxAcmt00100103 (); mx . setAcctOpngInstr ( new AccountOpeningInstructionV03 ()); List < ValidationProblem > r = engine . validateMessage ( mx ); MX message from xml content, in a String , delegating parsing to the engine: String xml = \"\" ; List < ValidationProblem > r = engine . validateMxMessage ( xml ); MX message from xml content, in a File , delegating reading and parsing to the engine: File xml = new File ( \"/tmp/camt.001.01.01.xml\" ; List < ValidationProblem > r = engine . validateMxMessage ( xml ); For a complete set of options, please check the engine javadoc at: http://api.prowidesoftware.com/integrator/com/prowidesoftware/swift/validator/ValidationEngine.html","title":"Validation process"},{"location":"integrator/validation/validation-process/#validation-process","text":"The validation process can be seen as a pipeline where rules evaluation is performed in the fixed order: structure, fields, semantic and custom. The validation process always perform the following tasks: Loads a proper message scheme definition, based on invocation parameters or using the message type information of the actual message. Evaluates the structure validation rules, matching the message scheme with the actual message content. For each field in the message, evaluate the corresponding field validation rule. Evaluates all semantic rules associated with the validating message type. Evaluates all user defined rules, if any, for the particular message type. The following sections describe each of the validation steps, specifically for MT, where the validation is more fragmented. For MX standard, based on XML, the process has fewer steps and a smaller rule set.","title":"Validation process"},{"location":"integrator/validation/validation-process/#validation-engine","text":"The entry point for the validation process is the ValidationEngine . In the simplest scenario the validation involves initiating the engine, passing the message to validate, checking the result and disposing of the engine. The following example performs validation of a message contained in the variable \"msg\": ValidationEngine engine = new ValidationEngine (); engine . initialize (); List < ValidationProblem > r = engine . validateMessage ( msg ); engine . dispose (); This call will initialize the validation engine and will apply the specific validation rule set for the message. If the resulting list is empty, the message is SWIFT standard compliance. Regarding the message parameter, the API supports different options, each for a different use case scenario. In short, there are options to validate messages when the specific message type is unknown, passing the content as String or model; and there are options to validate known messages contained in a model object (for example: MT103).","title":"Validation Engine"},{"location":"integrator/validation/validation-process/#quick-api-reference","text":"The following table synthesize the API entry point for common use case scenarios: Use Case API validate an message read from String \u2022 validationEngine.validateMtMessage(String) \u2022 validationEngine.validateMxMessage(String) validate a swift message built from API \u2022 validationEngine.validateMessage(MT103) \u2022 validationEngine.validateMessage(SwiftMessage, Scheme) \u2022 validationEngine.validateMessage(MxSecl00100101)","title":"Quick API reference"},{"location":"integrator/validation/validation-process/#engine-configuration","text":"Several behaviour of the validation engine can be configured in the enclosed ValidationConfiguration object. This configuration class enables for example to indicate wheater the BIC codes should be validated against a directory, if the IBAN validation should be anabled, if the MT set is GPI or not, and so on. The configuration object is initialized with default values, that can be change at any time before a validation call. ValidationEngine engine = new ValidationEngine (); engine . initialize (); engine . getConfig (). setBicDatabaseEnabled ( true ); List < ValidationProblem > r = engine . validateMessage ( msg );","title":"Engine configuration"},{"location":"integrator/validation/validation-process/#engine-cache","text":"This engine requires initialization and disposal, because it caches several internal structures that are reused acrross validation calls. So it is important when validating large bursts of messages to reuse the engine instance , for example by using a singleton pattern. Since the engine behaviour can be slightly customize with a ValidationConfiguration it could be that different message flows require a different configuration. In this use case scenario multiple instances of the engine can be created, each with its own configuration. But creating a new ValidationEngine per validation call is discouraged, as it will be slower and will consume more memory.","title":"Engine cache"},{"location":"integrator/validation/validation-process/#schema-cache","text":"To enhance the efficiency of the MX validation process, a Schema cache is implemented to significantly reduce the time required for schema creation, which is inherently time-consuming. This cache ensures that schemas are loaded only once and reused throughout the validation operations, leading to faster processing times. To activate this feature, you have to enable the cache in your validation engine instance: ValidationEngine engine = new ValidationEngine (); engine . initialize (); engine . getConfig (). setCache ( new SchemaCacheImpl ()); List < ValidationProblem > r = engine . validateMessage ( msg ); The SchemaCacheImpl is the default implementation of the SchemaCache interface, and it uses a simple Map to store the cached schemas, with no eviction. If you have specific caching requirements, you can tailor the caching behavior by creating your own implementation of the SchemaCache interface. You can for example use a third-party caching library, such as Ehcache, Caffeine or Guava; to provide more advanced caching features.","title":"Schema cache"},{"location":"integrator/validation/validation-process/#handling-validation-errors","text":"During the validation process a list of validation problems found is created. Note that by default the validation process is not stopped when the first problem is found, but it continues until the end of the validation process. The ValidationProblem object is the container for each validation error found during the evaluation. Its main attributes are: Error Key : A unique validation problem identifier. For MT messages this error code matches the FIN Service alphabetic error codes such as T13, H10, D20. Problem Type : The problem type is coupled to the validation implementation, and provides a classification indication where in the process the issue was found. The available types are: General, Structure, Field, Semantic and Mx. This attribute does not add much value to the final user, it is intended for programmatic error handling. Error Message : An error description suitable for user interface, these messages are fully configured by means of a property file and provided in English, Spanish, Italian, French, and Russian. Specific attributes for MT validation: Field Index: the position of the field with the encountered issue within block 4 (starting with zero at first block 4 field). Specific attributes for MX validation: Line and Column : when the error comes directly from XML parsing Path : Containing the full XPATH where the error is found Examples for MT validation: Problem Type : Structure Problem Key : T13 Error Message : Missing required field: 20 Problem Type : Structure Problem Key : T13 Error Message : Unexpected 99 field found Notice in the above cases, both problems share the same error key, but the description is slightly different. This is because FIN Error codes are very specific in some cases but very wide in others, catching multiple error conditions with a single code. Problem Type : Field Problem Key : T17 Error Message : Field 53A: If the slash ('/') is present, it's following party field information cannot be empty. Problem Type : Semantic Problem Key : E04 Error Message : If field 23B contains one of the code words SPRI, SSTD or SPAY and field 53a is present with option B, then the party identifier (component 1) must be present in that field 53B. Problem Type : Semantic Problem Key : C05 Error Message : The BIC at field 52A must not be a BEI. Problem Type : Semantic Problem Key : D20 Error Message : Field 71A must be present either in sequence A or in each occurrence of sequence B, but it must never be present in both sequences, nor be absent from both sequences. Examples for MX validation: Problem Type : Mx Problem Key : XSD_ERROR Error Message : Invalid content was found starting with element 'TxId'. One of '{\"urn:iso:std:iso:20022:tech:xsd: pacs.008.001.04\":EndToEndId}' is expected. Path : /Document/FIToFICstmrCdtTrf/CdtTrfTxInf/PmtId Line, Column : 29, 11","title":"Handling Validation Errors"},{"location":"integrator/validation/validation-process/#validating-files-versus-validating-objects","text":"It is important to notice the difference when the message to validate comes from a file or from a message object. Where a message from a file means a message that it is already in swift format (fin for MT or xml for MX), for example a message in a String variable (not necessarily a file system file). And a message object is a swift message created with the builder API, populating the swift message object. This is particularly important for MX messages because malformed/incorrect XML messages cannot always fit the java structure. Imagine inserting arbitrary tags in an MX message, there is no Java support for that in the model, since they do not belong to the message definition. So the parser will ignore those tags and the validation of the resulting MX swift object will not detect the errors. Analogously for MT, a not well-formed FIN messages could be although parsed into an MTnnn object, and the validation of the resulting object will not be able to detect some errors, for example unrecognized blocks, wrong CRLFs, incomplete headers. The following code samples illustrate these alternatives: MT message object created with builder API: MT103 mt = new MT103 (); m . addField ( new Field20 ( \"REFERENCE\" )); List < ValidationProblem > r = engine . validateMessage ( mt ); MT message already in FIN format, in a String , delegating parsing to the engine: String mt = \"{1:F01BIC...}\" ; List < ValidationProblem > r = engine . validateMtMessage ( mt ); MT message already in FIN format, in a File , delegating reading and parsing to the engine: File mt = new File \"/tmp/out-103.fin\" ; List < ValidationProblem > r = engine . validateMtMessage ( mt ); MX message created with builder API: MxAcmt00100103 mx = new MxAcmt00100103 (); mx . setAcctOpngInstr ( new AccountOpeningInstructionV03 ()); List < ValidationProblem > r = engine . validateMessage ( mx ); MX message from xml content, in a String , delegating parsing to the engine: String xml = \"\" ; List < ValidationProblem > r = engine . validateMxMessage ( xml ); MX message from xml content, in a File , delegating reading and parsing to the engine: File xml = new File ( \"/tmp/camt.001.01.01.xml\" ; List < ValidationProblem > r = engine . validateMxMessage ( xml ); For a complete set of options, please check the engine javadoc at: http://api.prowidesoftware.com/integrator/com/prowidesoftware/swift/validator/ValidationEngine.html","title":"Validating files versus validating objects"},{"location":"open-source/","text":"Prowide open source libraries The Prowide Core and Prowide ISO 20022 are open source Java libraries for managing SWIFT MT and ISO 20022 messages. The projects are: Actively maintained to the latest standard releases Hosted at public GitHub repositories Released under the Apache License 2.0 Production ready and commercially supported Compatible with Java 8+ Download coordinates Download Prowide Core Download Prowide ISO 20022","title":"Prowide open source libraries"},{"location":"open-source/#prowide-open-source-libraries","text":"The Prowide Core and Prowide ISO 20022 are open source Java libraries for managing SWIFT MT and ISO 20022 messages. The projects are: Actively maintained to the latest standard releases Hosted at public GitHub repositories Released under the Apache License 2.0 Production ready and commercially supported Compatible with Java 8+ Download coordinates Download Prowide Core Download Prowide ISO 20022","title":"Prowide open source libraries"},{"location":"open-source/core/","text":"Prowide Core Overview Prowide Core implements the foundation classes to handle SWIFT MT (FIN) messages in Java. The library provides a comprehensive model for all MT message categories. The API features include parsing messages from FIN format to Java, serializing Java model objects into the FIN format and the conversion between FIN messages and XML and JSON formats. The library implements the general ISO 20022 standard. Complementary packages with restricted ISO versions such as CBPR+, SEPA, and SIC are provided in the complementary, proprietary (not open source) library Prowide Integrator. Finally, this library is based on some components from the Prowide Core library. So in order to use this, you will also need the dependency for Prowide Core. Quick API reference The tables below synthesizes, by pseudocode, the entry point for common MT read/write use case scenarios. The use case is usually determined by whether you are creating a new SWIFT message or reading an existing SWIFT message. And in the case of reading, different API exists depending on whether you are processing messages generically, or if you are reading specific known type. Use Case API Parse a known MT message into a specific message model new MT103 ( String / InputStream fin ) MT103 . parse ( String / File / InputStream fin ) Read specific MT message content MT103 + getters Parse unknown MT message into generic swift model AbstractMT . parse ( String / InputStream fin ) Specialize generic MT message new MT103 ( MtSwiftMessage ) MT103 . parse ( MtSwiftMessage ) ( MT103 ) AbstractMT Load and persist an unknown MT message new MtSwiftMessage ( String / InputStream fin ) MtSwiftMessage . parse ( String / InputStream fin ) Build a new MT message new MT103 () + append ( Field ) Write a new MT message to swift string MT103 + message () -> fin Write a new MT message to swift file or stream MT103 + write ( OutputStream fin ) Javadoc Online javadoc Prowide Core Javadoc","title":"Prowide Core"},{"location":"open-source/core/#prowide-core","text":"","title":"Prowide Core"},{"location":"open-source/core/#overview","text":"Prowide Core implements the foundation classes to handle SWIFT MT (FIN) messages in Java. The library provides a comprehensive model for all MT message categories. The API features include parsing messages from FIN format to Java, serializing Java model objects into the FIN format and the conversion between FIN messages and XML and JSON formats. The library implements the general ISO 20022 standard. Complementary packages with restricted ISO versions such as CBPR+, SEPA, and SIC are provided in the complementary, proprietary (not open source) library Prowide Integrator. Finally, this library is based on some components from the Prowide Core library. So in order to use this, you will also need the dependency for Prowide Core.","title":"Overview"},{"location":"open-source/core/#quick-api-reference","text":"The tables below synthesizes, by pseudocode, the entry point for common MT read/write use case scenarios. The use case is usually determined by whether you are creating a new SWIFT message or reading an existing SWIFT message. And in the case of reading, different API exists depending on whether you are processing messages generically, or if you are reading specific known type. Use Case API Parse a known MT message into a specific message model new MT103 ( String / InputStream fin ) MT103 . parse ( String / File / InputStream fin ) Read specific MT message content MT103 + getters Parse unknown MT message into generic swift model AbstractMT . parse ( String / InputStream fin ) Specialize generic MT message new MT103 ( MtSwiftMessage ) MT103 . parse ( MtSwiftMessage ) ( MT103 ) AbstractMT Load and persist an unknown MT message new MtSwiftMessage ( String / InputStream fin ) MtSwiftMessage . parse ( String / InputStream fin ) Build a new MT message new MT103 () + append ( Field ) Write a new MT message to swift string MT103 + message () -> fin Write a new MT message to swift file or stream MT103 + write ( OutputStream fin )","title":"Quick API reference"},{"location":"open-source/core/#javadoc","text":"Online javadoc Prowide Core Javadoc","title":"Javadoc"},{"location":"open-source/core/mt-ack/","text":"Processing ACK/NAK Model and API to process SWIFT ACK notifications The acknowledge (ACK) or non-acknowledge (NAK) are service messages sent by the SWIFT interface to the user application to notify an outgoing message was accepted or not. The acceptance mainly depends on the message being standard compliant. Note that receiving an ACK does not mean the message was effectively delivered to the receiver, it is just a notification indicating if the SWIFT interface accepted the message as valid and entered the message in the network. In order to handle the acknowledges, for instance to change the message status in your application, you have to do some matching of the received notifications and the original sent message. This matching process is not provided as an out-of-the-box feature because it involves querying the application database or file system to find candidates. Anyway, the building blocks to accomplish this task is well supported by the API. ACK structure The structure of a service message is similar to the structure of the regular user message, with a different service id and the block 4 composed of inner sub-blocks instead of fields in lines. Within the service messages the ACK/NAK notifications are identified with service id 21. The following example is the basic structure of a an ACK message: {1:F21LITEBEBBAXXX0066000079}{4:{177:1104180901}{451:0}} Field 451 in the system message indicates whether the message was acked (0) or nacked (1). When nacked the field 405 will also contain a field indicating the error code. For example: {405:T33002} The SwiftParser can seamlessly parse this messages and the SwiftMessage objects provides the same API to retrieve the service message fields as in a regular user message. The methods SwiftMessage#isAck() and SwiftMessage#isNack() can be used to determine in the message is a notification and if it is positive or not. Depending on the SWIFT interface, the file containing the notification can be different. However, in all cases it is composed of the service message plus some reference of the original message. This reference can be for the original message MUR or a full copy of the original message. Matching ACK with full copy of original message The most common structure is the system message with the ACK/NAK followed by a full copy of the original message as in this example: {1:F21LITEBEBBAXXX0066000079}{4:{177:1104180901}{451:0}}{1:F01LITEBEBBAXXX0066000079}{2:I999LITEBEBBXXXXN}{4: :20:TESTREF1 :79:This is text line 1 -}{5:{CHK:7602B010CF31}{TNG:}} The following section describe the normal procedure to detect and pair the acknowledge with the original message and the convenient API to use for the task. First step would be to determine if a received message is and ACK/NAK. Once the message is parsed as SwiftMessage, this methods can be use to verify if it is a regular FIN user to user message or if it is an ACK/NAK notification: SwiftMessage . isServiceMessage21 () SwiftMessage . isAck () SwiftMessage . isNack () Second step would be to split the ACK/NAK information from the identification of the original message. This example uses the most common format which is the ACK/NAK message followed by the full copy of the original message (this is the for example the format used by SAA AFT, or SA Lite autoclient). To parse both the ACK/NAK and the original copy: Swiftparser parser = new SwiftParser () SwiftMessage ack = parser . parse ( msg ) SwiftMessage original = parser . parse ( ack . getUnparsedTexts (). getAsFINString ()) Finally, to match the acked/nacked message with its original message, a query on candidates must be done (usually searching for messages for the same day and same message type). Finding candidates is not covered here because it involves searching the application database or reading the sent messages from a file system directory. Once the candidates are retrieved, the matching can be accomplished like this: AckMessageComparator comparator = new AckMessageComparator (); for ( SwiftMessage candidate : candidates ) { if ( comparator . compare ( original , candidate ) == 0 ) { //candidate is the message acked/nacked } } Matching ACK with MUR Depending on the acknowledge notification source the structure of the message may differ. For instance the full copy of the original message could be missing. However, other kind of reference to the original acked/nacked message must be there, for example the MUR (Message User Reference) like this: {1:F21LITEBEBBAXXX0066000079}{4:{177:1104180901}{451:0}{108:FOO16101900001}} So to match the original message, instead of using the full message copy and the AckMessageComparator , a message with the same MUR must be found: for ( SwiftMessage candidate : candidates ) { if ( StringUtils . equals ( ack . getMUR (), candidate . getMUR ())) { candidate is the message acked / nacked } } Matching ACK with UUID If neither the original message copy nor the MUR are present in the ACK/NAK, the UUID (Unique Identifier) may be present. In this scenario the first step is to strip relevant information from the UUID such as the receiver address, message type and the reference. This fields should then be enough to perform a direct query in the application database to retrieve the unique original message matching the criteria. Related API documentation can be found online at SwiftMessage .","title":"Processing ACK/NAK"},{"location":"open-source/core/mt-ack/#processing-acknak","text":"Model and API to process SWIFT ACK notifications The acknowledge (ACK) or non-acknowledge (NAK) are service messages sent by the SWIFT interface to the user application to notify an outgoing message was accepted or not. The acceptance mainly depends on the message being standard compliant. Note that receiving an ACK does not mean the message was effectively delivered to the receiver, it is just a notification indicating if the SWIFT interface accepted the message as valid and entered the message in the network. In order to handle the acknowledges, for instance to change the message status in your application, you have to do some matching of the received notifications and the original sent message. This matching process is not provided as an out-of-the-box feature because it involves querying the application database or file system to find candidates. Anyway, the building blocks to accomplish this task is well supported by the API.","title":"Processing ACK/NAK"},{"location":"open-source/core/mt-ack/#ack-structure","text":"The structure of a service message is similar to the structure of the regular user message, with a different service id and the block 4 composed of inner sub-blocks instead of fields in lines. Within the service messages the ACK/NAK notifications are identified with service id 21. The following example is the basic structure of a an ACK message: {1:F21LITEBEBBAXXX0066000079}{4:{177:1104180901}{451:0}} Field 451 in the system message indicates whether the message was acked (0) or nacked (1). When nacked the field 405 will also contain a field indicating the error code. For example: {405:T33002} The SwiftParser can seamlessly parse this messages and the SwiftMessage objects provides the same API to retrieve the service message fields as in a regular user message. The methods SwiftMessage#isAck() and SwiftMessage#isNack() can be used to determine in the message is a notification and if it is positive or not. Depending on the SWIFT interface, the file containing the notification can be different. However, in all cases it is composed of the service message plus some reference of the original message. This reference can be for the original message MUR or a full copy of the original message.","title":"ACK structure"},{"location":"open-source/core/mt-ack/#matching-ack-with-full-copy-of-original-message","text":"The most common structure is the system message with the ACK/NAK followed by a full copy of the original message as in this example: {1:F21LITEBEBBAXXX0066000079}{4:{177:1104180901}{451:0}}{1:F01LITEBEBBAXXX0066000079}{2:I999LITEBEBBXXXXN}{4: :20:TESTREF1 :79:This is text line 1 -}{5:{CHK:7602B010CF31}{TNG:}} The following section describe the normal procedure to detect and pair the acknowledge with the original message and the convenient API to use for the task. First step would be to determine if a received message is and ACK/NAK. Once the message is parsed as SwiftMessage, this methods can be use to verify if it is a regular FIN user to user message or if it is an ACK/NAK notification: SwiftMessage . isServiceMessage21 () SwiftMessage . isAck () SwiftMessage . isNack () Second step would be to split the ACK/NAK information from the identification of the original message. This example uses the most common format which is the ACK/NAK message followed by the full copy of the original message (this is the for example the format used by SAA AFT, or SA Lite autoclient). To parse both the ACK/NAK and the original copy: Swiftparser parser = new SwiftParser () SwiftMessage ack = parser . parse ( msg ) SwiftMessage original = parser . parse ( ack . getUnparsedTexts (). getAsFINString ()) Finally, to match the acked/nacked message with its original message, a query on candidates must be done (usually searching for messages for the same day and same message type). Finding candidates is not covered here because it involves searching the application database or reading the sent messages from a file system directory. Once the candidates are retrieved, the matching can be accomplished like this: AckMessageComparator comparator = new AckMessageComparator (); for ( SwiftMessage candidate : candidates ) { if ( comparator . compare ( original , candidate ) == 0 ) { //candidate is the message acked/nacked } }","title":"Matching ACK with full copy of original message"},{"location":"open-source/core/mt-ack/#matching-ack-with-mur","text":"Depending on the acknowledge notification source the structure of the message may differ. For instance the full copy of the original message could be missing. However, other kind of reference to the original acked/nacked message must be there, for example the MUR (Message User Reference) like this: {1:F21LITEBEBBAXXX0066000079}{4:{177:1104180901}{451:0}{108:FOO16101900001}} So to match the original message, instead of using the full message copy and the AckMessageComparator , a message with the same MUR must be found: for ( SwiftMessage candidate : candidates ) { if ( StringUtils . equals ( ack . getMUR (), candidate . getMUR ())) { candidate is the message acked / nacked } }","title":"Matching ACK with MUR"},{"location":"open-source/core/mt-ack/#matching-ack-with-uuid","text":"If neither the original message copy nor the MUR are present in the ACK/NAK, the UUID (Unique Identifier) may be present. In this scenario the first step is to strip relevant information from the UUID such as the receiver address, message type and the reference. This fields should then be enough to perform a direct query in the application database to retrieve the unique original message matching the criteria. Related API documentation can be found online at SwiftMessage .","title":"Matching ACK with UUID"},{"location":"open-source/core/mt-build/","text":"MT Builder (Java to FIN MT) Functionality to create a new SWIFT message by populating Java objects, and writing the result in SWIFT FIN format The creation of a new message basically consists of creating an MT object for the specific message type, and the subsequent addition of fields in an orderly manner. The order of the fields is very important and should be done accordingly to the standard, the model does not prevent creating incorrect content (Standard compliance validation can be checked with Prowide Integrator). The following sections provides explanation by examples, creating messages in different common scenarios: Creating a message with MT classes The following example shows how to create a new MT103 message using the MT and Field helper classes. This is the easiest and recommended way to create a new message from scratch because the API will automatically fill mandatory header information with proper default values. The first step is to create the specific MT object and set its general attributes: final MT103 m = new MT103 (); m . setSender ( \"FOOSEDR0AXXX\" ); m . setReceiver ( \"FOORECV0XXXX\" ); In the above code you can use either a full logical terminal address as parameter (12 characters) or just a plain BIC code (8 or 11 characters) At this point all message blocks are initialized, and by default the message will be an outgoing message (input to SWIFT) with normal priority. The next step is adding the message fields. For simple fields the final value can be directly provided as a single String value, and for more complex fields with several subfields (components) the Field helper classes may be used. m . addField ( new Field20 ( \"REFERENCE\" )); m . addField ( new Field23B ( \"CRED\" )); Field32A f32A = new Field32A () . setDate ( Calendar . getInstance ()) . setCurrency ( \"EUR\" ) . setAmount ( \"1234567,89\" ); m . addField ( f32A ); Field50A f50A = new Field50A () . setAccount ( \"12345678901234567890\" ) . setBIC ( \"FOOBANKXXXXX\" ); m . addField ( f50A ); Field59 f59 = new Field59 () . setAccount ( \"12345678901234567890\" ) . setNameAndAddress ( \"JOE DOE\" ); m . addField ( f59 ); m . addField ( new Field71A ( \"OUR\" )); Finally the message() method converts the object into its SWIFT representation: System . out . println ( m . message ()); The output of the above example is: {1:F01FOOSEDR0AXXX0000000000}{2:IFOORECV0XXXXN}{4: :20:REFERENCE :23B:CRED :32A:1303EUR1234567,89 :50A:/12345678901234567890 FOOBANKXXXXX :59:/12345678901234567890 JOE DOE :71A:OUR -} Notice for instance how field 50A was serializing into a proper value including the slash prefix for the account number and the line feed between the account and the BIC code. /12345678901234567890 [CRLF] FOOBANKXXXXX The same procedure is used to create any type of message, changing the MT103 by any other available implementation. Creating inner sequences For more complex messages where fields must be contained in sequences (or sub blocks) some helper API is also provided by the message model. The following example shows how to append a General Information sequence A to an MT542: SequenceA A = MT542 . SequenceA . newInstance ( Field20C . tag ( \":SEME//2005071800000923\" ), Field23G . tag ( \"NEWM\" )); m . append ( A ); For boundary based sequences the opening and closing fields 16R and 16S will be automatically included. When the message is converted to FIN, the above sample code will generate the following SWIFT content: :16R:GENL :20C::SEME//2005071800000923 :23G:NEWM :16S:GENL Notice sequences should be appended in the correct order, as well as fields inside the sequence block. The API will not control the correctness of the content being generated. The main reason to use this helper sequences API is the constraint provided in the MTnnn classes where only the proper SequenceX inner classes will exist, this way you can rest assure that the appended sequences are part of the specific message type. Nested sequences can be also created with a similar API. The following example creates a complete MT517 with nested sequences A and A1: MT517 mt = new MT517 (). append ( MT517 . SequenceA . newInstance ( new SwiftTagListBlock () . append ( Field20C . tag ( \":SEME//2005071800000923\" )) . append ( Field23G . tag ( \"NEWM/CODU\" )) . append ( Field95P . tag ( \":AFFM//MGTCDE55\" )) . append ( MT517 . SequenceA1 . newInstance ( Field13A . tag ( \"LINK//515\" ), Field20C . tag ( \":RELA//FRTJ12CONF0002\" ))) . append ( MT517 . SequenceA1 . newInstance ( Field13A . tag ( \"LINK//512\" ), Field20C . tag (: RELA //FRTJ12CONF0003))) ) ); Notice how in order to append both Field and sequence objects to the container A sequence, we create a generic SwiftTagListBlock on the fly. The created FIN content for the above snippet is: {1:F01TESTUS00AXXX0000000000}{2:I517TESTUS00XXXXN}{4: :16R:GENL :20C::SEME//2005071800000923 :23G:NEWM/CODU :95P::AFFM//MGTCDE55 :16R:LINK :13A:LINK//515 :20C::RELA//FRTJ12CONF0002 :16S:LINK :16R:LINK :13A:LINK//512 :20C::RELA//FRTJ12CONF0003 :16S:LINK :16S:GENL -} Creating a message with specific header content To create headers with special information, the block's API can be accessed directly. The following example illustrates how to create a message using the low level model layer to create specific headers, overriding the ones created by default in the MT103 constructor. MT103 m = new MT103 (); SwiftBlock1 b1 = new SwiftBlock1 (); b1 . setApplicationId ( \"F\" ); b1 . setServiceId ( \"01\" ); b1 . setLogicalTerminal ( \"BICFOOYYAXXX\" ); b1 . setSessionNumber ( \"1234\" ); b1 . setSequenceNumber ( \"123456\" ); m . getSwiftMessage (). setBlock1 ( b1 ); SwiftBlock2Input b2 = new SwiftBlock2Input (); b2 . setMessageType ( \"103\" ); b2 . setReceiverAddress ( \"BICFOARXXXXX\" ); b2 . setDeliveryMonitoring ( \"1\" ); m . getSwiftMessage (). setBlock2 ( b2 ); m . getSwiftMessage (). setBlock3 ( new SwiftBlock3 ()); m . getSwiftMessage (). getBlock3 (). addTag ( Field113 . tag ( \"NOMT\" )); m . getSwiftMessage (). getBlock3 (). addTag ( Field108 . tag ( \"P22ABCD43C6J3XYZ\" )); In the above example a new and empty message object is created. The basic header (block 1) information is set with specific information, the application header (block 2) is created directly from a suitable string value with all its corresponding attributes pre set, and final an optional user header (block 3) is constructed by adding its tags. Since the MTnnn classes uses a SwiftMessage instance inside, both level API can be combined; the MTnnn and Fieldnnn classes can be use to create the main content of the message and then the SwiftMessage object can be accessed to add or change specific header or trailer information. Adding a message trailer block In most situations there is no need to create the trailer block because it will be added automatically by the FIN interface. However, the API allows the creation of the trailer block as well as any other optional message block as follows: MT103 m = new MT103 (); SwiftBlock5 block5 = new SwiftBlock5 (); block5 . addTag ( new Tag ( \"MAC\" , \"00000000\" )); block5 . addTag ( new Tag ( \"PDE\" , \"\" )); m . getSwiftMessage (). addBlock ( block5 ); The resulting block when the object is serialized to FIN will be: {5:{MAC:00000000}{PDE:}} Adding optional blocks Analogously to the description for Block 5, the same API can be used to create the optional User Header Block (block 3) or to add additional trailers. In particular for the block 3, a SwiftBlock3Builder helper class was introduced to ensure only valid fields are added to the block, and that fields are added in proper order. For backward compatibility we have kept the SwiftBlock3 structure which is a List but the new builder provides specific setters for each available block 3 field. The builder instance is created directly from the block and works as a decorator on the underlying list of tags. SwiftBlock3 b = new SwiftBlock3 (); b . builder () . setField121 ( new Field121 ( \"value121\" )) . setField106 ( new Field106 ( \"value106\" )) . setField165 ( new Field165 ( \"value165\" )) . setField106 ( new Field106 ( \"finalValue106\" )) . setField108 ( new Field108 ( \"value108\" )); Regardless of the setField calls order or repetition, the internal block 3 will be always consistent, and in the above example will produce this output: {3:{108:value108}{106:finalValue106}{121:value121}{165:value165}} The same applies when the message is created with an MT class. For instance if you need to add the MUR field 108 you can use the following: MT103_STP mt = new MT103_STP ( sender , receiver ); mt . getSwiftMessage (). getSwiftBlock3 (). builder (). setField108 ( value108 ); And the output will be: {3:{108:value108}{119:STP}{121:value121}} Notice, fields 119 and 121 were automatically added when the MT instance was created, and the manually added field 108 was placed in the correct position in the existing block 3. Finally this examples appends an optional application trailer block: SwiftBlockUser blockUser = new SwiftBlockUser ( \"S\" ); blockUser . addTag ( new Tag ( \"SAC\" , \"\" )); blockUser . addTag ( new Tag ( \"COP\" , \"P\" )); m . getSwiftMessage (). addBlock ( blockUser );","title":"MT Builder (Java to FIN MT)"},{"location":"open-source/core/mt-build/#mt-builder-java-to-fin-mt","text":"Functionality to create a new SWIFT message by populating Java objects, and writing the result in SWIFT FIN format The creation of a new message basically consists of creating an MT object for the specific message type, and the subsequent addition of fields in an orderly manner. The order of the fields is very important and should be done accordingly to the standard, the model does not prevent creating incorrect content (Standard compliance validation can be checked with Prowide Integrator). The following sections provides explanation by examples, creating messages in different common scenarios:","title":"MT Builder (Java to FIN MT)"},{"location":"open-source/core/mt-build/#creating-a-message-with-mt-classes","text":"The following example shows how to create a new MT103 message using the MT and Field helper classes. This is the easiest and recommended way to create a new message from scratch because the API will automatically fill mandatory header information with proper default values. The first step is to create the specific MT object and set its general attributes: final MT103 m = new MT103 (); m . setSender ( \"FOOSEDR0AXXX\" ); m . setReceiver ( \"FOORECV0XXXX\" ); In the above code you can use either a full logical terminal address as parameter (12 characters) or just a plain BIC code (8 or 11 characters) At this point all message blocks are initialized, and by default the message will be an outgoing message (input to SWIFT) with normal priority. The next step is adding the message fields. For simple fields the final value can be directly provided as a single String value, and for more complex fields with several subfields (components) the Field helper classes may be used. m . addField ( new Field20 ( \"REFERENCE\" )); m . addField ( new Field23B ( \"CRED\" )); Field32A f32A = new Field32A () . setDate ( Calendar . getInstance ()) . setCurrency ( \"EUR\" ) . setAmount ( \"1234567,89\" ); m . addField ( f32A ); Field50A f50A = new Field50A () . setAccount ( \"12345678901234567890\" ) . setBIC ( \"FOOBANKXXXXX\" ); m . addField ( f50A ); Field59 f59 = new Field59 () . setAccount ( \"12345678901234567890\" ) . setNameAndAddress ( \"JOE DOE\" ); m . addField ( f59 ); m . addField ( new Field71A ( \"OUR\" )); Finally the message() method converts the object into its SWIFT representation: System . out . println ( m . message ()); The output of the above example is: {1:F01FOOSEDR0AXXX0000000000}{2:IFOORECV0XXXXN}{4: :20:REFERENCE :23B:CRED :32A:1303EUR1234567,89 :50A:/12345678901234567890 FOOBANKXXXXX :59:/12345678901234567890 JOE DOE :71A:OUR -} Notice for instance how field 50A was serializing into a proper value including the slash prefix for the account number and the line feed between the account and the BIC code. /12345678901234567890 [CRLF] FOOBANKXXXXX The same procedure is used to create any type of message, changing the MT103 by any other available implementation.","title":"Creating a message with MT classes"},{"location":"open-source/core/mt-build/#creating-inner-sequences","text":"For more complex messages where fields must be contained in sequences (or sub blocks) some helper API is also provided by the message model. The following example shows how to append a General Information sequence A to an MT542: SequenceA A = MT542 . SequenceA . newInstance ( Field20C . tag ( \":SEME//2005071800000923\" ), Field23G . tag ( \"NEWM\" )); m . append ( A ); For boundary based sequences the opening and closing fields 16R and 16S will be automatically included. When the message is converted to FIN, the above sample code will generate the following SWIFT content: :16R:GENL :20C::SEME//2005071800000923 :23G:NEWM :16S:GENL Notice sequences should be appended in the correct order, as well as fields inside the sequence block. The API will not control the correctness of the content being generated. The main reason to use this helper sequences API is the constraint provided in the MTnnn classes where only the proper SequenceX inner classes will exist, this way you can rest assure that the appended sequences are part of the specific message type. Nested sequences can be also created with a similar API. The following example creates a complete MT517 with nested sequences A and A1: MT517 mt = new MT517 (). append ( MT517 . SequenceA . newInstance ( new SwiftTagListBlock () . append ( Field20C . tag ( \":SEME//2005071800000923\" )) . append ( Field23G . tag ( \"NEWM/CODU\" )) . append ( Field95P . tag ( \":AFFM//MGTCDE55\" )) . append ( MT517 . SequenceA1 . newInstance ( Field13A . tag ( \"LINK//515\" ), Field20C . tag ( \":RELA//FRTJ12CONF0002\" ))) . append ( MT517 . SequenceA1 . newInstance ( Field13A . tag ( \"LINK//512\" ), Field20C . tag (: RELA //FRTJ12CONF0003))) ) ); Notice how in order to append both Field and sequence objects to the container A sequence, we create a generic SwiftTagListBlock on the fly. The created FIN content for the above snippet is: {1:F01TESTUS00AXXX0000000000}{2:I517TESTUS00XXXXN}{4: :16R:GENL :20C::SEME//2005071800000923 :23G:NEWM/CODU :95P::AFFM//MGTCDE55 :16R:LINK :13A:LINK//515 :20C::RELA//FRTJ12CONF0002 :16S:LINK :16R:LINK :13A:LINK//512 :20C::RELA//FRTJ12CONF0003 :16S:LINK :16S:GENL -}","title":"Creating inner sequences"},{"location":"open-source/core/mt-build/#creating-a-message-with-specific-header-content","text":"To create headers with special information, the block's API can be accessed directly. The following example illustrates how to create a message using the low level model layer to create specific headers, overriding the ones created by default in the MT103 constructor. MT103 m = new MT103 (); SwiftBlock1 b1 = new SwiftBlock1 (); b1 . setApplicationId ( \"F\" ); b1 . setServiceId ( \"01\" ); b1 . setLogicalTerminal ( \"BICFOOYYAXXX\" ); b1 . setSessionNumber ( \"1234\" ); b1 . setSequenceNumber ( \"123456\" ); m . getSwiftMessage (). setBlock1 ( b1 ); SwiftBlock2Input b2 = new SwiftBlock2Input (); b2 . setMessageType ( \"103\" ); b2 . setReceiverAddress ( \"BICFOARXXXXX\" ); b2 . setDeliveryMonitoring ( \"1\" ); m . getSwiftMessage (). setBlock2 ( b2 ); m . getSwiftMessage (). setBlock3 ( new SwiftBlock3 ()); m . getSwiftMessage (). getBlock3 (). addTag ( Field113 . tag ( \"NOMT\" )); m . getSwiftMessage (). getBlock3 (). addTag ( Field108 . tag ( \"P22ABCD43C6J3XYZ\" )); In the above example a new and empty message object is created. The basic header (block 1) information is set with specific information, the application header (block 2) is created directly from a suitable string value with all its corresponding attributes pre set, and final an optional user header (block 3) is constructed by adding its tags. Since the MTnnn classes uses a SwiftMessage instance inside, both level API can be combined; the MTnnn and Fieldnnn classes can be use to create the main content of the message and then the SwiftMessage object can be accessed to add or change specific header or trailer information.","title":"Creating a message with specific header content"},{"location":"open-source/core/mt-build/#adding-a-message-trailer-block","text":"In most situations there is no need to create the trailer block because it will be added automatically by the FIN interface. However, the API allows the creation of the trailer block as well as any other optional message block as follows: MT103 m = new MT103 (); SwiftBlock5 block5 = new SwiftBlock5 (); block5 . addTag ( new Tag ( \"MAC\" , \"00000000\" )); block5 . addTag ( new Tag ( \"PDE\" , \"\" )); m . getSwiftMessage (). addBlock ( block5 ); The resulting block when the object is serialized to FIN will be: {5:{MAC:00000000}{PDE:}}","title":"Adding a message trailer block"},{"location":"open-source/core/mt-build/#adding-optional-blocks","text":"Analogously to the description for Block 5, the same API can be used to create the optional User Header Block (block 3) or to add additional trailers. In particular for the block 3, a SwiftBlock3Builder helper class was introduced to ensure only valid fields are added to the block, and that fields are added in proper order. For backward compatibility we have kept the SwiftBlock3 structure which is a List but the new builder provides specific setters for each available block 3 field. The builder instance is created directly from the block and works as a decorator on the underlying list of tags. SwiftBlock3 b = new SwiftBlock3 (); b . builder () . setField121 ( new Field121 ( \"value121\" )) . setField106 ( new Field106 ( \"value106\" )) . setField165 ( new Field165 ( \"value165\" )) . setField106 ( new Field106 ( \"finalValue106\" )) . setField108 ( new Field108 ( \"value108\" )); Regardless of the setField calls order or repetition, the internal block 3 will be always consistent, and in the above example will produce this output: {3:{108:value108}{106:finalValue106}{121:value121}{165:value165}} The same applies when the message is created with an MT class. For instance if you need to add the MUR field 108 you can use the following: MT103_STP mt = new MT103_STP ( sender , receiver ); mt . getSwiftMessage (). getSwiftBlock3 (). builder (). setField108 ( value108 ); And the output will be: {3:{108:value108}{119:STP}{121:value121}} Notice, fields 119 and 121 were automatically added when the MT instance was created, and the manually added field 108 was placed in the correct position in the existing block 3. Finally this examples appends an optional application trailer block: SwiftBlockUser blockUser = new SwiftBlockUser ( \"S\" ); blockUser . addTag ( new Tag ( \"SAC\" , \"\" )); blockUser . addTag ( new Tag ( \"COP\" , \"P\" )); m . getSwiftMessage (). addBlock ( blockUser );","title":"Adding optional blocks"},{"location":"open-source/core/mt-json/","text":"MT-JSON Conversion Back and forth conversion between MT messages and JSON Different JSON structures are created depending on the model object where the toJson is invoked. SwiftMessage JSON When SwiftMessage#toJson() in the backbone model is used, the generated JSON contains a generic structure with plain name/value tuples for the text block as in the example below. { \"version\" : 1 , \"timestamp\" : ' 2017-06-05 04 : 32 -0300 ' , \"data\" : { \"block1\" : { \"applicationId\" : \"F\" , \"serviceId\" : \"01\" , \"logicalTerminal\" : \"BICFOOYYAXXX\" , \"sessionNumber\" : \"8683\" , \"sequenceNumber\" : \"497519\" } , \"block2\" : { \"messageType\" : \"103\" , \"senderInputTime\" : \"1535\" , \"MIRDate\" : \"051028\" , \"MIRLogicalTerminal\" : \"ESPBESMMAXXX\" , \"MIRSessionNumber\" : \"5423\" , \"MIRSequenceNumber\" : \"752247\" , \"receiverOutputDate\" : \"051028\" , \"receiverOutputTime\" : \"1535\" , \"messagePriority\" : \"N\" } , \"block4\" : [ { \"20\" : \"0061350113089908\" }, { \"13C\" : \"/RNCTIME/1534+0000\" }, (...) { \"72\" : \"/BNF/TRANSF. BCO. FOO\" } ] } } AbstractMT JSON If the message is parsed into the AbstractMT using AbstractMT#parse or by creating any of the subclasses such as the MT103 , then a call to toJson() generates a similar structure, but for the text block each field is serialized into a specific structure. { \"type\" : \"MT\" , \"basicHeaderBlock\" : { \"applicationId\" : \"F\" , \"serviceId\" : \"01\" , \"logicalTerminal\" : \"AAAABEBBAXXX\" , \"sessionNumber\" : \"0001\" , \"sequenceNumber\" : \"000001\" }, \"applicationHeaderBlock\" : { \"receiverAddress\" : \"BBBBBEBBXBIL\" , \"messagePriority\" : \"N\" , \"messageType\" : \"565\" , \"blockType\" : \"I\" , \"direction\" : \"I\" }, \"userHeaderBlock\" : { \"fields\" : [ { \"name\" : \"108\" , \"mUR\" : \"495\" } ] }, \"textBlock\" : { \"fields\" : [ { \"name\" : \"16R\" , \"blockName\" : \"GENL\" }, { \"name\" : \"20C\" , \"qualifier\" : \"CORP\" , \"reference\" : \"ABCD1234\" }, { \"name\" : \"20C\" , \"qualifier\" : \"SEME\" , \"reference\" : \"123456789124001\" }, { \"name\" : \"23G\" , \"function\" : \"NEWM\" }, { \"name\" : \"22F\" , \"qualifier\" : \"CAEV\" , \"indicator\" : \"CONV\" }, { \"name\" : \"98C\" , \"qualifier\" : \"PREP\" , \"date\" : \"20210912\" , \"time\" : \"123111\" }, { \"name\" : \"16R\" , \"blockName\" : \"LINK\" }, { \"name\" : \"22F\" , \"qualifier\" : \"LINK\" , \"indicator\" : \"INFO\" }, { \"name\" : \"13A\" , \"qualifier\" : \"LINK\" , \"numberId\" : \"564\" }, { \"name\" : \"20C\" , \"qualifier\" : \"RELA\" , \"reference\" : \"NONREF\" }, { \"name\" : \"16S\" , \"blockName\" : \"LINK\" }, { \"name\" : \"16S\" , \"blockName\" : \"GENL\" }, { \"name\" : \"16R\" , \"blockName\" : \"CAINST\" }, { \"name\" : \"13A\" , \"qualifier\" : \"CAON\" , \"numberId\" : \"002\" }, { \"name\" : \"22F\" , \"qualifier\" : \"CAOP\" , \"indicator\" : \"CONY\" }, { \"name\" : \"35B\" , \"qualifier\" : \"ISIN\" , \"iSIN\" : \"LU0123456789\" , \"description\" : \"ABCD CORP ORD SHS\" }, { \"name\" : \"36B\" , \"qualifier\" : \"QINS\" , \"quantityTypeCode\" : \"FAMT\" , \"quantity\" : \"50000,\" }, { \"name\" : \"16S\" , \"blockName\" : \"CAINST\" } ] } } NarrativeContainer fields JSON When serializing the field into its specific structure, Field#toJson() in the backbone model is used, there is a special treatment if the field is a NarrativeContainer . These fields support having a simple unstructured content split in lines and also a structured version with codewords. The codewords are separated with slashes and can be used to categorize part of the narrative content. When the structured option is used, different line formats are supported depending on the actual field. In most of the fields the only element in the structured format is the actual text. Some fields can include bank code, currency and amount, country codes or the narrative partitioned as a main narrative and a supplement. Supported line formats are: Format 1 Line 1: /8a/[additional information] (Code)(Narrative) Lines 2-n: /8a/[additional information] (Code)(Narrative) or [//continuation of additional information] (Narrative) Format 2 Line 1: /8c/[additional information] (Code)(Narrative) Lines 2-n: /8c/[additional information] (Code)(Narrative) or [//continuation of additional information] (Narrative) Format 3 Line 1: /8c/[3!a13d][additional information] (Code)(Currency)(Amount)(Narrative) Lines 2-6: /8c/[3!a13d][additional information] (Code)(Currency)(Amount)(Narrative) or [//continuation of additional information] (Narrative) Format 4 Line 1: /8c/[additional information] (Code)(Narrative) Lines 2-3: [//continuation of additional information] (Narrative) Variant for cat 1 with country Line 1: /8c/2!a[//additional information] (Code)(Country)(Narrative) Lines 2-3: [//continuation of additional information] (Narrative) Format 5 Line 1: /2n/[supplement 1][/supplement2] (Query Number)(Narrative 1)(Narrative 2) Lines 2-6: /2n/[supplement 1][/supplement2] or [//continuation of supplementary information] Format 6 Line 1: /6c/[additional information] (Code)(Narrative) Lines 2-100: /6c/[additional information] (Code)(Narrative) or [continuation of additional information] (Narrative) (cannot start with slash) Format 7 Code between slashes at the beginning of a line Format 8 Free format codes in slashes, not necessary on new lines Thus the JSON conversion, will include both the plain narrative lines, and also the result of serializing into JSON the same content parsed into Narrative model, returning for example this JSON content: { \"name\" : \"71B\" , \"narrative\" : \"/WITX/CAPITAL GAINS TAX RELATING TO\\n//THE PERIOD 1999-01-01 2022-10-30\\n//REF 009524780123\\n//BANCA DEL TEST\\n//(REF. ART. 6 DL 461/97)\" , \"structured\" :[ { \"narrativeFragments\" :[ \"CAPITAL GAINS TAX RELATING TO\" , \"THE PERIOD 1999-01-01 2022-10-30\" , \"REF 009524780123\" , \"BANCA DEL TEST\" , \"(REF. ART. 6 DL 461/97)\" ], \"narrativeSupplementFragments\" :[], \"codeword\" : \"WITX\" } ], \"unstructuredFragments\" :[] } As for the reverse conversion, the from JSON method can consume either the plain narrative line elements or the structured narrative elements. Meaning the reverse can consume also a JSON with this structure: { \"name\" : \"71B\" , \"narrative\" : \"/WITX/CAPITAL GAINS TAX RELATING TO\\n//THE PERIOD 1999-01-01 2022-10-30\\n//REF 009524780123\\n//BANCA DEL TEST\\n//(REF. ART. 6 DL 461/97)\" , } And also this other version, producing the same Field71B instance: { \"name\" : \"71B\" , \"structured\" :[ { \"narrativeFragments\" :[ \"CAPITAL GAINS TAX RELATING TO\" , \"THE PERIOD 1999-01-01 2022-10-30\" , \"REF 009524780123\" , \"BANCA DEL TEST\" , \"(REF. ART. 6 DL 461/97)\" ], \"narrativeSupplementFragments\" :[], \"codeword\" : \"WITX\" } ], \"unstructuredFragments\" :[] } Finally for backward compatibility, the JSON unmarshaller can also consume a JSON with the plain narrative lines split into individual elements such as: { \"name\" : \"71B\" , \"narrative\" : \"/WITX/CAPITAL GAINS TAX RELATING TO\" , \"narrative2\" : \"//THE PERIOD 1999-01-01 2022-10-30\" , \"narrative3\" : \"//REF 009524780123\" , \"narrative4\" : \"//BANCA DEL TEST\" , \"narrative\" : \"//(REF. ART. 6 DL 461/97)\" } MtSwiftMessage JSON Finally, there also exists yet another JSON structure if serialization is done using the persistence model MtSwiftMessage. Given the following message content: {1:F01AAAAUSC0ADDD0344000050}{2:I103BBBBUSC0XFFFN}{4: :20:TBEXO200909031 :23B:CRED :32A:090903USD23453, :50K:/01111001759234567890 JOE DOE R00000V0574734 :53B:/00010013800002001234 MI BANCO :59:/00013500510020179998 FOO CORP R00000V000034534 :71A:OUR :72:/TIPO/422 -}{5:{PDE:FOO}} If the message is parsed into an MtSwiftMessage model structure, and some status info and message notes are added, the JSON representation would be like this: { \"pde\" : \"FOO\" , \"uuid\" : \"IBBBBUSC0FFF103TBEXO200909031\" , \"identifier\" : \"fin.103\" , \"sender\" : \"AAAAUSC0DDD\" , \"receiver\" : \"BBBBUSC0FFF\" , \"message\" : \"{1:F01AAAAUSC0ADDD0344000050}{2:I103BBBBUSC0XFFFN}{4:\\n:20:TBEXO200909031\\n:23B:CRED\\n:32A:090903USD23453,\\n:50K:/01111001759234567890\\nJOE DOE\\nR00000V0574734\\n:53B:/00010013800002001234\\nMI BANCO\\n:59:/00013500510020179998\\nFOO CORP\\nR00000V000034534\\n:71A:OUR\\n:72:/TIPO/422\\n-}{5:{PDE:FOO}}\" , \"direction\" : \"outgoing\" , \"checksum\" : \"5c15a3803c4d91d7241534b01a9cf624\" , \"checksumBody\" : \"d4e96cd0c1684cfc218089875d64187b\" , \"lastModified\" : { \"year\" : 2022 , \"month\" : 10 , \"dayOfMonth\" : 17 , \"hourOfDay\" : 14 , \"minute\" : 36 , \"second\" : 28 }, \"creationDate\" : { \"year\" : 2022 , \"month\" : 10 , \"dayOfMonth\" : 17 , \"hourOfDay\" : 14 , \"minute\" : 36 , \"second\" : 27 }, \"statusTrail\" : [ { \"name\" : \"name\" , \"comments\" : \"comments\" , \"creationDate\" : { \"year\" : 2022 , \"month\" : 10 , \"dayOfMonth\" : 17 , \"hourOfDay\" : 14 , \"minute\" : 36 , \"second\" : 28 }, \"creationUser\" : \"creationUser\" , \"data\" : \"data\" } ], \"notes\" : [ { \"creationDate\" : { \"year\" : 2022 , \"month\" : 10 , \"dayOfMonth\" : 17 , \"hourOfDay\" : 14 , \"minute\" : 36 , \"second\" : 28 }, \"creationUser\" : \"creationUser\" , \"text\" : \"text\" } ], \"properties\" : { }, \"fileFormat\" : \"FIN\" , \"reference\" : \"TBEXO200909031\" , \"currency\" : \"USD\" , \"amount\" : 23453 , \"revisions\" : [ ], \"valueDate\" : { \"year\" : 2009 , \"month\" : 8 , \"dayOfMonth\" : 3 , \"hourOfDay\" : 0 , \"minute\" : 0 , \"second\" : 0 } }","title":"MT-JSON Conversion"},{"location":"open-source/core/mt-json/#mt-json-conversion","text":"Back and forth conversion between MT messages and JSON Different JSON structures are created depending on the model object where the toJson is invoked.","title":"MT-JSON Conversion"},{"location":"open-source/core/mt-json/#swiftmessage-json","text":"When SwiftMessage#toJson() in the backbone model is used, the generated JSON contains a generic structure with plain name/value tuples for the text block as in the example below. { \"version\" : 1 , \"timestamp\" : ' 2017-06-05 04 : 32 -0300 ' , \"data\" : { \"block1\" : { \"applicationId\" : \"F\" , \"serviceId\" : \"01\" , \"logicalTerminal\" : \"BICFOOYYAXXX\" , \"sessionNumber\" : \"8683\" , \"sequenceNumber\" : \"497519\" } , \"block2\" : { \"messageType\" : \"103\" , \"senderInputTime\" : \"1535\" , \"MIRDate\" : \"051028\" , \"MIRLogicalTerminal\" : \"ESPBESMMAXXX\" , \"MIRSessionNumber\" : \"5423\" , \"MIRSequenceNumber\" : \"752247\" , \"receiverOutputDate\" : \"051028\" , \"receiverOutputTime\" : \"1535\" , \"messagePriority\" : \"N\" } , \"block4\" : [ { \"20\" : \"0061350113089908\" }, { \"13C\" : \"/RNCTIME/1534+0000\" }, (...) { \"72\" : \"/BNF/TRANSF. BCO. FOO\" } ] } }","title":"SwiftMessage JSON"},{"location":"open-source/core/mt-json/#abstractmt-json","text":"If the message is parsed into the AbstractMT using AbstractMT#parse or by creating any of the subclasses such as the MT103 , then a call to toJson() generates a similar structure, but for the text block each field is serialized into a specific structure. { \"type\" : \"MT\" , \"basicHeaderBlock\" : { \"applicationId\" : \"F\" , \"serviceId\" : \"01\" , \"logicalTerminal\" : \"AAAABEBBAXXX\" , \"sessionNumber\" : \"0001\" , \"sequenceNumber\" : \"000001\" }, \"applicationHeaderBlock\" : { \"receiverAddress\" : \"BBBBBEBBXBIL\" , \"messagePriority\" : \"N\" , \"messageType\" : \"565\" , \"blockType\" : \"I\" , \"direction\" : \"I\" }, \"userHeaderBlock\" : { \"fields\" : [ { \"name\" : \"108\" , \"mUR\" : \"495\" } ] }, \"textBlock\" : { \"fields\" : [ { \"name\" : \"16R\" , \"blockName\" : \"GENL\" }, { \"name\" : \"20C\" , \"qualifier\" : \"CORP\" , \"reference\" : \"ABCD1234\" }, { \"name\" : \"20C\" , \"qualifier\" : \"SEME\" , \"reference\" : \"123456789124001\" }, { \"name\" : \"23G\" , \"function\" : \"NEWM\" }, { \"name\" : \"22F\" , \"qualifier\" : \"CAEV\" , \"indicator\" : \"CONV\" }, { \"name\" : \"98C\" , \"qualifier\" : \"PREP\" , \"date\" : \"20210912\" , \"time\" : \"123111\" }, { \"name\" : \"16R\" , \"blockName\" : \"LINK\" }, { \"name\" : \"22F\" , \"qualifier\" : \"LINK\" , \"indicator\" : \"INFO\" }, { \"name\" : \"13A\" , \"qualifier\" : \"LINK\" , \"numberId\" : \"564\" }, { \"name\" : \"20C\" , \"qualifier\" : \"RELA\" , \"reference\" : \"NONREF\" }, { \"name\" : \"16S\" , \"blockName\" : \"LINK\" }, { \"name\" : \"16S\" , \"blockName\" : \"GENL\" }, { \"name\" : \"16R\" , \"blockName\" : \"CAINST\" }, { \"name\" : \"13A\" , \"qualifier\" : \"CAON\" , \"numberId\" : \"002\" }, { \"name\" : \"22F\" , \"qualifier\" : \"CAOP\" , \"indicator\" : \"CONY\" }, { \"name\" : \"35B\" , \"qualifier\" : \"ISIN\" , \"iSIN\" : \"LU0123456789\" , \"description\" : \"ABCD CORP ORD SHS\" }, { \"name\" : \"36B\" , \"qualifier\" : \"QINS\" , \"quantityTypeCode\" : \"FAMT\" , \"quantity\" : \"50000,\" }, { \"name\" : \"16S\" , \"blockName\" : \"CAINST\" } ] } }","title":"AbstractMT JSON"},{"location":"open-source/core/mt-json/#narrativecontainer-fields-json","text":"When serializing the field into its specific structure, Field#toJson() in the backbone model is used, there is a special treatment if the field is a NarrativeContainer . These fields support having a simple unstructured content split in lines and also a structured version with codewords. The codewords are separated with slashes and can be used to categorize part of the narrative content. When the structured option is used, different line formats are supported depending on the actual field. In most of the fields the only element in the structured format is the actual text. Some fields can include bank code, currency and amount, country codes or the narrative partitioned as a main narrative and a supplement. Supported line formats are: Format 1 Line 1: /8a/[additional information] (Code)(Narrative) Lines 2-n: /8a/[additional information] (Code)(Narrative) or [//continuation of additional information] (Narrative) Format 2 Line 1: /8c/[additional information] (Code)(Narrative) Lines 2-n: /8c/[additional information] (Code)(Narrative) or [//continuation of additional information] (Narrative) Format 3 Line 1: /8c/[3!a13d][additional information] (Code)(Currency)(Amount)(Narrative) Lines 2-6: /8c/[3!a13d][additional information] (Code)(Currency)(Amount)(Narrative) or [//continuation of additional information] (Narrative) Format 4 Line 1: /8c/[additional information] (Code)(Narrative) Lines 2-3: [//continuation of additional information] (Narrative) Variant for cat 1 with country Line 1: /8c/2!a[//additional information] (Code)(Country)(Narrative) Lines 2-3: [//continuation of additional information] (Narrative) Format 5 Line 1: /2n/[supplement 1][/supplement2] (Query Number)(Narrative 1)(Narrative 2) Lines 2-6: /2n/[supplement 1][/supplement2] or [//continuation of supplementary information] Format 6 Line 1: /6c/[additional information] (Code)(Narrative) Lines 2-100: /6c/[additional information] (Code)(Narrative) or [continuation of additional information] (Narrative) (cannot start with slash) Format 7 Code between slashes at the beginning of a line Format 8 Free format codes in slashes, not necessary on new lines Thus the JSON conversion, will include both the plain narrative lines, and also the result of serializing into JSON the same content parsed into Narrative model, returning for example this JSON content: { \"name\" : \"71B\" , \"narrative\" : \"/WITX/CAPITAL GAINS TAX RELATING TO\\n//THE PERIOD 1999-01-01 2022-10-30\\n//REF 009524780123\\n//BANCA DEL TEST\\n//(REF. ART. 6 DL 461/97)\" , \"structured\" :[ { \"narrativeFragments\" :[ \"CAPITAL GAINS TAX RELATING TO\" , \"THE PERIOD 1999-01-01 2022-10-30\" , \"REF 009524780123\" , \"BANCA DEL TEST\" , \"(REF. ART. 6 DL 461/97)\" ], \"narrativeSupplementFragments\" :[], \"codeword\" : \"WITX\" } ], \"unstructuredFragments\" :[] } As for the reverse conversion, the from JSON method can consume either the plain narrative line elements or the structured narrative elements. Meaning the reverse can consume also a JSON with this structure: { \"name\" : \"71B\" , \"narrative\" : \"/WITX/CAPITAL GAINS TAX RELATING TO\\n//THE PERIOD 1999-01-01 2022-10-30\\n//REF 009524780123\\n//BANCA DEL TEST\\n//(REF. ART. 6 DL 461/97)\" , } And also this other version, producing the same Field71B instance: { \"name\" : \"71B\" , \"structured\" :[ { \"narrativeFragments\" :[ \"CAPITAL GAINS TAX RELATING TO\" , \"THE PERIOD 1999-01-01 2022-10-30\" , \"REF 009524780123\" , \"BANCA DEL TEST\" , \"(REF. ART. 6 DL 461/97)\" ], \"narrativeSupplementFragments\" :[], \"codeword\" : \"WITX\" } ], \"unstructuredFragments\" :[] } Finally for backward compatibility, the JSON unmarshaller can also consume a JSON with the plain narrative lines split into individual elements such as: { \"name\" : \"71B\" , \"narrative\" : \"/WITX/CAPITAL GAINS TAX RELATING TO\" , \"narrative2\" : \"//THE PERIOD 1999-01-01 2022-10-30\" , \"narrative3\" : \"//REF 009524780123\" , \"narrative4\" : \"//BANCA DEL TEST\" , \"narrative\" : \"//(REF. ART. 6 DL 461/97)\" }","title":"NarrativeContainer fields JSON"},{"location":"open-source/core/mt-json/#mtswiftmessage-json","text":"Finally, there also exists yet another JSON structure if serialization is done using the persistence model MtSwiftMessage. Given the following message content: {1:F01AAAAUSC0ADDD0344000050}{2:I103BBBBUSC0XFFFN}{4: :20:TBEXO200909031 :23B:CRED :32A:090903USD23453, :50K:/01111001759234567890 JOE DOE R00000V0574734 :53B:/00010013800002001234 MI BANCO :59:/00013500510020179998 FOO CORP R00000V000034534 :71A:OUR :72:/TIPO/422 -}{5:{PDE:FOO}} If the message is parsed into an MtSwiftMessage model structure, and some status info and message notes are added, the JSON representation would be like this: { \"pde\" : \"FOO\" , \"uuid\" : \"IBBBBUSC0FFF103TBEXO200909031\" , \"identifier\" : \"fin.103\" , \"sender\" : \"AAAAUSC0DDD\" , \"receiver\" : \"BBBBUSC0FFF\" , \"message\" : \"{1:F01AAAAUSC0ADDD0344000050}{2:I103BBBBUSC0XFFFN}{4:\\n:20:TBEXO200909031\\n:23B:CRED\\n:32A:090903USD23453,\\n:50K:/01111001759234567890\\nJOE DOE\\nR00000V0574734\\n:53B:/00010013800002001234\\nMI BANCO\\n:59:/00013500510020179998\\nFOO CORP\\nR00000V000034534\\n:71A:OUR\\n:72:/TIPO/422\\n-}{5:{PDE:FOO}}\" , \"direction\" : \"outgoing\" , \"checksum\" : \"5c15a3803c4d91d7241534b01a9cf624\" , \"checksumBody\" : \"d4e96cd0c1684cfc218089875d64187b\" , \"lastModified\" : { \"year\" : 2022 , \"month\" : 10 , \"dayOfMonth\" : 17 , \"hourOfDay\" : 14 , \"minute\" : 36 , \"second\" : 28 }, \"creationDate\" : { \"year\" : 2022 , \"month\" : 10 , \"dayOfMonth\" : 17 , \"hourOfDay\" : 14 , \"minute\" : 36 , \"second\" : 27 }, \"statusTrail\" : [ { \"name\" : \"name\" , \"comments\" : \"comments\" , \"creationDate\" : { \"year\" : 2022 , \"month\" : 10 , \"dayOfMonth\" : 17 , \"hourOfDay\" : 14 , \"minute\" : 36 , \"second\" : 28 }, \"creationUser\" : \"creationUser\" , \"data\" : \"data\" } ], \"notes\" : [ { \"creationDate\" : { \"year\" : 2022 , \"month\" : 10 , \"dayOfMonth\" : 17 , \"hourOfDay\" : 14 , \"minute\" : 36 , \"second\" : 28 }, \"creationUser\" : \"creationUser\" , \"text\" : \"text\" } ], \"properties\" : { }, \"fileFormat\" : \"FIN\" , \"reference\" : \"TBEXO200909031\" , \"currency\" : \"USD\" , \"amount\" : 23453 , \"revisions\" : [ ], \"valueDate\" : { \"year\" : 2009 , \"month\" : 8 , \"dayOfMonth\" : 3 , \"hourOfDay\" : 0 , \"minute\" : 0 , \"second\" : 0 } }","title":"MtSwiftMessage JSON"},{"location":"open-source/core/mt-model/","text":"Java model for MT messages The message model for MT messages is a set of Java classes representing the structure and content of a SWIFT MT (ISO 15022) message. The message model is a central part of the library suited for message creation, parsing and persistence. It is designed in three layers of specific use; each provides a different level of abstraction. Persistence - Lightweight Layer The upper layer is a generic representation for all messages mainly intended for message persistence. The model includes specific attributes for header and trailer information, while the body content (business payload) is kept as a single String attribute (not parsed). Since this model is generic, message objects can be instantiated without prior knowledge of the specific type of message. This design is therefore optimal for database persistence because all message types can share a simple and efficient database structure. It can be thought of as a wrapper of a swift message file. Besides message content, the model provides several metadata containers very useful for a message management application, such as a holder for message status, attached notes and extendable properties. The main classes for this layer are the AbstractSwiftMessage and MtSwiftMessage . Parse/Build - Functional Layer The middle layer is a functional view of a specific message, for example an MT103 . The provided API allows you to read data from a known message easily, as well as API to build new messages. This layer provides a specific class for each message type, with getters for its inner sequences and fields. Also a specific class for each possible field of the message, for example Field32A , with methods to retrieve any internal component (subfield), for example the Calendar , Currency and Amount of Field32A . These specific classes can be thought of as a facade or view of the internal message content. The entry point for this layer is the AbstractMT and all its subclasses that represent a specific message type. Notice these objects are not intended for message modification because when you read content with a getFieldNN the returned object is detached from the underlying model. Details on how to modify a message are described later in this document. NarrativeContainer fields Some fields, such as Field71B , implements the NarrativeContainer interface and provide methods to access the narrative content in a structured way. These fields support having a simple unstructured content split in lines and also a structured version with codewords. Where the codewords are separated with slashes and can be used to categorize part of the narrative content. The internal component structure for these fields is just a plain single String with the whole value. But the structured content can be retrieve using: Narrative narrative = f . narrative (); Where the Narrative object provides methods to access the different parts of the narrative by the codewords. The NarrativeResolver parser can automatically detect the narrative structure and create the Narrative depending on the field value. In most of the fields the only element in the structured format is the actual text. however, some fields can include bank code, currency and amount, country codes or the narrative partitioned as a main narrative and a supplement fragments. Supported line formats are: Format 1 Line 1: /8a/[additional information] (Code)(Narrative) Lines 2-n: /8a/[additional information] (Code)(Narrative) or [//continuation of additional information] (Narrative) Format 2 Line 1: /8c/[additional information] (Code)(Narrative) Lines 2-n: /8c/[additional information] (Code)(Narrative) or [//continuation of additional information] (Narrative) Format 3 Line 1: /8c/[3!a13d][additional information] (Code)(Currency)(Amount)(Narrative) Lines 2-6: /8c/[3!a13d][additional information] (Code)(Currency)(Amount)(Narrative) or [//continuation of additional information] (Narrative) Format 4 Line 1: /8c/[additional information] (Code)(Narrative) Lines 2-3: [//continuation of additional information] (Narrative) Variant for cat 1 with country Line 1: /8c/2!a[//additional information] (Code)(Country)(Narrative) Lines 2-3: [//continuation of additional information] (Narrative) Format 5 Line 1: /2n/[supplement 1][/supplement2] (Query Number)(Narrative 1)(Narrative 2) Lines 2-6: /2n/[supplement 1][/supplement2] or [//continuation of supplementary information] Format 6 Line 1: /6c/[additional information] (Code)(Narrative) Lines 2-100: /6c/[additional information] (Code)(Narrative) or [continuation of additional information] (Narrative) (cannot start with slash) Format 7 Code between slashes at the beginning of a line Format 8 Free format codes in slashes, not necessary on new lines The same Narrative model can be used to create this fields content when building messages from scratch. Backbone - Structure Layer The lower layer is the internal backbone of the upper one, and in most cases there is no need to use this API from an application. The message representation at this level handles the message content as simple tuples of field name and field value and implements low level handling of sequences and blocks. This model is quite simple, generic and loosely coupled to specific messages, therefore being very efficient and requiring minimal construction constraints. Messages in this layer are represented by the SwiftMessage class, with its internal name-value tuples modeled by the Tag class. This layer is also the one used for content modification.","title":"Domain model"},{"location":"open-source/core/mt-model/#java-model-for-mt-messages","text":"The message model for MT messages is a set of Java classes representing the structure and content of a SWIFT MT (ISO 15022) message. The message model is a central part of the library suited for message creation, parsing and persistence. It is designed in three layers of specific use; each provides a different level of abstraction.","title":"Java model for MT messages"},{"location":"open-source/core/mt-model/#persistence-lightweight-layer","text":"The upper layer is a generic representation for all messages mainly intended for message persistence. The model includes specific attributes for header and trailer information, while the body content (business payload) is kept as a single String attribute (not parsed). Since this model is generic, message objects can be instantiated without prior knowledge of the specific type of message. This design is therefore optimal for database persistence because all message types can share a simple and efficient database structure. It can be thought of as a wrapper of a swift message file. Besides message content, the model provides several metadata containers very useful for a message management application, such as a holder for message status, attached notes and extendable properties. The main classes for this layer are the AbstractSwiftMessage and MtSwiftMessage .","title":"Persistence - Lightweight Layer"},{"location":"open-source/core/mt-model/#parsebuild-functional-layer","text":"The middle layer is a functional view of a specific message, for example an MT103 . The provided API allows you to read data from a known message easily, as well as API to build new messages. This layer provides a specific class for each message type, with getters for its inner sequences and fields. Also a specific class for each possible field of the message, for example Field32A , with methods to retrieve any internal component (subfield), for example the Calendar , Currency and Amount of Field32A . These specific classes can be thought of as a facade or view of the internal message content. The entry point for this layer is the AbstractMT and all its subclasses that represent a specific message type. Notice these objects are not intended for message modification because when you read content with a getFieldNN the returned object is detached from the underlying model. Details on how to modify a message are described later in this document.","title":"Parse/Build - Functional Layer"},{"location":"open-source/core/mt-model/#narrativecontainer-fields","text":"Some fields, such as Field71B , implements the NarrativeContainer interface and provide methods to access the narrative content in a structured way. These fields support having a simple unstructured content split in lines and also a structured version with codewords. Where the codewords are separated with slashes and can be used to categorize part of the narrative content. The internal component structure for these fields is just a plain single String with the whole value. But the structured content can be retrieve using: Narrative narrative = f . narrative (); Where the Narrative object provides methods to access the different parts of the narrative by the codewords. The NarrativeResolver parser can automatically detect the narrative structure and create the Narrative depending on the field value. In most of the fields the only element in the structured format is the actual text. however, some fields can include bank code, currency and amount, country codes or the narrative partitioned as a main narrative and a supplement fragments. Supported line formats are: Format 1 Line 1: /8a/[additional information] (Code)(Narrative) Lines 2-n: /8a/[additional information] (Code)(Narrative) or [//continuation of additional information] (Narrative) Format 2 Line 1: /8c/[additional information] (Code)(Narrative) Lines 2-n: /8c/[additional information] (Code)(Narrative) or [//continuation of additional information] (Narrative) Format 3 Line 1: /8c/[3!a13d][additional information] (Code)(Currency)(Amount)(Narrative) Lines 2-6: /8c/[3!a13d][additional information] (Code)(Currency)(Amount)(Narrative) or [//continuation of additional information] (Narrative) Format 4 Line 1: /8c/[additional information] (Code)(Narrative) Lines 2-3: [//continuation of additional information] (Narrative) Variant for cat 1 with country Line 1: /8c/2!a[//additional information] (Code)(Country)(Narrative) Lines 2-3: [//continuation of additional information] (Narrative) Format 5 Line 1: /2n/[supplement 1][/supplement2] (Query Number)(Narrative 1)(Narrative 2) Lines 2-6: /2n/[supplement 1][/supplement2] or [//continuation of supplementary information] Format 6 Line 1: /6c/[additional information] (Code)(Narrative) Lines 2-100: /6c/[additional information] (Code)(Narrative) or [continuation of additional information] (Narrative) (cannot start with slash) Format 7 Code between slashes at the beginning of a line Format 8 Free format codes in slashes, not necessary on new lines The same Narrative model can be used to create this fields content when building messages from scratch.","title":"NarrativeContainer fields"},{"location":"open-source/core/mt-model/#backbone-structure-layer","text":"The lower layer is the internal backbone of the upper one, and in most cases there is no need to use this API from an application. The message representation at this level handles the message content as simple tuples of field name and field value and implements low level handling of sequences and blocks. This model is quite simple, generic and loosely coupled to specific messages, therefore being very efficient and requiring minimal construction constraints. Messages in this layer are represented by the SwiftMessage class, with its internal name-value tuples modeled by the Tag class. This layer is also the one used for content modification.","title":"Backbone - Structure Layer"},{"location":"open-source/core/mt-modify/","text":"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 . 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\" ))","title":"MT content modification"},{"location":"open-source/core/mt-modify/#mt-content-modification","text":"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.","title":"MT content modification"},{"location":"open-source/core/mt-modify/#updating-a-field-value","text":"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.","title":"Updating a field value"},{"location":"open-source/core/mt-modify/#inserting-new-fields-in-mt-message","text":"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 . 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.","title":"Inserting new fields in MT message"},{"location":"open-source/core/mt-modify/#using-the-tag-index","text":"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","title":"Using the tag index"},{"location":"open-source/core/mt-modify/#using-the-swiftblock3builder","text":"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\" ))","title":"Using the SwiftBlock3Builder"},{"location":"open-source/core/mt-parser/","text":"Parser (FIN MT to Java) The parser provides functionality to convert SWIFT messages FIN text into the Java message model By doing this, you can work with SWIFT messages focusing on the data and not having to deal with low level syntax details. The parser always performs a best effort heuristic to parse the message even if it is not well formed. All the information is read and put in a suitable object of the message model regardless of the message being SWIFT compliant. The parser functionality has different entry point depending on the use case: Generic processing of unknown messages In situations where the message type is unknown, the easiest and recommended way to read and parse messages is by means of the abstract class AbstractMT. This class provides static methods to parse an unknown message from a String or InputStream . For example consider the following SWIFT message example: {1:F01BANKDEFMAXXX2039063581}{2:O1031609050901BANKDEFXAXXX89549829458949811609N}{4: :20:007505327853 :23B:CRED :32A:050902JPY3520000, :33B:JPY3520000, :50K:EUROXXXEI :52A:FEBXXXM1 :53A:MHCXXXJT :54A:FOOBICXX :59:/13212312 RECEIVER NAME S.A :70:FUTURES :71A:SHA :71F:EUR12,00 :71F:EUR2,34 -} Assuming the message is in a String variable \"fin\", the following code will parse the FIN message into a message object object, where several getters are available to read message header information. AbstractMT msg = AbstractMT . parse ( fin ); String sender = msg . getSender (); String type = msg . getMessageType (); Even though the message type is unknown the returned object will be parsed into its specific MTnnn model object. So once the message type is known a simple cast is enough to access detail information of the text block for reading or manipulating its content. In the example: System . out . println ( msg . getMessageType ()); if ( msg . isType ( 103 )) { MT103 mt = ( MT103 ) msg ; // print the message reference System . out . println ( \"Reference: \" + mt . getField20 (). getValue ()); // read components of a specific field Field32A f = mt . getField32A (); Calendar date = f . getComponent1AsCalendar (); Number amount = f . getComponent3AsNumber (); } Notice MTnnn classes provide API that is exclusively related to the fields that can be present in each message type. Parsing an unknown message for persistence While in the context of a parsing an unknown message, if the ultimate requirement is to read just headers information, persist the message into a database or to process large bursts of messages, the recommended way to read and parse messages is by means of the MtSwiftMessage class. This class also implements several ways to create the message instance from String , InputStream ; but only header information is read and the model is kept generic after the parse. Assuming the message is in a String or InputStream variable \"fin\" , the following code will parse the FIN message into a MtSwiftMessage object, and getters are used to access message header information. MtSwiftMessage msg = MtSwftMessage . parse ( fin ); String sender = msg . getSender (); String type = msg . getMessageType (); The MtSwiftMessage is a lightweight representation of the message where only the header and trailer blocks are parsed and modeled, while the text block (the actual business payload) is kept in its raw unparsed format. Specializing an unkown message The above way of reading messages is the most efficient in terms of performance and it is useful to process large burst of messages; but it is limited for content manipulation. However, once the message object is created and properly identified, it can be specialize to access the specific text block content, for example: MT103 mt = new MT103 ( msg ); Field32A f = mt . getField32A (); Calendar date = f . getComponent1AsCalendar (); Number amount = f . getComponent3AsNumber (); Notice that specializing a generic message from an AbstractMT requires only a cast to the specific MTnnn , while doing the same from an MtSwiftMessage requires a constructor. Another important thing to know when deciding to use the AbstractMT or the MtSwiftMessage is that parsing by an AbstractMT implies that the message type can be determined from the block 2 header, that's because internally the parser will create the corresponding message type object ( MTnnn ). While parsing by an MtSwiftMessage does not impose anything to the message content, that could be malformed or incomplete and the message object will be created anyway. Specific processing of a known message type When the message to parse is known, the specific model class can be used directly to parse and read the content. For example: MT103 model = MT103 . parse ( fin ); Where the fin parameter can be a String or InputStream with the message in its FIN format, and the parsing can be called using the static parse method (as in the example) or by an MTnnn constructor. Once the object is created all its specific content can be read using getters for specific sequences and fields. Parsing message with ACK There is a frequent misunderstanding of the FIN messages format when the actual message is preceded by a system ACK, and the expected behavior of Prowide Core parser when reading such messages. The following example is actually a service message for ACK, followed by the original MT940 sent: {1:F21FOOLHKH0AXXX0304009999}{4:{177:1608140809}{451:0}}{1:F01FOOLHKH0AXXX0304009999}{2:O9401609160814FOOLHKH0AXXX03040027341608141609N}{4: :20:USD940NO1 :21:123456/DEV :25:USD234567 :28C:1/1 :60F:C160418USD672, :61:160827C642,S1032 :86:ANDY :61:160827D42,S1032 :86:BANK CHARGES :62F:C160418USD1872, :64:C160418USD1872, -}{5:{CHK:0FEC1E4AEC53}{TNG:}}{S:{COP:S}} If you pass the above content to the parse method, by default the parser will get the first FIN message found in the file (the ACK service message), leaving the rest of the text into the UnparsedTextList structure. This is just fine when reading plain user to user messages, but when the message is preceded by a service message as in the example, the resulting parsed object may not be the expected one. When dealing with this scenario it is the user responsibility to check whether the message is a service message or not, and proceed accordingly, depending on the particular use case and application needs. If you are trying to match and process the ACK/NAK notifications you may be interested on the service message. However, if this is the way you receive the messages from the SWIFT interface and you need the actual user message following the ACK, then you have to do something else. The following example will parse the FIN content, check for the service id, and if it is a system message it will then gather the actual MT from the unparsed content: SwiftMessage sm = SwiftMessage . parse ( fin ); if ( sm . isServiceMessage ()) { sm = SwiftMessage . parse ( sm . getUnparsedTexts (). getAsFINString ()); } At this point the sm variable will contain the actual user to user message, regardless if it was preceded by and ACK. For more information on the ACK/NAK structure see Processing ACK/NAK. Direct usage of the SwiftParser Finally, the actual parser implementation class is another option to translate a raw message in its Java model object. SwiftMessage m = ( new SwiftParser ()). parse ( fin ); Direct usage of the SwiftParser class is discouraged but in may be useful on certain conditions where the lenient mode of the parser must be explicitly controlled by your application. The result of the parser is the backbone model implemented by the SwiftMessage class. So the parser will basically split the message content into the three primary elements that defines an MT message; the message itself, it's blocks, and the tag (or fields) inside each block. Reading fields like simple tuples of name and value makes the parser very efficient, while additional content parsing can be done with the message model in a following step. For the example, the following code can be use to gather some fields of the parsed message using the generic low level model: String val32a = m . getBlock4 (). getTagValue ( \"32A\" ); //get a simple value tag String [] list71 = m . getBlock4 (). getTagValues ( \"71F\" ); //get a repeated value tag The \"val32a\" String will contain the value \"050902JPY3520000,\" and \"list71\" will contains a list of String with values \"EUR12,00\" and \"EUR2,34\". The SwiftBlock4 object basically contains an ordered List of fields found content body of the SWIFT message and provides several API to manipulate and get the tags individually or by sub blocks. At this API level the message body can be think of as a text string, where instead of characters we found message fields and we can get for example all Tags before a given one, Tags between boundaries, etc.. This API is the base foundation of the high level Sequences API.","title":"MT Parser (FIN MT to Java)"},{"location":"open-source/core/mt-parser/#parser-fin-mt-to-java","text":"The parser provides functionality to convert SWIFT messages FIN text into the Java message model By doing this, you can work with SWIFT messages focusing on the data and not having to deal with low level syntax details. The parser always performs a best effort heuristic to parse the message even if it is not well formed. All the information is read and put in a suitable object of the message model regardless of the message being SWIFT compliant. The parser functionality has different entry point depending on the use case:","title":"Parser (FIN MT to Java)"},{"location":"open-source/core/mt-parser/#generic-processing-of-unknown-messages","text":"In situations where the message type is unknown, the easiest and recommended way to read and parse messages is by means of the abstract class AbstractMT. This class provides static methods to parse an unknown message from a String or InputStream . For example consider the following SWIFT message example: {1:F01BANKDEFMAXXX2039063581}{2:O1031609050901BANKDEFXAXXX89549829458949811609N}{4: :20:007505327853 :23B:CRED :32A:050902JPY3520000, :33B:JPY3520000, :50K:EUROXXXEI :52A:FEBXXXM1 :53A:MHCXXXJT :54A:FOOBICXX :59:/13212312 RECEIVER NAME S.A :70:FUTURES :71A:SHA :71F:EUR12,00 :71F:EUR2,34 -} Assuming the message is in a String variable \"fin\", the following code will parse the FIN message into a message object object, where several getters are available to read message header information. AbstractMT msg = AbstractMT . parse ( fin ); String sender = msg . getSender (); String type = msg . getMessageType (); Even though the message type is unknown the returned object will be parsed into its specific MTnnn model object. So once the message type is known a simple cast is enough to access detail information of the text block for reading or manipulating its content. In the example: System . out . println ( msg . getMessageType ()); if ( msg . isType ( 103 )) { MT103 mt = ( MT103 ) msg ; // print the message reference System . out . println ( \"Reference: \" + mt . getField20 (). getValue ()); // read components of a specific field Field32A f = mt . getField32A (); Calendar date = f . getComponent1AsCalendar (); Number amount = f . getComponent3AsNumber (); } Notice MTnnn classes provide API that is exclusively related to the fields that can be present in each message type.","title":"Generic processing of unknown messages"},{"location":"open-source/core/mt-parser/#parsing-an-unknown-message-for-persistence","text":"While in the context of a parsing an unknown message, if the ultimate requirement is to read just headers information, persist the message into a database or to process large bursts of messages, the recommended way to read and parse messages is by means of the MtSwiftMessage class. This class also implements several ways to create the message instance from String , InputStream ; but only header information is read and the model is kept generic after the parse. Assuming the message is in a String or InputStream variable \"fin\" , the following code will parse the FIN message into a MtSwiftMessage object, and getters are used to access message header information. MtSwiftMessage msg = MtSwftMessage . parse ( fin ); String sender = msg . getSender (); String type = msg . getMessageType (); The MtSwiftMessage is a lightweight representation of the message where only the header and trailer blocks are parsed and modeled, while the text block (the actual business payload) is kept in its raw unparsed format.","title":"Parsing an unknown message for persistence"},{"location":"open-source/core/mt-parser/#specializing-an-unkown-message","text":"The above way of reading messages is the most efficient in terms of performance and it is useful to process large burst of messages; but it is limited for content manipulation. However, once the message object is created and properly identified, it can be specialize to access the specific text block content, for example: MT103 mt = new MT103 ( msg ); Field32A f = mt . getField32A (); Calendar date = f . getComponent1AsCalendar (); Number amount = f . getComponent3AsNumber (); Notice that specializing a generic message from an AbstractMT requires only a cast to the specific MTnnn , while doing the same from an MtSwiftMessage requires a constructor. Another important thing to know when deciding to use the AbstractMT or the MtSwiftMessage is that parsing by an AbstractMT implies that the message type can be determined from the block 2 header, that's because internally the parser will create the corresponding message type object ( MTnnn ). While parsing by an MtSwiftMessage does not impose anything to the message content, that could be malformed or incomplete and the message object will be created anyway.","title":"Specializing an unkown message"},{"location":"open-source/core/mt-parser/#specific-processing-of-a-known-message-type","text":"When the message to parse is known, the specific model class can be used directly to parse and read the content. For example: MT103 model = MT103 . parse ( fin ); Where the fin parameter can be a String or InputStream with the message in its FIN format, and the parsing can be called using the static parse method (as in the example) or by an MTnnn constructor. Once the object is created all its specific content can be read using getters for specific sequences and fields.","title":"Specific processing of a known message type"},{"location":"open-source/core/mt-parser/#parsing-message-with-ack","text":"There is a frequent misunderstanding of the FIN messages format when the actual message is preceded by a system ACK, and the expected behavior of Prowide Core parser when reading such messages. The following example is actually a service message for ACK, followed by the original MT940 sent: {1:F21FOOLHKH0AXXX0304009999}{4:{177:1608140809}{451:0}}{1:F01FOOLHKH0AXXX0304009999}{2:O9401609160814FOOLHKH0AXXX03040027341608141609N}{4: :20:USD940NO1 :21:123456/DEV :25:USD234567 :28C:1/1 :60F:C160418USD672, :61:160827C642,S1032 :86:ANDY :61:160827D42,S1032 :86:BANK CHARGES :62F:C160418USD1872, :64:C160418USD1872, -}{5:{CHK:0FEC1E4AEC53}{TNG:}}{S:{COP:S}} If you pass the above content to the parse method, by default the parser will get the first FIN message found in the file (the ACK service message), leaving the rest of the text into the UnparsedTextList structure. This is just fine when reading plain user to user messages, but when the message is preceded by a service message as in the example, the resulting parsed object may not be the expected one. When dealing with this scenario it is the user responsibility to check whether the message is a service message or not, and proceed accordingly, depending on the particular use case and application needs. If you are trying to match and process the ACK/NAK notifications you may be interested on the service message. However, if this is the way you receive the messages from the SWIFT interface and you need the actual user message following the ACK, then you have to do something else. The following example will parse the FIN content, check for the service id, and if it is a system message it will then gather the actual MT from the unparsed content: SwiftMessage sm = SwiftMessage . parse ( fin ); if ( sm . isServiceMessage ()) { sm = SwiftMessage . parse ( sm . getUnparsedTexts (). getAsFINString ()); } At this point the sm variable will contain the actual user to user message, regardless if it was preceded by and ACK. For more information on the ACK/NAK structure see Processing ACK/NAK.","title":"Parsing message with ACK"},{"location":"open-source/core/mt-parser/#direct-usage-of-the-swiftparser","text":"Finally, the actual parser implementation class is another option to translate a raw message in its Java model object. SwiftMessage m = ( new SwiftParser ()). parse ( fin ); Direct usage of the SwiftParser class is discouraged but in may be useful on certain conditions where the lenient mode of the parser must be explicitly controlled by your application. The result of the parser is the backbone model implemented by the SwiftMessage class. So the parser will basically split the message content into the three primary elements that defines an MT message; the message itself, it's blocks, and the tag (or fields) inside each block. Reading fields like simple tuples of name and value makes the parser very efficient, while additional content parsing can be done with the message model in a following step. For the example, the following code can be use to gather some fields of the parsed message using the generic low level model: String val32a = m . getBlock4 (). getTagValue ( \"32A\" ); //get a simple value tag String [] list71 = m . getBlock4 (). getTagValues ( \"71F\" ); //get a repeated value tag The \"val32a\" String will contain the value \"050902JPY3520000,\" and \"list71\" will contains a list of String with values \"EUR12,00\" and \"EUR2,34\". The SwiftBlock4 object basically contains an ordered List of fields found content body of the SWIFT message and provides several API to manipulate and get the tags individually or by sub blocks. At this API level the message body can be think of as a text string, where instead of characters we found message fields and we can get for example all Tags before a given one, Tags between boundaries, etc.. This API is the base foundation of the high level Sequences API.","title":"Direct usage of the SwiftParser"},{"location":"open-source/core/mt-rje/","text":"RJE Reader/Writer Reader and Writer for FIN MT bulk messages files in RJE and PPC formats RJE Reader/Writer The RJE, remote job entry, file format is a text file containing multiple FIN messages separated by the '$' symbol. The RJEReader and RJEWriter are used to read and write bulk files containing multiple FIN MT messages in RJE format with ease. The RJEReader can be used as an iterator to read the bulk file and access each of the individual messages. The reader can be initialized with a File , Stream or String and it implements the Iterable and Iterator Java interfaces to loop the found messages with ease. The messages can be retrieve in the plain FIN MT format and also parsed into MT objects. The RJEWriter can take a list of FIN MT message objects and create as output the RJE file. Messages are converted into its FIN representation and written into the output file with proper delimiters and length. The writer can be used in two different ways: Writing messages directly into given Writer object, using the static write call method. Instantiating the writer for a particular File or stream, calling the write methods and closing the writer when all messages has been written PPC Reader/Writer The DOS-PCC is a legacy FIN MT file format. The files can contain multiple messages, as in RJE, but in a more complex structure with specific binary separators and fixed length constraints. The PPCReader and PPCWriter are used to read and write bulk files containing multiple FIN MT messages in PPC format. The API is analogous to the one provided to read and write RJE files. Related API documentation can be found online at RJEReader, RJEWriter","title":"RJE Reader/Writer"},{"location":"open-source/core/mt-rje/#rje-readerwriter","text":"Reader and Writer for FIN MT bulk messages files in RJE and PPC formats","title":"RJE Reader/Writer"},{"location":"open-source/core/mt-rje/#rje-readerwriter_1","text":"The RJE, remote job entry, file format is a text file containing multiple FIN messages separated by the '$' symbol. The RJEReader and RJEWriter are used to read and write bulk files containing multiple FIN MT messages in RJE format with ease. The RJEReader can be used as an iterator to read the bulk file and access each of the individual messages. The reader can be initialized with a File , Stream or String and it implements the Iterable and Iterator Java interfaces to loop the found messages with ease. The messages can be retrieve in the plain FIN MT format and also parsed into MT objects. The RJEWriter can take a list of FIN MT message objects and create as output the RJE file. Messages are converted into its FIN representation and written into the output file with proper delimiters and length. The writer can be used in two different ways: Writing messages directly into given Writer object, using the static write call method. Instantiating the writer for a particular File or stream, calling the write methods and closing the writer when all messages has been written","title":"RJE Reader/Writer"},{"location":"open-source/core/mt-rje/#ppc-readerwriter","text":"The DOS-PCC is a legacy FIN MT file format. The files can contain multiple messages, as in RJE, but in a more complex structure with specific binary separators and fixed length constraints. The PPCReader and PPCWriter are used to read and write bulk files containing multiple FIN MT messages in PPC format. The API is analogous to the one provided to read and write RJE files. Related API documentation can be found online at RJEReader, RJEWriter","title":"PPC Reader/Writer"},{"location":"open-source/core/mt-xml/","text":"MT-XML Conversion Back and forth conversion between MT messages and proprietary XML For MT to MX (ISO 20022) standard translations please check the Prowide Integrator MT-MX Translations module. To facilitate integration with other platforms and systems, MT format can be converted to XML. This XML format is proprietary and not part of the SWIFT standard, and basically consists of a linear translation of the hierarchical structure of blocks and fields of an MT swift message to XML. The main entry point for this feature is the AbstractMT class (actually any of its subclasses, for example MT103 ) where a simple call to the xml() method will return the message content in XML. The following example illustrates the XML format for the message headers: F 01 BICFOOYYAXXX 8683 497519 103 1535 051028 ESPBESMMAXXX 5423 752247 051028 1535 N ... A similar serialization is performed for user and trailer blocks. For the message text block (block 4) two different XML formats are supported, each related to a model layer. The simpler one serializes fields as simple name-value tuples, and the enriched one serializes each field component in individual XML tags. For example a Field13C instance in the enriched version will be splitted as: 13C RNCTIME 1534 + 0000 While in the compressed format this will be just: 13C RNCTIME1534+0000 The xml() method mentioned will return the enriched version. Additional XML related features are contained in the ConversionService class. The analogous translation from this XML into a SWIFT message is provided there, as well the serialization into the comprised XML format. The parser implementation can seamlessly read both plain and enriched formats.","title":"MT-XML Conversion"},{"location":"open-source/core/mt-xml/#mt-xml-conversion","text":"Back and forth conversion between MT messages and proprietary XML For MT to MX (ISO 20022) standard translations please check the Prowide Integrator MT-MX Translations module. To facilitate integration with other platforms and systems, MT format can be converted to XML. This XML format is proprietary and not part of the SWIFT standard, and basically consists of a linear translation of the hierarchical structure of blocks and fields of an MT swift message to XML. The main entry point for this feature is the AbstractMT class (actually any of its subclasses, for example MT103 ) where a simple call to the xml() method will return the message content in XML. The following example illustrates the XML format for the message headers: F 01 BICFOOYYAXXX 8683 497519 103 1535 051028 ESPBESMMAXXX 5423 752247 051028 1535 N ... A similar serialization is performed for user and trailer blocks. For the message text block (block 4) two different XML formats are supported, each related to a model layer. The simpler one serializes fields as simple name-value tuples, and the enriched one serializes each field component in individual XML tags. For example a Field13C instance in the enriched version will be splitted as: 13C RNCTIME 1534 + 0000 While in the compressed format this will be just: 13C RNCTIME1534+0000 The xml() method mentioned will return the enriched version. Additional XML related features are contained in the ConversionService class. The analogous translation from this XML into a SWIFT message is provided there, as well the serialization into the comprised XML format. The parser implementation can seamlessly read both plain and enriched formats.","title":"MT-XML Conversion"},{"location":"open-source/core/safexmlutils/","text":"SafeXmlUtils SafeXmlUtils is a class used in our library, in projects like iso20022 and Integrator. This class provides mechanisms for creating secure XML parsers and transformers, focusing on mitigating XXE (XML External Entity) attacks. The features of SafeXmlUtils are dependent on the implementation of XML APIs and have known issues with various versions of Xerces and Xalan. If an error occurs due to a feature not present in the environment, you can examine the XML-related dependencies and replace those that do not support the necessary feature. Configuration for Ignoring Unsupported Features In situations where dependencies cannot be modified to support a required XML feature, SafeXmlUtils allows for the bypassing of unsupported features by adding a property file to the classpath. Configuration Steps: Property File: Create a file named pw-swift-core.properties and place it in the classpath of your project. Properties Definition: Define the property safeXmlUtils.ignore in this file. Assign to this property a comma-separated list of XML features that should be ignored by SafeXmlUtils . For example: safeXmlUtils.ignore=http://xml.org/sax/features/external-general-entities,http://apache.org/xml/features/disallow-doctype-decl By listing features in this property, SafeXmlUtils will skip them, thereby preventing exceptions related to these features not being available in the runtime environment. Implementation Details SafeXmlUtils includes several methods tailored to create various types of XML parsers and transformers with safety configurations. These methods apply or bypass specific XML features based on the project\u2019s environment and needs. Key methods include: documentBuilder(boolean namespaceAware): Configures a DocumentBuilder with safety features. reader(boolean namespaceAware, Schema schema): Creates a SAX parser with customized features. inputFactory(): Sets up a StAX parser with specific security settings. transformer(): Provides a Transformer with restricted access to external DTD and Stylesheets. schemaFactory(): Configures a SchemaFactory with limited external DTD access. validator(Schema schema): Creates a Validator with controlled access to external DTD and Schema. Each of these methods handles specific XML features like \"http://xml.org/sax/features/external-general-entities\", \"http://apache.org/xml/features/disallow-doctype-decl\", and others, ensuring that only secure and supported XML processing features are utilized.","title":"SafeXmlUtils"},{"location":"open-source/core/safexmlutils/#safexmlutils","text":"SafeXmlUtils is a class used in our library, in projects like iso20022 and Integrator. This class provides mechanisms for creating secure XML parsers and transformers, focusing on mitigating XXE (XML External Entity) attacks. The features of SafeXmlUtils are dependent on the implementation of XML APIs and have known issues with various versions of Xerces and Xalan. If an error occurs due to a feature not present in the environment, you can examine the XML-related dependencies and replace those that do not support the necessary feature.","title":"SafeXmlUtils"},{"location":"open-source/core/safexmlutils/#configuration-for-ignoring-unsupported-features","text":"In situations where dependencies cannot be modified to support a required XML feature, SafeXmlUtils allows for the bypassing of unsupported features by adding a property file to the classpath. Configuration Steps: Property File: Create a file named pw-swift-core.properties and place it in the classpath of your project. Properties Definition: Define the property safeXmlUtils.ignore in this file. Assign to this property a comma-separated list of XML features that should be ignored by SafeXmlUtils . For example: safeXmlUtils.ignore=http://xml.org/sax/features/external-general-entities,http://apache.org/xml/features/disallow-doctype-decl By listing features in this property, SafeXmlUtils will skip them, thereby preventing exceptions related to these features not being available in the runtime environment.","title":"Configuration for Ignoring Unsupported Features"},{"location":"open-source/core/safexmlutils/#implementation-details","text":"SafeXmlUtils includes several methods tailored to create various types of XML parsers and transformers with safety configurations. These methods apply or bypass specific XML features based on the project\u2019s environment and needs. Key methods include: documentBuilder(boolean namespaceAware): Configures a DocumentBuilder with safety features. reader(boolean namespaceAware, Schema schema): Creates a SAX parser with customized features. inputFactory(): Sets up a StAX parser with specific security settings. transformer(): Provides a Transformer with restricted access to external DTD and Stylesheets. schemaFactory(): Configures a SchemaFactory with limited external DTD access. validator(Schema schema): Creates a Validator with controlled access to external DTD and Schema. Each of these methods handles specific XML features like \"http://xml.org/sax/features/external-general-entities\", \"http://apache.org/xml/features/disallow-doctype-decl\", and others, ensuring that only secure and supported XML processing features are utilized.","title":"Implementation Details"},{"location":"open-source/iso20022/","text":"Prowide ISO20022 Overview Prowide ISO 20022 implements the foundation classes to handle ISO 2022 (MX) messages in Java. The library provides a comprehensive model for all ISO 20022 message categories and versions. The API features include parsing messages from XML format to Java, serializing Java model objects into the XML format and the conversion between the model and JSON. Quick API reference The tables below synthesizes, by pseudocode, the entry point for common MX read/write use case scenarios. The use case is usually determined by whether you are creating a new SWIFT message or reading an existing SWIFT message. And in the case of reading, different API exists depending on whether you are processing messages generically, or if you are reading specific known type. Use Case API Parse a known MX message into a specific message model new MxPacs00800109 ( String / InputStream xml ) MxPacs00800109 . parse ( String xml ) Read specific MX message content MxPacs00800109 + getters Parse unknown MX message AbstractMX . parse ( String xml ) Specialize generic MX message new MxPacs00800109 ( MxSwiftMessage ) ( MxPacs00800109 ) AbstractMX Load and persist an unknown MX message new MxSwiftMessage ( String / InputStream xml ) MxSwiftMessage . parse ( String / InputStream xml ) Build a new MX message new MxPacs00800109 () + specific setters Write a new MX message to swift string MxPacs00800109 + message () -> xml Write a new MX message to swift file or stream MxPacs00800109 + write ( OutputStream xml ) Javadoc Online javadoc Prowide ISO 20022 Javadoc","title":"Prowide ISO20022"},{"location":"open-source/iso20022/#prowide-iso20022","text":"","title":"Prowide ISO20022"},{"location":"open-source/iso20022/#overview","text":"Prowide ISO 20022 implements the foundation classes to handle ISO 2022 (MX) messages in Java. The library provides a comprehensive model for all ISO 20022 message categories and versions. The API features include parsing messages from XML format to Java, serializing Java model objects into the XML format and the conversion between the model and JSON.","title":"Overview"},{"location":"open-source/iso20022/#quick-api-reference","text":"The tables below synthesizes, by pseudocode, the entry point for common MX read/write use case scenarios. The use case is usually determined by whether you are creating a new SWIFT message or reading an existing SWIFT message. And in the case of reading, different API exists depending on whether you are processing messages generically, or if you are reading specific known type. Use Case API Parse a known MX message into a specific message model new MxPacs00800109 ( String / InputStream xml ) MxPacs00800109 . parse ( String xml ) Read specific MX message content MxPacs00800109 + getters Parse unknown MX message AbstractMX . parse ( String xml ) Specialize generic MX message new MxPacs00800109 ( MxSwiftMessage ) ( MxPacs00800109 ) AbstractMX Load and persist an unknown MX message new MxSwiftMessage ( String / InputStream xml ) MxSwiftMessage . parse ( String / InputStream xml ) Build a new MX message new MxPacs00800109 () + specific setters Write a new MX message to swift string MxPacs00800109 + message () -> xml Write a new MX message to swift file or stream MxPacs00800109 + write ( OutputStream xml )","title":"Quick API reference"},{"location":"open-source/iso20022/#javadoc","text":"Online javadoc Prowide ISO 20022 Javadoc","title":"Javadoc"},{"location":"open-source/iso20022/iso20022-adapters/","text":"DateTime adapters The standard defines different types for representing date and time elements. For some of them multiple options are compliant for their string representation in the XML. To accommodate the flexibility and variability in representing date and time elements as per ISO standards and specific usage guidelines, the library employs type adapters. The Java model is annotated with generic type adapters, allowing multiple implementation options for marshalling and unmarshalling the different date and time values. Default Adapters The default implementations of these type adapters are designed to handle the most common cases. These default adapters ensure that date and time elements are serialized and deserialized in a manner that aligns with ISO conventions. For example, the default implementation for IsoDateTimeAdapter ensures that date-time values are represented as local time with a UTC offset in the format YYYY-MM-DDThh:mm:ss[.sss]+/-hh:mm . Similarly, the IsoDateAdapter handles date values in the format YYY-MM-DD , and the IsoTimeAdapter manages time values in the format hh:mm:ss[.sss]+/-hh:mm . This implementation by default will replace the Zulu indicator Z with the +00:00 offset, and will also trim meaningless zeros in the fractional seconds. However, you can customize this behavior by providing your own adapter. Customization for Specific Use Cases While the default adapters cover a wide range of scenarios, there may be cases where you need to tailor the serialization and/or deserialization of date and time elements to meet specific requirements. In such situations, the library allows you to override or replace the default adapters with your custom implementations. By creating custom adapters, you can precisely control how date and time values are represented in XML. This customization is particularly valuable when your XML documents need to adhere to specific standards or conventions that deviate from the default representations. The TypeAdaptersConfiguration holder DTO is used to set up a collection of adapters. This configuration is then used by the MxWriteConfiguration and MxReadConfiguration to set up the adapters in the JaxbContext. There are many ways to create custom adapters by just implementing the XmlAdapter interface. The following example leverage the default adapters to create custom adapters that preserve the default behavior but add additional customization with a simple string replace to preserve the Zulu indicator Z for offset date times in UTC. public class CustomDateTimeAdapter extends OffsetDateTimeAdapter { @Override public String marshal ( OffsetDateTime offsetDateTime ) throws Exception { return StringUtils . replace ( super . marshal ( offsetDateTime ), \"+00:00\" , \"Z\" ); } } The custom implementation can then be passed to the MxWriteConfiguration to override the default adapter. MxWriteConfiguration config = new MxWriteConfiguration (); config . adapters . dateTimeAdapter = new IsoDateTimeAdapter ( new CustomDateTimeAdapter ()); xml = mx . message ( config );","title":"DateTime adapters"},{"location":"open-source/iso20022/iso20022-adapters/#datetime-adapters","text":"The standard defines different types for representing date and time elements. For some of them multiple options are compliant for their string representation in the XML. To accommodate the flexibility and variability in representing date and time elements as per ISO standards and specific usage guidelines, the library employs type adapters. The Java model is annotated with generic type adapters, allowing multiple implementation options for marshalling and unmarshalling the different date and time values.","title":"DateTime adapters"},{"location":"open-source/iso20022/iso20022-adapters/#default-adapters","text":"The default implementations of these type adapters are designed to handle the most common cases. These default adapters ensure that date and time elements are serialized and deserialized in a manner that aligns with ISO conventions. For example, the default implementation for IsoDateTimeAdapter ensures that date-time values are represented as local time with a UTC offset in the format YYYY-MM-DDThh:mm:ss[.sss]+/-hh:mm . Similarly, the IsoDateAdapter handles date values in the format YYY-MM-DD , and the IsoTimeAdapter manages time values in the format hh:mm:ss[.sss]+/-hh:mm . This implementation by default will replace the Zulu indicator Z with the +00:00 offset, and will also trim meaningless zeros in the fractional seconds. However, you can customize this behavior by providing your own adapter.","title":"Default Adapters"},{"location":"open-source/iso20022/iso20022-adapters/#customization-for-specific-use-cases","text":"While the default adapters cover a wide range of scenarios, there may be cases where you need to tailor the serialization and/or deserialization of date and time elements to meet specific requirements. In such situations, the library allows you to override or replace the default adapters with your custom implementations. By creating custom adapters, you can precisely control how date and time values are represented in XML. This customization is particularly valuable when your XML documents need to adhere to specific standards or conventions that deviate from the default representations. The TypeAdaptersConfiguration holder DTO is used to set up a collection of adapters. This configuration is then used by the MxWriteConfiguration and MxReadConfiguration to set up the adapters in the JaxbContext. There are many ways to create custom adapters by just implementing the XmlAdapter interface. The following example leverage the default adapters to create custom adapters that preserve the default behavior but add additional customization with a simple string replace to preserve the Zulu indicator Z for offset date times in UTC. public class CustomDateTimeAdapter extends OffsetDateTimeAdapter { @Override public String marshal ( OffsetDateTime offsetDateTime ) throws Exception { return StringUtils . replace ( super . marshal ( offsetDateTime ), \"+00:00\" , \"Z\" ); } } The custom implementation can then be passed to the MxWriteConfiguration to override the default adapter. MxWriteConfiguration config = new MxWriteConfiguration (); config . adapters . dateTimeAdapter = new IsoDateTimeAdapter ( new CustomDateTimeAdapter ()); xml = mx . message ( config );","title":"Customization for Specific Use Cases"},{"location":"open-source/iso20022/iso20022-build/","text":"Builder API (Java to XML) The MX messages builder API is provided to create new MX messages from Java, and serialize its content into XML. The creation of a new message basically consists of creating an object that represents the message, and the subsequent addition of inner elements. The order is not important because the model is already constrained to the correspondent tree structure of the XML. Although this does not mean the builder API will verify validation constraints of the message but the model will naturally allow only proper elements to be appended. This Sample code shows how to create an MX ACMT.001.001.03 message: MxAcmt00100103 mx = new MxAcmt00100103 () . setAcctOpngInstr ( new AccountOpeningInstructionV03 () . setAcctPties ( new AccountParties6 () . setAdmstr ( new InvestmentAccountOwnershipInformation6 () . setClntId ( \"clntId\" )) . setPrncplAcctPty ( new AccountParties1Choice () . setNmnee ( new InvestmentAccountOwnershipInformation6 () . setPty ( new Party14Choice (). setOrg ( new Organisation13 (). setNm ( \"orgName\" )) ) ) ) ) ); String mxXml = mx . message (); System . out . println ( mxXml ); To simplify the resulting builder code, all setters in the business dictionary allow chained method calls. Also inner element class names match the exact names as defined in the MX standard documentation. The resulting XML is: orgName clntId Customization The builder API is designed to be flexible and allow customization of the resulting XML. This example shows how to customize the previous result. MxAcmt00100103 mx = new MxAcmt00100103 () . setAcctOpngInstr ( new AccountOpeningInstructionV03 () . setAcctPties ( new AccountParties6 () . setAdmstr ( new InvestmentAccountOwnershipInformation6 () . setClntId ( \"clntId\" )) . setPrncplAcctPty ( new AccountParties1Choice () . setNmnee ( new InvestmentAccountOwnershipInformation6 () . setPty ( new Party14Choice (). setOrg ( new Organisation13 (). setNm ( \"orgName\" )) ) ) ) ) ); MxWriteConfiguration conf = new MxWriteConfiguration (); conf . documentPrefix = null ; // remove the default Doc: prefix conf . indent = \" \" ; // use 1 space for indentation conf . includeXMLDeclaration = false ; // remove the default XML declaration String mxXml = mx . message ( conf ); System . out . println ( mxXml ); This will result in the following XML: orgName clntId Refer to the MxWriteConfiguration javadoc to review all the available customization options.","title":"MX Build (Java to XML)"},{"location":"open-source/iso20022/iso20022-build/#builder-api-java-to-xml","text":"The MX messages builder API is provided to create new MX messages from Java, and serialize its content into XML. The creation of a new message basically consists of creating an object that represents the message, and the subsequent addition of inner elements. The order is not important because the model is already constrained to the correspondent tree structure of the XML. Although this does not mean the builder API will verify validation constraints of the message but the model will naturally allow only proper elements to be appended. This Sample code shows how to create an MX ACMT.001.001.03 message: MxAcmt00100103 mx = new MxAcmt00100103 () . setAcctOpngInstr ( new AccountOpeningInstructionV03 () . setAcctPties ( new AccountParties6 () . setAdmstr ( new InvestmentAccountOwnershipInformation6 () . setClntId ( \"clntId\" )) . setPrncplAcctPty ( new AccountParties1Choice () . setNmnee ( new InvestmentAccountOwnershipInformation6 () . setPty ( new Party14Choice (). setOrg ( new Organisation13 (). setNm ( \"orgName\" )) ) ) ) ) ); String mxXml = mx . message (); System . out . println ( mxXml ); To simplify the resulting builder code, all setters in the business dictionary allow chained method calls. Also inner element class names match the exact names as defined in the MX standard documentation. The resulting XML is: orgName clntId ","title":"Builder API (Java to XML)"},{"location":"open-source/iso20022/iso20022-build/#customization","text":"The builder API is designed to be flexible and allow customization of the resulting XML. This example shows how to customize the previous result. MxAcmt00100103 mx = new MxAcmt00100103 () . setAcctOpngInstr ( new AccountOpeningInstructionV03 () . setAcctPties ( new AccountParties6 () . setAdmstr ( new InvestmentAccountOwnershipInformation6 () . setClntId ( \"clntId\" )) . setPrncplAcctPty ( new AccountParties1Choice () . setNmnee ( new InvestmentAccountOwnershipInformation6 () . setPty ( new Party14Choice (). setOrg ( new Organisation13 (). setNm ( \"orgName\" )) ) ) ) ) ); MxWriteConfiguration conf = new MxWriteConfiguration (); conf . documentPrefix = null ; // remove the default Doc: prefix conf . indent = \" \" ; // use 1 space for indentation conf . includeXMLDeclaration = false ; // remove the default XML declaration String mxXml = mx . message ( conf ); System . out . println ( mxXml ); This will result in the following XML: orgName clntId Refer to the MxWriteConfiguration javadoc to review all the available customization options.","title":"Customization"},{"location":"open-source/iso20022/iso20022-model/","text":"Java model for MX messages The message model for MX messages is a set of Java classes representing the structure and content of a SWIFT MX (ISO 20022) message. Being the MX standard based on XML, the Java model is an abstraction of the different XMLs defined by the standard with Java classes to represent each possible MX message. A business objects dictionary is part of the MX message model, representing any possible content element of an MX message. The scope of the message model for MX is the payload composed by the Application Header and the Document (with the actual body of the message). The overhead xml wrappers with transport information are not part of the model and if present, it will be ignored by the parser. In general the model was designed to mirror as much as possible the Prowide Core API for MT messages. In this sense there are two independent layers or levels of abstraction. The lower one being a generic tree representation of the XML with a node per XML tag. And a more business oriented layer with an implementation of each possible MX message type and business content. Unless explicitly remarked this document refers to the business model. Basically all MX model code is concentrated in two main packages: com.prowidesoftware.swift.model.mx for all classes that are a main entry point to MX messages, that is, the root class of the message. Reading and Writing a MX message starts by picking a class from this package which represents the message that will be used. com.prowidesoftware.swift.model.mx.dic supporting classes and reused objects for MX classes. These classes are used inside MX root classes. And for MX system messages another two packages has been added: * com.prowidesoftware.swift.model.mx.sys for the MX system message main classes. * com.prowidesoftware.swift.model.mx.sys.dic for the system messages data dictionary. Our class model for MX is generated from the standard XSD schemas. However it is not the default output of a jaxb compilation. The process uses several custom plugins in order to produce a special API in the Mx classes to parse XMLs sources with ease. And we also have a special process in the generation to merge the complex types implementation classes into a consolidated single dic package, this is important to avoid producing thousands or repetitive classes (notice the standard schemas does not include any common library for the types so a default jaxb generation per namespace is not feasible when targeting the complete set of message categories and versions). Class naming MX messages have this naming structure : Message bbbb.fff.vvv.nn maps to class MxBbbfffvvvnn where: bbbb: four characters indicating the business process of the message, all available business process can be found in the enum com.prowidesoftware.swift.model.MxBusinessProcess fff: 3 digits indicating the message functionality vvv: 3 digits indicating the message variant nn: 2 digits indicating the message version For example: MX message trea.001.001.02 is mapped to class MxTrea00100102 MX message camt.003.001.02 is mapped to class MxCamt00300102 The inner elements of the messages are composed by instances of the business dictionary where the model provides a class for each possible type defined in the MX standard for example: AccountParties6 , InvestmentAccountOwnershipInformation6 , AccountOpeningType1Code , etc... Supported MX Versions The library accumulates all historic versions for all message categories. And it is yearly updated with new versions of messages added per SRU.","title":"MX Model"},{"location":"open-source/iso20022/iso20022-model/#java-model-for-mx-messages","text":"The message model for MX messages is a set of Java classes representing the structure and content of a SWIFT MX (ISO 20022) message. Being the MX standard based on XML, the Java model is an abstraction of the different XMLs defined by the standard with Java classes to represent each possible MX message. A business objects dictionary is part of the MX message model, representing any possible content element of an MX message. The scope of the message model for MX is the payload composed by the Application Header and the Document (with the actual body of the message). The overhead xml wrappers with transport information are not part of the model and if present, it will be ignored by the parser. In general the model was designed to mirror as much as possible the Prowide Core API for MT messages. In this sense there are two independent layers or levels of abstraction. The lower one being a generic tree representation of the XML with a node per XML tag. And a more business oriented layer with an implementation of each possible MX message type and business content. Unless explicitly remarked this document refers to the business model. Basically all MX model code is concentrated in two main packages: com.prowidesoftware.swift.model.mx for all classes that are a main entry point to MX messages, that is, the root class of the message. Reading and Writing a MX message starts by picking a class from this package which represents the message that will be used. com.prowidesoftware.swift.model.mx.dic supporting classes and reused objects for MX classes. These classes are used inside MX root classes. And for MX system messages another two packages has been added: * com.prowidesoftware.swift.model.mx.sys for the MX system message main classes. * com.prowidesoftware.swift.model.mx.sys.dic for the system messages data dictionary. Our class model for MX is generated from the standard XSD schemas. However it is not the default output of a jaxb compilation. The process uses several custom plugins in order to produce a special API in the Mx classes to parse XMLs sources with ease. And we also have a special process in the generation to merge the complex types implementation classes into a consolidated single dic package, this is important to avoid producing thousands or repetitive classes (notice the standard schemas does not include any common library for the types so a default jaxb generation per namespace is not feasible when targeting the complete set of message categories and versions).","title":"Java model for MX messages"},{"location":"open-source/iso20022/iso20022-model/#class-naming","text":"MX messages have this naming structure : Message bbbb.fff.vvv.nn maps to class MxBbbfffvvvnn where: bbbb: four characters indicating the business process of the message, all available business process can be found in the enum com.prowidesoftware.swift.model.MxBusinessProcess fff: 3 digits indicating the message functionality vvv: 3 digits indicating the message variant nn: 2 digits indicating the message version For example: MX message trea.001.001.02 is mapped to class MxTrea00100102 MX message camt.003.001.02 is mapped to class MxCamt00300102 The inner elements of the messages are composed by instances of the business dictionary where the model provides a class for each possible type defined in the MX standard for example: AccountParties6 , InvestmentAccountOwnershipInformation6 , AccountOpeningType1Code , etc...","title":"Class naming"},{"location":"open-source/iso20022/iso20022-model/#supported-mx-versions","text":"The library accumulates all historic versions for all message categories. And it is yearly updated with new versions of messages added per SRU.","title":"Supported MX Versions"},{"location":"open-source/iso20022/iso20022-parser/","text":"Parser (XML to Java) The parser's main usage is to access the business content of the MX message from a business oriented Java model instead of dealing with the underlying xml structure. Therefore the parser allows the conversion of an XML message into a Java model that represents the message and provides specific getters to retrieve the elements read from the XML. It is important to remark that the parser will only accept well structured XML files (all tags properly closed) and it will only read the portions according to the corresponding MX message, meaning any unexpected xml content will be dropped. Also to remark, the parser does not perform any content validation regarding tags repetitions, charsets, qualifiers or semantics. There are several entry points for the MX parsing feature depending on the use case: Parsing a specific known message type When the specific MX message type is known a specific MX message object can be created from String or InputStream , as follows: MxCamt00300104 mx = MxCamt00300104 . parse ( xml ); The above code is also available in constructors. This is the more efficient way to read the message if the specific version is known in advance. The parser will read into the output object both the Document and the AppHdr (if present). The implementation is based on the JAXB2 unmarshaller. Parsing an unknown message type When the specific category and version of the message to read is unknown you can use the base calss of the message hierarchy to do the parsing, then cast if necessary to extract specific data. AbstractMX mx = AbstractMX . parse ( xml ); if ( \"camt.048.001.03\" . equals ( mx . getMxId (). id ())) { MxCamt04800103 camt = ( MxCamt04800103 ) mx ; System . out . println ( \"Message id: \" + camt . getModfyRsvatn (). getMsgHdr (). getMsgId ()); } The MX message model classes, such as MxPacs00800108 , that extend the AbstractMX are designed to parse and create specific message types . The AbstractMX is simply the parent class of the model hierarchy, and it is abstract . Thus, it is not intended to create messages from scratch, and in fact, you cannot create a new empty instance of it. It is only created in parse method calls . If you parse an XML with a specific model class, any element in the XML that does not belong to the specific schema is automatically dropped. This is because the model classes are designed for specific types. This means that you cannot parse an element such as /Document/GrpHdr/InstrctdAgt into a model if that model does not define such a path or element. When you parse an XML with the AbstractMX , the API internally autodetects the message type from the namespace and parses the XML with a specific model class. The AbstractMX is just a way to process messages without autodetecting or creating specific instances yourself. Parsing many unknown message types When you need to parse many unknown message types and just store the content in a database or read generic metadata that is common to all messages (such as the message type, sender, receiver and reference) you can use the generic MxSwiftMessage class for parsing: MxSwiftMessage msg = MxSwftMessage . parse ( xml ); The class implements several constructors and static methods to create the instance from different sources; String, InputStream, AbstractMX, etc... Only the header will be parsed in order into structured attributes, while the plain input XML will be stored as a String. This model object is also suited for persistence because it can be stored in a simple common table for all message types. If you need to read specific attributes not available in the generic metadata, you can use the specific classes such as MxSese02300201 to read specific data. Reading specific attributes from many message types Finally, you have yet another option if you need to read many attributes (not available in the MtSwiftMessage metadata) from many known or unknown message types. This is an alternative, low-level approach where the model objects are not used, and the underlying XML structure is directly traversed. MxNode n = MxNode . parse ( document ); String amount = n . singlePathValue ( \"/Document/etc\" ); This MxNode is a generic, lightweight, and fast XML tree representation that can be used to traverse or build any XML. You can think of it as a simplified DOM. It lacks several features of a full DOM but is much faster and lighter. The MxNode model and all its methods are part of a generic XML API. Its purpose is to provide an easy-to-use, generic XML handling API to avoid using Java's native APIs such as DOM, SAX, Stax, etc. The MxNode model is not specific to ISO 20022. You can use it to parse or create any XML structure. In particular, you can use the MxNode model to generically parse or create MX messages. However, the model itself does not impose any restrictions on what you can do. Performance: JaxbContext cache The parse methods available in the specific classes such as MxCamt00300104 or in the AbstractMX class uses JAXB unmarshaller. By default implementation will create a new JAXBContext for each parse invocation. While this is fine when you need to parse a low number of messages it might become a considerable performance issue for larger volumes. To deal with it the implementation supports injecting a cache for the JaxbContext . This is managed by a singleton class JaxbContextLoader like this: JaxbContextLoader . INSTANCE . setCacheImpl ( new JaxbContextCacheImpl ()); When a cache implementation is set in the loader, the created JAXBContext will be cached and re-used between parse and write calls. Meaning if you parse a sese.023.002.01, the first time the context will be initialized, but afterwards each time you parse another sese.023.002.01 the available context will be reused. The JaxbContextCacheImpl is a default out-of-the-box cache implementation based on a simple ConcurrentHashMap , with no eviction. This implementation is aimed to avoid additional third party dependencies. Meaning it can be used right away and it is a fair solution for the performance issue. However, since it has no eviction, if you process a wide variety of message types the cache will grow, consuming a lot of memory. For a more robust solution You can easily implement your own cache with Guava, Ehcache, Caffeine or any other cache library. For instance if your application already has the Guava library, you can write a Guava based cache like this: public class GuavaJaxbContextCache implements JaxbContextCache { private final Cache < Class , JAXBContext > cache = CacheBuilder . newBuilder (). maximumSize ( 100 ). build (); public JAXBContext get ( final Class messageClass , final Class [] classes ) throws ExecutionException { return cache . get ( messageClass , () -> JAXBContext . newInstance ( classes )); } } And then inject this implementation to the loader with: JaxbContextLoader . INSTANCE . setCacheImpl ( new GuavaJaxbContextCache ()); The Guava based example code is available at: https://github.com/prowide/prowide-iso20022-examples/","title":"MX Parser (XML to Java)"},{"location":"open-source/iso20022/iso20022-parser/#parser-xml-to-java","text":"The parser's main usage is to access the business content of the MX message from a business oriented Java model instead of dealing with the underlying xml structure. Therefore the parser allows the conversion of an XML message into a Java model that represents the message and provides specific getters to retrieve the elements read from the XML. It is important to remark that the parser will only accept well structured XML files (all tags properly closed) and it will only read the portions according to the corresponding MX message, meaning any unexpected xml content will be dropped. Also to remark, the parser does not perform any content validation regarding tags repetitions, charsets, qualifiers or semantics. There are several entry points for the MX parsing feature depending on the use case:","title":"Parser (XML to Java)"},{"location":"open-source/iso20022/iso20022-parser/#parsing-a-specific-known-message-type","text":"When the specific MX message type is known a specific MX message object can be created from String or InputStream , as follows: MxCamt00300104 mx = MxCamt00300104 . parse ( xml ); The above code is also available in constructors. This is the more efficient way to read the message if the specific version is known in advance. The parser will read into the output object both the Document and the AppHdr (if present). The implementation is based on the JAXB2 unmarshaller.","title":"Parsing a specific known message type"},{"location":"open-source/iso20022/iso20022-parser/#parsing-an-unknown-message-type","text":"When the specific category and version of the message to read is unknown you can use the base calss of the message hierarchy to do the parsing, then cast if necessary to extract specific data. AbstractMX mx = AbstractMX . parse ( xml ); if ( \"camt.048.001.03\" . equals ( mx . getMxId (). id ())) { MxCamt04800103 camt = ( MxCamt04800103 ) mx ; System . out . println ( \"Message id: \" + camt . getModfyRsvatn (). getMsgHdr (). getMsgId ()); } The MX message model classes, such as MxPacs00800108 , that extend the AbstractMX are designed to parse and create specific message types . The AbstractMX is simply the parent class of the model hierarchy, and it is abstract . Thus, it is not intended to create messages from scratch, and in fact, you cannot create a new empty instance of it. It is only created in parse method calls . If you parse an XML with a specific model class, any element in the XML that does not belong to the specific schema is automatically dropped. This is because the model classes are designed for specific types. This means that you cannot parse an element such as /Document/GrpHdr/InstrctdAgt into a model if that model does not define such a path or element. When you parse an XML with the AbstractMX , the API internally autodetects the message type from the namespace and parses the XML with a specific model class. The AbstractMX is just a way to process messages without autodetecting or creating specific instances yourself.","title":"Parsing an unknown message type"},{"location":"open-source/iso20022/iso20022-parser/#parsing-many-unknown-message-types","text":"When you need to parse many unknown message types and just store the content in a database or read generic metadata that is common to all messages (such as the message type, sender, receiver and reference) you can use the generic MxSwiftMessage class for parsing: MxSwiftMessage msg = MxSwftMessage . parse ( xml ); The class implements several constructors and static methods to create the instance from different sources; String, InputStream, AbstractMX, etc... Only the header will be parsed in order into structured attributes, while the plain input XML will be stored as a String. This model object is also suited for persistence because it can be stored in a simple common table for all message types. If you need to read specific attributes not available in the generic metadata, you can use the specific classes such as MxSese02300201 to read specific data.","title":"Parsing many unknown message types"},{"location":"open-source/iso20022/iso20022-parser/#reading-specific-attributes-from-many-message-types","text":"Finally, you have yet another option if you need to read many attributes (not available in the MtSwiftMessage metadata) from many known or unknown message types. This is an alternative, low-level approach where the model objects are not used, and the underlying XML structure is directly traversed. MxNode n = MxNode . parse ( document ); String amount = n . singlePathValue ( \"/Document/etc\" ); This MxNode is a generic, lightweight, and fast XML tree representation that can be used to traverse or build any XML. You can think of it as a simplified DOM. It lacks several features of a full DOM but is much faster and lighter. The MxNode model and all its methods are part of a generic XML API. Its purpose is to provide an easy-to-use, generic XML handling API to avoid using Java's native APIs such as DOM, SAX, Stax, etc. The MxNode model is not specific to ISO 20022. You can use it to parse or create any XML structure. In particular, you can use the MxNode model to generically parse or create MX messages. However, the model itself does not impose any restrictions on what you can do.","title":"Reading specific attributes from many message types"},{"location":"open-source/iso20022/iso20022-parser/#performance-jaxbcontext-cache","text":"The parse methods available in the specific classes such as MxCamt00300104 or in the AbstractMX class uses JAXB unmarshaller. By default implementation will create a new JAXBContext for each parse invocation. While this is fine when you need to parse a low number of messages it might become a considerable performance issue for larger volumes. To deal with it the implementation supports injecting a cache for the JaxbContext . This is managed by a singleton class JaxbContextLoader like this: JaxbContextLoader . INSTANCE . setCacheImpl ( new JaxbContextCacheImpl ()); When a cache implementation is set in the loader, the created JAXBContext will be cached and re-used between parse and write calls. Meaning if you parse a sese.023.002.01, the first time the context will be initialized, but afterwards each time you parse another sese.023.002.01 the available context will be reused. The JaxbContextCacheImpl is a default out-of-the-box cache implementation based on a simple ConcurrentHashMap , with no eviction. This implementation is aimed to avoid additional third party dependencies. Meaning it can be used right away and it is a fair solution for the performance issue. However, since it has no eviction, if you process a wide variety of message types the cache will grow, consuming a lot of memory. For a more robust solution You can easily implement your own cache with Guava, Ehcache, Caffeine or any other cache library. For instance if your application already has the Guava library, you can write a Guava based cache like this: public class GuavaJaxbContextCache implements JaxbContextCache { private final Cache < Class , JAXBContext > cache = CacheBuilder . newBuilder (). maximumSize ( 100 ). build (); public JAXBContext get ( final Class messageClass , final Class [] classes ) throws ExecutionException { return cache . get ( messageClass , () -> JAXBContext . newInstance ( classes )); } } And then inject this implementation to the loader with: JaxbContextLoader . INSTANCE . setCacheImpl ( new GuavaJaxbContextCache ()); The Guava based example code is available at: https://github.com/prowide/prowide-iso20022-examples/","title":"Performance: JaxbContext cache"},{"location":"release-notes/","text":"Release Notes This section contains the current and historic changelogs for all Prowide library artifacts within the SRU2023-9.4.x distribution branch. Notice this information is public, however, the Prowide Integrator artifacts are not open source, thus download and usage is restricted to licensed customers. Versions compatibility To keep the libraries up-to-date and compatible with the latest technologies and frameworks, we started the migration to Java 11 and Jakarta EE 10. To give all users time to migrate their systems, the existing versions will also be maintained. The following table summarizes versioning for current and upcoming releases, and the corresponding SRU and Java/Jakarta EE versions. Version SRU Java Jakarta EE 9.4.x 2023 8 Jaxb 2 10.1.x 2023 11 10 SRU stands for the SWIFT Standards Release Update . It reflects the messaging standard the libraries are compatible with. Notice the middle version is normally updated along a SRU change. Check the Versioning page for further details. As for the migration to Jakarta, overall, the migration process involves replacing the Java EE packages in your source code (javax) with their Jakarta EE counterparts (jakarta) and updating your application's dependencies to their Jakarta EE versions. The exact steps and level of effort required will depend on the specifics of your application and its dependencies. We believe that the benefits of these updates far outweigh any temporary inconvenience.","title":"Release Notes"},{"location":"release-notes/#release-notes","text":"This section contains the current and historic changelogs for all Prowide library artifacts within the SRU2023-9.4.x distribution branch. Notice this information is public, however, the Prowide Integrator artifacts are not open source, thus download and usage is restricted to licensed customers.","title":"Release Notes"},{"location":"release-notes/#versions-compatibility","text":"To keep the libraries up-to-date and compatible with the latest technologies and frameworks, we started the migration to Java 11 and Jakarta EE 10. To give all users time to migrate their systems, the existing versions will also be maintained. The following table summarizes versioning for current and upcoming releases, and the corresponding SRU and Java/Jakarta EE versions. Version SRU Java Jakarta EE 9.4.x 2023 8 Jaxb 2 10.1.x 2023 11 10 SRU stands for the SWIFT Standards Release Update . It reflects the messaging standard the libraries are compatible with. Notice the middle version is normally updated along a SRU change. Check the Versioning page for further details. As for the migration to Jakarta, overall, the migration process involves replacing the Java EE packages in your source code (javax) with their Jakarta EE counterparts (jakarta) and updating your application's dependencies to their Jakarta EE versions. The exact steps and level of effort required will depend on the specifics of your application and its dependencies. We believe that the benefits of these updates far outweigh any temporary inconvenience.","title":"Versions compatibility"},{"location":"release-notes/changelog-cbpr/","text":"Prowide Integrator CBPR+ - CHANGELOG Model extension for CBPR+ messages (Cross Border and Payments Regulation) 9.4.3 - SNAPSHOT Renamed validationKey() to businessService() in the CbprMessageType enum 9.4.2 - April 2024 Added a log when the CBPR+ message factory is used and the message sample contains a header other than BAH v2 9.4.1 - November 2023 (PW-1691) Fixed specific business service for each message type 9.4.0 - July 2023 Version aligned with Prowide Integrator 9.4.x for SRU2023 (PW-1444) Added model and parser for the CBPR+ pacs.010.001.03 Margin Collection message type 2.3.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 2.2.0 - March 2023 (PW-1300) Updated model to the CBPR+ 2023 release 2.1.9 - March 2023 (PW-1261) Enhanced the CbprMessageType.of(AppHdr) to work even if the MsgDefIdr contains a redundant variant such as pacs.008.001.08STP 2.1.8 - February 2023 Minor javadoc fixes 2.1.7 - February 2022 Prowide dependencies update 2.1.6 - December 2022 Switched to semantic versioning 2.1u5 - November 2022 Internal implementation enhancements 2.1u4 - November 2022 Updated Apache Commons Text dependency to 1.10 to fix reported CVE 2.1u3 - September 2022 Added the current SRU to the version number for consistent SRU based BOM and dependency with other Integrator artifacts 2.1u2 - April 2022 Internal schema compress to reduce jar size 2.1u1 - March 2022 Added the specific BAH v2 schema for CBPR+ along a CbprHeaderSchemaResolver util class to retrieve it (PW-863) Added support for customizable date and time adapters in the XML marshalling/unmarshalling 2.1 - January 2022 Updated implementation for the CBPR+ release 2.1 (effective in November 2022) 2.0u4 - January 2022 Added a CbprMessageFactory to create CBPR+ message objects from XML with type and variant auto detection Added CbprMessageType#of(AppHdr appHdr) to detect the type from an application header instance 2.0u3 - January 2022 Prowide Integrator SDK and Prowide Core updates 2.0u2 - December 2021 Added com.prowidesoftware.integrator.cbpr as automatic module name in the MANIFEST for JPMS support 2.0u1 - December 2021 Added a custom marshaller for date time elements to be compliant with CBPR_DateTime ('+00:00' offset instead of 'Z') 2.0 - November 2021 Updated implementation for the 17 message types in the CBPR+ release 2.0 (effective in November 2022) 1.2u2 - October 2020 Removed the CopyableTo implementation from the generated model Added a method to return the MxId and the targetNamespace in the CbprMessageType enumeration 1.2u1 - September 2020 Added phase II message types: pacs.010.001.03 and pacs.008.001.08_STP 1.2 Initial implementation for the CBPR+ releease 1.2","title":"Prowide Integrator CBPR+"},{"location":"release-notes/changelog-cbpr/#prowide-integrator-cbpr-changelog","text":"Model extension for CBPR+ messages (Cross Border and Payments Regulation)","title":"Prowide Integrator CBPR+ - CHANGELOG"},{"location":"release-notes/changelog-cbpr/#943-snapshot","text":"Renamed validationKey() to businessService() in the CbprMessageType enum","title":"9.4.3 - SNAPSHOT"},{"location":"release-notes/changelog-cbpr/#942-april-2024","text":"Added a log when the CBPR+ message factory is used and the message sample contains a header other than BAH v2","title":"9.4.2 - April 2024"},{"location":"release-notes/changelog-cbpr/#941-november-2023","text":"(PW-1691) Fixed specific business service for each message type","title":"9.4.1 - November 2023"},{"location":"release-notes/changelog-cbpr/#940-july-2023","text":"Version aligned with Prowide Integrator 9.4.x for SRU2023 (PW-1444) Added model and parser for the CBPR+ pacs.010.001.03 Margin Collection message type","title":"9.4.0 - July 2023"},{"location":"release-notes/changelog-cbpr/#230-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"2.3.0 - May 2023"},{"location":"release-notes/changelog-cbpr/#220-march-2023","text":"(PW-1300) Updated model to the CBPR+ 2023 release","title":"2.2.0 - March 2023"},{"location":"release-notes/changelog-cbpr/#219-march-2023","text":"(PW-1261) Enhanced the CbprMessageType.of(AppHdr) to work even if the MsgDefIdr contains a redundant variant such as pacs.008.001.08STP","title":"2.1.9 - March 2023"},{"location":"release-notes/changelog-cbpr/#218-february-2023","text":"Minor javadoc fixes","title":"2.1.8 - February 2023"},{"location":"release-notes/changelog-cbpr/#217-february-2022","text":"Prowide dependencies update","title":"2.1.7 - February 2022"},{"location":"release-notes/changelog-cbpr/#216-december-2022","text":"Switched to semantic versioning","title":"2.1.6 - December 2022"},{"location":"release-notes/changelog-cbpr/#21u5-november-2022","text":"Internal implementation enhancements","title":"2.1u5 - November 2022"},{"location":"release-notes/changelog-cbpr/#21u4-november-2022","text":"Updated Apache Commons Text dependency to 1.10 to fix reported CVE","title":"2.1u4 - November 2022"},{"location":"release-notes/changelog-cbpr/#21u3-september-2022","text":"Added the current SRU to the version number for consistent SRU based BOM and dependency with other Integrator artifacts","title":"2.1u3 - September 2022"},{"location":"release-notes/changelog-cbpr/#21u2-april-2022","text":"Internal schema compress to reduce jar size","title":"2.1u2 - April 2022"},{"location":"release-notes/changelog-cbpr/#21u1-march-2022","text":"Added the specific BAH v2 schema for CBPR+ along a CbprHeaderSchemaResolver util class to retrieve it (PW-863) Added support for customizable date and time adapters in the XML marshalling/unmarshalling","title":"2.1u1 - March 2022"},{"location":"release-notes/changelog-cbpr/#21-january-2022","text":"Updated implementation for the CBPR+ release 2.1 (effective in November 2022)","title":"2.1 - January 2022"},{"location":"release-notes/changelog-cbpr/#20u4-january-2022","text":"Added a CbprMessageFactory to create CBPR+ message objects from XML with type and variant auto detection Added CbprMessageType#of(AppHdr appHdr) to detect the type from an application header instance","title":"2.0u4 - January 2022"},{"location":"release-notes/changelog-cbpr/#20u3-january-2022","text":"Prowide Integrator SDK and Prowide Core updates","title":"2.0u3 - January 2022"},{"location":"release-notes/changelog-cbpr/#20u2-december-2021","text":"Added com.prowidesoftware.integrator.cbpr as automatic module name in the MANIFEST for JPMS support","title":"2.0u2 - December 2021"},{"location":"release-notes/changelog-cbpr/#20u1-december-2021","text":"Added a custom marshaller for date time elements to be compliant with CBPR_DateTime ('+00:00' offset instead of 'Z')","title":"2.0u1 - December 2021"},{"location":"release-notes/changelog-cbpr/#20-november-2021","text":"Updated implementation for the 17 message types in the CBPR+ release 2.0 (effective in November 2022)","title":"2.0 - November 2021"},{"location":"release-notes/changelog-cbpr/#12u2-october-2020","text":"Removed the CopyableTo implementation from the generated model Added a method to return the MxId and the targetNamespace in the CbprMessageType enumeration","title":"1.2u2 - October 2020"},{"location":"release-notes/changelog-cbpr/#12u1-september-2020","text":"Added phase II message types: pacs.010.001.03 and pacs.008.001.08_STP","title":"1.2u1 - September 2020"},{"location":"release-notes/changelog-cbpr/#12","text":"Initial implementation for the CBPR+ releease 1.2","title":"1.2"},{"location":"release-notes/changelog-consolidated/","text":"Consolidated releases This section contains the current and historic changelogs for all Prowide library artifacts within the SRU2023-9.4.x distribution branch. Bill of materials (BOM) This section lists the latest version for all libraries. Library Version Prowide Core SRU2023-9.4.16 Prowide ISO 20022 SRU2023-9.4.5 Prowide Integrator SDK SRU2023-9.4.25 Prowide Integrator Validation SRU2023-9.4.24 Prowide Integrator Translations SRU2023-9.4.40 Prowide Integrator MyFormat SRU2023-9.4.6 Prowide Integrator CBPR+ SRU2023-9.4.2 Prowide Integrator SEPA SRU2023-9.4.0 Prowide Integrator SIC SRU2023-9.4.1 Prowide Integrator SCORE SRU2023-9.4.7 Prowide GUI Tools 9.4.3","title":"Consolidated releases"},{"location":"release-notes/changelog-consolidated/#consolidated-releases","text":"This section contains the current and historic changelogs for all Prowide library artifacts within the SRU2023-9.4.x distribution branch.","title":"Consolidated releases"},{"location":"release-notes/changelog-consolidated/#bill-of-materials-bom","text":"This section lists the latest version for all libraries. Library Version Prowide Core SRU2023-9.4.16 Prowide ISO 20022 SRU2023-9.4.5 Prowide Integrator SDK SRU2023-9.4.25 Prowide Integrator Validation SRU2023-9.4.24 Prowide Integrator Translations SRU2023-9.4.40 Prowide Integrator MyFormat SRU2023-9.4.6 Prowide Integrator CBPR+ SRU2023-9.4.2 Prowide Integrator SEPA SRU2023-9.4.0 Prowide Integrator SIC SRU2023-9.4.1 Prowide Integrator SCORE SRU2023-9.4.7 Prowide GUI Tools 9.4.3","title":"Bill of materials (BOM)"},{"location":"release-notes/changelog-core/","text":"Prowide Core - CHANGELOG 9.4.16 - May 2024 (PW-1862) Added NarrativeFragment class for detailed line information in StructuredNarrative fragments Fixed SwiftMessage getPDE(): return empty value instead of null when codeword exists and has no value Added isPercentage() helper method to field 37K 9.4.15 - March 2024 (PW-1812) Updated the narrative resolver, format 2 (used in field 72 for example), to allow empty values as part of the narrative fragment Updated validators for BIC, country, and currency constraints to utilize keywords for i18n-compatible messages Deprecated unnecessary methods in the SafeXmlUtils class 9.4.14 - December 2023 (PW-1718) Changed the getComponentLabel(component) in Field59F to be dynamic based on the line identifiers (similar to existing API in Field50F) 9.4.13 - November 2023 (PW-1697) Fixed validation/parse pattern in field 29O (PW-1697) MT306 changes in field 30I Added DistinguishedName with Builder in order to encapsulate the BIC branch name logic 9.4.12 - November 2023 (PW-1697) Fixed validation pattern in fields 14[H,K,L,M,N,O] and 29J 9.4.11 - November 2023 (PW-1695) Fixed a stack overflow in the fields fromJson implementation when a malformed JSON input contains empty field names (PW-1688) Added missing field labels for SRU2023 changes in the pw_swift_*.properties file 9.4.10 - October 2023 (PW-1675) update to Field 31R to support also two date components as requested by SCORE messages Added 36B and 36D getters to MT543 9.4.9 - October 2023 (PW-1659) Field 24G deprecated Name and Address for Narrative 9.4.8 - October 2023 Added default methods for sender, receiver, and identifier extraction to the MessageExtractionStrategy Added JSON to the FileFormat enumeration 9.4.7 - September 2023 (PW-1478) Fixed Field 44J parse and getValue to enable proper data preservation when the field contains multiline content 9.4.6 - September 2023 Added support for an optional pw-swift-core.properties to customize the behavior of the SafeXmlUtils class 9.4.5 - August 2023 (PW-1478) Field 44J parse and getValue fix 9.4.4 - August 2023 (PW-1478) Field 44J format fixed to allow multiline 9.4.3 - July 2023 (PW-1461) Remove deprecation of field 31R model since is it used back in SRU2023 (PW-1405) Trim original String payload when creating an AbstractSwiftMessage 9.4.2 - June 2023 (GH-163) Remove unnecessary padding in sender and receiver in AbstractMT#creeate(number, sender, receiver) method (PW-1323) Fixing getValue method for pattern issue in Field44J 9.4.1 - June 2023 (PW-1323) Fixing missing pattern issue in Field44J 9.4.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 9.3.15 - May 2023 (PW-1341) Avoid log pollution with exception stacktrace in Field#formatAccount method (PW-1264) Added distinguishedName(boolean includeDefaultBranch) method to BIC in order to return default branch name 9.3.14 - March 2023 (PW-1182) Fixed MT internal Loops API, when strategy is GENERATED_FIXED_WITH_OPTIONAL_TAIL and the tail part contains repetitive fields, such as MT920 (PW-1241) Added addUnstructuredStrict method to Narrative in order to strictly wrap unstructured input 9.3.13 - March 2023 Deprecated all fields that are only used in SCORE messages and not in the general MT standard as they will eventually be removed from the library 9.3.12 - February 2023 (PW-1109) Changed Narrative Resolver to validate minimum codeword length of 1 char (GH-148) Fixed parser of Field61 amount component when number starts with the decimal comma (implicit zero in amount lower than 1) Added getComponent(String componentName) to retrieve the component based on the name instead of the number Added componentNameToNumber(String componentName) to retrieve the component number based on the component name 9.3.11 - January 2023 (PW-1152) Preserve line breaks when creating NarrativeContainer fields from JSON with legacy structure: narrative1, narrative2, etc... Fixed duplicate elements when serializing NarrativeContainer fields into JSON 9.3.10 - January 2023 (PW-1150) Added field model class for 31M (required in SCORE MT798_753) (PW-1150) Added field model class for 71E (required in SCORE MT798_755 and MT798_757) 9.3.9 - December 2022 (PW-1078) StructuredNarrative: Fixed parser to treat the optional [3!a13d] part as a unit block, both currency and amount present or missing 9.3.8 - November 2022 (GH-127) Enhanced field JSON serialization to include detailed structure when the field is a NarrativeContainer 9.3.7 - November 2022 (PW-1101) Fix field 35C labels to match the FIN xsd: Identification Of Instrument, Description Of Instrument 9.3.6 - November 2022 (PW-1086) Fixed typo in field 36D accessors (PW-1078) StructuredNarrative: Added getBankCode() methods in order to allow direct access to data (used in SCORE messages) (GH-88) Added missing constants for ISO 15022 codes MT540 and MT548 added missing getter for Field99C Added removeRepeatedBoundaries method in order to remove repeated tag boundaries 9.3.5 - October 2022 SRU2022 updates review: field 35C validation pattern changed to 9.3.4 - September 2022 Added getCADETL method for \"CADETL\" separator sequences (GH-119) MT566: Fixed repetitions of sequence USECU/FIA that is not repetitive Added sequence getters using the boundary field qualifier, for example getSequenceGENL() as equivalent to the existing getSequenceA() 9.3.3 - August 2022 (PW-1015) Added field model classes for 47E, 49D and 49F (required in SCORE MT798_774) 9.3.2 - July 2022 (PW-977) Changed the MT203 and MT210 inner structure from regular sequence to inner loop named Loop1 Added Loop1 getter API to MTs: 110, 201, 203, 210, 410, 412, 420, 422, 450, 456, 604, 605, 801, 920, 973 9.3.1 - July 2022 (PW-976) Added new MonetaryAmountContainer interface for fields having both an Amount and Currency (PW-969) Modified field 12E, 12K and 12R labels (PW-969) Added an optional narrative component to field 12R (required when the field is used in SCORE messages) (PW-898) Changed the heuristic to retrieve sequence B1 from MT300 and MT304 to be more efficient even if the message structure is invalid (PW-867) Enhanced the parsing of party fields A, B and D, to be more strict when splitting the /D/ or /C/ prefix from the account Enhanced MtId constructor with regex matching Added method namespaceURI() in the MtId class to return for example \"urn:swift:xsd:fin.103.2021\" for the MT103 9.3.0 - May 2022 SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Updated gson dependency to 2.9.0 9.2.13 - April 2022 (PW-892) Fixed AbstractMT#create when the message type number is less than 100 Added a convenient String message() method in the SwiftMessage object to get the FIN serialization of the message Fixed error in Field 94G getValue 9.2.12 - March 2022 (GH-103) fixed invalid ConstraintValidator annotation on CurrencyValidator (GH-95) patterns getters are now non-final to avoid overwriting; static constants have been deprecated RJE and PPC readers, added a constructor with explicit charset (same in swift parser from input stream) Validate.notNull -> Objects.requireNonNull Spotbugs code review 9.2.11 - January 2022 Added LineWrapper (utils) to replace Apache's WordUtils.wrap and thus the commons-text dependency Added convenient method in the envelop message MT798 to get the sub-message type as a SwiftMessage Added a copy constructor to the Tag class 9.2.10 - January 2022 (PW-815) Fixed getValue in field 12H (SCORE) where narrative is optional (GH-89) MT530: Fixed repetition of sequence C ADDINFO Updated dependency: gson:2.8.8 -> gson:2.8.9 Java 11 and 17 compatibility updates Added plugins for automatic versioning and code quality reporting 9.2.9 - December 2021 (GH-78) Fixed MT537#getSequenceBList where sequence B delimiter \"STAT\" overlaps with C3 and D1a1B1a delimiters (GH-74) Fixed parser for Field48 and similar cases to avoid trimming content when the component contains also the slash separator as part of the value (GH-62) Added com.prowidesoftware.core as automatic module name in the MANIFEST for JPMS support Fields getComponentLabel is now public, returning the specific label for each field component Fixed bug in PartyIdentifierUtils.getPartyIdentifier Fixes in field component names and optional status Fixes in field parsing Incompatible change in field 71N (changed from 7 Narrative lines to Code + 6 Narrative lines) Incompatible change for field 11T to have two lines (MT new-line DATE + TIME) Fixed Structured Narrative parsing to return an empty Narrative object with null string values 9.2.8 - November 2021 (PW-764) Added new variant values (RFDD, ISLFIN) (PW-703) Block 2 parser: lenient parser to avoid duplicate error when exception on invalid Input/Output indicator (CR-23) Enhanced getValueDisplay for fields (no decimal separator for numbers that are not amounts) 9.2.7 - October 2021 Field 98D, 98E and 98G: removed invalid get{Component4|Sign}AsCurrency and set{Component4|Sign}(Currency) as no currency applies to these fields Fields 94L and 85L: separated component 2 (Legal Entity Identifier) into two (Legal Entity Identifier Code and Legal Entity Identifier Number). Kept get/setLegalEntityIdentifier for backwards compatibility Field 94H: second component now has get{name}AsBIC and set{name}(BIC) methods Field 56B: now inherits from OptionBPartyField (to have get/setPartyIdentifier) Field 26C: separated component 5 into 5 (Denomination) and 6 (Form) for compatibility with Swift. Kept get/setDenominationForm for backwards compatibility Field 26A: now has 2 components (Number 1 and Number 2) for compatibility with Swift. get/setNumber is kept for backwards compatibility Field 23: fixed getValue and parse to properly handle missing intermediate fields Field 14S: has 4 new compatibility methods: getRateSource/setRateSource for Source and Number components and getTimeAndLocation/setTimeAndLocation for Time and Location components Field 12: component is now of expected to have a numeric type Code cleanup for Fields and Date|BIC|Amount|Currency Container Added support for BigDecimal and Long component types (instead of just Number) in several fields Fixed display text generation for fields having a date with pattern MMDD (only the month was included in the text) OptionAPartyField: added set/getPartyIdentifier (for components 1 and 2) and renamed BIC to IdentifierCode. Affects fields 42A, 51A, 52A, 53A, 54A, 55A, 56A, 57A, 58A, 81A, 82A, 83A, 84A, 85A, 86A, 87A, 88A, 89A, 91A and 96A OptionDPartyField: added set/getPartyIdentifier (for components 1 and 2). Affects fields 42D, 50D, 51D, 52D, 53D, 54D, 55D, 56D, 57D, 58D, 81D, 82D, 83D, 84D, 85D, 86D, 87D, 88D, 89D, 91D and 96D OptionBPartyField: added set/getPartyIdentifier (for components 1 and 2). Affects fields 52B, 53B, 54B, 55B, 57B, 58B, 82B, 84B, 85B, 86B, 87B and 88B Prepared Option A, B and D classes to support the PartyIdentifier interface with methods getPartyIdentifier and setPartyIdentifier Enhanced Block2 creation by enriching Block Type to \"O\" or \"I\". (PW-746) Fixed MT reference extraction for 20C in categories other than 5, and with MUR as fallback option (CR-23) Added SwiftMessage#getMOR Updated dependency: Apache Commons Lang 3.8.1 -> 3.12.0 Updated dependency: Apache Commons Text 1.6 -> 1.9 Updated dependency: Gson 2.8.2 -> 2.8.8 9.2.6 - October 2021 (GH-60) Enhanced parser for field 98C (PW-703) Enhanced SwiftParser in order to validate \"Input\" or \"Output\" Block 2 type Enhanced the MtId to automatically extract the variant from String identifiers such as \"fin.103.STP\" or \"202.COV\" 9.2.5 - September 2021 (PW-664) Parser enhancement to be lenient on LF before block identifier 9.2.4 - August 2021 MultiLineField: preserve starting component separator when getting lines with offset 9.2.3 - August 2021 Added user assigned country codes (example \"XE\") as valid codes in the IsoUtils country validation Added field classes for SCORE messages: 11T, 12[S,R], 25G, 31[J,K,T], 34[D,K,L,M,S,T,U,X,V,W], 49[J,K,L] (to be used in the proprietary payload of the MT798 envelop) MT564: Minor scheme fix, 92a TAXR and WITL can be repeated in CASHMOVE (E2) 9.2.2 - July 2021 (PW-627) fixed Narrative.builder() to compute \"//\" size in the lines wrapping (PW-581) the MultiLineField API now preserves any starting and trailing spaces in field lines MT565: fixed repetition of sequence B2 (multiple to single) MT548: Minor scheme fix, added letter option \"C\" in field \"98C:SCTS\" in sequence \"C1a1B1\" 9.2.1 - June 2021 Added \"ignore block 3\" and \"ignore priority\" options to the SwiftMessageComparator Added field classes for SCORE messages: 12[H,K,L], 20E, 25F, 29[D,F], 31R, 78B (to be used in the proprietary payload of the MT798 envelop) Enhanced parser for LogicalTerminalAddress when the parameter has 9 characters (PW-534) allowed null value for the Tag constructor 9.2.0 - May 2021 SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Fixed the getSequence API in MT classes when the sequence boundary field is repetitive, in some scenarios produced invalid results (PW-519) Field92H: Added \"Rate Status\" accessors (PW-519) Field92J: Replaced \"Narrative\" accessors by \"Rate Status\" accessors 9.1.4 - April 2021 Fixed getConditionalQualifier in fields 69C, 69D and 92H Fixed field 41D isOptional(component) method (PW-510) Fixed parser of field 90L (PW-508) Fixed validator pattern in field 98K Added MultiLineField interface implementation to fields: 45C, 45L and 49Z Removed MultiLineField interface implementation to field 77H since its value is always a single line (PW-501) Added getNarrative(deli), getNameAndAddress(deli) and similar getters in Field classes to get a concatenation of the relevant components with a specific delimiter (PW-501) Fixed the getNarrative(), getNameAndAddress() and similar getters in Field classes to do a simple join of the relevant components, without CRLF and without components value trim (PW-505) Fixed SwiftFormatUtils#decimalsInAmount(BigDecimal) NPE prevention in AbstractMT.getFields() when the parsed FIN content is invalid Added UETRUtils to generate the GPI unique end-to-end transaction reference, mandatory for several payment messages Added customizable strategies to set the MtSwiftMessage metadata fields: reference, main amount, value date, etc... Added field classes for SCORE messages: 13E, 21S, 21T, 27A, 29P, 29S, 29U, 49Z (to be used in the proprietary payload of the MT798 envelop) (PW-451) Added backward compatible implementation in setComponent and SetNarrative API of narrative container fields: 29A, 37N, 70, 71B, 71D, 72Z, 72, 73A, 73, 74, 75, 76, 77A, 77B, 77D, 77 (PW-445) Added backward compatible fromJson for narrative container fields: 29A, 37N, 45B, 46B, 49M, 49N, 70, 71B, 71D, 72Z, 72, 73A, 73, 74, 75, 76, 77A, 77B, 77D, 77J, 77 Added Direction to the SwiftBlock2Field enumeration Added more message type cases to the SwiftMessageUtils valueDate Minor fixes in MT530 model: fields B/22F and C/90[A,B] 9.1.3 - December 2020 Changed SwiftMessage#isGpi() to be true for: 103, 199, 299, 192, 196, 202COV or 205COV (mandatory outgoing GPI types) Removed the indexes from the AbstractSwiftMessage JPA mapping (can be created directly in the DB as needed) Added options in the MT message comparator to ignore the LT identifier or test flag when comparing header LT addresses Added asTestBic in BIC to create a test BIC by setting the second component of the location to zero Added API in the SwiftBlock2Output to set the MIR date and receiver date time fields from Calendar object 9.1.2 - October 2020 Fixed set of MUR when an MtSwiftMessage is created from an acknowledge (service 21 message) Changed AbstractSwiftMessage JPA mapping to EAGER load the status trail and the properties Added a new MessageDirection enum as alternative to the legacy MessageIOType 9.1.1 - September 2020 Fixed parser for fields 94L and 95L Added MurMessageComparator to match ACKs based on the MUR Changed the SwiftMessage#getMUR to retrieve field 108 from either block 3 or block 4 (system messages) Enhanced the AckMessageComparator to still match on differences in block 2 optional fields or block 4 EOL characters Minor refactor in MtSwiftMessage update from model (SwiftMessage) Added a trim to the content parsed from the RJE reader Fixed setPdm in MtSwiftMessage that was over writing the pde field Minor changes in the MtSwiftMessage to avoid log warnings when setting metadata from message model Added convenient field getters in the ServiceMessage21 (ACK/NAK) model class and made the getMtId() return \"gpa.021\" 9.1.0 - May 2020 SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Enhanced components namings in field 98[DEGH] Added rich API to parse and build narrative fields: 29A, 37N, 45B, 46B, 49M, 49N, 70, 71B, 71D, 72Z, 72, 73A, 73, 74, 75, 76, 77A, 77B, 77D, 77J, 77 Mx related classes moved to the prowide-iso20022 project (open source since October 2020) 8.0.2 - April 2019 Added IBAN validation for Seychelles Added field setters API in the SwiftBlock5 Added SwiftBlock5Field enumeration with commonly used block 5 trailer fields (CR #235) Added SafeXmlUtils to disallow XXE in all XML parsing code Fixed parser for fields 70[C,D,E,G], 94E, 95V when first line second component contains slashes Changed default root element for Mx from message to RequestPayload Fixed month day parsing in SwiftFormatUtils for leap years Added MxParser#containsLegacyHeader() to check weather the message uses the legacy SWIFT header or the ISO business header Added MtSwiftMessage constructor from AbstractMT Fixed parser to preserve trailing lines in field values, even if the lines are empty (empty trailing lines were trimmed before) (CR #203) Enhanced parser for party fields, explicit /D/ and /C/ is parsed as mark, otherwise any content following the / is parsed as account Fixed field 108 order and overwrite if exist logic in SwiftBlock3#generateMUR (CR #207) Added optional parameter in SwiftWriter and FINWriterVisitor to control whether field values should be trimmed 8.0.1 - October 2019 Added SwiftMessageUtils#currencyAmount to retrieve the main currency and amount from a message (CR #192) Fixed ConversionService#getFIN(SwiftMessage) to avoid altering the message parameter when removing empty blocks Added an optional SwiftWriter#writeMessage with ignoreEmptyBlocks parameter SwiftMessage#setUserBlocks(List) made public Removed the trim to field values in the XML to enable consistent round trip conversion between FIN and XML Explicit UTF-8 encoding was added where necessary to ensure portability Added MultiLineField implementation to 45D, 49G, 49M and 49N 8.0.0 - May 2019 JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Added common hierarchy for option J party fields 7.10.4 - May 2019 Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Added copy constructors to MT header blocks Added setDate(Calendar) to MIR object (Issue #25) Fixed padding in PPCWriter Added helper API SwiftTagListBlock#splitByTagName to get sub-blocks by field boundary Fixed IOB exception in SwiftBlock2Output#setMIR in lenient mode SwiftParser#tagStarts changed to protected to allow overwriting in custom parsers for non-compliant messages Moved getMessageType from MtSwiftMessage to parent class AbstractSwiftMessage Added getVariant and getMtId to MtSwiftMessage; added getMxId to MxSwiftMessage Added setMUR in SwiftMessage Added helper method in SwiftWriter to ensure break lines of any String has CRLF Added setSignature and getSignature to SwiftMessage and AbstractMT to set and retrieve MDG tag in S block (LAU computation available in Prowide Integrator) Added propertyValue to AbstractSwiftMessage to check if a property is set with a given value Changed IsoUtils implementation to use Currency.getAvailableCurrencies() in the initialization Deprecated AckSystemMessage in favor of ServiceMessage21 Fixed negative index bug in AbstractSwiftMessage#getPreviousStatusInfo when message has less than two statuses in the trail Fixed getLines API in Fields that in some cases was trimming the first line starting slash from the result Fixed eventual NPE produced in MxSwiftMessage#updateFromMessage() when creating MxSwiftMessage from XML document Fixed column length for \"variant\" in MxSwiftMessage persistence mapping Added a fields() method in SwiftTagListBlock to get all block Tag objects as Field objects Added API to field 50F and 59F to get structured content for the line numbers 7.10.3 - October 2018 License changed from LGPL to the more permissive Apache License 2.0 Fixed serialization of field 48 Completed SwiftMessageUtils#currencyAmount for missing MTs Fixed NPE in SwiftBlock4.removeEmptySequences with fields 15A as sequence boundary (Issue #15) MxParser.java typo analiseMessage -> analyseMessage Added getFields() to MT classes Added bean validation annotations for BIC, IBAN, ISO country and currency Enhanced the BIC internal model to allow accessor for all subfields Enhanced the BIC validation with enum to report the specific validation problem found Changed the default SwiftParser behavior to lenient, meaning by default it will not throw any IllegalArgumentException when headers size is invalid Fixed FIN writer to preserve trailing spaces in tag value Added JPA annotations to the SWIFT model intended for persistence (AbstractSwiftMessage and subclasses) Removed the old Hibernate XML mapping AbstractSwiftMessage.hbm.xml (in favor of generic JPA annotations in model) Added SwiftTagListBlock#removeSubBlocks to remove all instances of a given subblock (Issue #13) Fixed SwifttagListBlock#removeSubBlock Added JsonSerializable interface to all model classes implementing toJson() Added toJson and fromJson to MT and Field classes Added toJson and fromJson to the MtSwiftMessage and MxSwiftMessage model Added field 434 in SwiftBlock3Builder 7.10.2 - May 2018 Revamped the JSON API implementation using Gson, added missing fromJson methods 7.10.1 - April 2018 FIN writer: reverted the trim in tag values introduced in 7.8.9 7.10.0 - April 2018 SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Added API in SwiftMessage for the SWIFT gpi service: getters and setters for the service type identifier and UETR Added an automatically generated UETR when creating new MT instances for 103, 103 STP, 103 REMIT, 202, 202 COV, 205, or 205 COV Added API in SwiftMessage to set the variant (STP, REMIT, COV) New helper API for block 3 (SwiftBlock3Builder) to ensure only expected fields are added and in proper order 7.9.7 - April 2018 Dependencies: added gson 2.8.2 Added full IBAN validation including control digits and custom account numbers per country Added SwiftCharset and SwiftCharsetUtils helper API to validate SWIFT related charsets. Added SwiftTagListBlock#getFieldByQualifiers(name, qualifier, conditionalQualifier) to gather generic fields based on qualifiers content Added addTag(index, tag) and setTag(index, tag) in SwiftTagListBlock to insert new field in specific positions Added Field#is(String ...) to test component 1 of fields against a list of possible values Added non-ISO country code XK (Kosovo) to IsoUtils Added API in IsoUtils to add custom codes for countries and currencies Added read-only properties in AbstractSwiftMessage for the message creation year, month and day of moth Added support for custom split char in RJE reader/writer Fixed missing repetitive 35B in MT549 Build migrated to Gradle 7.9.6 - December 2017 Fixed conversion to XML with compressed parameter true in ConversionService 7.9.5 - December 2017 Fixed getValueDisplay in field 50F to strip the starting slash in the account number Added getLabelForLineNumber(String subfieldNumber) in Field50F to return the labels for the structured line identifiers Enhanced getComponentLabel(final int number) in Field50F to return proper dynamic labels based on line number identifiers Added getCorrespondentBIC to SwiftMessage and AbstractSwiftMessage Expanded sender/receiver in MtSwiftMessage and MxSwiftMessage from BIC8 to BIC11 in order to keep branch information in those cached attributes Added checksumBody to AbstractSwiftMessage for proprietary checksum calculated on the body only, as a complement to the existing checksum on the whole message Fixed AbstractSwiftMessage#copyTo(msg) implementation to perform hard copy of list objects (similar to a copy constructor implementation) Expanded precision in getValueDisplay for all numeric fields to preserve the decimal digits present in the original value Implemented SwiftMessage#getUUID and added getUID(Calendar, Long) Implemented SwiftMessageUtils#calculateChecksum as MD5 hash on whole FIN message content and added new checksum for the text block only 7.9.4 - November 2017 Internal code maintenance release 7.9.3 - October 2017 JRE requirement increased to Java 1.6 Added API in BIC to return the distinguished name (DN) for a BIC Added equalsIgnoreCR in Tag to compare values regardless of carriage return character being present or not in new lines Fixed MxParser#parseBusinessApplicationHeaderV01 (it was setting the FinInstnId/Nm as BIC) Removed invalid component in field 86J Fixed order of components in fields 98J and 98K Completed the component labels for all fields Changed field 22C structure into individual components for the function Enhanced fields parse/serialization to preserve any whitespace in a component 7.9.2 - August 2017 Fixed FINWriterVisitor to prevent printing 'null' tag values Deprecated custom resource properties for currency and country codes, in favor of Java nativa API in Currency and Locale Removed package-info.class from target jar to avoid class modifier issue in Java8 runtime Fixed serialization of field 50F to allow the first line without a starting forward slash 7.9.1 - June 2017 (Issue #5) Enhanced performance in SwiftParser Removed sequence API for inner loops (non sequence) in MTs 306, 320, 340, 360, 361, 362, 410, 412, 420, 422, 450, 456 7.9.0 - May 2017 SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX) (Issue #2) maven build issues (Issue #3) Field61 component 5 treated as amount (Issue #4) Field72 structure fixed to allow 6 components at most Field99A implements AmountContainer Field95L implements BICContainer 7.8.9 - May 2017 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Added convenient isType(int) to SwiftMessage Fixed amounts() in AmountContainer fields 7.8.8 - March 2017 Added hashcode and equals to MxId Added MUR generation in block 3 Added a multi-purpose SwiftMessageComparator for MT, as an abstraction of the existing AckMessageComparator Added helper API to remove empty sequences in block 4 Added ACK/NAK identifier constants and API in AbstractSwiftMessage Added getDateAsCalendar in MIR/MOR Added MtCategory enum for MT message categories and convenient category API in SwiftMessage Added support for system and service messages in metadata gathered from SwiftMesasge in MtSwiftMessage Added isServiceMessage in SwiftMessage Added static factory method parse to SwiftMessage Added new fields in AbstractSwiftMessage to hold main currency and amount, automatically set for most MTs from fields 32a, 33a, 34a, 19a and 62a Added conversion to and from LT address in SwiftFormatUtils (CR #10) Added comprehensive implementation of MT and Field classes for system messages (category 0) Added custom name for internal loop sequences in MTs 110, 360, 361, 604, 605, 609, 824, 920, 935, 940, 942, 971 and 973 Added more options to retrieve information from the status trail in AbstractSwiftMessage Reduced visibility from public to protected for MTs inner sequence classes mutable fields; START, END, TAIL. Fixed analyze and strip API in MxParser to support nested Document elements Fixed MT500 removed invalid fields after GENL linkage sequence Fixed AckMessageComparator to cover all fields in block 2 input and output Fixed getSender and getReceiver for service messages in SwiftMessage Fixed MT600, removed invalid fields 26F, 34G, 31C in sequence A Fixed parse for DATE1 (MMDD) to handle properly leap years Fixed RJEWriter to avoid writing the split character '$' and the end of the file, afterwards the last message Expanded helper API in AckSystemMessage TagListBlock tags field made private instead of package protected Enabled mutability of LogicalTerminalAddress objects, allowing setting the branch from superclass BIC Enhanced parser for fields 11R, 11S and 37H (NPE prevention) Removed invalid generated code for internal loops (non-sequence) in MTs: 110, 201, 360, 361, 559, 604, 605, 609, 824, 920, 935, 940, 942, 971, 973 Enhanced from() and to() methods in BusinessHeader to catch more options 7.8.7 - December 2016 Fixed getMessageType in MT103_STP, MT102_STP, MT103_REMIT, MT202COV and MT205COV to return the number without the validation flag (as expected per javadoc definition) MT518 fixed fieldset for Field 70 MT330 fixed qualifier in Field 22 MT513 and MT514 Field 11 moved outside previous fieldset MT541 to MT547 Field 90[A,B] changed to fieldset. MT564 fixed fieldset items in Field93[B,C] MT565 to MT567 Sequence D, fixed field 13 MT609 and MT798_763 fixed qualifiers in Field 29 When creating MT instances, the validation flag (STP, REMIT, COV) will be automatically created as block 3 field 119 when applies for the created MT Log warning when creating MTnnn objects from invalid message types, for example calling MT103.parse(fin) and passing FIN content for an MT 202 Ignore validation flag (STP, REMIT, COV) if it is not valid for the message type, when creating MT object from SwiftMessage (to avoid ClassNotFoundException) Enhanced semantic in AckMessageComparator when a blocks are null or empty (see javadoc for details on how blank blocks are handled in comparison) 7.8.6 - November 2016 MxParser; IOB exception prevention in strip methods when XML has empty header or document Prevention for IOB exception in ensureEOLS when converting MT message from model into FIN text Expanded API in SwiftParser with static parse methods for each MT block Expanded API in SwiftWriter to serialize any MT block into its native SWIFT representation, also made visit API in SwiftMessage static 7.8.5 - October 2016 Added getSubBlockByTagNames and getSubBlocksByTagNames in SwiftTagListBlock to retrieve subblocks based on comprehensive list or tag names Added API in BusinessHeader to create valid BAH from simple parameters Added API in BIC to get the branch and institution Added API to match message identifier by regex, for example fin.*STP Added API to strip header and document portion of Mx message in XML format Added analizeMessage in MxParser, lightweight API to retrieve structure information from an MX messages Added enumerations for message priority and delivery monitoring in MT block 2 Added json() to AbstractMT Added getComponentLabel(int) in Field classes Added updateFrom AbstractMT to MtSwiftMessage Added reference as class attribute in AbstractSwiftMessage (set by subclasses) Added FileFormat attribute to AbstractSwiftMessage for clear identification of content in implementing subclasses Added constructor of MxSwiftMessage from AbstracMX Added API to get BIC codes from DN in Mx messages Added MtId class, analogous to the existing MxId for MX messages SwiftParser parsing of block 4 published as static public method Added AbstractMessage as base class for specific MTnnn and MXmmm model hierarchy Added MessageStandardType with MT and MX values and ServiceIdType for header service id values Added nextSwiftMessage in RJE/PPC readers for system messages support Added valuesNumeric to MT enumeration MtType Added getValueDisplay with optional locale parameter to display formatted field and individual components values Added MTVariant enum and getVariant API in swift messages Added CONDITIONAL_QUALIFIER component number as static class field for all generic fields (fields implementing the GenericField interface) Added BusinessHeader serialization into xml and Element objects Added business header parse from Element object in MxParser Added RJEReader and RJEWriter to create MT message files in RJE format Added PPCWriter to create MT message files in DOS-PPC format (also enhanced API for the existing PPCFileReader) Added path() API in MxNode Added MtType, an enumeration of all available MTnnn implementations Added parse to Field classes to update field components from full value Added append lists of Tag or Field to TagListBlock Added support for attributes in MxNode Added generic setters for attributes in header blocks 1 and 2 using qualified names (#setField) Added write XML method for MX business header Added validName as static method in Field, to validate field names Added getField static API in Field to create new instances with reflection given the field name and value Added reference(msg) to SwiftMessageUtils to get the sender reference from messages that contain a reference field Added SwiftMessageRevision to the swift messages model, to hold and track changes in swift messages Fixed parser for field 98F Fixed field 61 parse allowing EC and ED as credit/debit mark subfield Fixed from() and to() methods in BusinessHeader to return the BIC code for both possible header types FIxed serialization of component 1 in field 50F Fixed parser and serialization in Field98F Fixed SwiftMessage.toJson single quote to double quote in timestamp field Fixed getLabel when used with the parameters combination of a valid mt and a null sequence Fixed getValue in Field61, Added proper implementation for isOptional(component) in Field61 Fixed components trim to null in parser for several fields when the component value is not present Fixed separators trim in getLine API Fixed setComponentN(Number) when component is not a SWIFT amount, Number is now serialized as an integer (without decimal separator) Fixed MT parser to allow additional lines in a field start with colon ':' Fixed field 32R second component changed from currency to string to allow codewords \u2019FOZ\u2019, \u2019GOZ\u2019, \u2019GRM\u2019, \u2019KLO\u2019, \u2018LIT\u2019, \u2019LOT\u2019, \u2018OTH\u2019, \u2018PND\u2019, \u2019TAL\u2019, \u2019TOL\u2019, \u2018TON\u2019, \u2018TOZ\u2019, \u2019UNT\u2019 Fixed field 33B first component changed from currency to string to allow codeword \u2019PCT\u2019 used in MT601 Fixed API inconsistencies in MtSwiftMessage when updating from SwiftMessage objects. Bugfix MT506 added mandatory field 28E Added missing getters for Sequence E1 in MT300 Changed MX messages detection in MxParser to lighter implementation using Stax Normalized Input/Output Outgoing/Incoming API in AbstractMT and SwiftMessage SwiftMessage.toJson changed timestamp format to the recommended ISO 8601 MxSwiftMessage meta-data (sender, receiver, reference, identifier) read and set from raw XML content Added support in XmlParser for the field version of Core proprietary XML format for MTs, the parser now reads both formats seamlessly Better header API in MxSwiftMessage to support both ISO and SWIFT business headers Elaborated identifier in MtSwiftMessage, using fin.type.variant instead of just the message type Added comprehensive sequence names into pw_swift_label property files Added translations of pw_swift_label property files to FR, DE and IT (complementing the existent EN, ES and RU files) Completed pw_swift_label property files for all field + mt + sequence combinations Complete application header parsing in MxParser Better application header detection in MxParser based on namespaces Added component labels for field 13K Fields 11R and 11S component 3 split into two independent components. In Field61, component 6 was splitted into two independent components to hold the \"transaction type\" and the \"identification code\" as stated in the standard definition for function Added SwiftParserConfiguration to encapsulate several parsing options, allowing fast parsing of AbstractMT by reading the text block in raw format 7.7.0 - October 2015 valueDate in SwiftMessageUtils isType(int...) in SwiftMessage Enhanced the getSequence API in MT classes with support to nested sequences, allowing for ex: getSequenceE1(getSequenceEList().get(n)) getLine API for FieldNN classes based on semantic lines number identification Copy constructors for FieldNN classes, performing a deep copy of the components' list MxParser message detection New generic XML model and API, as backbone for MX messages. Headers Blocks: new generic getters in blocks 1 and 2 to retrieve attributes using full qualified names from enums; for example getField(SwiftBlock1Field.LogicalTerminal) Static labels for subfields in FieldNN classes to allow for example getComponent(Field93B.BALANCE) BIC: API to check for live and non-live bics MxParser: parseApplicationHeader and constructors from several sources Added missing labels' API to fields: 36E, 69A, 69C, 69D, 70C, 70D, 70G, 90F, 90J, 92D, 92L, 92M, 92N, 92R Added the ApplicationHeader attribute to AbstractMX Added API to search nodes or content by path or name in the MxNode tree returned by the MxParser Added json() and xml() methods to MT classes Added write to file and output streams to AbstractMT and AbstractMX Added consistent constructors from String, File or InputStream to MTnnn classes Added static parse methods to create MTnnn objects from String, File, InputStream or MtSwiftMessage Added consistent constructors from String, File or InputStream to AbstractSwiftMessage and subclasses MtSwiftMessage and MxSwiftMessage Added static parse methods to create MtSwiftMessage and MxSwiftMessage objects from String, File or InputStream Lib: added read from input streams NPE prevention in SwiftFormatUtils.getCurrency Fixed getSender and getReceiver for MTxxx to return accurate information regardless the message being of type input or output (also to be consistent with analogous methods in SwiftMessage) Added CR and LF to charset z and x at SwiftcharsetUtils Fixed validation of fields 70F, 77S and 77T that unnecessary restricted the allowed amount of lines (not it is unlimited because charset Z allows CRLF). Fixed OutOfBound exception at MxNode findFirst implementation when a node has multiple children Fixed getDescription for Field35B, now returning component 3 instead of 2 Better API consistency between MT and MX implementations, with common ways to parse and build. Changed sender and receiver attributes for MtSwiftMessage to hold BIC8 instead of full LT identifiers. Deprecated the use of model message inside MtSwiftMessage Simplified distribution zip with -sources and -javadoc jars 7.6.0 - October 2014 New BIC API: isTestAndTraining(), getLogicalTerminalIdentifier(), bic8() and bic11() New model for LT addresses, and its related API in header classes New SwiftMessage API: AbstractMT toMT() New AbstractMT API: getSequence(name), getSequenceList(name) Added builder API: constructors and append methods to add content with chaining support Added missing getValue() implementations to field classes. Example: Field26C Added annotations to MTNNN classes to identify sequence split strategy involved (more traceable code) SRU 2014. Affected MTs: 300, 304, 305, 306, 340, 341, 360, 361, 380, 381, 502, 506, 508, 509, 513, 514, 515, 518, 527, 530, 536, 537, 538, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 558, 564, 565, 566, 567, 568, 569, 575, 600, 601, 942 Added description and release javadoc comments to MT classes Added MX Generic model support Added MX parse Added MT300.getSequenceE() Minor fix in MT300 sequences structure, B1 and B2 inside B, and named D's subsequence as D1 SwiftTagListBlock implements Iterable Bugfix SwitTagListBlock.countTagsStarsWith(string,string) was ignoring tagnames in count 7.5.0 - August 2014 Added toJson in SwiftMessage and SwiftTagListBlock, SwiftBlock1 and 2 Added to SwiftTagListBlock getFieldByName(String, being) Added to SwiftTagListBlock getFieldByName(String, being, component2) Added to SwiftTagListBlock getFieldByNumber(int , being) Added START_TAG and END_TAG constant to Sequence inner classes Added Sequence.newInstance() method Added static method Field.emptyTag() Added to SwiftTagListBlock append(SwiftTagListBlock) Changed SwiftFormatUtils.getNumber(Number) to allow variable amount of decimal parts without the previous limit of two Added support for national clearing system codes in party identifier components: example 52A starting with //AT123 JSON serialization: fixed missing quotes escaping and newline in some occasions, getSequenceA() incorrectly returned null instead of empty sequence as stated in javadoc Refactored Field77A to include 20 independent components instead of just one (current implementation is similar to Field79) Deprecated isAnyOf(String ... names) and added isNameAnyOf(String ... names) semantics of method more clear with its name Changed the semantic of getAccount methods to remove starting slashes if any Some javadoc for BICRecord Added serialization timestamp to JSON generation In Field* void set changed to Class set so we can support the code style new Field().setThis().setThat().setThatToo() Added Field.asTag() Added option in XMLWriterVisitor to serialize field instead of tag 7.4.0 - March 2014 In BIC added subtype attribute and getBranch method ReaderIterator to read a file from a classpath resource and split its content by the '$' symbol In SwiftMessage new API to check and get linkages sequences In AbstractSwiftMessage new constructor using MTSwiftMessage as parameter In MTSwiftMessage updateFromModel and updateFromFIN using internal attributes Several helper methods to parse field content using SwiftParseUtils Field classes implementation for fields belonging to System and Service Messages (i.e. 451) Resource bundle labels for System and Service Messages fields MOR class to represent the message output reference (inherited from the MIR) SwiftParseUtils: getTokenSecond and getTokenSecondLast with prefix getAll(SwiftMessage) in every FieldNN class getAll(SwiftTagListBlock) in every FieldNN class New constant in Field suitable for import static SwiftTagListBlock: constructors made public SwiftTagListBlock: added filterByNameOrdered(String ...) SwiftTagListBlock: added getFieldsByNumber(int) SwiftTagListBlock: added removeSubBlock(String) SwiftTagListBlock: deprecated int getTagCount(String) SwiftTagListBlock: added int countByName(String) SwiftTagListBlock: deprecated int getTagCount() SwiftTagListBlock: added int countAll() SwiftTagListBlock: added method boolean containsAllOf(String...) Improved toString in SwiftTagListBlock and Tag Javadoc improvements Fixed SwiftBlock1 constructor to allow LTs missing the optional A, B or C identifier (11 characters length); ex. FOOOAR22XXX Fixed getStatusInfo and getPreviousStatus in messages base class that was causing IOB exceptions Issue 39: missing trimToEmpty in getComponent2 in 50H MT207: fixed maximum repetitions of sequence B from 1 to unlimited 7.3.0 - January 2014 removed log4j.properties New API: Field.isAnyOf(String...) Added many methods in SwiftTagListBlock in resemblance to String manipulation API SwiftTagListBlock added: getTagsByNumber(int), SwiftTagListBlock removeAfterFirst(String, boolean) Added Tag.startsWith Added Tag.contains Added PPCFileReader iterator to read and split pc connect files 7.2.0 - September 2013 Added Field.letterOption Added SwiftTagListBlock.getSubBlockBeforeFirst Added SwiftTagListBlock.filterByName Fixed Field.appendInLines that was causing the getValue of several fields (ex 35B) to start with unexpected EOL Fixed NPE in XMLParser with null value in tags Fixed Avoid usage of double in amount resolver 7.0.0 - August 2013 Enhanced messages model with base support for MX messages. New messages meta-data model to handle additional information: Status history, User notes, Properties list. Useful API to SwiftMessage to get: direction, PDE, PDM, UUID, MIR, MUR and getTypeInt Complete FieldNN implementation classes Complete MT helper classes, covering all message types Added model and API to handle Sequences at MT classes, covering all sequences based on 16R/16S boundaries. New API to handle sub blocks: SwiftTagListBlock.removeUntilFirst, SwiftTagListBlock.containsAnyOf Ensuring of SWIFT EOL at ConversionService.getFIN Fixed getValue of several fields to prevent printing of null Fixed getValue of several fields with missing slash separator on optional components Added missing field getters for MT classes with fieldsets: for example 93B at MT564. getValue for Field35B. Thanks to Raghu rathorr@users.sf.net getCalendar bug related to unused format parameter Changed Field26C parser and subfields structure to split the string before the VAR-SEQU into independent components Removed deprecated net.sourceforge classes Removed unimplemented method amounts() in AmountContainer 6.4.0 - March 2013 Added visitor API on tag list block New interface to identify and use generic fields (notice DSS methods are not part of non-generic fields) Added API on MT classes to simplify messages creation Comprehensive getters and setter API for field classes using functional names Added PatternContainer interface and implemented in field Better CurrencyContainer API Added API to SwiftFormatUtils to get String components from Calendar using different SWIFT date/time formats Implemented API for CurrencyContainer for all Fields Added MT helper classes for MTs: 518, 549, 800, 801, 802, 824, 600, 601, 604, 605, 606, 607, 608, 609 Added Field implementations for 33G, 35U, 86B, 68A, 68B, 68C, 94C, 31F, 37a, 34J, 35H, 31X Added API to simplify messages creation; defaults for header blocks attributes, addField to Block4, setSender at Block1 6.3.0 - October 2012 Added MT helper classes for MTs: 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 565 Fixed getAsCalendar for year component of field 77H Fixed parsing of field 50F Added field class for: 26C Support to identify which sequence a tag belongs to Added API to FieldNN classes to get the DSS field Added API to FieldNN classes to get the qualifier and conditional qualifier components Added API to FieldNN classes to determine if field is generic or non generic Field class made abstract FieldNN isOptional: method to check if a given component is optional for the field Field getLabel: support for label exceptions per mt and sequence SwiftParser changes to distinguish the presence of brackets when they are block boundaries or part of an invalid field value Improved parsing of Field35B, first and second components are set only if \"ISIN \" is present SR2012 update: deprecated fields 23C, 23F. Updated MT300, MT304, MT305 with field changes. Added serialization for: 20E, 29G, 31G, 36E, 50G, 50H, 69B, 69D, 69F, 77H, 90F, 90J, 90K, 92D, 92L, 92M, 92N, 94D, 94G, 95T, 98F Fixed serialization of field 59A 6.2.0 - June 2012 Purged and some tunning of parser log Added getField* API con block4 Added Tag API: public boolean contains(String ... values) Added more API to get subblocks based on tag number boundaries regardless of letter options Fixed Tag.isNumber to consider the whole number and not just the prefix, isNumber(58) returns true to 58A but not to 5 Added Tag.getNumber() API Fixed build to include MTs and FieldNN source codes in the package Fixed parser for fields: 94D, 50H, 50G and 52G Added MT helper classes for MTs: 567, 900, 910, 920, 935, 941, 970, 971, 972, 973, 985, 986 Added API for getLabel at Field objects, to retrieve business oriented names from resource bundles 6.1.0 - March 2012 Added BICContainer interface Added MT helper classes for MTs: 360, 361, 362, 364, 365, 381, n90, n92, n95, n96, n98, 420, 422, 430, 450, 455, 456, 701, 705, 711, 720, 721, 732, 734, 740, 742, 747, 750, 752, 754, 756, 768 Added getValue for Field13E Fixed getValue for Field31R (2nd component is optional) 6.0.0 - February 2012 Merged patches from Walter Birch SwiftParser: fix for parse error with malformed tag 72 Implemented getValue for Fields: 19B, 31D, 31P, 31R, 39P, 40B, 41D, 92F, 93B, 98E and others with the same parser pattern Changed packages in Hibernate mappings from sourceforge to prowidesoftware Added SwiftMessageUtils class Added date container interface to Fields to better support higher level model expressions Added currency container interface to Fields to better support higher level model expressions SWIFT standard update (Nov 2011) Fixed field parser for 35B Changed SwiftParser log level Build: consistent release in jar, sources and javadocs jars, include dependent jars in lib directory API to create FieldNN objects from Tag objects Fixed field parser for 35B when first component is an ISIN number Added DATE1 support for fields parser (fixes Field61) SwiftMessage API to get sender and receiver addresses from message headers Added MT helper classes for MTs: 101, 104, 105, 107, 110, 111, 112, 200, 201, 204, 205, 205COV, 207, 256, 300, 305, 306, 307, 330, 340, 341, 350, 540, 541, 542, 543, 564, 566 MT helper classes 102_not_STP and 103_not_STP with inheritance from defaults MT103 and MT102 classes Added Field implementations for 36E, 69B, 69D, 69F, 90F, 90J, 93B, 93C, 94G, 95T, 95S, 98E, 98F, 98L, 67A, 77J, 92E, 98D, 95S, 50G, 50H, 52G, 31G, 77H TIME3 implementation to format utils Suppress warnings for unused imports in eclipse 6.0.0-RC5 - August 2011 Fixed parser for Field20E Added Field implementations for 90K, 92D, 92L, 92M, 92N 6.0.0-RC4 - July 2011 Added MT helper classes for MTs (SCORE): 798<743>, 798<745>, 798<760>, 798<761>, 798<762>, 798<763>, 798<764>, 798<766>, 798<767>, 798<769>, 798<779>, 798<788>, 798<789>, 798<790>, 798<791>, 798<793>, 798<794>, 798<799> Added MT helper classes for MTs: 191, 291, 391, 399, 491, 535, 591, 691, 699, 707, 760, 767, 769, 790, 791, 891, 991, 999 Added Field implementations for 13E, 20E, 22L, 23X, 24E, 27A, 29D, 29G, 29S, 31R, 39D, 39P, 49H, 49J, 50M, 72C, 77C, 77E, 78B 6.0.0-RC3 - April 2011 Added MT helper classes for MTs: 304, 320, 321, 210, 599 Added Field implementations for 19B, 32H, 32R, 34E, 37G, 37M, 37R, 38J, 92F, 62A, 62B 6.0.0-RC2 - February 2011 Added Field implementation for 15 (A,B,C,D,E,F,G,H,I,J,K,L,M,N) Added MT helper classes for MTs: 300, 400, 410, 412, 416, 499, 544, 545, 546, 547, 548, 700, 710, 730, 799 Added Field implementations for 31D, 31P, 40B, 41A, 41D, 45A, 45B, 46A, 46B, 47A, 47B field serialization from components values into SWIFT single string value Removed log4.properties from distribution jar MTs API: fixed field mutiplicity when a field becomes repetitive being present on multiple sequences or at repetitive sequences. Hibernate mappings: removed confusing/commented blocktype mappings at SwiftBlock.hbm.xml Hibernate mappings: package rename 6.0.0-RC1 - October 2010 Migrated src code to java 1.5 (binary distribution is still 1.4 compatible by means of http://retroweaver.sourceforge.net/) Java 1.4 compatibility changes normalization of linefeeds to CRLF at Tag creation from XML parsing Removed deprecated API Added new package io with subpackages parser and writer; added new package utils. Renamed all packages to com.prowidesoftware (backward compatibility maintained with facades) Added implementation for MTs 102 not STP, 102 STP, 103 not STP, 103 STP, 195, 199, 202, 202COV, 203, 295, 299, 940, 942, 950 Added new SWIFT MT high level generated API, with classes for specific message types New source package for generated swift model Merged project \"prowide SWIFT Fields\" into \"WIFE\" Added comparison options to AckMessageComparator Removed old and incorrect charset validator class net.sourceforge.wife.swift.MessageValidator Fix in remove user block method, thanks to Herman's contribution and patience Parser API for (new SwiftParser()).parse(messageToParse); Replaced commons-lang-2.3 -> 2.4 Fixed message writer: system messages' block4 generated with inline tags SwiftMessage API to check if it's Straight Through Processing (STP), based on the content of the User Header SwiftMessage API to check if it's a cover payment (COV), based on the content of the User Header SwiftTagListBlock API to check if contains a specific Tag Removed unimplemented and confusing package net.sourceforge.wife.validation Deprecated old and unused validation-related classes Added AckMessageComparator which is useful of identify the ack of a given message. SwiftTagListBlock API to get a sub block given its name or its starting and ending Tag SwiftTagListBlock API to get tags by content, given its exact or partial value Helper methods from Block4 moved to SwiftTagListBlock SwiftTagListBlock is no longer abstract, so it can be used to create instances for subblocks Required JVM upgrade to 1.5 Initial update of upload-sf target for release to sourceforge 5.2.0 - February 2009 Added missing hashcode and equals Javadocs improvements Revised and tested hibernate mappings Added getBlockType Added length to unparsed text persistence mappings Fixed persistence mapping for block2 inheritance Updated hibernate libs to version 3.2.6 Added isOutput isInput made concrete, not abstract Added abstract isInput() method to SwiftBlock2 for safer casting subblocks when input/output is unknown 5.1.0 - July 2007 Migrated logging to java logging api Removed SwiftBlock's deprecated methods. Moved some common methods in SwiftBlock2Input/SwiftBlock2Output to parent class SwiftBlock2. Upgraded commons-lang to version 2.3 Improved persistence mapping. Move persistence (helper) package to wife-test project. Minor javadoc fixes. Fixed some warnings. 5.0.0 - June 2007 Improved Hibernate mapping for simplified and more efficient data base schema. Added support for unparsed text to model, persistence mapping and conversion services (needed for some MT0xx for example). XML to SwiftMessage parsing methods moved from ConversionService to XMLParser in \"parser\" package. New package created for parser classes \"net.sourceforge.wife.swift.parser\". Made abstract intermediate classes of blocks object hierarchy. Added support for user custom blocks in model, persistence mapping and conversion services. Improved overall test cases coverage and source/resources structure. Fixed some warnings. Swift Parser enhancements; don't throw exception on unrecognized data, but preserve an internal list of errors. Added reference to current message in parser, so it can take decisions based on parsed data. Added constant for possible values for application id to SwiftBlock1. Updated dependency: hsqldb 1.8.0.4 -> hsqldb 1.8.0.7. Updated dependency: hibernate 3.1.3 -> hibernate 3.2.3.ga. 4.0.0 - April 2007 Moving to junit 4 - some new tests are being written with junit4, this should make testing some features singificantly easier. Move size and isEmpty methods to subclasses. Improved deprecated exception messages and javadoc. Added useful getter for the MIR field in Block 2 output. Added support for optional fields in Block 2 input. Method specific to each block moved to each block class, when possible compatibility methods were left in old places, marked as deprecated to provide a smoother migration path. Removed deprecated API in SwiftBlock. Adapted parser to new model refactor. More javadoc in parser. Improved xml writer (more clean tabs and EOL). Refactored and fixed XML parsing for blocks 3 and 5. Fixed build.xml to include resources in generated jar files. Improved javadoc and validations in fin writer. Completed basic internal XML parsing. Added more tests for XML conversion. Implemented XML conversion parsing for all blocks (except 4). Updated passing test in conversion service. 3.4.0 - March 2007 Added license header to source files. Minor fixes in build system. Enhanced IBAN validation routine. Added numerous tests for IBAN validation. Added JSValidationUnit backed by Rhino, to support easy extension of validations. Made all loggers private static transient final. Enhanced overview documentation. Javadoc updates. Code clean up. Added many tag specific validation units targeting MT103 validation. Removed ant junit fork since it broke in ant 1.7. 3.3.0 - January 2007 Initiated MT103 validation rule. Validation framework core classes written. Utility classes for validation. Removed old and deprecated/replaces writer component. Dependencies clean up, ant downloads less libs now. Added Currency ISO Codes (needed for validations). VF: implemented TagExists and ConditionalTagPresence validation units. Started implementation of validation units. Initial implementation of BIC validation. Initial implementation of IBAN validation. Added ISO Countries for IBAN validation. Fixed issue in writer with block5 as mentioned in bug 1601122. Fixed issue 1595631. 3.2.0 - 2006 Parser logging information cleanup. Migrating to log4j 1.2.8 for better compatibility (issued with trace method on some servers). Fixed build to properly include current timestamp in dist target when property release.name is not set. Fixed bug in parser/writer integration which included double block number when using the writer with an object of a just parsed message(1595589). Updated code to fix issue mentioned in https://sourceforge.net/forum/message.php?msg_id=4001538. 3.1.1 - 2006 Small fixes for java 1.4 compatibility. 3.1.0 - 2006 Fixes to compile for java 1.4 by default. Fixed test for bug 1540294, typo in block number. Use system EOL in XML writer. Added compile timestamp to manifest in created jars. 3.0.0 - 2006 Build: Added release.name property to manifest. Build: added selection of tests known to fail and those known to pass. Fixed persistence mapping. Improved build and added control to exclude tests that are know to fail. Model simplification: SwiftBlockN classes are being removed in favor of base class SwiftBlock removed list of blocks in message which was confusing when not all blocks present. SwiftBlock (base class) and subclasses are mapped and persisted ok, either the base class or the subclasses. Added many tests for Hibernate persistence of SwiftMessage hierarchy. Added XML Visitor to write a swift message to an XML representation. Added ConversionService class which encapsulates many services conveniently. 2.0.0 - 2006 New parser component highly tested on production and unit tests. Writer component usable. while it has many limitations, it can be used as it is now. Work in progress swift message persistence mapping. Work in progress swift expression <-> regular expression conversion.","title":"Prowide Core"},{"location":"release-notes/changelog-core/#prowide-core-changelog","text":"","title":"Prowide Core - CHANGELOG"},{"location":"release-notes/changelog-core/#9416-may-2024","text":"(PW-1862) Added NarrativeFragment class for detailed line information in StructuredNarrative fragments Fixed SwiftMessage getPDE(): return empty value instead of null when codeword exists and has no value Added isPercentage() helper method to field 37K","title":"9.4.16 - May 2024"},{"location":"release-notes/changelog-core/#9415-march-2024","text":"(PW-1812) Updated the narrative resolver, format 2 (used in field 72 for example), to allow empty values as part of the narrative fragment Updated validators for BIC, country, and currency constraints to utilize keywords for i18n-compatible messages Deprecated unnecessary methods in the SafeXmlUtils class","title":"9.4.15 - March 2024"},{"location":"release-notes/changelog-core/#9414-december-2023","text":"(PW-1718) Changed the getComponentLabel(component) in Field59F to be dynamic based on the line identifiers (similar to existing API in Field50F)","title":"9.4.14 - December 2023"},{"location":"release-notes/changelog-core/#9413-november-2023","text":"(PW-1697) Fixed validation/parse pattern in field 29O (PW-1697) MT306 changes in field 30I Added DistinguishedName with Builder in order to encapsulate the BIC branch name logic","title":"9.4.13 - November 2023"},{"location":"release-notes/changelog-core/#9412-november-2023","text":"(PW-1697) Fixed validation pattern in fields 14[H,K,L,M,N,O] and 29J","title":"9.4.12 - November 2023"},{"location":"release-notes/changelog-core/#9411-november-2023","text":"(PW-1695) Fixed a stack overflow in the fields fromJson implementation when a malformed JSON input contains empty field names (PW-1688) Added missing field labels for SRU2023 changes in the pw_swift_*.properties file","title":"9.4.11 - November 2023"},{"location":"release-notes/changelog-core/#9410-october-2023","text":"(PW-1675) update to Field 31R to support also two date components as requested by SCORE messages Added 36B and 36D getters to MT543","title":"9.4.10 - October 2023"},{"location":"release-notes/changelog-core/#949-october-2023","text":"(PW-1659) Field 24G deprecated Name and Address for Narrative","title":"9.4.9 - October 2023"},{"location":"release-notes/changelog-core/#948-october-2023","text":"Added default methods for sender, receiver, and identifier extraction to the MessageExtractionStrategy Added JSON to the FileFormat enumeration","title":"9.4.8 - October 2023"},{"location":"release-notes/changelog-core/#947-september-2023","text":"(PW-1478) Fixed Field 44J parse and getValue to enable proper data preservation when the field contains multiline content","title":"9.4.7 - September 2023"},{"location":"release-notes/changelog-core/#946-september-2023","text":"Added support for an optional pw-swift-core.properties to customize the behavior of the SafeXmlUtils class","title":"9.4.6 - September 2023"},{"location":"release-notes/changelog-core/#945-august-2023","text":"(PW-1478) Field 44J parse and getValue fix","title":"9.4.5 - August 2023"},{"location":"release-notes/changelog-core/#944-august-2023","text":"(PW-1478) Field 44J format fixed to allow multiline","title":"9.4.4 - August 2023"},{"location":"release-notes/changelog-core/#943-july-2023","text":"(PW-1461) Remove deprecation of field 31R model since is it used back in SRU2023 (PW-1405) Trim original String payload when creating an AbstractSwiftMessage","title":"9.4.3 - July 2023"},{"location":"release-notes/changelog-core/#942-june-2023","text":"(GH-163) Remove unnecessary padding in sender and receiver in AbstractMT#creeate(number, sender, receiver) method (PW-1323) Fixing getValue method for pattern issue in Field44J","title":"9.4.2 - June 2023"},{"location":"release-notes/changelog-core/#941-june-2023","text":"(PW-1323) Fixing missing pattern issue in Field44J","title":"9.4.1 - June 2023"},{"location":"release-notes/changelog-core/#940-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"9.4.0 - May 2023"},{"location":"release-notes/changelog-core/#9315-may-2023","text":"(PW-1341) Avoid log pollution with exception stacktrace in Field#formatAccount method (PW-1264) Added distinguishedName(boolean includeDefaultBranch) method to BIC in order to return default branch name","title":"9.3.15 - May 2023"},{"location":"release-notes/changelog-core/#9314-march-2023","text":"(PW-1182) Fixed MT internal Loops API, when strategy is GENERATED_FIXED_WITH_OPTIONAL_TAIL and the tail part contains repetitive fields, such as MT920 (PW-1241) Added addUnstructuredStrict method to Narrative in order to strictly wrap unstructured input","title":"9.3.14 - March 2023"},{"location":"release-notes/changelog-core/#9313-march-2023","text":"Deprecated all fields that are only used in SCORE messages and not in the general MT standard as they will eventually be removed from the library","title":"9.3.13 - March 2023"},{"location":"release-notes/changelog-core/#9312-february-2023","text":"(PW-1109) Changed Narrative Resolver to validate minimum codeword length of 1 char (GH-148) Fixed parser of Field61 amount component when number starts with the decimal comma (implicit zero in amount lower than 1) Added getComponent(String componentName) to retrieve the component based on the name instead of the number Added componentNameToNumber(String componentName) to retrieve the component number based on the component name","title":"9.3.12 - February 2023"},{"location":"release-notes/changelog-core/#9311-january-2023","text":"(PW-1152) Preserve line breaks when creating NarrativeContainer fields from JSON with legacy structure: narrative1, narrative2, etc... Fixed duplicate elements when serializing NarrativeContainer fields into JSON","title":"9.3.11 - January 2023"},{"location":"release-notes/changelog-core/#9310-january-2023","text":"(PW-1150) Added field model class for 31M (required in SCORE MT798_753) (PW-1150) Added field model class for 71E (required in SCORE MT798_755 and MT798_757)","title":"9.3.10 - January 2023"},{"location":"release-notes/changelog-core/#939-december-2022","text":"(PW-1078) StructuredNarrative: Fixed parser to treat the optional [3!a13d] part as a unit block, both currency and amount present or missing","title":"9.3.9 - December 2022"},{"location":"release-notes/changelog-core/#938-november-2022","text":"(GH-127) Enhanced field JSON serialization to include detailed structure when the field is a NarrativeContainer","title":"9.3.8 - November 2022"},{"location":"release-notes/changelog-core/#937-november-2022","text":"(PW-1101) Fix field 35C labels to match the FIN xsd: Identification Of Instrument, Description Of Instrument","title":"9.3.7 - November 2022"},{"location":"release-notes/changelog-core/#936-november-2022","text":"(PW-1086) Fixed typo in field 36D accessors (PW-1078) StructuredNarrative: Added getBankCode() methods in order to allow direct access to data (used in SCORE messages) (GH-88) Added missing constants for ISO 15022 codes MT540 and MT548 added missing getter for Field99C Added removeRepeatedBoundaries method in order to remove repeated tag boundaries","title":"9.3.6 - November 2022"},{"location":"release-notes/changelog-core/#935-october-2022","text":"SRU2022 updates review: field 35C validation pattern changed to","title":"9.3.5 - October 2022"},{"location":"release-notes/changelog-core/#934-september-2022","text":"Added getCADETL method for \"CADETL\" separator sequences (GH-119) MT566: Fixed repetitions of sequence USECU/FIA that is not repetitive Added sequence getters using the boundary field qualifier, for example getSequenceGENL() as equivalent to the existing getSequenceA()","title":"9.3.4 - September 2022"},{"location":"release-notes/changelog-core/#933-august-2022","text":"(PW-1015) Added field model classes for 47E, 49D and 49F (required in SCORE MT798_774)","title":"9.3.3 - August 2022"},{"location":"release-notes/changelog-core/#932-july-2022","text":"(PW-977) Changed the MT203 and MT210 inner structure from regular sequence to inner loop named Loop1 Added Loop1 getter API to MTs: 110, 201, 203, 210, 410, 412, 420, 422, 450, 456, 604, 605, 801, 920, 973","title":"9.3.2 - July 2022"},{"location":"release-notes/changelog-core/#931-july-2022","text":"(PW-976) Added new MonetaryAmountContainer interface for fields having both an Amount and Currency (PW-969) Modified field 12E, 12K and 12R labels (PW-969) Added an optional narrative component to field 12R (required when the field is used in SCORE messages) (PW-898) Changed the heuristic to retrieve sequence B1 from MT300 and MT304 to be more efficient even if the message structure is invalid (PW-867) Enhanced the parsing of party fields A, B and D, to be more strict when splitting the /D/ or /C/ prefix from the account Enhanced MtId constructor with regex matching Added method namespaceURI() in the MtId class to return for example \"urn:swift:xsd:fin.103.2021\" for the MT103","title":"9.3.1 - July 2022"},{"location":"release-notes/changelog-core/#930-may-2022","text":"SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Updated gson dependency to 2.9.0","title":"9.3.0 - May 2022"},{"location":"release-notes/changelog-core/#9213-april-2022","text":"(PW-892) Fixed AbstractMT#create when the message type number is less than 100 Added a convenient String message() method in the SwiftMessage object to get the FIN serialization of the message Fixed error in Field 94G getValue","title":"9.2.13 - April 2022"},{"location":"release-notes/changelog-core/#9212-march-2022","text":"(GH-103) fixed invalid ConstraintValidator annotation on CurrencyValidator (GH-95) patterns getters are now non-final to avoid overwriting; static constants have been deprecated RJE and PPC readers, added a constructor with explicit charset (same in swift parser from input stream) Validate.notNull -> Objects.requireNonNull Spotbugs code review","title":"9.2.12 - March 2022"},{"location":"release-notes/changelog-core/#9211-january-2022","text":"Added LineWrapper (utils) to replace Apache's WordUtils.wrap and thus the commons-text dependency Added convenient method in the envelop message MT798 to get the sub-message type as a SwiftMessage Added a copy constructor to the Tag class","title":"9.2.11 - January 2022"},{"location":"release-notes/changelog-core/#9210-january-2022","text":"(PW-815) Fixed getValue in field 12H (SCORE) where narrative is optional (GH-89) MT530: Fixed repetition of sequence C ADDINFO Updated dependency: gson:2.8.8 -> gson:2.8.9 Java 11 and 17 compatibility updates Added plugins for automatic versioning and code quality reporting","title":"9.2.10 - January 2022"},{"location":"release-notes/changelog-core/#929-december-2021","text":"(GH-78) Fixed MT537#getSequenceBList where sequence B delimiter \"STAT\" overlaps with C3 and D1a1B1a delimiters (GH-74) Fixed parser for Field48 and similar cases to avoid trimming content when the component contains also the slash separator as part of the value (GH-62) Added com.prowidesoftware.core as automatic module name in the MANIFEST for JPMS support Fields getComponentLabel is now public, returning the specific label for each field component Fixed bug in PartyIdentifierUtils.getPartyIdentifier Fixes in field component names and optional status Fixes in field parsing Incompatible change in field 71N (changed from 7 Narrative lines to Code + 6 Narrative lines) Incompatible change for field 11T to have two lines (MT new-line DATE + TIME) Fixed Structured Narrative parsing to return an empty Narrative object with null string values","title":"9.2.9 - December 2021"},{"location":"release-notes/changelog-core/#928-november-2021","text":"(PW-764) Added new variant values (RFDD, ISLFIN) (PW-703) Block 2 parser: lenient parser to avoid duplicate error when exception on invalid Input/Output indicator (CR-23) Enhanced getValueDisplay for fields (no decimal separator for numbers that are not amounts)","title":"9.2.8 - November 2021"},{"location":"release-notes/changelog-core/#927-october-2021","text":"Field 98D, 98E and 98G: removed invalid get{Component4|Sign}AsCurrency and set{Component4|Sign}(Currency) as no currency applies to these fields Fields 94L and 85L: separated component 2 (Legal Entity Identifier) into two (Legal Entity Identifier Code and Legal Entity Identifier Number). Kept get/setLegalEntityIdentifier for backwards compatibility Field 94H: second component now has get{name}AsBIC and set{name}(BIC) methods Field 56B: now inherits from OptionBPartyField (to have get/setPartyIdentifier) Field 26C: separated component 5 into 5 (Denomination) and 6 (Form) for compatibility with Swift. Kept get/setDenominationForm for backwards compatibility Field 26A: now has 2 components (Number 1 and Number 2) for compatibility with Swift. get/setNumber is kept for backwards compatibility Field 23: fixed getValue and parse to properly handle missing intermediate fields Field 14S: has 4 new compatibility methods: getRateSource/setRateSource for Source and Number components and getTimeAndLocation/setTimeAndLocation for Time and Location components Field 12: component is now of expected to have a numeric type Code cleanup for Fields and Date|BIC|Amount|Currency Container Added support for BigDecimal and Long component types (instead of just Number) in several fields Fixed display text generation for fields having a date with pattern MMDD (only the month was included in the text) OptionAPartyField: added set/getPartyIdentifier (for components 1 and 2) and renamed BIC to IdentifierCode. Affects fields 42A, 51A, 52A, 53A, 54A, 55A, 56A, 57A, 58A, 81A, 82A, 83A, 84A, 85A, 86A, 87A, 88A, 89A, 91A and 96A OptionDPartyField: added set/getPartyIdentifier (for components 1 and 2). Affects fields 42D, 50D, 51D, 52D, 53D, 54D, 55D, 56D, 57D, 58D, 81D, 82D, 83D, 84D, 85D, 86D, 87D, 88D, 89D, 91D and 96D OptionBPartyField: added set/getPartyIdentifier (for components 1 and 2). Affects fields 52B, 53B, 54B, 55B, 57B, 58B, 82B, 84B, 85B, 86B, 87B and 88B Prepared Option A, B and D classes to support the PartyIdentifier interface with methods getPartyIdentifier and setPartyIdentifier Enhanced Block2 creation by enriching Block Type to \"O\" or \"I\". (PW-746) Fixed MT reference extraction for 20C in categories other than 5, and with MUR as fallback option (CR-23) Added SwiftMessage#getMOR Updated dependency: Apache Commons Lang 3.8.1 -> 3.12.0 Updated dependency: Apache Commons Text 1.6 -> 1.9 Updated dependency: Gson 2.8.2 -> 2.8.8","title":"9.2.7 - October 2021"},{"location":"release-notes/changelog-core/#926-october-2021","text":"(GH-60) Enhanced parser for field 98C (PW-703) Enhanced SwiftParser in order to validate \"Input\" or \"Output\" Block 2 type Enhanced the MtId to automatically extract the variant from String identifiers such as \"fin.103.STP\" or \"202.COV\"","title":"9.2.6 - October 2021"},{"location":"release-notes/changelog-core/#925-september-2021","text":"(PW-664) Parser enhancement to be lenient on LF before block identifier","title":"9.2.5 - September 2021"},{"location":"release-notes/changelog-core/#924-august-2021","text":"MultiLineField: preserve starting component separator when getting lines with offset","title":"9.2.4 - August 2021"},{"location":"release-notes/changelog-core/#923-august-2021","text":"Added user assigned country codes (example \"XE\") as valid codes in the IsoUtils country validation Added field classes for SCORE messages: 11T, 12[S,R], 25G, 31[J,K,T], 34[D,K,L,M,S,T,U,X,V,W], 49[J,K,L] (to be used in the proprietary payload of the MT798 envelop) MT564: Minor scheme fix, 92a TAXR and WITL can be repeated in CASHMOVE (E2)","title":"9.2.3 - August 2021"},{"location":"release-notes/changelog-core/#922-july-2021","text":"(PW-627) fixed Narrative.builder() to compute \"//\" size in the lines wrapping (PW-581) the MultiLineField API now preserves any starting and trailing spaces in field lines MT565: fixed repetition of sequence B2 (multiple to single) MT548: Minor scheme fix, added letter option \"C\" in field \"98C:SCTS\" in sequence \"C1a1B1\"","title":"9.2.2 - July 2021"},{"location":"release-notes/changelog-core/#921-june-2021","text":"Added \"ignore block 3\" and \"ignore priority\" options to the SwiftMessageComparator Added field classes for SCORE messages: 12[H,K,L], 20E, 25F, 29[D,F], 31R, 78B (to be used in the proprietary payload of the MT798 envelop) Enhanced parser for LogicalTerminalAddress when the parameter has 9 characters (PW-534) allowed null value for the Tag constructor","title":"9.2.1 - June 2021"},{"location":"release-notes/changelog-core/#920-may-2021","text":"SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Fixed the getSequence API in MT classes when the sequence boundary field is repetitive, in some scenarios produced invalid results (PW-519) Field92H: Added \"Rate Status\" accessors (PW-519) Field92J: Replaced \"Narrative\" accessors by \"Rate Status\" accessors","title":"9.2.0 - May 2021"},{"location":"release-notes/changelog-core/#914-april-2021","text":"Fixed getConditionalQualifier in fields 69C, 69D and 92H Fixed field 41D isOptional(component) method (PW-510) Fixed parser of field 90L (PW-508) Fixed validator pattern in field 98K Added MultiLineField interface implementation to fields: 45C, 45L and 49Z Removed MultiLineField interface implementation to field 77H since its value is always a single line (PW-501) Added getNarrative(deli), getNameAndAddress(deli) and similar getters in Field classes to get a concatenation of the relevant components with a specific delimiter (PW-501) Fixed the getNarrative(), getNameAndAddress() and similar getters in Field classes to do a simple join of the relevant components, without CRLF and without components value trim (PW-505) Fixed SwiftFormatUtils#decimalsInAmount(BigDecimal) NPE prevention in AbstractMT.getFields() when the parsed FIN content is invalid Added UETRUtils to generate the GPI unique end-to-end transaction reference, mandatory for several payment messages Added customizable strategies to set the MtSwiftMessage metadata fields: reference, main amount, value date, etc... Added field classes for SCORE messages: 13E, 21S, 21T, 27A, 29P, 29S, 29U, 49Z (to be used in the proprietary payload of the MT798 envelop) (PW-451) Added backward compatible implementation in setComponent and SetNarrative API of narrative container fields: 29A, 37N, 70, 71B, 71D, 72Z, 72, 73A, 73, 74, 75, 76, 77A, 77B, 77D, 77 (PW-445) Added backward compatible fromJson for narrative container fields: 29A, 37N, 45B, 46B, 49M, 49N, 70, 71B, 71D, 72Z, 72, 73A, 73, 74, 75, 76, 77A, 77B, 77D, 77J, 77 Added Direction to the SwiftBlock2Field enumeration Added more message type cases to the SwiftMessageUtils valueDate Minor fixes in MT530 model: fields B/22F and C/90[A,B]","title":"9.1.4 - April 2021"},{"location":"release-notes/changelog-core/#913-december-2020","text":"Changed SwiftMessage#isGpi() to be true for: 103, 199, 299, 192, 196, 202COV or 205COV (mandatory outgoing GPI types) Removed the indexes from the AbstractSwiftMessage JPA mapping (can be created directly in the DB as needed) Added options in the MT message comparator to ignore the LT identifier or test flag when comparing header LT addresses Added asTestBic in BIC to create a test BIC by setting the second component of the location to zero Added API in the SwiftBlock2Output to set the MIR date and receiver date time fields from Calendar object","title":"9.1.3 - December 2020"},{"location":"release-notes/changelog-core/#912-october-2020","text":"Fixed set of MUR when an MtSwiftMessage is created from an acknowledge (service 21 message) Changed AbstractSwiftMessage JPA mapping to EAGER load the status trail and the properties Added a new MessageDirection enum as alternative to the legacy MessageIOType","title":"9.1.2 - October 2020"},{"location":"release-notes/changelog-core/#911-september-2020","text":"Fixed parser for fields 94L and 95L Added MurMessageComparator to match ACKs based on the MUR Changed the SwiftMessage#getMUR to retrieve field 108 from either block 3 or block 4 (system messages) Enhanced the AckMessageComparator to still match on differences in block 2 optional fields or block 4 EOL characters Minor refactor in MtSwiftMessage update from model (SwiftMessage) Added a trim to the content parsed from the RJE reader Fixed setPdm in MtSwiftMessage that was over writing the pde field Minor changes in the MtSwiftMessage to avoid log warnings when setting metadata from message model Added convenient field getters in the ServiceMessage21 (ACK/NAK) model class and made the getMtId() return \"gpa.021\"","title":"9.1.1 - September 2020"},{"location":"release-notes/changelog-core/#910-may-2020","text":"SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Enhanced components namings in field 98[DEGH] Added rich API to parse and build narrative fields: 29A, 37N, 45B, 46B, 49M, 49N, 70, 71B, 71D, 72Z, 72, 73A, 73, 74, 75, 76, 77A, 77B, 77D, 77J, 77 Mx related classes moved to the prowide-iso20022 project (open source since October 2020)","title":"9.1.0 - May 2020"},{"location":"release-notes/changelog-core/#802-april-2019","text":"Added IBAN validation for Seychelles Added field setters API in the SwiftBlock5 Added SwiftBlock5Field enumeration with commonly used block 5 trailer fields (CR #235) Added SafeXmlUtils to disallow XXE in all XML parsing code Fixed parser for fields 70[C,D,E,G], 94E, 95V when first line second component contains slashes Changed default root element for Mx from message to RequestPayload Fixed month day parsing in SwiftFormatUtils for leap years Added MxParser#containsLegacyHeader() to check weather the message uses the legacy SWIFT header or the ISO business header Added MtSwiftMessage constructor from AbstractMT Fixed parser to preserve trailing lines in field values, even if the lines are empty (empty trailing lines were trimmed before) (CR #203) Enhanced parser for party fields, explicit /D/ and /C/ is parsed as mark, otherwise any content following the / is parsed as account Fixed field 108 order and overwrite if exist logic in SwiftBlock3#generateMUR (CR #207) Added optional parameter in SwiftWriter and FINWriterVisitor to control whether field values should be trimmed","title":"8.0.2 - April 2019"},{"location":"release-notes/changelog-core/#801-october-2019","text":"Added SwiftMessageUtils#currencyAmount to retrieve the main currency and amount from a message (CR #192) Fixed ConversionService#getFIN(SwiftMessage) to avoid altering the message parameter when removing empty blocks Added an optional SwiftWriter#writeMessage with ignoreEmptyBlocks parameter SwiftMessage#setUserBlocks(List) made public Removed the trim to field values in the XML to enable consistent round trip conversion between FIN and XML Explicit UTF-8 encoding was added where necessary to ensure portability Added MultiLineField implementation to 45D, 49G, 49M and 49N","title":"8.0.1 - October 2019"},{"location":"release-notes/changelog-core/#800-may-2019","text":"JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Added common hierarchy for option J party fields","title":"8.0.0 - May 2019"},{"location":"release-notes/changelog-core/#7104-may-2019","text":"Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Added copy constructors to MT header blocks Added setDate(Calendar) to MIR object (Issue #25) Fixed padding in PPCWriter Added helper API SwiftTagListBlock#splitByTagName to get sub-blocks by field boundary Fixed IOB exception in SwiftBlock2Output#setMIR in lenient mode SwiftParser#tagStarts changed to protected to allow overwriting in custom parsers for non-compliant messages Moved getMessageType from MtSwiftMessage to parent class AbstractSwiftMessage Added getVariant and getMtId to MtSwiftMessage; added getMxId to MxSwiftMessage Added setMUR in SwiftMessage Added helper method in SwiftWriter to ensure break lines of any String has CRLF Added setSignature and getSignature to SwiftMessage and AbstractMT to set and retrieve MDG tag in S block (LAU computation available in Prowide Integrator) Added propertyValue to AbstractSwiftMessage to check if a property is set with a given value Changed IsoUtils implementation to use Currency.getAvailableCurrencies() in the initialization Deprecated AckSystemMessage in favor of ServiceMessage21 Fixed negative index bug in AbstractSwiftMessage#getPreviousStatusInfo when message has less than two statuses in the trail Fixed getLines API in Fields that in some cases was trimming the first line starting slash from the result Fixed eventual NPE produced in MxSwiftMessage#updateFromMessage() when creating MxSwiftMessage from XML document Fixed column length for \"variant\" in MxSwiftMessage persistence mapping Added a fields() method in SwiftTagListBlock to get all block Tag objects as Field objects Added API to field 50F and 59F to get structured content for the line numbers","title":"7.10.4 - May 2019"},{"location":"release-notes/changelog-core/#7103-october-2018","text":"License changed from LGPL to the more permissive Apache License 2.0 Fixed serialization of field 48 Completed SwiftMessageUtils#currencyAmount for missing MTs Fixed NPE in SwiftBlock4.removeEmptySequences with fields 15A as sequence boundary (Issue #15) MxParser.java typo analiseMessage -> analyseMessage Added getFields() to MT classes Added bean validation annotations for BIC, IBAN, ISO country and currency Enhanced the BIC internal model to allow accessor for all subfields Enhanced the BIC validation with enum to report the specific validation problem found Changed the default SwiftParser behavior to lenient, meaning by default it will not throw any IllegalArgumentException when headers size is invalid Fixed FIN writer to preserve trailing spaces in tag value Added JPA annotations to the SWIFT model intended for persistence (AbstractSwiftMessage and subclasses) Removed the old Hibernate XML mapping AbstractSwiftMessage.hbm.xml (in favor of generic JPA annotations in model) Added SwiftTagListBlock#removeSubBlocks to remove all instances of a given subblock (Issue #13) Fixed SwifttagListBlock#removeSubBlock Added JsonSerializable interface to all model classes implementing toJson() Added toJson and fromJson to MT and Field classes Added toJson and fromJson to the MtSwiftMessage and MxSwiftMessage model Added field 434 in SwiftBlock3Builder","title":"7.10.3 - October 2018"},{"location":"release-notes/changelog-core/#7102-may-2018","text":"Revamped the JSON API implementation using Gson, added missing fromJson methods","title":"7.10.2 - May 2018"},{"location":"release-notes/changelog-core/#7101-april-2018","text":"FIN writer: reverted the trim in tag values introduced in 7.8.9","title":"7.10.1 - April 2018"},{"location":"release-notes/changelog-core/#7100-april-2018","text":"SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Added API in SwiftMessage for the SWIFT gpi service: getters and setters for the service type identifier and UETR Added an automatically generated UETR when creating new MT instances for 103, 103 STP, 103 REMIT, 202, 202 COV, 205, or 205 COV Added API in SwiftMessage to set the variant (STP, REMIT, COV) New helper API for block 3 (SwiftBlock3Builder) to ensure only expected fields are added and in proper order","title":"7.10.0 - April 2018"},{"location":"release-notes/changelog-core/#797-april-2018","text":"Dependencies: added gson 2.8.2 Added full IBAN validation including control digits and custom account numbers per country Added SwiftCharset and SwiftCharsetUtils helper API to validate SWIFT related charsets. Added SwiftTagListBlock#getFieldByQualifiers(name, qualifier, conditionalQualifier) to gather generic fields based on qualifiers content Added addTag(index, tag) and setTag(index, tag) in SwiftTagListBlock to insert new field in specific positions Added Field#is(String ...) to test component 1 of fields against a list of possible values Added non-ISO country code XK (Kosovo) to IsoUtils Added API in IsoUtils to add custom codes for countries and currencies Added read-only properties in AbstractSwiftMessage for the message creation year, month and day of moth Added support for custom split char in RJE reader/writer Fixed missing repetitive 35B in MT549 Build migrated to Gradle","title":"7.9.7 - April 2018"},{"location":"release-notes/changelog-core/#796-december-2017","text":"Fixed conversion to XML with compressed parameter true in ConversionService","title":"7.9.6 - December 2017"},{"location":"release-notes/changelog-core/#795-december-2017","text":"Fixed getValueDisplay in field 50F to strip the starting slash in the account number Added getLabelForLineNumber(String subfieldNumber) in Field50F to return the labels for the structured line identifiers Enhanced getComponentLabel(final int number) in Field50F to return proper dynamic labels based on line number identifiers Added getCorrespondentBIC to SwiftMessage and AbstractSwiftMessage Expanded sender/receiver in MtSwiftMessage and MxSwiftMessage from BIC8 to BIC11 in order to keep branch information in those cached attributes Added checksumBody to AbstractSwiftMessage for proprietary checksum calculated on the body only, as a complement to the existing checksum on the whole message Fixed AbstractSwiftMessage#copyTo(msg) implementation to perform hard copy of list objects (similar to a copy constructor implementation) Expanded precision in getValueDisplay for all numeric fields to preserve the decimal digits present in the original value Implemented SwiftMessage#getUUID and added getUID(Calendar, Long) Implemented SwiftMessageUtils#calculateChecksum as MD5 hash on whole FIN message content and added new checksum for the text block only","title":"7.9.5 - December 2017"},{"location":"release-notes/changelog-core/#794-november-2017","text":"Internal code maintenance release","title":"7.9.4 - November 2017"},{"location":"release-notes/changelog-core/#793-october-2017","text":"JRE requirement increased to Java 1.6 Added API in BIC to return the distinguished name (DN) for a BIC Added equalsIgnoreCR in Tag to compare values regardless of carriage return character being present or not in new lines Fixed MxParser#parseBusinessApplicationHeaderV01 (it was setting the FinInstnId/Nm as BIC) Removed invalid component in field 86J Fixed order of components in fields 98J and 98K Completed the component labels for all fields Changed field 22C structure into individual components for the function Enhanced fields parse/serialization to preserve any whitespace in a component","title":"7.9.3 - October 2017"},{"location":"release-notes/changelog-core/#792-august-2017","text":"Fixed FINWriterVisitor to prevent printing 'null' tag values Deprecated custom resource properties for currency and country codes, in favor of Java nativa API in Currency and Locale Removed package-info.class from target jar to avoid class modifier issue in Java8 runtime Fixed serialization of field 50F to allow the first line without a starting forward slash","title":"7.9.2 - August 2017"},{"location":"release-notes/changelog-core/#791-june-2017","text":"(Issue #5) Enhanced performance in SwiftParser Removed sequence API for inner loops (non sequence) in MTs 306, 320, 340, 360, 361, 362, 410, 412, 420, 422, 450, 456","title":"7.9.1 - June 2017"},{"location":"release-notes/changelog-core/#790-may-2017","text":"SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX) (Issue #2) maven build issues (Issue #3) Field61 component 5 treated as amount (Issue #4) Field72 structure fixed to allow 6 components at most Field99A implements AmountContainer Field95L implements BICContainer","title":"7.9.0 - May 2017"},{"location":"release-notes/changelog-core/#789-may-2017","text":"Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Added convenient isType(int) to SwiftMessage Fixed amounts() in AmountContainer fields","title":"7.8.9 - May 2017"},{"location":"release-notes/changelog-core/#788-march-2017","text":"Added hashcode and equals to MxId Added MUR generation in block 3 Added a multi-purpose SwiftMessageComparator for MT, as an abstraction of the existing AckMessageComparator Added helper API to remove empty sequences in block 4 Added ACK/NAK identifier constants and API in AbstractSwiftMessage Added getDateAsCalendar in MIR/MOR Added MtCategory enum for MT message categories and convenient category API in SwiftMessage Added support for system and service messages in metadata gathered from SwiftMesasge in MtSwiftMessage Added isServiceMessage in SwiftMessage Added static factory method parse to SwiftMessage Added new fields in AbstractSwiftMessage to hold main currency and amount, automatically set for most MTs from fields 32a, 33a, 34a, 19a and 62a Added conversion to and from LT address in SwiftFormatUtils (CR #10) Added comprehensive implementation of MT and Field classes for system messages (category 0) Added custom name for internal loop sequences in MTs 110, 360, 361, 604, 605, 609, 824, 920, 935, 940, 942, 971 and 973 Added more options to retrieve information from the status trail in AbstractSwiftMessage Reduced visibility from public to protected for MTs inner sequence classes mutable fields; START, END, TAIL. Fixed analyze and strip API in MxParser to support nested Document elements Fixed MT500 removed invalid fields after GENL linkage sequence Fixed AckMessageComparator to cover all fields in block 2 input and output Fixed getSender and getReceiver for service messages in SwiftMessage Fixed MT600, removed invalid fields 26F, 34G, 31C in sequence A Fixed parse for DATE1 (MMDD) to handle properly leap years Fixed RJEWriter to avoid writing the split character '$' and the end of the file, afterwards the last message Expanded helper API in AckSystemMessage TagListBlock tags field made private instead of package protected Enabled mutability of LogicalTerminalAddress objects, allowing setting the branch from superclass BIC Enhanced parser for fields 11R, 11S and 37H (NPE prevention) Removed invalid generated code for internal loops (non-sequence) in MTs: 110, 201, 360, 361, 559, 604, 605, 609, 824, 920, 935, 940, 942, 971, 973 Enhanced from() and to() methods in BusinessHeader to catch more options","title":"7.8.8 - March 2017"},{"location":"release-notes/changelog-core/#787-december-2016","text":"Fixed getMessageType in MT103_STP, MT102_STP, MT103_REMIT, MT202COV and MT205COV to return the number without the validation flag (as expected per javadoc definition) MT518 fixed fieldset for Field 70 MT330 fixed qualifier in Field 22 MT513 and MT514 Field 11 moved outside previous fieldset MT541 to MT547 Field 90[A,B] changed to fieldset. MT564 fixed fieldset items in Field93[B,C] MT565 to MT567 Sequence D, fixed field 13 MT609 and MT798_763 fixed qualifiers in Field 29 When creating MT instances, the validation flag (STP, REMIT, COV) will be automatically created as block 3 field 119 when applies for the created MT Log warning when creating MTnnn objects from invalid message types, for example calling MT103.parse(fin) and passing FIN content for an MT 202 Ignore validation flag (STP, REMIT, COV) if it is not valid for the message type, when creating MT object from SwiftMessage (to avoid ClassNotFoundException) Enhanced semantic in AckMessageComparator when a blocks are null or empty (see javadoc for details on how blank blocks are handled in comparison)","title":"7.8.7 - December 2016"},{"location":"release-notes/changelog-core/#786-november-2016","text":"MxParser; IOB exception prevention in strip methods when XML has empty header or document Prevention for IOB exception in ensureEOLS when converting MT message from model into FIN text Expanded API in SwiftParser with static parse methods for each MT block Expanded API in SwiftWriter to serialize any MT block into its native SWIFT representation, also made visit API in SwiftMessage static","title":"7.8.6 - November 2016"},{"location":"release-notes/changelog-core/#785-october-2016","text":"Added getSubBlockByTagNames and getSubBlocksByTagNames in SwiftTagListBlock to retrieve subblocks based on comprehensive list or tag names Added API in BusinessHeader to create valid BAH from simple parameters Added API in BIC to get the branch and institution Added API to match message identifier by regex, for example fin.*STP Added API to strip header and document portion of Mx message in XML format Added analizeMessage in MxParser, lightweight API to retrieve structure information from an MX messages Added enumerations for message priority and delivery monitoring in MT block 2 Added json() to AbstractMT Added getComponentLabel(int) in Field classes Added updateFrom AbstractMT to MtSwiftMessage Added reference as class attribute in AbstractSwiftMessage (set by subclasses) Added FileFormat attribute to AbstractSwiftMessage for clear identification of content in implementing subclasses Added constructor of MxSwiftMessage from AbstracMX Added API to get BIC codes from DN in Mx messages Added MtId class, analogous to the existing MxId for MX messages SwiftParser parsing of block 4 published as static public method Added AbstractMessage as base class for specific MTnnn and MXmmm model hierarchy Added MessageStandardType with MT and MX values and ServiceIdType for header service id values Added nextSwiftMessage in RJE/PPC readers for system messages support Added valuesNumeric to MT enumeration MtType Added getValueDisplay with optional locale parameter to display formatted field and individual components values Added MTVariant enum and getVariant API in swift messages Added CONDITIONAL_QUALIFIER component number as static class field for all generic fields (fields implementing the GenericField interface) Added BusinessHeader serialization into xml and Element objects Added business header parse from Element object in MxParser Added RJEReader and RJEWriter to create MT message files in RJE format Added PPCWriter to create MT message files in DOS-PPC format (also enhanced API for the existing PPCFileReader) Added path() API in MxNode Added MtType, an enumeration of all available MTnnn implementations Added parse to Field classes to update field components from full value Added append lists of Tag or Field to TagListBlock Added support for attributes in MxNode Added generic setters for attributes in header blocks 1 and 2 using qualified names (#setField) Added write XML method for MX business header Added validName as static method in Field, to validate field names Added getField static API in Field to create new instances with reflection given the field name and value Added reference(msg) to SwiftMessageUtils to get the sender reference from messages that contain a reference field Added SwiftMessageRevision to the swift messages model, to hold and track changes in swift messages Fixed parser for field 98F Fixed field 61 parse allowing EC and ED as credit/debit mark subfield Fixed from() and to() methods in BusinessHeader to return the BIC code for both possible header types FIxed serialization of component 1 in field 50F Fixed parser and serialization in Field98F Fixed SwiftMessage.toJson single quote to double quote in timestamp field Fixed getLabel when used with the parameters combination of a valid mt and a null sequence Fixed getValue in Field61, Added proper implementation for isOptional(component) in Field61 Fixed components trim to null in parser for several fields when the component value is not present Fixed separators trim in getLine API Fixed setComponentN(Number) when component is not a SWIFT amount, Number is now serialized as an integer (without decimal separator) Fixed MT parser to allow additional lines in a field start with colon ':' Fixed field 32R second component changed from currency to string to allow codewords \u2019FOZ\u2019, \u2019GOZ\u2019, \u2019GRM\u2019, \u2019KLO\u2019, \u2018LIT\u2019, \u2019LOT\u2019, \u2018OTH\u2019, \u2018PND\u2019, \u2019TAL\u2019, \u2019TOL\u2019, \u2018TON\u2019, \u2018TOZ\u2019, \u2019UNT\u2019 Fixed field 33B first component changed from currency to string to allow codeword \u2019PCT\u2019 used in MT601 Fixed API inconsistencies in MtSwiftMessage when updating from SwiftMessage objects. Bugfix MT506 added mandatory field 28E Added missing getters for Sequence E1 in MT300 Changed MX messages detection in MxParser to lighter implementation using Stax Normalized Input/Output Outgoing/Incoming API in AbstractMT and SwiftMessage SwiftMessage.toJson changed timestamp format to the recommended ISO 8601 MxSwiftMessage meta-data (sender, receiver, reference, identifier) read and set from raw XML content Added support in XmlParser for the field version of Core proprietary XML format for MTs, the parser now reads both formats seamlessly Better header API in MxSwiftMessage to support both ISO and SWIFT business headers Elaborated identifier in MtSwiftMessage, using fin.type.variant instead of just the message type Added comprehensive sequence names into pw_swift_label property files Added translations of pw_swift_label property files to FR, DE and IT (complementing the existent EN, ES and RU files) Completed pw_swift_label property files for all field + mt + sequence combinations Complete application header parsing in MxParser Better application header detection in MxParser based on namespaces Added component labels for field 13K Fields 11R and 11S component 3 split into two independent components. In Field61, component 6 was splitted into two independent components to hold the \"transaction type\" and the \"identification code\" as stated in the standard definition for function Added SwiftParserConfiguration to encapsulate several parsing options, allowing fast parsing of AbstractMT by reading the text block in raw format","title":"7.8.5 - October 2016"},{"location":"release-notes/changelog-core/#770-october-2015","text":"valueDate in SwiftMessageUtils isType(int...) in SwiftMessage Enhanced the getSequence API in MT classes with support to nested sequences, allowing for ex: getSequenceE1(getSequenceEList().get(n)) getLine API for FieldNN classes based on semantic lines number identification Copy constructors for FieldNN classes, performing a deep copy of the components' list MxParser message detection New generic XML model and API, as backbone for MX messages. Headers Blocks: new generic getters in blocks 1 and 2 to retrieve attributes using full qualified names from enums; for example getField(SwiftBlock1Field.LogicalTerminal) Static labels for subfields in FieldNN classes to allow for example getComponent(Field93B.BALANCE) BIC: API to check for live and non-live bics MxParser: parseApplicationHeader and constructors from several sources Added missing labels' API to fields: 36E, 69A, 69C, 69D, 70C, 70D, 70G, 90F, 90J, 92D, 92L, 92M, 92N, 92R Added the ApplicationHeader attribute to AbstractMX Added API to search nodes or content by path or name in the MxNode tree returned by the MxParser Added json() and xml() methods to MT classes Added write to file and output streams to AbstractMT and AbstractMX Added consistent constructors from String, File or InputStream to MTnnn classes Added static parse methods to create MTnnn objects from String, File, InputStream or MtSwiftMessage Added consistent constructors from String, File or InputStream to AbstractSwiftMessage and subclasses MtSwiftMessage and MxSwiftMessage Added static parse methods to create MtSwiftMessage and MxSwiftMessage objects from String, File or InputStream Lib: added read from input streams NPE prevention in SwiftFormatUtils.getCurrency Fixed getSender and getReceiver for MTxxx to return accurate information regardless the message being of type input or output (also to be consistent with analogous methods in SwiftMessage) Added CR and LF to charset z and x at SwiftcharsetUtils Fixed validation of fields 70F, 77S and 77T that unnecessary restricted the allowed amount of lines (not it is unlimited because charset Z allows CRLF). Fixed OutOfBound exception at MxNode findFirst implementation when a node has multiple children Fixed getDescription for Field35B, now returning component 3 instead of 2 Better API consistency between MT and MX implementations, with common ways to parse and build. Changed sender and receiver attributes for MtSwiftMessage to hold BIC8 instead of full LT identifiers. Deprecated the use of model message inside MtSwiftMessage Simplified distribution zip with -sources and -javadoc jars","title":"7.7.0 - October 2015"},{"location":"release-notes/changelog-core/#760-october-2014","text":"New BIC API: isTestAndTraining(), getLogicalTerminalIdentifier(), bic8() and bic11() New model for LT addresses, and its related API in header classes New SwiftMessage API: AbstractMT toMT() New AbstractMT API: getSequence(name), getSequenceList(name) Added builder API: constructors and append methods to add content with chaining support Added missing getValue() implementations to field classes. Example: Field26C Added annotations to MTNNN classes to identify sequence split strategy involved (more traceable code) SRU 2014. Affected MTs: 300, 304, 305, 306, 340, 341, 360, 361, 380, 381, 502, 506, 508, 509, 513, 514, 515, 518, 527, 530, 536, 537, 538, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 558, 564, 565, 566, 567, 568, 569, 575, 600, 601, 942 Added description and release javadoc comments to MT classes Added MX Generic model support Added MX parse Added MT300.getSequenceE() Minor fix in MT300 sequences structure, B1 and B2 inside B, and named D's subsequence as D1 SwiftTagListBlock implements Iterable Bugfix SwitTagListBlock.countTagsStarsWith(string,string) was ignoring tagnames in count","title":"7.6.0 - October 2014"},{"location":"release-notes/changelog-core/#750-august-2014","text":"Added toJson in SwiftMessage and SwiftTagListBlock, SwiftBlock1 and 2 Added to SwiftTagListBlock getFieldByName(String, being) Added to SwiftTagListBlock getFieldByName(String, being, component2) Added to SwiftTagListBlock getFieldByNumber(int , being) Added START_TAG and END_TAG constant to Sequence inner classes Added Sequence.newInstance() method Added static method Field.emptyTag() Added to SwiftTagListBlock append(SwiftTagListBlock) Changed SwiftFormatUtils.getNumber(Number) to allow variable amount of decimal parts without the previous limit of two Added support for national clearing system codes in party identifier components: example 52A starting with //AT123 JSON serialization: fixed missing quotes escaping and newline in some occasions, getSequenceA() incorrectly returned null instead of empty sequence as stated in javadoc Refactored Field77A to include 20 independent components instead of just one (current implementation is similar to Field79) Deprecated isAnyOf(String ... names) and added isNameAnyOf(String ... names) semantics of method more clear with its name Changed the semantic of getAccount methods to remove starting slashes if any Some javadoc for BICRecord Added serialization timestamp to JSON generation In Field* void set changed to Class set so we can support the code style new Field().setThis().setThat().setThatToo() Added Field.asTag() Added option in XMLWriterVisitor to serialize field instead of tag","title":"7.5.0 - August 2014"},{"location":"release-notes/changelog-core/#740-march-2014","text":"In BIC added subtype attribute and getBranch method ReaderIterator to read a file from a classpath resource and split its content by the '$' symbol In SwiftMessage new API to check and get linkages sequences In AbstractSwiftMessage new constructor using MTSwiftMessage as parameter In MTSwiftMessage updateFromModel and updateFromFIN using internal attributes Several helper methods to parse field content using SwiftParseUtils Field classes implementation for fields belonging to System and Service Messages (i.e. 451) Resource bundle labels for System and Service Messages fields MOR class to represent the message output reference (inherited from the MIR) SwiftParseUtils: getTokenSecond and getTokenSecondLast with prefix getAll(SwiftMessage) in every FieldNN class getAll(SwiftTagListBlock) in every FieldNN class New constant in Field suitable for import static SwiftTagListBlock: constructors made public SwiftTagListBlock: added filterByNameOrdered(String ...) SwiftTagListBlock: added getFieldsByNumber(int) SwiftTagListBlock: added removeSubBlock(String) SwiftTagListBlock: deprecated int getTagCount(String) SwiftTagListBlock: added int countByName(String) SwiftTagListBlock: deprecated int getTagCount() SwiftTagListBlock: added int countAll() SwiftTagListBlock: added method boolean containsAllOf(String...) Improved toString in SwiftTagListBlock and Tag Javadoc improvements Fixed SwiftBlock1 constructor to allow LTs missing the optional A, B or C identifier (11 characters length); ex. FOOOAR22XXX Fixed getStatusInfo and getPreviousStatus in messages base class that was causing IOB exceptions Issue 39: missing trimToEmpty in getComponent2 in 50H MT207: fixed maximum repetitions of sequence B from 1 to unlimited","title":"7.4.0 - March 2014"},{"location":"release-notes/changelog-core/#730-january-2014","text":"removed log4j.properties New API: Field.isAnyOf(String...) Added many methods in SwiftTagListBlock in resemblance to String manipulation API SwiftTagListBlock added: getTagsByNumber(int), SwiftTagListBlock removeAfterFirst(String, boolean) Added Tag.startsWith Added Tag.contains Added PPCFileReader iterator to read and split pc connect files","title":"7.3.0 - January 2014"},{"location":"release-notes/changelog-core/#720-september-2013","text":"Added Field.letterOption Added SwiftTagListBlock.getSubBlockBeforeFirst Added SwiftTagListBlock.filterByName Fixed Field.appendInLines that was causing the getValue of several fields (ex 35B) to start with unexpected EOL Fixed NPE in XMLParser with null value in tags Fixed Avoid usage of double in amount resolver","title":"7.2.0 - September 2013"},{"location":"release-notes/changelog-core/#700-august-2013","text":"Enhanced messages model with base support for MX messages. New messages meta-data model to handle additional information: Status history, User notes, Properties list. Useful API to SwiftMessage to get: direction, PDE, PDM, UUID, MIR, MUR and getTypeInt Complete FieldNN implementation classes Complete MT helper classes, covering all message types Added model and API to handle Sequences at MT classes, covering all sequences based on 16R/16S boundaries. New API to handle sub blocks: SwiftTagListBlock.removeUntilFirst, SwiftTagListBlock.containsAnyOf Ensuring of SWIFT EOL at ConversionService.getFIN Fixed getValue of several fields to prevent printing of null Fixed getValue of several fields with missing slash separator on optional components Added missing field getters for MT classes with fieldsets: for example 93B at MT564. getValue for Field35B. Thanks to Raghu rathorr@users.sf.net getCalendar bug related to unused format parameter Changed Field26C parser and subfields structure to split the string before the VAR-SEQU into independent components Removed deprecated net.sourceforge classes Removed unimplemented method amounts() in AmountContainer","title":"7.0.0 - August 2013"},{"location":"release-notes/changelog-core/#640-march-2013","text":"Added visitor API on tag list block New interface to identify and use generic fields (notice DSS methods are not part of non-generic fields) Added API on MT classes to simplify messages creation Comprehensive getters and setter API for field classes using functional names Added PatternContainer interface and implemented in field Better CurrencyContainer API Added API to SwiftFormatUtils to get String components from Calendar using different SWIFT date/time formats Implemented API for CurrencyContainer for all Fields Added MT helper classes for MTs: 518, 549, 800, 801, 802, 824, 600, 601, 604, 605, 606, 607, 608, 609 Added Field implementations for 33G, 35U, 86B, 68A, 68B, 68C, 94C, 31F, 37a, 34J, 35H, 31X Added API to simplify messages creation; defaults for header blocks attributes, addField to Block4, setSender at Block1","title":"6.4.0 - March 2013"},{"location":"release-notes/changelog-core/#630-october-2012","text":"Added MT helper classes for MTs: 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 565 Fixed getAsCalendar for year component of field 77H Fixed parsing of field 50F Added field class for: 26C Support to identify which sequence a tag belongs to Added API to FieldNN classes to get the DSS field Added API to FieldNN classes to get the qualifier and conditional qualifier components Added API to FieldNN classes to determine if field is generic or non generic Field class made abstract FieldNN isOptional: method to check if a given component is optional for the field Field getLabel: support for label exceptions per mt and sequence SwiftParser changes to distinguish the presence of brackets when they are block boundaries or part of an invalid field value Improved parsing of Field35B, first and second components are set only if \"ISIN \" is present SR2012 update: deprecated fields 23C, 23F. Updated MT300, MT304, MT305 with field changes. Added serialization for: 20E, 29G, 31G, 36E, 50G, 50H, 69B, 69D, 69F, 77H, 90F, 90J, 90K, 92D, 92L, 92M, 92N, 94D, 94G, 95T, 98F Fixed serialization of field 59A","title":"6.3.0 - October 2012"},{"location":"release-notes/changelog-core/#620-june-2012","text":"Purged and some tunning of parser log Added getField* API con block4 Added Tag API: public boolean contains(String ... values) Added more API to get subblocks based on tag number boundaries regardless of letter options Fixed Tag.isNumber to consider the whole number and not just the prefix, isNumber(58) returns true to 58A but not to 5 Added Tag.getNumber() API Fixed build to include MTs and FieldNN source codes in the package Fixed parser for fields: 94D, 50H, 50G and 52G Added MT helper classes for MTs: 567, 900, 910, 920, 935, 941, 970, 971, 972, 973, 985, 986 Added API for getLabel at Field objects, to retrieve business oriented names from resource bundles","title":"6.2.0 - June 2012"},{"location":"release-notes/changelog-core/#610-march-2012","text":"Added BICContainer interface Added MT helper classes for MTs: 360, 361, 362, 364, 365, 381, n90, n92, n95, n96, n98, 420, 422, 430, 450, 455, 456, 701, 705, 711, 720, 721, 732, 734, 740, 742, 747, 750, 752, 754, 756, 768 Added getValue for Field13E Fixed getValue for Field31R (2nd component is optional)","title":"6.1.0 - March 2012"},{"location":"release-notes/changelog-core/#600-february-2012","text":"Merged patches from Walter Birch SwiftParser: fix for parse error with malformed tag 72 Implemented getValue for Fields: 19B, 31D, 31P, 31R, 39P, 40B, 41D, 92F, 93B, 98E and others with the same parser pattern Changed packages in Hibernate mappings from sourceforge to prowidesoftware Added SwiftMessageUtils class Added date container interface to Fields to better support higher level model expressions Added currency container interface to Fields to better support higher level model expressions SWIFT standard update (Nov 2011) Fixed field parser for 35B Changed SwiftParser log level Build: consistent release in jar, sources and javadocs jars, include dependent jars in lib directory API to create FieldNN objects from Tag objects Fixed field parser for 35B when first component is an ISIN number Added DATE1 support for fields parser (fixes Field61) SwiftMessage API to get sender and receiver addresses from message headers Added MT helper classes for MTs: 101, 104, 105, 107, 110, 111, 112, 200, 201, 204, 205, 205COV, 207, 256, 300, 305, 306, 307, 330, 340, 341, 350, 540, 541, 542, 543, 564, 566 MT helper classes 102_not_STP and 103_not_STP with inheritance from defaults MT103 and MT102 classes Added Field implementations for 36E, 69B, 69D, 69F, 90F, 90J, 93B, 93C, 94G, 95T, 95S, 98E, 98F, 98L, 67A, 77J, 92E, 98D, 95S, 50G, 50H, 52G, 31G, 77H TIME3 implementation to format utils Suppress warnings for unused imports in eclipse","title":"6.0.0 - February 2012"},{"location":"release-notes/changelog-core/#600-rc5-august-2011","text":"Fixed parser for Field20E Added Field implementations for 90K, 92D, 92L, 92M, 92N","title":"6.0.0-RC5 - August 2011"},{"location":"release-notes/changelog-core/#600-rc4-july-2011","text":"Added MT helper classes for MTs (SCORE): 798<743>, 798<745>, 798<760>, 798<761>, 798<762>, 798<763>, 798<764>, 798<766>, 798<767>, 798<769>, 798<779>, 798<788>, 798<789>, 798<790>, 798<791>, 798<793>, 798<794>, 798<799> Added MT helper classes for MTs: 191, 291, 391, 399, 491, 535, 591, 691, 699, 707, 760, 767, 769, 790, 791, 891, 991, 999 Added Field implementations for 13E, 20E, 22L, 23X, 24E, 27A, 29D, 29G, 29S, 31R, 39D, 39P, 49H, 49J, 50M, 72C, 77C, 77E, 78B","title":"6.0.0-RC4 - July 2011"},{"location":"release-notes/changelog-core/#600-rc3-april-2011","text":"Added MT helper classes for MTs: 304, 320, 321, 210, 599 Added Field implementations for 19B, 32H, 32R, 34E, 37G, 37M, 37R, 38J, 92F, 62A, 62B","title":"6.0.0-RC3 - April 2011"},{"location":"release-notes/changelog-core/#600-rc2-february-2011","text":"Added Field implementation for 15 (A,B,C,D,E,F,G,H,I,J,K,L,M,N) Added MT helper classes for MTs: 300, 400, 410, 412, 416, 499, 544, 545, 546, 547, 548, 700, 710, 730, 799 Added Field implementations for 31D, 31P, 40B, 41A, 41D, 45A, 45B, 46A, 46B, 47A, 47B field serialization from components values into SWIFT single string value Removed log4.properties from distribution jar MTs API: fixed field mutiplicity when a field becomes repetitive being present on multiple sequences or at repetitive sequences. Hibernate mappings: removed confusing/commented blocktype mappings at SwiftBlock.hbm.xml Hibernate mappings: package rename","title":"6.0.0-RC2 - February 2011"},{"location":"release-notes/changelog-core/#600-rc1-october-2010","text":"Migrated src code to java 1.5 (binary distribution is still 1.4 compatible by means of http://retroweaver.sourceforge.net/) Java 1.4 compatibility changes normalization of linefeeds to CRLF at Tag creation from XML parsing Removed deprecated API Added new package io with subpackages parser and writer; added new package utils. Renamed all packages to com.prowidesoftware (backward compatibility maintained with facades) Added implementation for MTs 102 not STP, 102 STP, 103 not STP, 103 STP, 195, 199, 202, 202COV, 203, 295, 299, 940, 942, 950 Added new SWIFT MT high level generated API, with classes for specific message types New source package for generated swift model Merged project \"prowide SWIFT Fields\" into \"WIFE\" Added comparison options to AckMessageComparator Removed old and incorrect charset validator class net.sourceforge.wife.swift.MessageValidator Fix in remove user block method, thanks to Herman's contribution and patience Parser API for (new SwiftParser()).parse(messageToParse); Replaced commons-lang-2.3 -> 2.4 Fixed message writer: system messages' block4 generated with inline tags SwiftMessage API to check if it's Straight Through Processing (STP), based on the content of the User Header SwiftMessage API to check if it's a cover payment (COV), based on the content of the User Header SwiftTagListBlock API to check if contains a specific Tag Removed unimplemented and confusing package net.sourceforge.wife.validation Deprecated old and unused validation-related classes Added AckMessageComparator which is useful of identify the ack of a given message. SwiftTagListBlock API to get a sub block given its name or its starting and ending Tag SwiftTagListBlock API to get tags by content, given its exact or partial value Helper methods from Block4 moved to SwiftTagListBlock SwiftTagListBlock is no longer abstract, so it can be used to create instances for subblocks Required JVM upgrade to 1.5 Initial update of upload-sf target for release to sourceforge","title":"6.0.0-RC1 - October 2010"},{"location":"release-notes/changelog-core/#520-february-2009","text":"Added missing hashcode and equals Javadocs improvements Revised and tested hibernate mappings Added getBlockType Added length to unparsed text persistence mappings Fixed persistence mapping for block2 inheritance Updated hibernate libs to version 3.2.6 Added isOutput isInput made concrete, not abstract Added abstract isInput() method to SwiftBlock2 for safer casting subblocks when input/output is unknown","title":"5.2.0 - February 2009"},{"location":"release-notes/changelog-core/#510-july-2007","text":"Migrated logging to java logging api Removed SwiftBlock's deprecated methods. Moved some common methods in SwiftBlock2Input/SwiftBlock2Output to parent class SwiftBlock2. Upgraded commons-lang to version 2.3 Improved persistence mapping. Move persistence (helper) package to wife-test project. Minor javadoc fixes. Fixed some warnings.","title":"5.1.0 - July 2007"},{"location":"release-notes/changelog-core/#500-june-2007","text":"Improved Hibernate mapping for simplified and more efficient data base schema. Added support for unparsed text to model, persistence mapping and conversion services (needed for some MT0xx for example). XML to SwiftMessage parsing methods moved from ConversionService to XMLParser in \"parser\" package. New package created for parser classes \"net.sourceforge.wife.swift.parser\". Made abstract intermediate classes of blocks object hierarchy. Added support for user custom blocks in model, persistence mapping and conversion services. Improved overall test cases coverage and source/resources structure. Fixed some warnings. Swift Parser enhancements; don't throw exception on unrecognized data, but preserve an internal list of errors. Added reference to current message in parser, so it can take decisions based on parsed data. Added constant for possible values for application id to SwiftBlock1. Updated dependency: hsqldb 1.8.0.4 -> hsqldb 1.8.0.7. Updated dependency: hibernate 3.1.3 -> hibernate 3.2.3.ga.","title":"5.0.0 - June 2007"},{"location":"release-notes/changelog-core/#400-april-2007","text":"Moving to junit 4 - some new tests are being written with junit4, this should make testing some features singificantly easier. Move size and isEmpty methods to subclasses. Improved deprecated exception messages and javadoc. Added useful getter for the MIR field in Block 2 output. Added support for optional fields in Block 2 input. Method specific to each block moved to each block class, when possible compatibility methods were left in old places, marked as deprecated to provide a smoother migration path. Removed deprecated API in SwiftBlock. Adapted parser to new model refactor. More javadoc in parser. Improved xml writer (more clean tabs and EOL). Refactored and fixed XML parsing for blocks 3 and 5. Fixed build.xml to include resources in generated jar files. Improved javadoc and validations in fin writer. Completed basic internal XML parsing. Added more tests for XML conversion. Implemented XML conversion parsing for all blocks (except 4). Updated passing test in conversion service.","title":"4.0.0 - April 2007"},{"location":"release-notes/changelog-core/#340-march-2007","text":"Added license header to source files. Minor fixes in build system. Enhanced IBAN validation routine. Added numerous tests for IBAN validation. Added JSValidationUnit backed by Rhino, to support easy extension of validations. Made all loggers private static transient final. Enhanced overview documentation. Javadoc updates. Code clean up. Added many tag specific validation units targeting MT103 validation. Removed ant junit fork since it broke in ant 1.7.","title":"3.4.0 - March 2007"},{"location":"release-notes/changelog-core/#330-january-2007","text":"Initiated MT103 validation rule. Validation framework core classes written. Utility classes for validation. Removed old and deprecated/replaces writer component. Dependencies clean up, ant downloads less libs now. Added Currency ISO Codes (needed for validations). VF: implemented TagExists and ConditionalTagPresence validation units. Started implementation of validation units. Initial implementation of BIC validation. Initial implementation of IBAN validation. Added ISO Countries for IBAN validation. Fixed issue in writer with block5 as mentioned in bug 1601122. Fixed issue 1595631.","title":"3.3.0 - January 2007"},{"location":"release-notes/changelog-core/#320-2006","text":"Parser logging information cleanup. Migrating to log4j 1.2.8 for better compatibility (issued with trace method on some servers). Fixed build to properly include current timestamp in dist target when property release.name is not set. Fixed bug in parser/writer integration which included double block number when using the writer with an object of a just parsed message(1595589). Updated code to fix issue mentioned in https://sourceforge.net/forum/message.php?msg_id=4001538.","title":"3.2.0 - 2006"},{"location":"release-notes/changelog-core/#311-2006","text":"Small fixes for java 1.4 compatibility.","title":"3.1.1 - 2006"},{"location":"release-notes/changelog-core/#310-2006","text":"Fixes to compile for java 1.4 by default. Fixed test for bug 1540294, typo in block number. Use system EOL in XML writer. Added compile timestamp to manifest in created jars.","title":"3.1.0 - 2006"},{"location":"release-notes/changelog-core/#300-2006","text":"Build: Added release.name property to manifest. Build: added selection of tests known to fail and those known to pass. Fixed persistence mapping. Improved build and added control to exclude tests that are know to fail. Model simplification: SwiftBlockN classes are being removed in favor of base class SwiftBlock removed list of blocks in message which was confusing when not all blocks present. SwiftBlock (base class) and subclasses are mapped and persisted ok, either the base class or the subclasses. Added many tests for Hibernate persistence of SwiftMessage hierarchy. Added XML Visitor to write a swift message to an XML representation. Added ConversionService class which encapsulates many services conveniently.","title":"3.0.0 - 2006"},{"location":"release-notes/changelog-core/#200-2006","text":"New parser component highly tested on production and unit tests. Writer component usable. while it has many limitations, it can be used as it is now. Work in progress swift message persistence mapping. Work in progress swift expression <-> regular expression conversion.","title":"2.0.0 - 2006"},{"location":"release-notes/changelog-guitools/","text":"Prowide GUI Tools - CHANGELOG 9.4.3 - January 2024 (PW-1725) Added support for UETR, in the auto-generation of form values 9.4.2 - November 2023 (PW-1686) In the auto-generation of form values, support both system default times and custom zone id (per user) (PW-1686) Deprecated property in MxConf to override AppHdr dateTime in favor of the new auto generation feature Changed the configuration property to show/hide auto-generated fields in favor of a readonly flag 9.4.1 - October 2023 New feature to enable auto generation of values for some specific paths (added in a config file) to be rendered in the message-entry form. New configuration option to hide or show this auto generated values as inputs in the message-entry form. Fix render UI date fields related with types YearMonth, Year, Month. 9.4.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase 9.3.0 - July 2023 Version aligned with Prowide Integrator 9.3.x for SRU2022 1.2.29 - July 2023 (PW-1446) reduce log verbosity in MX form builder when applying external code set 1.2.28 - January 2023 (PW-1140/PW-1142) Fix duplicated header in MX Form View when multiple header is enabled 1.2.27 - November 2022 (PW-1117) Fix combo pre-select when they contain a single option, the element is mandatory but the parent is optional (PW-1115) Fix comparison paths at verification removing predicates from the fields path 1.2.26 - November 2022 Fixed date picker in BAH headers 2 and 3 1.2.25 - November 2022 Added support for BusinessAppHdrV03 1.2.24 - November 2022 Dependencies and deprecated API updates for SRU2022 Added the customizable IBICDirectory in the form builder write detail method call, since the SdkConfiguration class is deprecated 1.2.23 - October 2022 (PW-1025) Enable relative paths for verification, all the children are considered as verifiable fields 1.2.22 - October 2022 (PW-1071) Fixed MX repairing form when the XML has a non-standard namespace, such as for the SIC4 schemas (PW-1071) Added TARGET_BIC to the elements detected as BIC codes for autocomplete (PW-1071) Fixed date time form elements handling when the XSD pattern is not as in ISO 20022 schemas (PW-1071) Enhancement to pre-select combos when they contain a single option and the element is mandatory (PW-1064) Fallback option to system classloader in resource loading (PW-1000) Fix defaultValue comparison, trimming values at RenderUtil to define selected value in combo 1.2.21 - July 2022 (PW-995) Downgrade jquery-ui from 1.13.0 to 1.12.1 to fix hang problem at html autocomplete inputs (PW-993) Fixed AppHdr creation date for BAH V1 that requires a date in UTC zone with explicit Z suffix 1.2.20 - June 2022 (PW-857) Update jquery from 3.5.0 to 3.5.1 to fix compatibility with bootstrap 1.2.19 - June 2022 (PW-857) Update jquery from 3.4.1 to 3.5.0 and jquery-ui from 1.12.1 to 1.13.0 to fix CVE (PW-495) Fixed unicode replacements to support SICText pattern (PW-495) Enhanced the Mx form builder to support custom schemas with namespace other than the ISO 20022, for example schemas for SIC4 Added support in the MtFormBuilder to create forms from external FIN schemas 1.2.18 - May 2022 (CR-138) New MX form builder configuration option to instruct the map from request to message, to use a custom ZoneId instead of the system default offset New MX form builder configuration option to instruct the map from request to message, to overwrite the MX header creation date time with the current zoned time 1.2.17 - May 2022 (PW-813) Internal enhancement to fix CVE 1.2.16 - May 2022 Internal refactor to use XmlBlock4 from the SDK instead of the legacy xml2mt API New configuration option to enable multiple ISO 2022 header version in the MX forms 1.2.15 - March 2022 (PW-863) Fixed CBPR time element creation in form (PW-860) Message repair does not maintain selected BIC when sender/receiver addresses are parameterized from list (PW-854) Added a parameter to the MX form builder to pass a custom header schema, such as the CBPR+ custom BAH v2 schema Unmarshall/marshal MX form data to apply adapters 1.2.14 - January 2022 (PW-854) fixed CBPR+ datetime pattern processing in the webjar JS when building the XML for the POST 1.2.13 - January 2022 (PW-852) Fixed bug when creating an MX form with the ISO 20022 external code set enabled 1.2.12 - January 2022 (PW-784) Added an option in the MT form builder to create and Output block 2 (along existing options for Input and any direction) (PW-828) Added UETR generator to UETR elements in MX (similar to field 121 in MT block 3) Added bicField class for fields with name starting with AnyBic or BICFI, to enable autocomplete 1.2.11 - December 2021 (PW-407-671) New lenient converter for MT to internal XML to enable repairing in GUI malformed messages (even with missing mandatory fields) (PW-530) Added a \"Content pattern\" title on mouse over on fields with the pattern of the element 1.2.10 - November 2021 (CR-23) Add formatter for Rate fields. (CR-23) Add decimals in Amount Fields. (CR-23) Fix Offset field format. (CR-23) Fix Datetime format at Tree View. 1.2.9 - September 2021 (PW-670) Added a parameter to explicitly indicate the message types for which to generate automatically the UETR 1.2.8 - August 2021 (PW-651) Added a parameter in the MT form builder to customize the indicator for any letter options in MT fields: for example 50a -> 50* (PW-576) fixed propagation of minOccurs from SEQUENCE to children fields 1.2.7 - July 2021 Add a new flag browserAutoComplete to switch on/off HTML Input/TextArea 'autocomplete' property. Fixed css set for bicField, currencyField and countryField in MX 1.2.6 - April 2021 Compatibility update for Prowide Integrator SDK 9.1.11+ 1.2.5 - March 2021 (PW-490) Added the autogenerate/autofill UETR when creating new MT202 and MT205 (PW-490) Added the \"generate new UETR\" button for all the MT messages Minor JS client validation fix of mandatory elements in dynamically added form fields 1.2.4 - March 2021 Fixed generation of sequence boundary field in message repairing Fixed form elements removal after validation action Added codeword to sequence names for better sequence type identification (ex: GENL, LINK, TRADDET) Added the qualifier/codeword in all combo selections along the text description 1.2.3 - March 2021 Fixed bug when repairing messages with a PDM trailer field 1.2.2 - February 2021 Normalized the generated form HTML to use double quotes Added HTML escape to input and textarea values when repairing messages Added org.apache.commons:commons-text:1.6 as dependency 1.2.1 - February 2021 Fixed bug in MT form processing on certain combinations of a nested sequence structure 1.2.0 - January 2021 Added a feature to create message verification forms; with a specific subset of fields as input and the rest as read only 1.1.4 - December 2020 Added support for BIC4 in license 1.1.3 - November 2020 Fixed configuration option to display blocks collapsed by default (example block 3 and 5) Added MtFormBuilder default constructor (with default english locale) 1.1.2 - November 2020 Fixed getElementsByTagName issue in main js 1.1.1 - November 2020 Simplified the MT form rendering, removing intermediate useless combo selectors and toggleable elements Fixed the server side form POST to XML builder for some special category 5 fieldset structures 1.1.0 - November 2020 Added API to build a form with presets from a key-value list (useful to create message from template data) Added MT form configuration per block to enable or disable printing the root element Added MT form configuration per block to show the root element collapsed or expanded Changed the amount formatter to always display the decimal part (even for zero) Refactored the MT form mapping to render the internal XML in the backend instead of client side Added parameters in the form builders to set fixed values for the message sender and receiver Added support for ISO 20022 variants: CBPR+, SEPA, SIC when creating MX forms Added support for Business Application Header version 2 1.0.9 - August 2020 (PW-361) Renamed the internal textarea escape element to avoid conflict with third party JS libraries 1.0.8 - August 2020 Thread safe patch in rendering to avoid: org.xml.sax.SAXException: FWK005 parse may not be called while parsing 1.0.7 - July 2020 Added the sequence alphanumeric identifier to sequence labels in MT Enhanced the tooltip/title documentation definition for elements, and added a configuration flag to switch it off Fixed NPE in MT repair form when the PDE trailer field is present with the tag name only and no value Hide field 15a in MT forms to avoid invalid field validation for this field that has empty value Hide by default the 16R and 16S boundary fields, and several block 1 fields in MT that user's should not fill Enhanced log for unexpected exceptions 1.0.6u1 - July 2020 Recompiled with latest core (8.0.2u1) to avoid NoSuchMethod exception in SwiftMessage 1.0.6 - March 2020 (PW-269) Added lenient support to repair messages with invalid component length and charset Prevent printing id=null when message is not null but id is null (in MX form builder) 1.0.5 - January 2020 Fixed XXE vulnerability processing form POST data Prevent printing id=null when message is not null but id is null Added a formatter to the MX mapper to have the created XML with indentation 1.0.4 - December 2019 (PW-226) Added support for the legacy SWIFT application header v10 as alternative for the ISO business header 1.0.3 - December 2019 (PW-193) Added support for character set extensions (such as Arabic) in the form configuration 1.0.2 - October 2019 Fixed license check in message detail function (PW-199) Updated jquery 1.12.2 -> 3.4.1 Updated jquery.validate 1.15.0 -> 1.19.0 Updated jquery.mask 1.14.0 -> 1.14.15 Updated jquery.inputmask 3.3.2-106 -> 3.3.7 1.0.1 - August 2019 Added lenient handling of EOLS (supporting either LF or CRLF) in the MT form builder when repairing messages 1.0.0 Added option to include the raw value in select option, active by default, for example \"Shared Charges (SHA)\" Webjars compliance for resources First release as standalone library, extracted from Prowide Enterprise Message Entry module","title":"Prowide GUI Tools"},{"location":"release-notes/changelog-guitools/#prowide-gui-tools-changelog","text":"","title":"Prowide GUI Tools - CHANGELOG"},{"location":"release-notes/changelog-guitools/#943-january-2024","text":"(PW-1725) Added support for UETR, in the auto-generation of form values","title":"9.4.3 - January 2024"},{"location":"release-notes/changelog-guitools/#942-november-2023","text":"(PW-1686) In the auto-generation of form values, support both system default times and custom zone id (per user) (PW-1686) Deprecated property in MxConf to override AppHdr dateTime in favor of the new auto generation feature Changed the configuration property to show/hide auto-generated fields in favor of a readonly flag","title":"9.4.2 - November 2023"},{"location":"release-notes/changelog-guitools/#941-october-2023","text":"New feature to enable auto generation of values for some specific paths (added in a config file) to be rendered in the message-entry form. New configuration option to hide or show this auto generated values as inputs in the message-entry form. Fix render UI date fields related with types YearMonth, Year, Month.","title":"9.4.1 - October 2023"},{"location":"release-notes/changelog-guitools/#940-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase","title":"9.4.0 - May 2023"},{"location":"release-notes/changelog-guitools/#930-july-2023","text":"Version aligned with Prowide Integrator 9.3.x for SRU2022","title":"9.3.0 - July 2023"},{"location":"release-notes/changelog-guitools/#1229-july-2023","text":"(PW-1446) reduce log verbosity in MX form builder when applying external code set","title":"1.2.29 - July 2023"},{"location":"release-notes/changelog-guitools/#1228-january-2023","text":"(PW-1140/PW-1142) Fix duplicated header in MX Form View when multiple header is enabled","title":"1.2.28 - January 2023"},{"location":"release-notes/changelog-guitools/#1227-november-2022","text":"(PW-1117) Fix combo pre-select when they contain a single option, the element is mandatory but the parent is optional (PW-1115) Fix comparison paths at verification removing predicates from the fields path","title":"1.2.27 - November 2022"},{"location":"release-notes/changelog-guitools/#1226-november-2022","text":"Fixed date picker in BAH headers 2 and 3","title":"1.2.26 - November 2022"},{"location":"release-notes/changelog-guitools/#1225-november-2022","text":"Added support for BusinessAppHdrV03","title":"1.2.25 - November 2022"},{"location":"release-notes/changelog-guitools/#1224-november-2022","text":"Dependencies and deprecated API updates for SRU2022 Added the customizable IBICDirectory in the form builder write detail method call, since the SdkConfiguration class is deprecated","title":"1.2.24 - November 2022"},{"location":"release-notes/changelog-guitools/#1223-october-2022","text":"(PW-1025) Enable relative paths for verification, all the children are considered as verifiable fields","title":"1.2.23 - October 2022"},{"location":"release-notes/changelog-guitools/#1222-october-2022","text":"(PW-1071) Fixed MX repairing form when the XML has a non-standard namespace, such as for the SIC4 schemas (PW-1071) Added TARGET_BIC to the elements detected as BIC codes for autocomplete (PW-1071) Fixed date time form elements handling when the XSD pattern is not as in ISO 20022 schemas (PW-1071) Enhancement to pre-select combos when they contain a single option and the element is mandatory (PW-1064) Fallback option to system classloader in resource loading (PW-1000) Fix defaultValue comparison, trimming values at RenderUtil to define selected value in combo","title":"1.2.22 - October 2022"},{"location":"release-notes/changelog-guitools/#1221-july-2022","text":"(PW-995) Downgrade jquery-ui from 1.13.0 to 1.12.1 to fix hang problem at html autocomplete inputs (PW-993) Fixed AppHdr creation date for BAH V1 that requires a date in UTC zone with explicit Z suffix","title":"1.2.21 - July 2022"},{"location":"release-notes/changelog-guitools/#1220-june-2022","text":"(PW-857) Update jquery from 3.5.0 to 3.5.1 to fix compatibility with bootstrap","title":"1.2.20 - June 2022"},{"location":"release-notes/changelog-guitools/#1219-june-2022","text":"(PW-857) Update jquery from 3.4.1 to 3.5.0 and jquery-ui from 1.12.1 to 1.13.0 to fix CVE (PW-495) Fixed unicode replacements to support SICText pattern (PW-495) Enhanced the Mx form builder to support custom schemas with namespace other than the ISO 20022, for example schemas for SIC4 Added support in the MtFormBuilder to create forms from external FIN schemas","title":"1.2.19 - June 2022"},{"location":"release-notes/changelog-guitools/#1218-may-2022","text":"(CR-138) New MX form builder configuration option to instruct the map from request to message, to use a custom ZoneId instead of the system default offset New MX form builder configuration option to instruct the map from request to message, to overwrite the MX header creation date time with the current zoned time","title":"1.2.18 - May 2022"},{"location":"release-notes/changelog-guitools/#1217-may-2022","text":"(PW-813) Internal enhancement to fix CVE","title":"1.2.17 - May 2022"},{"location":"release-notes/changelog-guitools/#1216-may-2022","text":"Internal refactor to use XmlBlock4 from the SDK instead of the legacy xml2mt API New configuration option to enable multiple ISO 2022 header version in the MX forms","title":"1.2.16 - May 2022"},{"location":"release-notes/changelog-guitools/#1215-march-2022","text":"(PW-863) Fixed CBPR time element creation in form (PW-860) Message repair does not maintain selected BIC when sender/receiver addresses are parameterized from list (PW-854) Added a parameter to the MX form builder to pass a custom header schema, such as the CBPR+ custom BAH v2 schema Unmarshall/marshal MX form data to apply adapters","title":"1.2.15 - March 2022"},{"location":"release-notes/changelog-guitools/#1214-january-2022","text":"(PW-854) fixed CBPR+ datetime pattern processing in the webjar JS when building the XML for the POST","title":"1.2.14 - January 2022"},{"location":"release-notes/changelog-guitools/#1213-january-2022","text":"(PW-852) Fixed bug when creating an MX form with the ISO 20022 external code set enabled","title":"1.2.13 - January 2022"},{"location":"release-notes/changelog-guitools/#1212-january-2022","text":"(PW-784) Added an option in the MT form builder to create and Output block 2 (along existing options for Input and any direction) (PW-828) Added UETR generator to UETR elements in MX (similar to field 121 in MT block 3) Added bicField class for fields with name starting with AnyBic or BICFI, to enable autocomplete","title":"1.2.12 - January 2022"},{"location":"release-notes/changelog-guitools/#1211-december-2021","text":"(PW-407-671) New lenient converter for MT to internal XML to enable repairing in GUI malformed messages (even with missing mandatory fields) (PW-530) Added a \"Content pattern\" title on mouse over on fields with the pattern of the element","title":"1.2.11 - December 2021"},{"location":"release-notes/changelog-guitools/#1210-november-2021","text":"(CR-23) Add formatter for Rate fields. (CR-23) Add decimals in Amount Fields. (CR-23) Fix Offset field format. (CR-23) Fix Datetime format at Tree View.","title":"1.2.10 - November 2021"},{"location":"release-notes/changelog-guitools/#129-september-2021","text":"(PW-670) Added a parameter to explicitly indicate the message types for which to generate automatically the UETR","title":"1.2.9 - September 2021"},{"location":"release-notes/changelog-guitools/#128-august-2021","text":"(PW-651) Added a parameter in the MT form builder to customize the indicator for any letter options in MT fields: for example 50a -> 50* (PW-576) fixed propagation of minOccurs from SEQUENCE to children fields","title":"1.2.8 - August 2021"},{"location":"release-notes/changelog-guitools/#127-july-2021","text":"Add a new flag browserAutoComplete to switch on/off HTML Input/TextArea 'autocomplete' property. Fixed css set for bicField, currencyField and countryField in MX","title":"1.2.7 - July 2021"},{"location":"release-notes/changelog-guitools/#126-april-2021","text":"Compatibility update for Prowide Integrator SDK 9.1.11+","title":"1.2.6 - April 2021"},{"location":"release-notes/changelog-guitools/#125-march-2021","text":"(PW-490) Added the autogenerate/autofill UETR when creating new MT202 and MT205 (PW-490) Added the \"generate new UETR\" button for all the MT messages Minor JS client validation fix of mandatory elements in dynamically added form fields","title":"1.2.5 - March 2021"},{"location":"release-notes/changelog-guitools/#124-march-2021","text":"Fixed generation of sequence boundary field in message repairing Fixed form elements removal after validation action Added codeword to sequence names for better sequence type identification (ex: GENL, LINK, TRADDET) Added the qualifier/codeword in all combo selections along the text description","title":"1.2.4 - March 2021"},{"location":"release-notes/changelog-guitools/#123-march-2021","text":"Fixed bug when repairing messages with a PDM trailer field","title":"1.2.3 - March 2021"},{"location":"release-notes/changelog-guitools/#122-february-2021","text":"Normalized the generated form HTML to use double quotes Added HTML escape to input and textarea values when repairing messages Added org.apache.commons:commons-text:1.6 as dependency","title":"1.2.2 - February 2021"},{"location":"release-notes/changelog-guitools/#121-february-2021","text":"Fixed bug in MT form processing on certain combinations of a nested sequence structure","title":"1.2.1 - February 2021"},{"location":"release-notes/changelog-guitools/#120-january-2021","text":"Added a feature to create message verification forms; with a specific subset of fields as input and the rest as read only","title":"1.2.0 - January 2021"},{"location":"release-notes/changelog-guitools/#114-december-2020","text":"Added support for BIC4 in license","title":"1.1.4 - December 2020"},{"location":"release-notes/changelog-guitools/#113-november-2020","text":"Fixed configuration option to display blocks collapsed by default (example block 3 and 5) Added MtFormBuilder default constructor (with default english locale)","title":"1.1.3 - November 2020"},{"location":"release-notes/changelog-guitools/#112-november-2020","text":"Fixed getElementsByTagName issue in main js","title":"1.1.2 - November 2020"},{"location":"release-notes/changelog-guitools/#111-november-2020","text":"Simplified the MT form rendering, removing intermediate useless combo selectors and toggleable elements Fixed the server side form POST to XML builder for some special category 5 fieldset structures","title":"1.1.1 - November 2020"},{"location":"release-notes/changelog-guitools/#110-november-2020","text":"Added API to build a form with presets from a key-value list (useful to create message from template data) Added MT form configuration per block to enable or disable printing the root element Added MT form configuration per block to show the root element collapsed or expanded Changed the amount formatter to always display the decimal part (even for zero) Refactored the MT form mapping to render the internal XML in the backend instead of client side Added parameters in the form builders to set fixed values for the message sender and receiver Added support for ISO 20022 variants: CBPR+, SEPA, SIC when creating MX forms Added support for Business Application Header version 2","title":"1.1.0 - November 2020"},{"location":"release-notes/changelog-guitools/#109-august-2020","text":"(PW-361) Renamed the internal textarea escape element to avoid conflict with third party JS libraries","title":"1.0.9 - August 2020"},{"location":"release-notes/changelog-guitools/#108-august-2020","text":"Thread safe patch in rendering to avoid: org.xml.sax.SAXException: FWK005 parse may not be called while parsing","title":"1.0.8 - August 2020"},{"location":"release-notes/changelog-guitools/#107-july-2020","text":"Added the sequence alphanumeric identifier to sequence labels in MT Enhanced the tooltip/title documentation definition for elements, and added a configuration flag to switch it off Fixed NPE in MT repair form when the PDE trailer field is present with the tag name only and no value Hide field 15a in MT forms to avoid invalid field validation for this field that has empty value Hide by default the 16R and 16S boundary fields, and several block 1 fields in MT that user's should not fill Enhanced log for unexpected exceptions","title":"1.0.7 - July 2020"},{"location":"release-notes/changelog-guitools/#106u1-july-2020","text":"Recompiled with latest core (8.0.2u1) to avoid NoSuchMethod exception in SwiftMessage","title":"1.0.6u1 - July 2020"},{"location":"release-notes/changelog-guitools/#106-march-2020","text":"(PW-269) Added lenient support to repair messages with invalid component length and charset Prevent printing id=null when message is not null but id is null (in MX form builder)","title":"1.0.6 - March 2020"},{"location":"release-notes/changelog-guitools/#105-january-2020","text":"Fixed XXE vulnerability processing form POST data Prevent printing id=null when message is not null but id is null Added a formatter to the MX mapper to have the created XML with indentation","title":"1.0.5 - January 2020"},{"location":"release-notes/changelog-guitools/#104-december-2019","text":"(PW-226) Added support for the legacy SWIFT application header v10 as alternative for the ISO business header","title":"1.0.4 - December 2019"},{"location":"release-notes/changelog-guitools/#103-december-2019","text":"(PW-193) Added support for character set extensions (such as Arabic) in the form configuration","title":"1.0.3 - December 2019"},{"location":"release-notes/changelog-guitools/#102-october-2019","text":"Fixed license check in message detail function (PW-199) Updated jquery 1.12.2 -> 3.4.1 Updated jquery.validate 1.15.0 -> 1.19.0 Updated jquery.mask 1.14.0 -> 1.14.15 Updated jquery.inputmask 3.3.2-106 -> 3.3.7","title":"1.0.2 - October 2019"},{"location":"release-notes/changelog-guitools/#101-august-2019","text":"Added lenient handling of EOLS (supporting either LF or CRLF) in the MT form builder when repairing messages","title":"1.0.1 - August 2019"},{"location":"release-notes/changelog-guitools/#100","text":"Added option to include the raw value in select option, active by default, for example \"Shared Charges (SHA)\" Webjars compliance for resources First release as standalone library, extracted from Prowide Enterprise Message Entry module","title":"1.0.0"},{"location":"release-notes/changelog-iso20022/","text":"Prowide ISO 20022 - CHANGELOG 9.4.5 - May 2024 (PW-1875) Changed the BusinessApplicationHeaderV01 marshaller to always use Zulu timezone with \"Z\" indicator 9.4.4 - January 2024 Enhanced the identifier extraction of the MxSwiftMessage to use the AppHdr when the Document namespace is missing Enhanced the generic AbstractMX#parse to detect the message type from the AppHdr when the Document namespace is missing Added default metadata extraction implementation for pacs and camt amounts and value dates Added default methods for sender, receiver, and identifier extraction to the MxSwiftMessage. Replaced the DistinguishedName parse logic with proprietary util class from the Prowide Core library 9.4.3 - August 2023 Enhanced metadata extraction for xsys messages getting sender/receiver BICs from the RequestHeader element Make the message metadata extraction lenient, by fixing the XML instruction of the payload when it contains invalid case 9.4.2 - July 2023 Added new utility class SupplementaryDataUtils to facilitate \"SplmtryData\" extraction from MX messages 9.4.1 - June 2023 (PW-1392) Fixed the default escape handler when serializing model objects into XML, that was duplicated quote characters in the output 9.4.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 9.3.6 - March 2023 (GH-74) Added a parameter in the MxWriteParams to define a custom indentation string to use when marshalling into XML 9.3.5 - January 2023 Added an optional way to pass a JaxbContext instance to the parse and write methods 9.3.4 - November 2022 (GH-63) Added message type versions in categories: acmt, admi, auth, caaa, camt, catm, fxtr, pacs, reda, seev, semt, sese, setr, supl and trck Added new business process and messages for: caad, cafc, cain, casp Removed obsolete trea (treasury) message types Added model and support for the BusinessApplicationHeaderV03 9.3.3 - October 2022 (PW-1082) Added support in the JaxbContextCache and its default implementation to create the context without the classes parameter 9.3.2 - August 2022 (PW-922) Added a parameter in the MxReadParams used by the AbstractMX#parse to control the log verbosity when parsing unrecognized messages 9.3.1 - August 2022 Added model for \"trck\" types 9.3.0 - May 2022 SWIFT Standard release update 2022 (live 21 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Updated gson dependency to 2.9.0 (GH-45) Fixed Json serialization in Java 17 9.2.6 - March 2022 (GH-36) Added customizable datetime, date and time adapter in the MxWriteConfiguration, MxReadConfiguration Changed the default date time serialization to local time with UTC offset format YYYY-MM-DDThh ss[.sss]+/-hh:mm Changed the default time serialization to local time with UTC offset format hh ss[.sss]+/-hh:mm Encapsulated the serialization options in a DTO, when calling xml or message methods in AbstractMX and AppHdr Validate.notNull -> Objects.requireNonNull 9.2.5 - January 2022 (GH-37) Updated dependency: gson:2.8.8 -> gson:2.8.9 9.2.4 - December 2021 Added com.prowidesoftware.iso20022 as automatic module name in the MANIFEST for JPMS support 9.2.3 - October 2021 Updated dependency: Apache Commons Lang 3.8.1 -> 3.12.0 Updated dependency: Apache Commons Text 1.6 -> 1.9 Updated dependency: Gson 2.8.2 -> 2.8.8 9.2.2 - October 2021 (PW-584) Enhanced the XML serialization to use localized line separators 9.2.1 - June 2021 NamespaceReader utility class made public with method to extract namespaces from XML, or to check if an element exists NamespaceAndElementFilter made public, used by the parser, handy to implement a validator (GH-26) Fixed AppHdr JSON conversion with explicit new namespace field as discriminator (GH-24) Added a new MxWriteConfiguration and EscapeHandler API to tweak the serialization into XML 9.2.0 - May 2021 SWIFT Standard release update 2021 (live 22 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.1.6 - April 2021 (GH-17|PW-506) Enhanced the XML format in the serializing, spaces and line breaks (GH-18) Fixed NPE in json serialization/deserialization of XMLGregorianCalendar fractional second Added customizable strategies to set the MxSwiftMessage metadata fields: reference, main amount, value date, etc... 9.1.5 - December 2020 (GH-8) (JR-428) Fixed parser to skip unbounded content such as the @XmlAnyElement(lax = true) elements used in many schemas for supplementary data 9.1.4 - November 2020 Fixed javadoc jar 9.1.3 - October 2020 Fixed pom file 9.1.2 - October 2020 Added AppHdrType enum and AppHdrFactory method to create headers with the enum as parameter Added targetNamespace method to the AbstractMX Internal SCM refactor for OS release Revamped the parser implementation with SAX to avoid custom namespace preprocessing Added AppHdrParser utility class Removed the CopyableTo implementation from the generated model Change the generic AbstractMX#parse to throw runtime exception when XML parameter is blank or null (same semantic as Mx classes parse method) 9.1.1 - September 2021 Removed blank lines in MX writer (marshalling) Fixed generic AbstractMX parse for system messages (xsys) 9.1.0 - May 2020 SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.0.1 - May 2021 Added a new extensible interface based model for the application headers: AppHdr Added support for the ISO Business Application Header version 2: head.001.001.02 9.0.0 - May 2020 ISO 20022 module extracted from Prowide Integrator to its own library, with its own version from now on","title":"Prowide ISO 20022"},{"location":"release-notes/changelog-iso20022/#prowide-iso-20022-changelog","text":"","title":"Prowide ISO 20022 - CHANGELOG"},{"location":"release-notes/changelog-iso20022/#945-may-2024","text":"(PW-1875) Changed the BusinessApplicationHeaderV01 marshaller to always use Zulu timezone with \"Z\" indicator","title":"9.4.5 - May 2024"},{"location":"release-notes/changelog-iso20022/#944-january-2024","text":"Enhanced the identifier extraction of the MxSwiftMessage to use the AppHdr when the Document namespace is missing Enhanced the generic AbstractMX#parse to detect the message type from the AppHdr when the Document namespace is missing Added default metadata extraction implementation for pacs and camt amounts and value dates Added default methods for sender, receiver, and identifier extraction to the MxSwiftMessage. Replaced the DistinguishedName parse logic with proprietary util class from the Prowide Core library","title":"9.4.4 - January 2024"},{"location":"release-notes/changelog-iso20022/#943-august-2023","text":"Enhanced metadata extraction for xsys messages getting sender/receiver BICs from the RequestHeader element Make the message metadata extraction lenient, by fixing the XML instruction of the payload when it contains invalid case","title":"9.4.3 - August 2023"},{"location":"release-notes/changelog-iso20022/#942-july-2023","text":"Added new utility class SupplementaryDataUtils to facilitate \"SplmtryData\" extraction from MX messages","title":"9.4.2 - July 2023"},{"location":"release-notes/changelog-iso20022/#941-june-2023","text":"(PW-1392) Fixed the default escape handler when serializing model objects into XML, that was duplicated quote characters in the output","title":"9.4.1 - June 2023"},{"location":"release-notes/changelog-iso20022/#940-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"9.4.0 - May 2023"},{"location":"release-notes/changelog-iso20022/#936-march-2023","text":"(GH-74) Added a parameter in the MxWriteParams to define a custom indentation string to use when marshalling into XML","title":"9.3.6 - March 2023"},{"location":"release-notes/changelog-iso20022/#935-january-2023","text":"Added an optional way to pass a JaxbContext instance to the parse and write methods","title":"9.3.5 - January 2023"},{"location":"release-notes/changelog-iso20022/#934-november-2022","text":"(GH-63) Added message type versions in categories: acmt, admi, auth, caaa, camt, catm, fxtr, pacs, reda, seev, semt, sese, setr, supl and trck Added new business process and messages for: caad, cafc, cain, casp Removed obsolete trea (treasury) message types Added model and support for the BusinessApplicationHeaderV03","title":"9.3.4 - November 2022"},{"location":"release-notes/changelog-iso20022/#933-october-2022","text":"(PW-1082) Added support in the JaxbContextCache and its default implementation to create the context without the classes parameter","title":"9.3.3 - October 2022"},{"location":"release-notes/changelog-iso20022/#932-august-2022","text":"(PW-922) Added a parameter in the MxReadParams used by the AbstractMX#parse to control the log verbosity when parsing unrecognized messages","title":"9.3.2 - August 2022"},{"location":"release-notes/changelog-iso20022/#931-august-2022","text":"Added model for \"trck\" types","title":"9.3.1 - August 2022"},{"location":"release-notes/changelog-iso20022/#930-may-2022","text":"SWIFT Standard release update 2022 (live 21 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Updated gson dependency to 2.9.0 (GH-45) Fixed Json serialization in Java 17","title":"9.3.0 - May 2022"},{"location":"release-notes/changelog-iso20022/#926-march-2022","text":"(GH-36) Added customizable datetime, date and time adapter in the MxWriteConfiguration, MxReadConfiguration Changed the default date time serialization to local time with UTC offset format YYYY-MM-DDThh ss[.sss]+/-hh:mm Changed the default time serialization to local time with UTC offset format hh ss[.sss]+/-hh:mm Encapsulated the serialization options in a DTO, when calling xml or message methods in AbstractMX and AppHdr Validate.notNull -> Objects.requireNonNull","title":"9.2.6 - March 2022"},{"location":"release-notes/changelog-iso20022/#925-january-2022","text":"(GH-37) Updated dependency: gson:2.8.8 -> gson:2.8.9","title":"9.2.5 - January 2022"},{"location":"release-notes/changelog-iso20022/#924-december-2021","text":"Added com.prowidesoftware.iso20022 as automatic module name in the MANIFEST for JPMS support","title":"9.2.4 - December 2021"},{"location":"release-notes/changelog-iso20022/#923-october-2021","text":"Updated dependency: Apache Commons Lang 3.8.1 -> 3.12.0 Updated dependency: Apache Commons Text 1.6 -> 1.9 Updated dependency: Gson 2.8.2 -> 2.8.8","title":"9.2.3 - October 2021"},{"location":"release-notes/changelog-iso20022/#922-october-2021","text":"(PW-584) Enhanced the XML serialization to use localized line separators","title":"9.2.2 - October 2021"},{"location":"release-notes/changelog-iso20022/#921-june-2021","text":"NamespaceReader utility class made public with method to extract namespaces from XML, or to check if an element exists NamespaceAndElementFilter made public, used by the parser, handy to implement a validator (GH-26) Fixed AppHdr JSON conversion with explicit new namespace field as discriminator (GH-24) Added a new MxWriteConfiguration and EscapeHandler API to tweak the serialization into XML","title":"9.2.1 - June 2021"},{"location":"release-notes/changelog-iso20022/#920-may-2021","text":"SWIFT Standard release update 2021 (live 22 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.2.0 - May 2021"},{"location":"release-notes/changelog-iso20022/#916-april-2021","text":"(GH-17|PW-506) Enhanced the XML format in the serializing, spaces and line breaks (GH-18) Fixed NPE in json serialization/deserialization of XMLGregorianCalendar fractional second Added customizable strategies to set the MxSwiftMessage metadata fields: reference, main amount, value date, etc...","title":"9.1.6 - April 2021"},{"location":"release-notes/changelog-iso20022/#915-december-2020","text":"(GH-8) (JR-428) Fixed parser to skip unbounded content such as the @XmlAnyElement(lax = true) elements used in many schemas for supplementary data","title":"9.1.5 - December 2020"},{"location":"release-notes/changelog-iso20022/#914-november-2020","text":"Fixed javadoc jar","title":"9.1.4 - November 2020"},{"location":"release-notes/changelog-iso20022/#913-october-2020","text":"Fixed pom file","title":"9.1.3 - October 2020"},{"location":"release-notes/changelog-iso20022/#912-october-2020","text":"Added AppHdrType enum and AppHdrFactory method to create headers with the enum as parameter Added targetNamespace method to the AbstractMX Internal SCM refactor for OS release Revamped the parser implementation with SAX to avoid custom namespace preprocessing Added AppHdrParser utility class Removed the CopyableTo implementation from the generated model Change the generic AbstractMX#parse to throw runtime exception when XML parameter is blank or null (same semantic as Mx classes parse method)","title":"9.1.2 - October 2020"},{"location":"release-notes/changelog-iso20022/#911-september-2021","text":"Removed blank lines in MX writer (marshalling) Fixed generic AbstractMX parse for system messages (xsys)","title":"9.1.1 - September 2021"},{"location":"release-notes/changelog-iso20022/#910-may-2020","text":"SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.1.0 - May 2020"},{"location":"release-notes/changelog-iso20022/#901-may-2021","text":"Added a new extensible interface based model for the application headers: AppHdr Added support for the ISO Business Application Header version 2: head.001.001.02","title":"9.0.1 - May 2021"},{"location":"release-notes/changelog-iso20022/#900-may-2020","text":"ISO 20022 module extracted from Prowide Integrator to its own library, with its own version from now on","title":"9.0.0 - May 2020"},{"location":"release-notes/changelog-myformat/","text":"Prowide Integrator MyFormat - CHANGELOG 9.4.6 - June 2024 Added a convenient write method with default write mode in the MessageWriter interface 9.4.5 - December 2023 Added schema paths validation for source and target selectors in the conversion from or to MX 9.4.4 - October 2023 (PW-1604) Added concat function to MatrixReader in order to allow retrieving multiples source value during foreach iterations 9.4.3 - October 2023 (PW-1642) Changed the mapping validator to enable literal() in the source selector, this makes sense when combined with a defaultString(value) transformation 9.4.2 - September 2023 (PW-1118) Changed MtReader in order to include null value items in readMany results when valueSelector is used 9.4.1 - June 2023 Enhancements to fully support propagation of foreach indexes into the target selectors, including Line, such asf A[2]/B[{n}]/B1[3]/23A[{m}]/Line[{o}] 9.4.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 9.3.14 - May 2023 (PW-1370) Fixed the MxReader so that it can properly extract content from /AppHdr and /Document paths in conversions from MX (PW-1232) Changed the CSV writer to be more lenient; enabling empty rows, auto extend by default when using addRows, and single separator in the whole CSV Internal implementation enhancement 9.3.13 - April 2023 Refactored the MappingTable spreadsheet loader to use the new MappingTableExcelLoader Refactored the MappingValidator in order to optimize the Rules Parsing, Validation and Process steps 9.3.12 - March 2023 Fixed transformation toTimeZone when both source and target zone identifiers are used as parameters 9.3.11 - March 2023 Internal implementation enhancement in the SETUP commands API 9.3.10 - February 2023 (PW-1174) Added SETUP function to indicate the appHdrType for MX messages in the externalized configuration (spreadsheet or DB) Added support for Zone Ids such as \"America/Argentina\" to the offset parameters in the transformation functions 9.3.9 - February 2023 Added transformation now() to get the current datetime in local timezone, formatted as yyyy-MM-dd'T'HH ss.SSSZ (ISO 8601) Added transformation now(utcOffset)to get the current datetime in the specified time-zone, formatted as yyyy-MM-dd'T'HH ss.SSSZ (ISO 8601) Added transformation uetr() to generates a new random UETR (unique end to end reference) used in both MT and ISO 20022 messages Added transformation toTimeZone(dateTimeFormat, targetOffset) to transform a given datetime in local time and convert it to the target UTC timezone Added transformation toTimeZone(dateTimeFormat, sourceOffset, targetOffset) to transform an input datetime from a specific UTC timezone to another MtPath enhancement to enable using component names (labels) in the selector expressions instead of component numbers 9.3.8 - January 2023 Enhanced selector validation, checking that value selectors (secondary selector in expression) do not contain variables Added support for JSON as source and target formats for the conversion 9.3.7 - December 2022 (PW-1118) minor fixes and added \"@main\" to MtReader to work with main message (when processing an attachment) Minor internal code enhancements Fixed error text formatting in transformations validation 9.3.6 - December 2022 (PW-1105) Added support in the CSV writer setup to pass \"\\t\" as parameter to require the tab character as separator Added a constraint for the CsvFieldsDef to match the pattern ([A-Za-z0-9_]*) and thus avoid mapping selector parsing issues 9.3.5 - November 2022 Updated Apache Commons Text dependency to 1.10 to fix reported CVE Added SETUP functions to indicate the source and target formats in the externalized configuration (spreadsheet or DB) Added SETUP functions to indicate the target MT type or target MX type in the externalized configuration (spreadsheet or DB) Added SETUP function to set up the mapping name in the externalized configuration (spreadsheet or DB) Added support in the MtWriter to generate automatically the field 15 in the sequences separated by 15a 9.3.4 - October 2022 Added API in the MxWriter to configure the specific AppHdr version to use when creating MX messages as output Set the default AppHdr version when creating MX messages to ISO Business Application Header v2 Added ifElse power function to facilitate conditional mappings 9.3.3 - October 2022 (PW-1064) Fallback option to system classloader in resource loading 9.3.2 - September 2022 Added transformation functions logicalTerminalAddress, logicalTerminalAddressSend and logicalTerminalAddressReceive Added transformation function sum 9.3.1 - August 2022 (PW-1010) Added an automatic sanitization when converting into MT, to fix start of line characters and some missing components 9.3.0 - May 2022 SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.2.6 - May 2022 (PW-813) Internal enhancement to fix CVE Deprecation API review 9.2.5 - April 2022 Minor fix in the database loader, to set the table name with the configuration name parameter Fixed mapping table validation when there are SETUP commands in the mappings Minor internal code enhancements Prowide Integrator SDK and Prowide Core updates 9.2.4 - January 2022 Prowide Integrator SDK and Prowide Core updates 9.2.3 - December 2021 Added com.prowidesoftware.integrator.myformat as automatic module name in the MANIFEST for JPMS support 9.2.2 - June 2021 Added support to read and write block 5 fields with selectors such as \"b5/CHK\" 9.2.1 - June 2021 (PW-527) Additional change in the XML and MX reader to trim indentation and trailing spaces from elements while preserving line feeds (PW-527) Changed the XML and MX reader to preserve whitespaces from elements content (PW-527) Added transformation functions wrapLinesPreserve and wrapLinesPreservePrepend 9.2.0 - May 2021 SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.1.8 - April 2021 (PW-502) Added MappingTableDatabaseLoader for more flexible data base access and querying when load the mappings 9.1.7 - March 2021 (PW-480) Fixed mapping into block 2 using whole block value as input data 9.1.6 - February 2021 Added validation of the new SETUP commands: separator, smartQuotes, smartEscapes, addFieldNames and columnNames 9.1.5 - January 2021 Fixed CSV writer with APPEND mode Added SETUP commands to the externalized mapping into CSV: separator, smartQuotes, smartEscapes, addFieldNames and columnNames 9.1.4 - January 2021 Fixed semantic of the MtReader to return null content if the MT selector targets a missing field component Fixed transformation \"rightPad\" Fixed transformation \"formatDecimal\" when input number contains decimal separator and no decimal digits (valid case in MT amounts) Fixed transformation \"fixed\" to avoud setting the default value if the input content is null (not found in source) Fixed transformations \"append\", \"prepend\", \"replaceIfEquals\" and \"wrap\" to avoid generating value if input is null Fixed transformations \"indexOf\", \"indexOfIgnoreCase\", \"lastIndexOf\" and \"lastIndexOfIgnoreCase\" when found substring is at index 0 Enhanced number parse exception handling in transformations using or expecting integers and decimal numbers 9.1.3 - December 2020 License check review 9.1.2 - November 2020 (CR-27) Added support for forced double quotes for CSVWriter (CR-27) Added support for disable smart escaping (ex: comma inside double quotes are not escaped) for CSVWriter (CR-27) Added support to generate header column with field names for CSVWriter (CR-29) Added support in the MtWriter to create internal loop (sequences without 16R and 16S boundary) present for example in MT940 (CR-28) Added support in the MtWriter to create block 1 and block 2 from whole value strings (not targeting individual fields) (CR-28) Added support in the MtReader to retrieve the whole block 1 or block 2 value with selectors \"b1\" and \"b2\" Minor fix in formatDecimal transformation when default locale has comma for decimal separator 9.1.1 - September 2020 (PW-334) Added backward compatibility support for custom(\"MyCustomTransformer\") in the mapping transformations 9.1.0 - May 2020 SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.0.1 - May 2020 Internal implementation changes to the use the new AppHdr model in the SDK 9.0.0 - May 2020 MyFormat module extracted to its own jar in the distribution, with its own version from now on 8.0.7 - May 2020 Added a CsvReader constructor parsing a whole csv where the first row is used as field definition for the mappings Fixed index in CsvFieldsDef constructor to be zero-based instead of one-based 8.0.6 - February 2020 (PW-237) Added ifMatches and IfNotMatches power functions to facilitate conditional mappings 8.0.3 - September 2019 (PW-179) Added support for custom transformations in externalized mapping tables Added support for header rows skip configuration in CsvReader 8.0.2 - August 2019 Added support in the CsvFileReader for the header offset parameter, rows are now skipped directly by the Iterator 8.0.1 - July 2019 Fixed XML and MX writer to avoid creating empty elements if the source content is null Fixed bug in MX/XML writer when creating more than 100 target elements in a rule with variables Added support for foreach when converting from MT 8.0.0 - May 2019 JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 7.10.9 - May 2019 Enhanced selectors for CSV with support for repetition, variables and filters. Added support for FIXED-LENGTH files as source and target message format. Added API to load the mappings from a database, providing a data source or a context name for JNDI lookup Added automatic sequence creation in conversions to MT, for example /E/E1/95Q will create E and E1 boundary fields Fixed block 3 fields order when target is MT and the writer has a pre-filled block 3 Added CONCAT function in source selector to combine the result of a list of selectors in a single rule Added wrapLinesPrepend transformation to split content in to lines, with both fixed length and a prefix Added support for FOREACH in the mappings to process a list of source elements in a single rule Added support for parameterized predicates in the selector to map repetitions from source to target message Added the token LITERAL as alternative to indicate a source content is a plain literal instead of a selector Enhanced reporting in the mapping rules validation, detail message when the selectors are invalid 7.10.8 - March 2019 Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Fixed obfuscation to keep directories in jar Added transformation: abbreviate, unwrap, wrapLines, remove and replace functions based on regex Added support for custom transformation functions When using the CsvFileReader, the iteration counter variable can be used in both target and source selectors Fixed handling of row header offset in CsvFileReader Fixed CSV selector for empty column values (consecutive split characters without values) 7.10.7 - January 2019 Added a constructor with AbstractMT in the MtWriter to initialize the writer with a pre-filled message Added MessageReaderIterator to do n to 1 translations from multiple rows in CSV to single consolidated output Added constructors to create MxWriter from existing AbstractMX message and from MxType identifier 7.10.0 - April 2018 SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 7.9.7 - January 2018 Changes in the distribution package: Command line tools in the bic directory changed from jar files to wrapper scripts Dependencies directory renamed to lib Removed the BUILD id timestamp from the jar files Added constructor from stream in XlsReader 7.9.4 - November 2017 JRE requirement backported to Java 1.6 7.9 - May 2017 SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX) 7.8.9 - May 2017 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 7.8.6 - November 2016 JRE requirement increased to Java 1.7 (only for Integrator SDK and modules, Core still works on 1.5) 7.8.5 - October 2016 Added out-of-the-box translation from MT300 into MxFxtr014 Added transformation to perform content replacement based on map of tuples Added transformation to create fixed values Added transformations for BIC related operations (bic8, bic11, branch, country, etc...) 7.8.3 - Jul 2016 Generic XML API moved to SDK","title":"Prowide Integrator MyFormat"},{"location":"release-notes/changelog-myformat/#prowide-integrator-myformat-changelog","text":"","title":"Prowide Integrator MyFormat - CHANGELOG"},{"location":"release-notes/changelog-myformat/#946-june-2024","text":"Added a convenient write method with default write mode in the MessageWriter interface","title":"9.4.6 - June 2024"},{"location":"release-notes/changelog-myformat/#945-december-2023","text":"Added schema paths validation for source and target selectors in the conversion from or to MX","title":"9.4.5 - December 2023"},{"location":"release-notes/changelog-myformat/#944-october-2023","text":"(PW-1604) Added concat function to MatrixReader in order to allow retrieving multiples source value during foreach iterations","title":"9.4.4 - October 2023"},{"location":"release-notes/changelog-myformat/#943-october-2023","text":"(PW-1642) Changed the mapping validator to enable literal() in the source selector, this makes sense when combined with a defaultString(value) transformation","title":"9.4.3 - October 2023"},{"location":"release-notes/changelog-myformat/#942-september-2023","text":"(PW-1118) Changed MtReader in order to include null value items in readMany results when valueSelector is used","title":"9.4.2 - September 2023"},{"location":"release-notes/changelog-myformat/#941-june-2023","text":"Enhancements to fully support propagation of foreach indexes into the target selectors, including Line, such asf A[2]/B[{n}]/B1[3]/23A[{m}]/Line[{o}]","title":"9.4.1 - June 2023"},{"location":"release-notes/changelog-myformat/#940-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"9.4.0 - May 2023"},{"location":"release-notes/changelog-myformat/#9314-may-2023","text":"(PW-1370) Fixed the MxReader so that it can properly extract content from /AppHdr and /Document paths in conversions from MX (PW-1232) Changed the CSV writer to be more lenient; enabling empty rows, auto extend by default when using addRows, and single separator in the whole CSV Internal implementation enhancement","title":"9.3.14 - May 2023"},{"location":"release-notes/changelog-myformat/#9313-april-2023","text":"Refactored the MappingTable spreadsheet loader to use the new MappingTableExcelLoader Refactored the MappingValidator in order to optimize the Rules Parsing, Validation and Process steps","title":"9.3.13 - April 2023"},{"location":"release-notes/changelog-myformat/#9312-march-2023","text":"Fixed transformation toTimeZone when both source and target zone identifiers are used as parameters","title":"9.3.12 - March 2023"},{"location":"release-notes/changelog-myformat/#9311-march-2023","text":"Internal implementation enhancement in the SETUP commands API","title":"9.3.11 - March 2023"},{"location":"release-notes/changelog-myformat/#9310-february-2023","text":"(PW-1174) Added SETUP function to indicate the appHdrType for MX messages in the externalized configuration (spreadsheet or DB) Added support for Zone Ids such as \"America/Argentina\" to the offset parameters in the transformation functions","title":"9.3.10 - February 2023"},{"location":"release-notes/changelog-myformat/#939-february-2023","text":"Added transformation now() to get the current datetime in local timezone, formatted as yyyy-MM-dd'T'HH ss.SSSZ (ISO 8601) Added transformation now(utcOffset)to get the current datetime in the specified time-zone, formatted as yyyy-MM-dd'T'HH ss.SSSZ (ISO 8601) Added transformation uetr() to generates a new random UETR (unique end to end reference) used in both MT and ISO 20022 messages Added transformation toTimeZone(dateTimeFormat, targetOffset) to transform a given datetime in local time and convert it to the target UTC timezone Added transformation toTimeZone(dateTimeFormat, sourceOffset, targetOffset) to transform an input datetime from a specific UTC timezone to another MtPath enhancement to enable using component names (labels) in the selector expressions instead of component numbers","title":"9.3.9 - February 2023"},{"location":"release-notes/changelog-myformat/#938-january-2023","text":"Enhanced selector validation, checking that value selectors (secondary selector in expression) do not contain variables Added support for JSON as source and target formats for the conversion","title":"9.3.8 - January 2023"},{"location":"release-notes/changelog-myformat/#937-december-2022","text":"(PW-1118) minor fixes and added \"@main\" to MtReader to work with main message (when processing an attachment) Minor internal code enhancements Fixed error text formatting in transformations validation","title":"9.3.7 - December 2022"},{"location":"release-notes/changelog-myformat/#936-december-2022","text":"(PW-1105) Added support in the CSV writer setup to pass \"\\t\" as parameter to require the tab character as separator Added a constraint for the CsvFieldsDef to match the pattern ([A-Za-z0-9_]*) and thus avoid mapping selector parsing issues","title":"9.3.6 - December 2022"},{"location":"release-notes/changelog-myformat/#935-november-2022","text":"Updated Apache Commons Text dependency to 1.10 to fix reported CVE Added SETUP functions to indicate the source and target formats in the externalized configuration (spreadsheet or DB) Added SETUP functions to indicate the target MT type or target MX type in the externalized configuration (spreadsheet or DB) Added SETUP function to set up the mapping name in the externalized configuration (spreadsheet or DB) Added support in the MtWriter to generate automatically the field 15 in the sequences separated by 15a","title":"9.3.5 - November 2022"},{"location":"release-notes/changelog-myformat/#934-october-2022","text":"Added API in the MxWriter to configure the specific AppHdr version to use when creating MX messages as output Set the default AppHdr version when creating MX messages to ISO Business Application Header v2 Added ifElse power function to facilitate conditional mappings","title":"9.3.4 - October 2022"},{"location":"release-notes/changelog-myformat/#933-october-2022","text":"(PW-1064) Fallback option to system classloader in resource loading","title":"9.3.3 - October 2022"},{"location":"release-notes/changelog-myformat/#932-september-2022","text":"Added transformation functions logicalTerminalAddress, logicalTerminalAddressSend and logicalTerminalAddressReceive Added transformation function sum","title":"9.3.2 - September 2022"},{"location":"release-notes/changelog-myformat/#931-august-2022","text":"(PW-1010) Added an automatic sanitization when converting into MT, to fix start of line characters and some missing components","title":"9.3.1 - August 2022"},{"location":"release-notes/changelog-myformat/#930-may-2022","text":"SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.3.0 - May 2022"},{"location":"release-notes/changelog-myformat/#926-may-2022","text":"(PW-813) Internal enhancement to fix CVE Deprecation API review","title":"9.2.6 - May 2022"},{"location":"release-notes/changelog-myformat/#925-april-2022","text":"Minor fix in the database loader, to set the table name with the configuration name parameter Fixed mapping table validation when there are SETUP commands in the mappings Minor internal code enhancements Prowide Integrator SDK and Prowide Core updates","title":"9.2.5 - April 2022"},{"location":"release-notes/changelog-myformat/#924-january-2022","text":"Prowide Integrator SDK and Prowide Core updates","title":"9.2.4 - January 2022"},{"location":"release-notes/changelog-myformat/#923-december-2021","text":"Added com.prowidesoftware.integrator.myformat as automatic module name in the MANIFEST for JPMS support","title":"9.2.3 - December 2021"},{"location":"release-notes/changelog-myformat/#922-june-2021","text":"Added support to read and write block 5 fields with selectors such as \"b5/CHK\"","title":"9.2.2 - June 2021"},{"location":"release-notes/changelog-myformat/#921-june-2021","text":"(PW-527) Additional change in the XML and MX reader to trim indentation and trailing spaces from elements while preserving line feeds (PW-527) Changed the XML and MX reader to preserve whitespaces from elements content (PW-527) Added transformation functions wrapLinesPreserve and wrapLinesPreservePrepend","title":"9.2.1 - June 2021"},{"location":"release-notes/changelog-myformat/#920-may-2021","text":"SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.2.0 - May 2021"},{"location":"release-notes/changelog-myformat/#918-april-2021","text":"(PW-502) Added MappingTableDatabaseLoader for more flexible data base access and querying when load the mappings","title":"9.1.8 - April 2021"},{"location":"release-notes/changelog-myformat/#917-march-2021","text":"(PW-480) Fixed mapping into block 2 using whole block value as input data","title":"9.1.7 - March 2021"},{"location":"release-notes/changelog-myformat/#916-february-2021","text":"Added validation of the new SETUP commands: separator, smartQuotes, smartEscapes, addFieldNames and columnNames","title":"9.1.6 - February 2021"},{"location":"release-notes/changelog-myformat/#915-january-2021","text":"Fixed CSV writer with APPEND mode Added SETUP commands to the externalized mapping into CSV: separator, smartQuotes, smartEscapes, addFieldNames and columnNames","title":"9.1.5 - January 2021"},{"location":"release-notes/changelog-myformat/#914-january-2021","text":"Fixed semantic of the MtReader to return null content if the MT selector targets a missing field component Fixed transformation \"rightPad\" Fixed transformation \"formatDecimal\" when input number contains decimal separator and no decimal digits (valid case in MT amounts) Fixed transformation \"fixed\" to avoud setting the default value if the input content is null (not found in source) Fixed transformations \"append\", \"prepend\", \"replaceIfEquals\" and \"wrap\" to avoid generating value if input is null Fixed transformations \"indexOf\", \"indexOfIgnoreCase\", \"lastIndexOf\" and \"lastIndexOfIgnoreCase\" when found substring is at index 0 Enhanced number parse exception handling in transformations using or expecting integers and decimal numbers","title":"9.1.4 - January 2021"},{"location":"release-notes/changelog-myformat/#913-december-2020","text":"License check review","title":"9.1.3 - December 2020"},{"location":"release-notes/changelog-myformat/#912-november-2020","text":"(CR-27) Added support for forced double quotes for CSVWriter (CR-27) Added support for disable smart escaping (ex: comma inside double quotes are not escaped) for CSVWriter (CR-27) Added support to generate header column with field names for CSVWriter (CR-29) Added support in the MtWriter to create internal loop (sequences without 16R and 16S boundary) present for example in MT940 (CR-28) Added support in the MtWriter to create block 1 and block 2 from whole value strings (not targeting individual fields) (CR-28) Added support in the MtReader to retrieve the whole block 1 or block 2 value with selectors \"b1\" and \"b2\" Minor fix in formatDecimal transformation when default locale has comma for decimal separator","title":"9.1.2 - November 2020"},{"location":"release-notes/changelog-myformat/#911-september-2020","text":"(PW-334) Added backward compatibility support for custom(\"MyCustomTransformer\") in the mapping transformations","title":"9.1.1 - September 2020"},{"location":"release-notes/changelog-myformat/#910-may-2020","text":"SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.1.0 - May 2020"},{"location":"release-notes/changelog-myformat/#901-may-2020","text":"Internal implementation changes to the use the new AppHdr model in the SDK","title":"9.0.1 - May 2020"},{"location":"release-notes/changelog-myformat/#900-may-2020","text":"MyFormat module extracted to its own jar in the distribution, with its own version from now on","title":"9.0.0 - May 2020"},{"location":"release-notes/changelog-myformat/#807-may-2020","text":"Added a CsvReader constructor parsing a whole csv where the first row is used as field definition for the mappings Fixed index in CsvFieldsDef constructor to be zero-based instead of one-based","title":"8.0.7 - May 2020"},{"location":"release-notes/changelog-myformat/#806-february-2020","text":"(PW-237) Added ifMatches and IfNotMatches power functions to facilitate conditional mappings","title":"8.0.6 - February 2020"},{"location":"release-notes/changelog-myformat/#803-september-2019","text":"(PW-179) Added support for custom transformations in externalized mapping tables Added support for header rows skip configuration in CsvReader","title":"8.0.3 - September 2019"},{"location":"release-notes/changelog-myformat/#802-august-2019","text":"Added support in the CsvFileReader for the header offset parameter, rows are now skipped directly by the Iterator","title":"8.0.2 - August 2019"},{"location":"release-notes/changelog-myformat/#801-july-2019","text":"Fixed XML and MX writer to avoid creating empty elements if the source content is null Fixed bug in MX/XML writer when creating more than 100 target elements in a rule with variables Added support for foreach when converting from MT","title":"8.0.1 - July 2019"},{"location":"release-notes/changelog-myformat/#800-may-2019","text":"JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"8.0.0 - May 2019"},{"location":"release-notes/changelog-myformat/#7109-may-2019","text":"Enhanced selectors for CSV with support for repetition, variables and filters. Added support for FIXED-LENGTH files as source and target message format. Added API to load the mappings from a database, providing a data source or a context name for JNDI lookup Added automatic sequence creation in conversions to MT, for example /E/E1/95Q will create E and E1 boundary fields Fixed block 3 fields order when target is MT and the writer has a pre-filled block 3 Added CONCAT function in source selector to combine the result of a list of selectors in a single rule Added wrapLinesPrepend transformation to split content in to lines, with both fixed length and a prefix Added support for FOREACH in the mappings to process a list of source elements in a single rule Added support for parameterized predicates in the selector to map repetitions from source to target message Added the token LITERAL as alternative to indicate a source content is a plain literal instead of a selector Enhanced reporting in the mapping rules validation, detail message when the selectors are invalid","title":"7.10.9 - May 2019"},{"location":"release-notes/changelog-myformat/#7108-march-2019","text":"Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Fixed obfuscation to keep directories in jar Added transformation: abbreviate, unwrap, wrapLines, remove and replace functions based on regex Added support for custom transformation functions When using the CsvFileReader, the iteration counter variable can be used in both target and source selectors Fixed handling of row header offset in CsvFileReader Fixed CSV selector for empty column values (consecutive split characters without values)","title":"7.10.8 - March 2019"},{"location":"release-notes/changelog-myformat/#7107-january-2019","text":"Added a constructor with AbstractMT in the MtWriter to initialize the writer with a pre-filled message Added MessageReaderIterator to do n to 1 translations from multiple rows in CSV to single consolidated output Added constructors to create MxWriter from existing AbstractMX message and from MxType identifier","title":"7.10.7 - January 2019"},{"location":"release-notes/changelog-myformat/#7100-april-2018","text":"SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"7.10.0 - April 2018"},{"location":"release-notes/changelog-myformat/#797-january-2018","text":"Changes in the distribution package: Command line tools in the bic directory changed from jar files to wrapper scripts Dependencies directory renamed to lib Removed the BUILD id timestamp from the jar files Added constructor from stream in XlsReader","title":"7.9.7 - January 2018"},{"location":"release-notes/changelog-myformat/#794-november-2017","text":"JRE requirement backported to Java 1.6","title":"7.9.4 - November 2017"},{"location":"release-notes/changelog-myformat/#79-may-2017","text":"SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX)","title":"7.9 - May 2017"},{"location":"release-notes/changelog-myformat/#789-may-2017","text":"Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"7.8.9 - May 2017"},{"location":"release-notes/changelog-myformat/#786-november-2016","text":"JRE requirement increased to Java 1.7 (only for Integrator SDK and modules, Core still works on 1.5)","title":"7.8.6 - November 2016"},{"location":"release-notes/changelog-myformat/#785-october-2016","text":"Added out-of-the-box translation from MT300 into MxFxtr014 Added transformation to perform content replacement based on map of tuples Added transformation to create fixed values Added transformations for BIC related operations (bic8, bic11, branch, country, etc...)","title":"7.8.5 - October 2016"},{"location":"release-notes/changelog-myformat/#783-jul-2016","text":"Generic XML API moved to SDK","title":"7.8.3 - Jul 2016"},{"location":"release-notes/changelog-score/","text":"Prowide Integrator SCORE - CHANGELOG Model extension for SCORE messages (SWIFT for corporates) 9.4.7 - January 2024 (PW-1751) Fixed schemes for MT 798<760> B2C 9.4.6 - November 2023 Added new custom semantic rules to the MT798<700> message structure scheme Fixed SRU2023 qualification for MT 798 sub-message types 700, 707, 708, 759, 761, 765, 767, 769, 785, 786, 787 9.4.5 - November 2023 (PW-994) Fixed schemes for MT 798<760> B2C 9.4.4 - November 2023 (PW-1058) Fixed schemes for MT 798<767> 9.4.3 - November 2023 (PW-1675) Fixed schemes for MT 798<760/765/767/775> 9.4.2 - September 2023 (PW-1575) MT SCORE 798<700/701/707/708>: Fixed B2C schemes, replace field 21A with 21P (PW-1572) Fixes in structure for qualifiers validation in MT 798<710> 9.4.1 - August 2023 PW-1461: Remove field 31R from SCORE since it was moved back to Prowide Core 9.4.0 - July 2023 Version aligned with Prowide Integrator 9.4.x for SRU2023 1.4.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 1.3.10 - May 2023 (PW-1373) Additional fixes in structure for qualifiers validation in MT 798<720> 1.3.9 - May 2023 (PW-1373) Fixed structure for qualifiers validation in MT 798<720> 1.3.8 - May 2023 (PW-1367) Added MT SCORE 798 sub-message types: 722_LC_C2B, 726_LC_C2B, 735_LC_C2B, 770_LC_C2B, 772_LC_C2B (PW-1373) MT SCORE 798<720>: Fixed codewords and rules for fields 40B and 41a 1.3.7 - March 2023 (PW-1231) MT SCORE 798<758>: Added missing fields after field 33a 1.3.6 - February 2023 (PW-1206) Added message model for the MT SCORE subtypes 707/708/710/711/720/721/732/734/750 (PW-1198) Added validation for MT SCORE subtype 767 - Sequence B optional for 22A ISCA or ICCA 1.3.5 - February 2023 Model for SCORE fields moved from the Prowide Core library to this Prowide Integrator SCORE library (PW-1168) Added message model for the MT SCORE subtypes 723/733/737/751/758/776/780/782 1.3.4 - January 2023 (PW-1150) Added message model for the MT SCORE subtypes 731/736/748/753/755/757/771/773 1.3.3 - November 2022 Updated Apache Commons Text dependency to 1.10 to fix reported CVE 1.3.2 - September 2022 (PW-1058) Fix SCORE 798<767> and 798<775> B2C - field 21 is optional Added the current SRU to the version number for consistent SRU based BOM and dependency with other Integrator artifacts 1.3.1 - August 2022 (PW-1015) Added schemes for submessage types 700, 701 and 774 PW-994: Removed NONREF qualifier to the B/20 field in scheme 1.3.0 - May 2022 SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 1.2.3 - March 2022 (PW-882) SCORE 798_760 scheme change to have sequence B optional (mandatory presence checked by semantic rule as necessary) 1.2.2 - January 2022 Prowide Integrator SDK and Prowide Core updates 1.2.1 - December 2021 Added com.prowidesoftware.integrator.score as automatic module name in the MANIFEST for JPMS support 1.2.0 - August 2021 Comprehensive implementation of message types 1.0.0 - February 2021 Initial version including support for Guarantee/Standby LC: request for amendment, notification of amendment, response","title":"Prowide Integrator SCORE"},{"location":"release-notes/changelog-score/#prowide-integrator-score-changelog","text":"Model extension for SCORE messages (SWIFT for corporates)","title":"Prowide Integrator SCORE - CHANGELOG"},{"location":"release-notes/changelog-score/#947-january-2024","text":"(PW-1751) Fixed schemes for MT 798<760> B2C","title":"9.4.7 - January 2024"},{"location":"release-notes/changelog-score/#946-november-2023","text":"Added new custom semantic rules to the MT798<700> message structure scheme Fixed SRU2023 qualification for MT 798 sub-message types 700, 707, 708, 759, 761, 765, 767, 769, 785, 786, 787","title":"9.4.6 - November 2023"},{"location":"release-notes/changelog-score/#945-november-2023","text":"(PW-994) Fixed schemes for MT 798<760> B2C","title":"9.4.5 - November 2023"},{"location":"release-notes/changelog-score/#944-november-2023","text":"(PW-1058) Fixed schemes for MT 798<767>","title":"9.4.4 - November 2023"},{"location":"release-notes/changelog-score/#943-november-2023","text":"(PW-1675) Fixed schemes for MT 798<760/765/767/775>","title":"9.4.3 - November 2023"},{"location":"release-notes/changelog-score/#942-september-2023","text":"(PW-1575) MT SCORE 798<700/701/707/708>: Fixed B2C schemes, replace field 21A with 21P (PW-1572) Fixes in structure for qualifiers validation in MT 798<710>","title":"9.4.2 - September 2023"},{"location":"release-notes/changelog-score/#941-august-2023","text":"PW-1461: Remove field 31R from SCORE since it was moved back to Prowide Core","title":"9.4.1 - August 2023"},{"location":"release-notes/changelog-score/#940-july-2023","text":"Version aligned with Prowide Integrator 9.4.x for SRU2023","title":"9.4.0 - July 2023"},{"location":"release-notes/changelog-score/#140-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"1.4.0 - May 2023"},{"location":"release-notes/changelog-score/#1310-may-2023","text":"(PW-1373) Additional fixes in structure for qualifiers validation in MT 798<720>","title":"1.3.10 - May 2023"},{"location":"release-notes/changelog-score/#139-may-2023","text":"(PW-1373) Fixed structure for qualifiers validation in MT 798<720>","title":"1.3.9 - May 2023"},{"location":"release-notes/changelog-score/#138-may-2023","text":"(PW-1367) Added MT SCORE 798 sub-message types: 722_LC_C2B, 726_LC_C2B, 735_LC_C2B, 770_LC_C2B, 772_LC_C2B (PW-1373) MT SCORE 798<720>: Fixed codewords and rules for fields 40B and 41a","title":"1.3.8 - May 2023"},{"location":"release-notes/changelog-score/#137-march-2023","text":"(PW-1231) MT SCORE 798<758>: Added missing fields after field 33a","title":"1.3.7 - March 2023"},{"location":"release-notes/changelog-score/#136-february-2023","text":"(PW-1206) Added message model for the MT SCORE subtypes 707/708/710/711/720/721/732/734/750 (PW-1198) Added validation for MT SCORE subtype 767 - Sequence B optional for 22A ISCA or ICCA","title":"1.3.6 - February 2023"},{"location":"release-notes/changelog-score/#135-february-2023","text":"Model for SCORE fields moved from the Prowide Core library to this Prowide Integrator SCORE library (PW-1168) Added message model for the MT SCORE subtypes 723/733/737/751/758/776/780/782","title":"1.3.5 - February 2023"},{"location":"release-notes/changelog-score/#134-january-2023","text":"(PW-1150) Added message model for the MT SCORE subtypes 731/736/748/753/755/757/771/773","title":"1.3.4 - January 2023"},{"location":"release-notes/changelog-score/#133-november-2022","text":"Updated Apache Commons Text dependency to 1.10 to fix reported CVE","title":"1.3.3 - November 2022"},{"location":"release-notes/changelog-score/#132-september-2022","text":"(PW-1058) Fix SCORE 798<767> and 798<775> B2C - field 21 is optional Added the current SRU to the version number for consistent SRU based BOM and dependency with other Integrator artifacts","title":"1.3.2 - September 2022"},{"location":"release-notes/changelog-score/#131-august-2022","text":"(PW-1015) Added schemes for submessage types 700, 701 and 774 PW-994: Removed NONREF qualifier to the B/20 field in scheme","title":"1.3.1 - August 2022"},{"location":"release-notes/changelog-score/#130-may-2022","text":"SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"1.3.0 - May 2022"},{"location":"release-notes/changelog-score/#123-march-2022","text":"(PW-882) SCORE 798_760 scheme change to have sequence B optional (mandatory presence checked by semantic rule as necessary)","title":"1.2.3 - March 2022"},{"location":"release-notes/changelog-score/#122-january-2022","text":"Prowide Integrator SDK and Prowide Core updates","title":"1.2.2 - January 2022"},{"location":"release-notes/changelog-score/#121-december-2021","text":"Added com.prowidesoftware.integrator.score as automatic module name in the MANIFEST for JPMS support","title":"1.2.1 - December 2021"},{"location":"release-notes/changelog-score/#120-august-2021","text":"Comprehensive implementation of message types","title":"1.2.0 - August 2021"},{"location":"release-notes/changelog-score/#100-february-2021","text":"Initial version including support for Guarantee/Standby LC: request for amendment, notification of amendment, response","title":"1.0.0 - February 2021"},{"location":"release-notes/changelog-sdk/","text":"Prowide Integrator SDK - CHANGELOG 9.4.26 - SNAPSHOT MT SchemeXmlWriter: make description and release optional 9.4.25 - May 2024 (PW-1868) Added a DataPDUWriterFactory to create specific versions of the writer instance based on the Revision element in the XML (PW-1870) Added new method to MxPrintoutVisitor in order to allow printing the MX path for a given element 9.4.24 - April 2024 (PW-1844) Enhanced the DataPDUWriter to propagate the original Document namespace when not strictly ISO-20022 (for example SIC) 9.4.23 - April 2024 (PW-1836) Fixed scheme for MT 537, enabling repetitions of sequence C2a 9.4.22 - April 2024 (PW-1816) Added XmlNode support for default namespaces 9.4.21 - March 2024 (PW-1810) Added changes to allow removing AppHdr and Document namespaces prefixes when creating a DataPDU XML 9.4.20 - March 2024 (PW-1755) Fix Block4Xml for field 37K to handle the special \"PCT\" (percentage) in the currency field (used in MT305) (PW-1697) Fix Block4Xml for fields 29O and 37K, affecting MT306 structure validation Added method findAllContainingValue in XmlNode class 9.4.19 - February 2024 Updated the SchemeMatcherQualifier report logic to provide Code word errors information 9.4.18 - January 2024 (PW-1743) Remove usage of deprecated SafeXMLUtils methods 9.4.17 - January 2024 (PW-1739) Fixed field 23 expanded printout in order to match specification for MT102/MT103/MT305/MT601 Added method findFirstByValue in XmlNode class 9.4.16 - January 2024 (PW-1734) Fixed schemes for MT503/504/506/507/510,517/538/541/567/575. Converted optional subsequences to mandatory 9.4.15 - December 2023 (PW-1732) Fixed scheme for MT543: sequence E3 Amounts is mandatory 9.4.14 - December 2023 (PW-1718) Fixed fields 50F and 59F expanded printout missing components Added Xsd Path Generator in order to generate all valid paths from a XSD element Added XsdPath validation classes: AppHdrPathValidator, MxPathValidator, and XsdPathValidator interface. 9.4.13 - December 2023 (PW-1718) Fixed the TXT expanded printout for fields 50 and 59 that was missing some components 9.4.12 - November 2023 (PW-1697) Fixed scheme for MT306 9.4.11 - November 2023 (PW-1688) Updated the pw_mt_info properties with labels and descriptions from the SRU2023 changes (PW-1675) Updated Scheme 765 adding new semantic check for field 31R 9.4.10 - October 2023 (PW-1639) Added options in the LAU signing and verification processing parameters to support latest version of SWIFT Alliance Lite 9.4.9 - October 2023 (PW-1667) Updated Scheme 671 schema to fix field 95 9.4.8 - October 2023 (PW-1664) Updated MT543 schema to fix field 36[B,D] PAIR/TURN position within LINK subsequence 9.4.7 - October 2023 Added JSON file format support in the AbstractSwiftMessageFactory to automatically detect the JSON structure and parse it into an MT or MX message Added missing versions to the AbstractDataPDU generic parse 9.4.6 - September 2023 (PW-1612) Fixed Block4Xml serialization of field 72 in MT102_STP and MT103_STP tht was producing a non XSD compatible structure (PW-1605) Fixed the SwiftMessageFactory#toggleDirection to use 24-hour time format in the Block2 Output 9.4.5 - September 2023 (PW-1594) Fixed invalid qualifier in MT543 scheme; qualifier MFKT -> MRKT in sequence B1 9.4.4 - September 2023 (PW-1578) Updated schemes 710, 720 to fix a bug introduced in 9.4.1 (PW-1449) Added support for version 2.0.14 of the SAA DataPDU wrapper (PW-1118) Added support in MtPath extract content from Block3 given an existing MtPathResult as parameter 9.4.3 - July 2023 (PW-1423) Added a RitsMessageIdentifierGenerator helper class to generate RITS MX message identifiers 9.4.2 - June 2023 (PW-1369) Added a property to the TxtPrintoutVisitor to opt out printing the label for the components within a field (PW-1369) Added an includeComponentLabel boolean to the MTInfo#fieldValue method to opt out printing the label for the components within a field (PW-1369) Added an onField method to the PrintoutVisitor interface to customize how field components are split and printed Changed the MtPathExpression to support variables in predicates, such as A[2]/B[{n}]/B1[3]/23A[{m}]/Line[{o}] 9.4.1 - June 2023 Fixed MT schemes fo MT537 Fixed MT schemes fo MT710 and MT720 9.4.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 9.3.23 - April 2023 (PW-1350) Added 2 MxWriteParams vars to XmlV2Configuration in order to allow custom setting of AppHdr and Document namespaces prefixes when creating a DataPDU XML 9.3.22 - April 2023 (PW-1348) Added a IBICDirectory setter to the MTInfo to customize the directory used when doing expanded printout of BIC codes 9.3.21 - March 2023 (PW-1239) Further enhanced the PrintoutWriter to resolve the labels of the MT798 proprietary fields, for any recognized sub-message type Changed the MTInfo.fieldValue to use the same implementation as the PrintoutWriter, which is more complete and produces a better result 9.3.20 - March 2023 (PW-1239) Enhanced the PrintoutWriter to resolve the labels of the MT798_700 proprietary fields 9.3.19 - March 2023 (PW-1195) Revert charset to system default value instead of fixed UTF-8 in: XmlNode, DataPDU, MxPrintoutWriter and LAU 9.3.18 - March 2023 Fixed MtPath log verbosity when querying fields with wildcard letter option, such as 93a Re-enabled the BIC query tool command line to check the integrator data jar file contains the imported data 9.3.17 - February 2023 Minor javadoc fixes 9.3.16 - February 2023 (PW-1168) Added message model for the MT SCORE subtypes 723/733/737/751/758/776/780/782/731/736/748/753/755/757/771/773 9.3.15 - February 2023 Prowide Core dependency update 9.3.14 - January 2023 (PW-1149) Added UETR to the MT expanded printout, and fixed indentation when printing multiline fields in TXT format 9.3.13 - December 2022 Removed the deprecated \"eval\" JS expressions from the MT schemes, in favor of the new \"qualifierValidation\" structure 9.3.12 - November 2022 (GH-63) Added message type versions in categories: acmt, admi, auth, caaa, camt, catm, fxtr, pacs, reda, seev, semt, sese, setr, supl and trck Added new business process and messages for: caad, cafc, cain, casp 9.3.11 - November 2022 (PW-1109) Fixed BLock4Xml for narrative container fields having a codeword without any narrative text Added DataPDU model for versions 2.0.1, 2.0.2, 2.0.3, 2.0.4, 2.0.5, 2.0.6, 2.0.8, 2.0.9 and 2.0.10 Deprecated the SdkConfiguration in favor of localized configuration API in each module/feature Fixed the embedded BIC directory connection handling, with automatic reopening after a closed connection 9.3.10 - November 2022 Updated Apache Commons Text dependency to 1.10 to fix reported CVE (PW-1101) Fixed field 35C unmarshalling in XmlBlock4 (PW-1086) Fixed field 36D unmarshalling in XmlBlock4 (PW-1085) Moved the custom BIC directory implementation setter from the SDK singleton configuration to the PrintoutWriter constructor 9.3.9 - October 2022 (PW-1082) Added support for cached JaxbContext in the DataPDU parsing to achieve better performance 9.3.8 - October 2022 Added a StringSchemaProvider that can be used to provide a schema from a String when using the Mx API 9.3.7 - September 2022 (PW-1058) Fix SCORE 798<767> and 798<775> B2C - field 21 is optional (PW-1048) Added options in the SwiftMessageFactory to create an ACK from an MX message 9.3.6 - September 2022 (GH-119) MT566: Fixed repetitions of sequence USECU/FIA that is not repetitive Minor fix in MT internal schemes, added some missing \"rules\" reference attributes 9.3.5 - August 2022 MT schemes refactor to decommission the need for the Rhino dependency when validating MT message structure 9.3.4 - August 2022 (PW-1010) Added helper API MtSanitizer to fix MT content charset, start of line characters and certain missing components (PW-1015) Added field validation for fields 47E, 49D and 49F (required in SCORE MT798_774) (PW-922) MxPrintout: Added support for xsys message types SchemeXmlWriter/Reader fixed and refactored 9.3.3 - August 2022 (PW-922) Added a fallback option to the MX printout writer to handle unknown message types 9.3.2 - July 2022 (PW-977) Fixed MT scheme 203 with inner loops instead of formal sequences (PW-969) fixes to xml converters for fields 12E, 12K and 12R (PW-895) Fixed Block4Xml to properly name anonymous sequences (LoopN) (PW-894) Fixed MT scheme 203 with inner loops instead of formal sequences (PW-873) Added a new MxPrintoutWriter to generate a human-friendly view of MX messages in plain text (PW-873) Added the MxLabelInfo helper class to retrieve business labels for MX message elements Split MxType into enumeration per category to deal with compiler class size limitations Added internal loops API to MTs: 110, 201, 203, 210, 410, 412, 420, 422, 450, 456, 604, 605, 801, 920, 973 Added support for Loop selectors in MtPath, example: Loop1/58A/1 MtType: added a method to retrieve the MtId equivalent MtType: enhanced the enum to implement the SchemaProvider interface, and thus return XSD schemas for MTs Added PathSchemaProvider helper class to read the schemas from a file path Added missing schemas for new versions of MX messages 9.3.1 - May 2022 Fixed packaging 9.3.0 - May 2022 SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Updated gson dependency to 2.9.0 9.2.21 - May 2022 (PW-923) Updated org.apache.santuario:xmlsec dependency to 2.3.1 (only used in LAU signing) to fix CVE-2022-23437 (PW-813) Internal enhancement to fix CVE Deprecation API review 9.2.20 - May 2022 Fixed security vulnerabilities for XML to MT Block4 parser 9.2.19 - April 2022 Fixed MT LAU sign/verify when an ACK + Msg is received 9.2.18 - April 2022 Internal schema compress to reduce jar size (PW-877) Added XmlBlock4; XML to MT Block4 conversion, with an XML structure compatible with the XSD for FIN by SWIFT Fixes to Block4ToXml (PW-810) Fix un LAU signing and verifying algorithm 9.2.17 - March 2022 (PW-877) Fixed exception in Block4Xml when not using Apache xalan 9.2.16 - March 2022 (PW-871) Fixed Block4ToXml for field 46B Added @attach feature to the MtPath, specially suited to retrieve content from the original message attached to an ACK/NAK 9.2.15 - March 2022 Added implementation for version 2.0.11 and 2.0.13 of the SAA DataPDU wrapper Added support for multiple versions of the SAA DataPDU wrapper 9.2.14 - February 2022 (PW-829) In the MT text expanded printout, line feeds are now system dependant 9.2.13 - January 2022 (PW-833) Fixed mandatory field 77E in MTn98 scheme 9.2.12 - January 2022 (PW-819-820) Fixed scheme for SCORE message MT798_760 NPE prevention in SwiftMessageFactory#toggleDirection 9.2.11 - January 2022 MT530: Fixed repetition of sequence C ADDINFO Updated dependency: gson:2.8.8 -> gson:2.8.9 9.2.10 - December 2021 Added Block4Xml; a new converter from MT Block4 into the XML structure compatible with the XSD for FIN by SWIFT Added com.prowidesoftware.integrator.sdk as automatic module name in the MANIFEST for JPMS support (PW-785) Added the original sent message content in the expanded printout of service 21 messages (ACK/NAK) 9.2.9 - November 2021 Fixed MT509 scheme: letter options in B/98a 9.2.8 - October 2021 (PW-750) Fixed MT527 scheme, invalid 94L qualifiers (CR-23) Added MOR to the expanded printout of for inbound MT messages (PW-749) Updated dependency: org.apache.santuario:xmlsec -> 2.2.3 to fix vulnerability (only used in XML v2 features) Updated dependency: Apache Commons Lang 3.8.1 -> 3.12.0 Updated dependency: Apache Commons Text 1.6 -> 1.9 Updated dependency: Gson 2.8.2 -> 2.8.8 9.2.7 - October 2021 (PW-723) Fixed LT identifier (X or default) in SwiftMessageFactory#toggleDirection (PW-719) fixed 77H qualifiers in MT 300, 304, 305 and 306 9.2.6 - October 20221 Added a SchemeXmlWriter class to serialize the MT structure structure definitions into plain XML 9.2.5 - September 2021 Added support for block 5 in the MtPath selector expressions such as b5/MRF 9.2.4 - August 2021 (PW-654) Fixed bic importer parameter path 9.2.3 - August 2021 (PW-599) MT564: Minor scheme fix, 92a TAXR and WITL can be repeated in CASHMOVE (E2) 9.2.2 - July 2021 MT548: Minor scheme fix, added letter option \"C\" in field \"98C:SCTS\" in sequence \"C1a1B1\" (PW-625) XMLv2 DataPDU: mapped Block3/103 into CopyService, and Block3/111 into ServiceLevelAgreement with default to \"001\" (PW-590) Fixed MtPath evaluator when selecting an inner sequence with no unique boundary separator, such as B1 (FIA) in MT564 9.2.1 - June 2021 Changed the generic XmlParser to preserve whitespace by default (added a new method to use the previous implementation) Minor special case fix in MtPath when the source result targets the same field/qualifier as the target expression Added sameQualifier(Field) in the MtPathExpression adn asList() in MtPathResult MT537 scheme fixed fieldset definition for 95PQR ACOW CACO in D1a1B1 MT548 scheme fixed fieldset definition for 22F TRTR, SETR in C1a1B1 Minor fixes in scheme for MT575 9.2.0 - May 2021 SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.1.11 - April 2021 (PW-460) Divided the internal schemas package into packages by category to allow trimming the jar by use (PW-500) Fixed schemes for MT565, qualifier check for field 90[F,J]:OFFR in CAINST sequence 9.1.10 - March 2021 (PW-499) Fixed schemes for MT513, MT564 and MT566: invalid qualifier in field 69D 9.1.9 - March 2021 (PW-494) Fixed schemes for MT565 (sequence B can be repeated up to 1) and MT568 (sequence B is optional, not mandatory) 9.1.8 - March 2021 (PW-493) Fixed scheme for MT671, missing :22H::PRCD//PREF in Other Details sequence 9.1.7 - March 2021 Added expanded printout support for service 21 messages (ACK and NAK) Enhanced the MTInfo implementation to be lenient on the detected message type 9.1.6 - February 2021 (PW-455) Added lenient parsing of MT headers in conversion to XML v2 9.1.5 - January 2021 Added selector b2/Direction in MtPath returning Input or Output Added valueForPath in the MtPathResult to get precise values related to the queried path 9.1.4 - December 2020 Added GpiUtils to determine if the UETR field in block 3 is mandatory for an MT Added explicit file format to model when creating messages with the AbstractSwiftMessageFactory 9.1.3 - November 2020 (PW-414) Fixed DataPDU parsing of LocalOutputTime into block2 receiver date and time fields Added API in Scheme to check if an MT Scheme contains sequences or internal loops (CR-28) Enhanced MtPath to support full-block selector expressions \"b1\" and \"b2\", returning the complete block value as a single result Added targetNamespace() method to the SchemaProvider interface and to the MxType enumeration Fixed MT537 scheme: field 19A in sequence D1a1B1 Transaction Details (PW-387) In the DataPDU parser for MT messages, the Body element is autodetected expecting either a complete MT content or only the block 4 (PW-387) DataPDUWriter: Added generation of the Message/InterfaceInfo 9.1.2 - September 2020 (PW-358) Added LAU signing and verification for FileAct (XML v2 companion files detached from actual payload) (PW-343) Added canonicalization to signed XMLv2 messages (PW-357) PrintoutWriter: Added a setter to overwrite the default BICDirectory 9.1.1 - August 2020 (PW-343) Added API in the XML v2 and LAU classes to compute and verify the binary prefix in XML v2 messages (PW-344) Fixed the XML v2 parser of MT headers when message is Output (inbound) and Body contains only block 4 (PW-316) Added LAU signature creation and verification for the XML v2 message wrapper (PW-327) Added support in the XML v2 API to parse DataPDU TransmissionReport into ACK/NACK messages (PW-324) Fixed the XML v2 parser to capture gpi fields (111 and 121) from the FINUserHeader element when present (PW-324) Updated the XML v2 DataPDU wrapper model to version SAA 2.0.7 (PW-195) Added handy methods in the BICDirectory to query by institution and country Internal refactor of generated MT Scheme classes to avoid MethodTooLargeException in runtime (PW-322) Fixed the XML v2 parser for MT Output messages with DataPDU Body containing only the block 4 9.1.0 - May 2020 SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.0.1 - May 2020 (PW-301) Minor fix in SwiftMessageFactory.toggle that was not setting sender input time in outbound to inbound conversion 9.0.0 - May 2020 Prowide Integrator fatjar split into single jars for the SDK and modules, each with its own versioning from now on 8.0.9 - May 2020 Fixed scheme for 564, typo in MET2 and MET3 qualifiers 8.0.8 - April 2020 Expanded the ISO 20022 model to include all the historic message versions, not only the latest Added a specific model library including the set of restricted ISO 20022 for CBPR+ (Cross-border Payments and Reporting Plus) release 1.2 Enhanced the PrintoutWriter to support invalid message types and invalid fields NPE prevention in BICDirectory create connection 8.0.7 - March 2020 Added a specific model library including the set of restricted ISO 20022 for SIC (Swiss RTGS) v4.6 release Added support for keywords \"sender\" and \"receiver\" in MtPath expressions to retrieve header addresses regardless of the message direction 8.0.6 - February 2020 Added parser and model classes for seev.045, seev.046, seev.047, seev.048, seev.049 8.0.5 - January 2019 (PW-235) Added SafeXmlUtils to disallow XXE in all XML parsing and validation code Added abstract message() serialization method to AbstractMessage (implemented by the AbstractMT and AbstractMX subclasses) Fixed NPE in MtPath evaluation with null blocks as parameter Added support for \"child\" axis in MtPath expressions to query direct children of sequences instead of the default \"all descendants\" behaviour BusinessHeader added factory methods to create the ISO business header or the legacy SWIFT header given a few simple parameters 8.0.4 - December 2019 Prevention of NPE in expanded printout when sender or receiver BIC are null Changed default MX serialization root element \"message\" to \"RequestPayload\" when both Document and AppHdr are present Changed default MX serialization in AbstractMX#message() to include the AppHdr when present and not just the Document Added a jaxb context cache to boost performance when parsing MX messages, this can be enabled with SdkConfiguration#setCachedJaxbContext 8.0.3 - September 2019 (PW-189) Added back message model for pain.008.001.02, pain.001.001.05 and pain.002.001.05 (PW-186) Added fallback option to load IBAN property file from different classloader Added a specific model library including all SEPA messages of the EPC 2019 v1.0 release Added the SchemaProvider interface, implemented by the MxType enum, to get the default ISO schemas for each message type 8.0.2 - August 2019 Explicit UTF-8 encoding was added where necessary to ensure portability Added fallback option to load license from different classloader 8.0.1 - July 2019 Fixed BIC Directory imported (truncation error for BIC PLus files) Fixed SwiftMessageFactory#ACK that was appending the original message to the ACK twice 8.0.0 - May 2019 JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 7.10.9 - May 2019 Fixed classpath in bin/*.bat scripts Added support for field repetitions in MtPath expressions, such as /A/22F[3] to select the third 22F in sequence A Fixed stack overflow exception in XmlParser#parse(Stream) Fixed SwiftMessageFactory#ACK the MUR field goes to block 4 instead of block 3 7.10.8 - March 2019 Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Fixed obfuscation to keep directories in jar Added API to sign and validate LAU signatures in MT messages Added valueDate and tradeDate to the AbstractSwiftMessage model 7.10.7 - January 2019 Fixed constructor for String or MxSwiftMessage in the MX model classes (subclasses of AbstractMX) Added support for legacy pain.002.001.03 Fixed semantic rules for MT 360 and 361 Moved MtSchemeValidator from internal package to com.prowidesoftware.swift.scheme as part of the public API 7.10.6 - November 2018 (PW-120) Added an SDK configuration option to indicate if the institution is a GPI member Added tag index information to the MtPath results when the expression targets a field or a component within a field Added a builder pattern implementation to the MtPathResult Fixed MX parser for Java 8+ to enable parsing recognized MX messages with non-standard (swift or iso) xmlns Fixed writer and parser for XML v2 (block 4 only mode): removed trailing line break in last tag Fixed writer for XML v2 (whole message mode): removed empty blocks before base64 encoding 7.10.5 - October 2018 Added checkFormat in AbstractSwiftMessageFactory to validate a raw SWIFT content against an expected format Added XmlV2Configuration to customize the behaviour of the XML v2 parser and writer API Fixed DataPDUWriter creation from AbstractMX that was not propagating the MX header 7.10.3 - July 2018 Removed deprecated Hibernate XML mappings for MT schemes (Scheme.hbm.xml, SchemeElement.hbm.xml, SchemeFieldDefaultValue.hbm.xml) 7.10.2 - July 2018 JPA annotations moved from accessors to fields Fixed com.sun.xml reference in MX marshalling Added toJson and fromJson to MX classes (AbstractMX and subclasses) 7.10.0 - April 2018 SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) BIC directory: added support to seamlessly import BIC Plus or BIC Directory 2018 txt files from swiftrefdata.com 7.9.7u1 - February 2018 (PW-54) New API in SwiftMessageFactory to toggle the message direction 7.9.7 - January 2018 Changes in the distribution package: Command line tools in the bic directory changed from jar files to wrapper scripts Dependencies directory renamed to lib Removed the BUILD id timestamp from the jar files Updated dependency: org.apache.derby:derby:10.10.1.1 -> org.apache.derby:derby:10.12.+ Updated dependency: com.google.code.gson:gson 1.7.1 -> com.google.code.gson:gson:2.8.2 7.9.6 - December 2017 Added isEmpty API in MtPathResult XmlNode: added support for parent steps (..) in find API 7.9.5 - December 2017 PrintoutVisitor: added onBICExpansion event to customize how BIC codes are expanded with information from the catalog PrintoutVisitor: added ACCOUNT as FieldType to customize how to render account numbers Added \"ignore whitespaces and case\" to value comparator Changed checksum fields in persistence mapping from length 30 to 32 to support uncoded MD5 hashes size Added checksumBody to persistence mapping Deprecated message relation DUPLICATE in favour of DUPLICATE OF and DUPLICATED BY 7.9.4 - November 2017 JRE requirement backported to Java 1.6 BIC directory: added all fields from the FI specification to both the importer tool and the query API Fixed MANIFEST classpath for bicimporter.jar tool 7.9.3 - October 2017 Added MtPathType in MtPathResult and MtPathExpression MtPath: enhanced support in nested queries, check javadoc for MtPath#evaluate(String path, MtPathResult source) Added attributes in MtPathResult to hold the original message and path used for the query Fixed MtPath when querying for fields within other source field block and with an expression not targeting a component New helper API to trim segments in XPath New out-of-the-box XML expanded printout for MTs (XmlPrintoutVisitor) Added comprehensive support for MX system messages (xsys category) Added API in MtPath API to query content within a specific given block Fixed city heading import in BIC directory 7.9.2 - August 2017 Added API in generic XmlNode implementation: hasAttributes(), isEmpty() and removeEmptyElements() Added schemes and model for MX cbrf category Added missing updates for MX supl XPath added API to strip predicates and to collapse parent segments XmlNode more API for siblings, enhanced path() to include predicates when element is repeated Removed commons-beanutils and dom4j dependencies Updated pom.xml for Integrator 7.9.1 - June 2017 Added customizable expanded printout for MT messages, to display MT messages in human-friendly TXT and HTML 7.9 - May 2017 SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX) 7.8.9 - May 2017 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 7.8.8 - March 2017 Added helper class BICDirectoryUtils to expand BIC codes New MXInfo feature to retrieve MX messages names and description in english 7.8.7 - December 2016 New generic ValueComparator to compare field and components values with special equality condition based on exceptions Internal code clean ups (removing SRU2015 stuff) 7.8.6 - November 2016 JRE requirement increased to Java 1.7 (only for Integrator SDK and modules, Core still works on 1.5) New internal MT-XML converter New internal XSD package for MT Internal code clean ups (removing deprecated SRU2014 stuff) Updated all internal XSD schemas for MX to the latest enriched version 7.8.4 - Oct 2016 Enhanced AbstractMX parse to support namespaces with single quotes Expanded BIC directory and bicimporter to include institution name, city and country as table columns Added updateFrom AbstractMX to MxSwiftMessage Fixed MxSwiftMessage mapping to store BusinessProcess enum as simple string New AbstractSwiftMessageFactory to create messages from different source formats and objects Enhanced Mx parsing to support a wider range of XMLs, reading AppHdr and Document as partial chunks and ignoring the rest Mx reader migrated from SAX to StAX for better performance Support for SAA message wrapper (DataPDU) used in XML v2 formats for both MT and MX 7.8.3 - Jul 2016 Generic XML API migrated from MyFormat to SDK Removed invalid Mx classes generated from FIN schemas 7.8.2 - Jul 2016 Fixed schemes: definition of field 12A in FIA subsequences of MTs 54x Semantic 283 bugfix (used in MTs 307,503,504,505,506,536,537,548,578,586) 2016 June Added API Scheme.getSequenceByField Added API SchemeManager schemes loading from MT message objects Added API SchemeManager to get default scheme name for MT messages 2015 November Added API to control prefix, and XML declaration when serializing Mx headers and documents Added wrapper API, with SNL wrapper as initial implementation Added MxParserIntegrator containing generic Mx parsing (common API to parse all Mx) Fixed entity escape in serialization to XML (for example: & instead of & in the generated XML) Fixed serialization of field 11R, 11S and 32R 2015 August Fields 11R and 11S component 3 split into two independent components. 2014 December MX: Fixed attribute handling in xml event writer MX: Better XML error handling Added adhoc sequence code to MT609 SwiftTagListBlock: more consistent append api, deprecated replaced methods SwiftParser: Added a lenient version to allow partial parsing of blocks 1 and blocks 2 when the total value size is invalid 2014 June Release package includes now both checkouts of core examples and integrator examples from github Examples moved out to github repository 2014 April Added Field.is(String,String) 2014 March Added missing SwiftCharset_it.properties Added exists() to BICDirectory Added IntegratorConfiguration class Optional BIC Directory query and app to import into internal database Added a BIC directory importing command line application Added model and API for BIC Directory information 2013 September SRU 2013 update","title":"Prowide Integrator SDK"},{"location":"release-notes/changelog-sdk/#prowide-integrator-sdk-changelog","text":"","title":"Prowide Integrator SDK - CHANGELOG"},{"location":"release-notes/changelog-sdk/#9426-snapshot","text":"MT SchemeXmlWriter: make description and release optional","title":"9.4.26 - SNAPSHOT"},{"location":"release-notes/changelog-sdk/#9425-may-2024","text":"(PW-1868) Added a DataPDUWriterFactory to create specific versions of the writer instance based on the Revision element in the XML (PW-1870) Added new method to MxPrintoutVisitor in order to allow printing the MX path for a given element","title":"9.4.25 - May 2024"},{"location":"release-notes/changelog-sdk/#9424-april-2024","text":"(PW-1844) Enhanced the DataPDUWriter to propagate the original Document namespace when not strictly ISO-20022 (for example SIC)","title":"9.4.24 - April 2024"},{"location":"release-notes/changelog-sdk/#9423-april-2024","text":"(PW-1836) Fixed scheme for MT 537, enabling repetitions of sequence C2a","title":"9.4.23 - April 2024"},{"location":"release-notes/changelog-sdk/#9422-april-2024","text":"(PW-1816) Added XmlNode support for default namespaces","title":"9.4.22 - April 2024"},{"location":"release-notes/changelog-sdk/#9421-march-2024","text":"(PW-1810) Added changes to allow removing AppHdr and Document namespaces prefixes when creating a DataPDU XML","title":"9.4.21 - March 2024"},{"location":"release-notes/changelog-sdk/#9420-march-2024","text":"(PW-1755) Fix Block4Xml for field 37K to handle the special \"PCT\" (percentage) in the currency field (used in MT305) (PW-1697) Fix Block4Xml for fields 29O and 37K, affecting MT306 structure validation Added method findAllContainingValue in XmlNode class","title":"9.4.20 - March 2024"},{"location":"release-notes/changelog-sdk/#9419-february-2024","text":"Updated the SchemeMatcherQualifier report logic to provide Code word errors information","title":"9.4.19 - February 2024"},{"location":"release-notes/changelog-sdk/#9418-january-2024","text":"(PW-1743) Remove usage of deprecated SafeXMLUtils methods","title":"9.4.18 - January 2024"},{"location":"release-notes/changelog-sdk/#9417-january-2024","text":"(PW-1739) Fixed field 23 expanded printout in order to match specification for MT102/MT103/MT305/MT601 Added method findFirstByValue in XmlNode class","title":"9.4.17 - January 2024"},{"location":"release-notes/changelog-sdk/#9416-january-2024","text":"(PW-1734) Fixed schemes for MT503/504/506/507/510,517/538/541/567/575. Converted optional subsequences to mandatory","title":"9.4.16 - January 2024"},{"location":"release-notes/changelog-sdk/#9415-december-2023","text":"(PW-1732) Fixed scheme for MT543: sequence E3 Amounts is mandatory","title":"9.4.15 - December 2023"},{"location":"release-notes/changelog-sdk/#9414-december-2023","text":"(PW-1718) Fixed fields 50F and 59F expanded printout missing components Added Xsd Path Generator in order to generate all valid paths from a XSD element Added XsdPath validation classes: AppHdrPathValidator, MxPathValidator, and XsdPathValidator interface.","title":"9.4.14 - December 2023"},{"location":"release-notes/changelog-sdk/#9413-december-2023","text":"(PW-1718) Fixed the TXT expanded printout for fields 50 and 59 that was missing some components","title":"9.4.13 - December 2023"},{"location":"release-notes/changelog-sdk/#9412-november-2023","text":"(PW-1697) Fixed scheme for MT306","title":"9.4.12 - November 2023"},{"location":"release-notes/changelog-sdk/#9411-november-2023","text":"(PW-1688) Updated the pw_mt_info properties with labels and descriptions from the SRU2023 changes (PW-1675) Updated Scheme 765 adding new semantic check for field 31R","title":"9.4.11 - November 2023"},{"location":"release-notes/changelog-sdk/#9410-october-2023","text":"(PW-1639) Added options in the LAU signing and verification processing parameters to support latest version of SWIFT Alliance Lite","title":"9.4.10 - October 2023"},{"location":"release-notes/changelog-sdk/#949-october-2023","text":"(PW-1667) Updated Scheme 671 schema to fix field 95","title":"9.4.9 - October 2023"},{"location":"release-notes/changelog-sdk/#948-october-2023","text":"(PW-1664) Updated MT543 schema to fix field 36[B,D] PAIR/TURN position within LINK subsequence","title":"9.4.8 - October 2023"},{"location":"release-notes/changelog-sdk/#947-october-2023","text":"Added JSON file format support in the AbstractSwiftMessageFactory to automatically detect the JSON structure and parse it into an MT or MX message Added missing versions to the AbstractDataPDU generic parse","title":"9.4.7 - October 2023"},{"location":"release-notes/changelog-sdk/#946-september-2023","text":"(PW-1612) Fixed Block4Xml serialization of field 72 in MT102_STP and MT103_STP tht was producing a non XSD compatible structure (PW-1605) Fixed the SwiftMessageFactory#toggleDirection to use 24-hour time format in the Block2 Output","title":"9.4.6 - September 2023"},{"location":"release-notes/changelog-sdk/#945-september-2023","text":"(PW-1594) Fixed invalid qualifier in MT543 scheme; qualifier MFKT -> MRKT in sequence B1","title":"9.4.5 - September 2023"},{"location":"release-notes/changelog-sdk/#944-september-2023","text":"(PW-1578) Updated schemes 710, 720 to fix a bug introduced in 9.4.1 (PW-1449) Added support for version 2.0.14 of the SAA DataPDU wrapper (PW-1118) Added support in MtPath extract content from Block3 given an existing MtPathResult as parameter","title":"9.4.4 - September 2023"},{"location":"release-notes/changelog-sdk/#943-july-2023","text":"(PW-1423) Added a RitsMessageIdentifierGenerator helper class to generate RITS MX message identifiers","title":"9.4.3 - July 2023"},{"location":"release-notes/changelog-sdk/#942-june-2023","text":"(PW-1369) Added a property to the TxtPrintoutVisitor to opt out printing the label for the components within a field (PW-1369) Added an includeComponentLabel boolean to the MTInfo#fieldValue method to opt out printing the label for the components within a field (PW-1369) Added an onField method to the PrintoutVisitor interface to customize how field components are split and printed Changed the MtPathExpression to support variables in predicates, such as A[2]/B[{n}]/B1[3]/23A[{m}]/Line[{o}]","title":"9.4.2 - June 2023"},{"location":"release-notes/changelog-sdk/#941-june-2023","text":"Fixed MT schemes fo MT537 Fixed MT schemes fo MT710 and MT720","title":"9.4.1 - June 2023"},{"location":"release-notes/changelog-sdk/#940-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"9.4.0 - May 2023"},{"location":"release-notes/changelog-sdk/#9323-april-2023","text":"(PW-1350) Added 2 MxWriteParams vars to XmlV2Configuration in order to allow custom setting of AppHdr and Document namespaces prefixes when creating a DataPDU XML","title":"9.3.23 - April 2023"},{"location":"release-notes/changelog-sdk/#9322-april-2023","text":"(PW-1348) Added a IBICDirectory setter to the MTInfo to customize the directory used when doing expanded printout of BIC codes","title":"9.3.22 - April 2023"},{"location":"release-notes/changelog-sdk/#9321-march-2023","text":"(PW-1239) Further enhanced the PrintoutWriter to resolve the labels of the MT798 proprietary fields, for any recognized sub-message type Changed the MTInfo.fieldValue to use the same implementation as the PrintoutWriter, which is more complete and produces a better result","title":"9.3.21 - March 2023"},{"location":"release-notes/changelog-sdk/#9320-march-2023","text":"(PW-1239) Enhanced the PrintoutWriter to resolve the labels of the MT798_700 proprietary fields","title":"9.3.20 - March 2023"},{"location":"release-notes/changelog-sdk/#9319-march-2023","text":"(PW-1195) Revert charset to system default value instead of fixed UTF-8 in: XmlNode, DataPDU, MxPrintoutWriter and LAU","title":"9.3.19 - March 2023"},{"location":"release-notes/changelog-sdk/#9318-march-2023","text":"Fixed MtPath log verbosity when querying fields with wildcard letter option, such as 93a Re-enabled the BIC query tool command line to check the integrator data jar file contains the imported data","title":"9.3.18 - March 2023"},{"location":"release-notes/changelog-sdk/#9317-february-2023","text":"Minor javadoc fixes","title":"9.3.17 - February 2023"},{"location":"release-notes/changelog-sdk/#9316-february-2023","text":"(PW-1168) Added message model for the MT SCORE subtypes 723/733/737/751/758/776/780/782/731/736/748/753/755/757/771/773","title":"9.3.16 - February 2023"},{"location":"release-notes/changelog-sdk/#9315-february-2023","text":"Prowide Core dependency update","title":"9.3.15 - February 2023"},{"location":"release-notes/changelog-sdk/#9314-january-2023","text":"(PW-1149) Added UETR to the MT expanded printout, and fixed indentation when printing multiline fields in TXT format","title":"9.3.14 - January 2023"},{"location":"release-notes/changelog-sdk/#9313-december-2022","text":"Removed the deprecated \"eval\" JS expressions from the MT schemes, in favor of the new \"qualifierValidation\" structure","title":"9.3.13 - December 2022"},{"location":"release-notes/changelog-sdk/#9312-november-2022","text":"(GH-63) Added message type versions in categories: acmt, admi, auth, caaa, camt, catm, fxtr, pacs, reda, seev, semt, sese, setr, supl and trck Added new business process and messages for: caad, cafc, cain, casp","title":"9.3.12 - November 2022"},{"location":"release-notes/changelog-sdk/#9311-november-2022","text":"(PW-1109) Fixed BLock4Xml for narrative container fields having a codeword without any narrative text Added DataPDU model for versions 2.0.1, 2.0.2, 2.0.3, 2.0.4, 2.0.5, 2.0.6, 2.0.8, 2.0.9 and 2.0.10 Deprecated the SdkConfiguration in favor of localized configuration API in each module/feature Fixed the embedded BIC directory connection handling, with automatic reopening after a closed connection","title":"9.3.11 - November 2022"},{"location":"release-notes/changelog-sdk/#9310-november-2022","text":"Updated Apache Commons Text dependency to 1.10 to fix reported CVE (PW-1101) Fixed field 35C unmarshalling in XmlBlock4 (PW-1086) Fixed field 36D unmarshalling in XmlBlock4 (PW-1085) Moved the custom BIC directory implementation setter from the SDK singleton configuration to the PrintoutWriter constructor","title":"9.3.10 - November 2022"},{"location":"release-notes/changelog-sdk/#939-october-2022","text":"(PW-1082) Added support for cached JaxbContext in the DataPDU parsing to achieve better performance","title":"9.3.9 - October 2022"},{"location":"release-notes/changelog-sdk/#938-october-2022","text":"Added a StringSchemaProvider that can be used to provide a schema from a String when using the Mx API","title":"9.3.8 - October 2022"},{"location":"release-notes/changelog-sdk/#937-september-2022","text":"(PW-1058) Fix SCORE 798<767> and 798<775> B2C - field 21 is optional (PW-1048) Added options in the SwiftMessageFactory to create an ACK from an MX message","title":"9.3.7 - September 2022"},{"location":"release-notes/changelog-sdk/#936-september-2022","text":"(GH-119) MT566: Fixed repetitions of sequence USECU/FIA that is not repetitive Minor fix in MT internal schemes, added some missing \"rules\" reference attributes","title":"9.3.6 - September 2022"},{"location":"release-notes/changelog-sdk/#935-august-2022","text":"MT schemes refactor to decommission the need for the Rhino dependency when validating MT message structure","title":"9.3.5 - August 2022"},{"location":"release-notes/changelog-sdk/#934-august-2022","text":"(PW-1010) Added helper API MtSanitizer to fix MT content charset, start of line characters and certain missing components (PW-1015) Added field validation for fields 47E, 49D and 49F (required in SCORE MT798_774) (PW-922) MxPrintout: Added support for xsys message types SchemeXmlWriter/Reader fixed and refactored","title":"9.3.4 - August 2022"},{"location":"release-notes/changelog-sdk/#933-august-2022","text":"(PW-922) Added a fallback option to the MX printout writer to handle unknown message types","title":"9.3.3 - August 2022"},{"location":"release-notes/changelog-sdk/#932-july-2022","text":"(PW-977) Fixed MT scheme 203 with inner loops instead of formal sequences (PW-969) fixes to xml converters for fields 12E, 12K and 12R (PW-895) Fixed Block4Xml to properly name anonymous sequences (LoopN) (PW-894) Fixed MT scheme 203 with inner loops instead of formal sequences (PW-873) Added a new MxPrintoutWriter to generate a human-friendly view of MX messages in plain text (PW-873) Added the MxLabelInfo helper class to retrieve business labels for MX message elements Split MxType into enumeration per category to deal with compiler class size limitations Added internal loops API to MTs: 110, 201, 203, 210, 410, 412, 420, 422, 450, 456, 604, 605, 801, 920, 973 Added support for Loop selectors in MtPath, example: Loop1/58A/1 MtType: added a method to retrieve the MtId equivalent MtType: enhanced the enum to implement the SchemaProvider interface, and thus return XSD schemas for MTs Added PathSchemaProvider helper class to read the schemas from a file path Added missing schemas for new versions of MX messages","title":"9.3.2 - July 2022"},{"location":"release-notes/changelog-sdk/#931-may-2022","text":"Fixed packaging","title":"9.3.1 - May 2022"},{"location":"release-notes/changelog-sdk/#930-may-2022","text":"SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Updated gson dependency to 2.9.0","title":"9.3.0 - May 2022"},{"location":"release-notes/changelog-sdk/#9221-may-2022","text":"(PW-923) Updated org.apache.santuario:xmlsec dependency to 2.3.1 (only used in LAU signing) to fix CVE-2022-23437 (PW-813) Internal enhancement to fix CVE Deprecation API review","title":"9.2.21 - May 2022"},{"location":"release-notes/changelog-sdk/#9220-may-2022","text":"Fixed security vulnerabilities for XML to MT Block4 parser","title":"9.2.20 - May 2022"},{"location":"release-notes/changelog-sdk/#9219-april-2022","text":"Fixed MT LAU sign/verify when an ACK + Msg is received","title":"9.2.19 - April 2022"},{"location":"release-notes/changelog-sdk/#9218-april-2022","text":"Internal schema compress to reduce jar size (PW-877) Added XmlBlock4; XML to MT Block4 conversion, with an XML structure compatible with the XSD for FIN by SWIFT Fixes to Block4ToXml (PW-810) Fix un LAU signing and verifying algorithm","title":"9.2.18 - April 2022"},{"location":"release-notes/changelog-sdk/#9217-march-2022","text":"(PW-877) Fixed exception in Block4Xml when not using Apache xalan","title":"9.2.17 - March 2022"},{"location":"release-notes/changelog-sdk/#9216-march-2022","text":"(PW-871) Fixed Block4ToXml for field 46B Added @attach feature to the MtPath, specially suited to retrieve content from the original message attached to an ACK/NAK","title":"9.2.16 - March 2022"},{"location":"release-notes/changelog-sdk/#9215-march-2022","text":"Added implementation for version 2.0.11 and 2.0.13 of the SAA DataPDU wrapper Added support for multiple versions of the SAA DataPDU wrapper","title":"9.2.15 - March 2022"},{"location":"release-notes/changelog-sdk/#9214-february-2022","text":"(PW-829) In the MT text expanded printout, line feeds are now system dependant","title":"9.2.14 - February 2022"},{"location":"release-notes/changelog-sdk/#9213-january-2022","text":"(PW-833) Fixed mandatory field 77E in MTn98 scheme","title":"9.2.13 - January 2022"},{"location":"release-notes/changelog-sdk/#9212-january-2022","text":"(PW-819-820) Fixed scheme for SCORE message MT798_760 NPE prevention in SwiftMessageFactory#toggleDirection","title":"9.2.12 - January 2022"},{"location":"release-notes/changelog-sdk/#9211-january-2022","text":"MT530: Fixed repetition of sequence C ADDINFO Updated dependency: gson:2.8.8 -> gson:2.8.9","title":"9.2.11 - January 2022"},{"location":"release-notes/changelog-sdk/#9210-december-2021","text":"Added Block4Xml; a new converter from MT Block4 into the XML structure compatible with the XSD for FIN by SWIFT Added com.prowidesoftware.integrator.sdk as automatic module name in the MANIFEST for JPMS support (PW-785) Added the original sent message content in the expanded printout of service 21 messages (ACK/NAK)","title":"9.2.10 - December 2021"},{"location":"release-notes/changelog-sdk/#929-november-2021","text":"Fixed MT509 scheme: letter options in B/98a","title":"9.2.9 - November 2021"},{"location":"release-notes/changelog-sdk/#928-october-2021","text":"(PW-750) Fixed MT527 scheme, invalid 94L qualifiers (CR-23) Added MOR to the expanded printout of for inbound MT messages (PW-749) Updated dependency: org.apache.santuario:xmlsec -> 2.2.3 to fix vulnerability (only used in XML v2 features) Updated dependency: Apache Commons Lang 3.8.1 -> 3.12.0 Updated dependency: Apache Commons Text 1.6 -> 1.9 Updated dependency: Gson 2.8.2 -> 2.8.8","title":"9.2.8 - October 2021"},{"location":"release-notes/changelog-sdk/#927-october-2021","text":"(PW-723) Fixed LT identifier (X or default) in SwiftMessageFactory#toggleDirection (PW-719) fixed 77H qualifiers in MT 300, 304, 305 and 306","title":"9.2.7 - October 2021"},{"location":"release-notes/changelog-sdk/#926-october-20221","text":"Added a SchemeXmlWriter class to serialize the MT structure structure definitions into plain XML","title":"9.2.6 - October 20221"},{"location":"release-notes/changelog-sdk/#925-september-2021","text":"Added support for block 5 in the MtPath selector expressions such as b5/MRF","title":"9.2.5 - September 2021"},{"location":"release-notes/changelog-sdk/#924-august-2021","text":"(PW-654) Fixed bic importer parameter path","title":"9.2.4 - August 2021"},{"location":"release-notes/changelog-sdk/#923-august-2021","text":"(PW-599) MT564: Minor scheme fix, 92a TAXR and WITL can be repeated in CASHMOVE (E2)","title":"9.2.3 - August 2021"},{"location":"release-notes/changelog-sdk/#922-july-2021","text":"MT548: Minor scheme fix, added letter option \"C\" in field \"98C:SCTS\" in sequence \"C1a1B1\" (PW-625) XMLv2 DataPDU: mapped Block3/103 into CopyService, and Block3/111 into ServiceLevelAgreement with default to \"001\" (PW-590) Fixed MtPath evaluator when selecting an inner sequence with no unique boundary separator, such as B1 (FIA) in MT564","title":"9.2.2 - July 2021"},{"location":"release-notes/changelog-sdk/#921-june-2021","text":"Changed the generic XmlParser to preserve whitespace by default (added a new method to use the previous implementation) Minor special case fix in MtPath when the source result targets the same field/qualifier as the target expression Added sameQualifier(Field) in the MtPathExpression adn asList() in MtPathResult MT537 scheme fixed fieldset definition for 95PQR ACOW CACO in D1a1B1 MT548 scheme fixed fieldset definition for 22F TRTR, SETR in C1a1B1 Minor fixes in scheme for MT575","title":"9.2.1 - June 2021"},{"location":"release-notes/changelog-sdk/#920-may-2021","text":"SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.2.0 - May 2021"},{"location":"release-notes/changelog-sdk/#9111-april-2021","text":"(PW-460) Divided the internal schemas package into packages by category to allow trimming the jar by use (PW-500) Fixed schemes for MT565, qualifier check for field 90[F,J]:OFFR in CAINST sequence","title":"9.1.11 - April 2021"},{"location":"release-notes/changelog-sdk/#9110-march-2021","text":"(PW-499) Fixed schemes for MT513, MT564 and MT566: invalid qualifier in field 69D","title":"9.1.10 - March 2021"},{"location":"release-notes/changelog-sdk/#919-march-2021","text":"(PW-494) Fixed schemes for MT565 (sequence B can be repeated up to 1) and MT568 (sequence B is optional, not mandatory)","title":"9.1.9 - March 2021"},{"location":"release-notes/changelog-sdk/#918-march-2021","text":"(PW-493) Fixed scheme for MT671, missing :22H::PRCD//PREF in Other Details sequence","title":"9.1.8 - March 2021"},{"location":"release-notes/changelog-sdk/#917-march-2021","text":"Added expanded printout support for service 21 messages (ACK and NAK) Enhanced the MTInfo implementation to be lenient on the detected message type","title":"9.1.7 - March 2021"},{"location":"release-notes/changelog-sdk/#916-february-2021","text":"(PW-455) Added lenient parsing of MT headers in conversion to XML v2","title":"9.1.6 - February 2021"},{"location":"release-notes/changelog-sdk/#915-january-2021","text":"Added selector b2/Direction in MtPath returning Input or Output Added valueForPath in the MtPathResult to get precise values related to the queried path","title":"9.1.5 - January 2021"},{"location":"release-notes/changelog-sdk/#914-december-2020","text":"Added GpiUtils to determine if the UETR field in block 3 is mandatory for an MT Added explicit file format to model when creating messages with the AbstractSwiftMessageFactory","title":"9.1.4 - December 2020"},{"location":"release-notes/changelog-sdk/#913-november-2020","text":"(PW-414) Fixed DataPDU parsing of LocalOutputTime into block2 receiver date and time fields Added API in Scheme to check if an MT Scheme contains sequences or internal loops (CR-28) Enhanced MtPath to support full-block selector expressions \"b1\" and \"b2\", returning the complete block value as a single result Added targetNamespace() method to the SchemaProvider interface and to the MxType enumeration Fixed MT537 scheme: field 19A in sequence D1a1B1 Transaction Details (PW-387) In the DataPDU parser for MT messages, the Body element is autodetected expecting either a complete MT content or only the block 4 (PW-387) DataPDUWriter: Added generation of the Message/InterfaceInfo","title":"9.1.3 - November 2020"},{"location":"release-notes/changelog-sdk/#912-september-2020","text":"(PW-358) Added LAU signing and verification for FileAct (XML v2 companion files detached from actual payload) (PW-343) Added canonicalization to signed XMLv2 messages (PW-357) PrintoutWriter: Added a setter to overwrite the default BICDirectory","title":"9.1.2 - September 2020"},{"location":"release-notes/changelog-sdk/#911-august-2020","text":"(PW-343) Added API in the XML v2 and LAU classes to compute and verify the binary prefix in XML v2 messages (PW-344) Fixed the XML v2 parser of MT headers when message is Output (inbound) and Body contains only block 4 (PW-316) Added LAU signature creation and verification for the XML v2 message wrapper (PW-327) Added support in the XML v2 API to parse DataPDU TransmissionReport into ACK/NACK messages (PW-324) Fixed the XML v2 parser to capture gpi fields (111 and 121) from the FINUserHeader element when present (PW-324) Updated the XML v2 DataPDU wrapper model to version SAA 2.0.7 (PW-195) Added handy methods in the BICDirectory to query by institution and country Internal refactor of generated MT Scheme classes to avoid MethodTooLargeException in runtime (PW-322) Fixed the XML v2 parser for MT Output messages with DataPDU Body containing only the block 4","title":"9.1.1 - August 2020"},{"location":"release-notes/changelog-sdk/#910-may-2020","text":"SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.1.0 - May 2020"},{"location":"release-notes/changelog-sdk/#901-may-2020","text":"(PW-301) Minor fix in SwiftMessageFactory.toggle that was not setting sender input time in outbound to inbound conversion","title":"9.0.1 - May 2020"},{"location":"release-notes/changelog-sdk/#900-may-2020","text":"Prowide Integrator fatjar split into single jars for the SDK and modules, each with its own versioning from now on","title":"9.0.0 - May 2020"},{"location":"release-notes/changelog-sdk/#809-may-2020","text":"Fixed scheme for 564, typo in MET2 and MET3 qualifiers","title":"8.0.9 - May 2020"},{"location":"release-notes/changelog-sdk/#808-april-2020","text":"Expanded the ISO 20022 model to include all the historic message versions, not only the latest Added a specific model library including the set of restricted ISO 20022 for CBPR+ (Cross-border Payments and Reporting Plus) release 1.2 Enhanced the PrintoutWriter to support invalid message types and invalid fields NPE prevention in BICDirectory create connection","title":"8.0.8 - April 2020"},{"location":"release-notes/changelog-sdk/#807-march-2020","text":"Added a specific model library including the set of restricted ISO 20022 for SIC (Swiss RTGS) v4.6 release Added support for keywords \"sender\" and \"receiver\" in MtPath expressions to retrieve header addresses regardless of the message direction","title":"8.0.7 - March 2020"},{"location":"release-notes/changelog-sdk/#806-february-2020","text":"Added parser and model classes for seev.045, seev.046, seev.047, seev.048, seev.049","title":"8.0.6 - February 2020"},{"location":"release-notes/changelog-sdk/#805-january-2019","text":"(PW-235) Added SafeXmlUtils to disallow XXE in all XML parsing and validation code Added abstract message() serialization method to AbstractMessage (implemented by the AbstractMT and AbstractMX subclasses) Fixed NPE in MtPath evaluation with null blocks as parameter Added support for \"child\" axis in MtPath expressions to query direct children of sequences instead of the default \"all descendants\" behaviour BusinessHeader added factory methods to create the ISO business header or the legacy SWIFT header given a few simple parameters","title":"8.0.5 - January 2019"},{"location":"release-notes/changelog-sdk/#804-december-2019","text":"Prevention of NPE in expanded printout when sender or receiver BIC are null Changed default MX serialization root element \"message\" to \"RequestPayload\" when both Document and AppHdr are present Changed default MX serialization in AbstractMX#message() to include the AppHdr when present and not just the Document Added a jaxb context cache to boost performance when parsing MX messages, this can be enabled with SdkConfiguration#setCachedJaxbContext","title":"8.0.4 - December 2019"},{"location":"release-notes/changelog-sdk/#803-september-2019","text":"(PW-189) Added back message model for pain.008.001.02, pain.001.001.05 and pain.002.001.05 (PW-186) Added fallback option to load IBAN property file from different classloader Added a specific model library including all SEPA messages of the EPC 2019 v1.0 release Added the SchemaProvider interface, implemented by the MxType enum, to get the default ISO schemas for each message type","title":"8.0.3 - September 2019"},{"location":"release-notes/changelog-sdk/#802-august-2019","text":"Explicit UTF-8 encoding was added where necessary to ensure portability Added fallback option to load license from different classloader","title":"8.0.2 - August 2019"},{"location":"release-notes/changelog-sdk/#801-july-2019","text":"Fixed BIC Directory imported (truncation error for BIC PLus files) Fixed SwiftMessageFactory#ACK that was appending the original message to the ACK twice","title":"8.0.1 - July 2019"},{"location":"release-notes/changelog-sdk/#800-may-2019","text":"JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"8.0.0 - May 2019"},{"location":"release-notes/changelog-sdk/#7109-may-2019","text":"Fixed classpath in bin/*.bat scripts Added support for field repetitions in MtPath expressions, such as /A/22F[3] to select the third 22F in sequence A Fixed stack overflow exception in XmlParser#parse(Stream) Fixed SwiftMessageFactory#ACK the MUR field goes to block 4 instead of block 3","title":"7.10.9 - May 2019"},{"location":"release-notes/changelog-sdk/#7108-march-2019","text":"Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Fixed obfuscation to keep directories in jar Added API to sign and validate LAU signatures in MT messages Added valueDate and tradeDate to the AbstractSwiftMessage model","title":"7.10.8 - March 2019"},{"location":"release-notes/changelog-sdk/#7107-january-2019","text":"Fixed constructor for String or MxSwiftMessage in the MX model classes (subclasses of AbstractMX) Added support for legacy pain.002.001.03 Fixed semantic rules for MT 360 and 361 Moved MtSchemeValidator from internal package to com.prowidesoftware.swift.scheme as part of the public API","title":"7.10.7 - January 2019"},{"location":"release-notes/changelog-sdk/#7106-november-2018","text":"(PW-120) Added an SDK configuration option to indicate if the institution is a GPI member Added tag index information to the MtPath results when the expression targets a field or a component within a field Added a builder pattern implementation to the MtPathResult Fixed MX parser for Java 8+ to enable parsing recognized MX messages with non-standard (swift or iso) xmlns Fixed writer and parser for XML v2 (block 4 only mode): removed trailing line break in last tag Fixed writer for XML v2 (whole message mode): removed empty blocks before base64 encoding","title":"7.10.6 - November 2018"},{"location":"release-notes/changelog-sdk/#7105-october-2018","text":"Added checkFormat in AbstractSwiftMessageFactory to validate a raw SWIFT content against an expected format Added XmlV2Configuration to customize the behaviour of the XML v2 parser and writer API Fixed DataPDUWriter creation from AbstractMX that was not propagating the MX header","title":"7.10.5 - October 2018"},{"location":"release-notes/changelog-sdk/#7103-july-2018","text":"Removed deprecated Hibernate XML mappings for MT schemes (Scheme.hbm.xml, SchemeElement.hbm.xml, SchemeFieldDefaultValue.hbm.xml)","title":"7.10.3 - July 2018"},{"location":"release-notes/changelog-sdk/#7102-july-2018","text":"JPA annotations moved from accessors to fields Fixed com.sun.xml reference in MX marshalling Added toJson and fromJson to MX classes (AbstractMX and subclasses)","title":"7.10.2 - July 2018"},{"location":"release-notes/changelog-sdk/#7100-april-2018","text":"SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) BIC directory: added support to seamlessly import BIC Plus or BIC Directory 2018 txt files from swiftrefdata.com","title":"7.10.0 - April 2018"},{"location":"release-notes/changelog-sdk/#797u1-february-2018","text":"(PW-54) New API in SwiftMessageFactory to toggle the message direction","title":"7.9.7u1 - February 2018"},{"location":"release-notes/changelog-sdk/#797-january-2018","text":"Changes in the distribution package: Command line tools in the bic directory changed from jar files to wrapper scripts Dependencies directory renamed to lib Removed the BUILD id timestamp from the jar files Updated dependency: org.apache.derby:derby:10.10.1.1 -> org.apache.derby:derby:10.12.+ Updated dependency: com.google.code.gson:gson 1.7.1 -> com.google.code.gson:gson:2.8.2","title":"7.9.7 - January 2018"},{"location":"release-notes/changelog-sdk/#796-december-2017","text":"Added isEmpty API in MtPathResult XmlNode: added support for parent steps (..) in find API","title":"7.9.6 - December 2017"},{"location":"release-notes/changelog-sdk/#795-december-2017","text":"PrintoutVisitor: added onBICExpansion event to customize how BIC codes are expanded with information from the catalog PrintoutVisitor: added ACCOUNT as FieldType to customize how to render account numbers Added \"ignore whitespaces and case\" to value comparator Changed checksum fields in persistence mapping from length 30 to 32 to support uncoded MD5 hashes size Added checksumBody to persistence mapping Deprecated message relation DUPLICATE in favour of DUPLICATE OF and DUPLICATED BY","title":"7.9.5 - December 2017"},{"location":"release-notes/changelog-sdk/#794-november-2017","text":"JRE requirement backported to Java 1.6 BIC directory: added all fields from the FI specification to both the importer tool and the query API Fixed MANIFEST classpath for bicimporter.jar tool","title":"7.9.4 - November 2017"},{"location":"release-notes/changelog-sdk/#793-october-2017","text":"Added MtPathType in MtPathResult and MtPathExpression MtPath: enhanced support in nested queries, check javadoc for MtPath#evaluate(String path, MtPathResult source) Added attributes in MtPathResult to hold the original message and path used for the query Fixed MtPath when querying for fields within other source field block and with an expression not targeting a component New helper API to trim segments in XPath New out-of-the-box XML expanded printout for MTs (XmlPrintoutVisitor) Added comprehensive support for MX system messages (xsys category) Added API in MtPath API to query content within a specific given block Fixed city heading import in BIC directory","title":"7.9.3 - October 2017"},{"location":"release-notes/changelog-sdk/#792-august-2017","text":"Added API in generic XmlNode implementation: hasAttributes(), isEmpty() and removeEmptyElements() Added schemes and model for MX cbrf category Added missing updates for MX supl XPath added API to strip predicates and to collapse parent segments XmlNode more API for siblings, enhanced path() to include predicates when element is repeated Removed commons-beanutils and dom4j dependencies Updated pom.xml for Integrator","title":"7.9.2 - August 2017"},{"location":"release-notes/changelog-sdk/#791-june-2017","text":"Added customizable expanded printout for MT messages, to display MT messages in human-friendly TXT and HTML","title":"7.9.1 - June 2017"},{"location":"release-notes/changelog-sdk/#79-may-2017","text":"SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX)","title":"7.9 - May 2017"},{"location":"release-notes/changelog-sdk/#789-may-2017","text":"Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"7.8.9 - May 2017"},{"location":"release-notes/changelog-sdk/#788-march-2017","text":"Added helper class BICDirectoryUtils to expand BIC codes New MXInfo feature to retrieve MX messages names and description in english","title":"7.8.8 - March 2017"},{"location":"release-notes/changelog-sdk/#787-december-2016","text":"New generic ValueComparator to compare field and components values with special equality condition based on exceptions Internal code clean ups (removing SRU2015 stuff)","title":"7.8.7 - December 2016"},{"location":"release-notes/changelog-sdk/#786-november-2016","text":"JRE requirement increased to Java 1.7 (only for Integrator SDK and modules, Core still works on 1.5) New internal MT-XML converter New internal XSD package for MT Internal code clean ups (removing deprecated SRU2014 stuff) Updated all internal XSD schemas for MX to the latest enriched version","title":"7.8.6 - November 2016"},{"location":"release-notes/changelog-sdk/#784-oct-2016","text":"Enhanced AbstractMX parse to support namespaces with single quotes Expanded BIC directory and bicimporter to include institution name, city and country as table columns Added updateFrom AbstractMX to MxSwiftMessage Fixed MxSwiftMessage mapping to store BusinessProcess enum as simple string New AbstractSwiftMessageFactory to create messages from different source formats and objects Enhanced Mx parsing to support a wider range of XMLs, reading AppHdr and Document as partial chunks and ignoring the rest Mx reader migrated from SAX to StAX for better performance Support for SAA message wrapper (DataPDU) used in XML v2 formats for both MT and MX","title":"7.8.4 - Oct 2016"},{"location":"release-notes/changelog-sdk/#783-jul-2016","text":"Generic XML API migrated from MyFormat to SDK Removed invalid Mx classes generated from FIN schemas","title":"7.8.3 - Jul 2016"},{"location":"release-notes/changelog-sdk/#782-jul-2016","text":"Fixed schemes: definition of field 12A in FIA subsequences of MTs 54x Semantic 283 bugfix (used in MTs 307,503,504,505,506,536,537,548,578,586)","title":"7.8.2 - Jul 2016"},{"location":"release-notes/changelog-sdk/#2016-june","text":"Added API Scheme.getSequenceByField Added API SchemeManager schemes loading from MT message objects Added API SchemeManager to get default scheme name for MT messages","title":"2016 June"},{"location":"release-notes/changelog-sdk/#2015-november","text":"Added API to control prefix, and XML declaration when serializing Mx headers and documents Added wrapper API, with SNL wrapper as initial implementation Added MxParserIntegrator containing generic Mx parsing (common API to parse all Mx) Fixed entity escape in serialization to XML (for example: & instead of & in the generated XML) Fixed serialization of field 11R, 11S and 32R","title":"2015 November"},{"location":"release-notes/changelog-sdk/#2015-august","text":"Fields 11R and 11S component 3 split into two independent components.","title":"2015 August"},{"location":"release-notes/changelog-sdk/#2014-december","text":"MX: Fixed attribute handling in xml event writer MX: Better XML error handling Added adhoc sequence code to MT609 SwiftTagListBlock: more consistent append api, deprecated replaced methods SwiftParser: Added a lenient version to allow partial parsing of blocks 1 and blocks 2 when the total value size is invalid","title":"2014 December"},{"location":"release-notes/changelog-sdk/#2014-june","text":"Release package includes now both checkouts of core examples and integrator examples from github Examples moved out to github repository","title":"2014 June"},{"location":"release-notes/changelog-sdk/#2014-april","text":"Added Field.is(String,String)","title":"2014 April"},{"location":"release-notes/changelog-sdk/#2014-march","text":"Added missing SwiftCharset_it.properties Added exists() to BICDirectory Added IntegratorConfiguration class Optional BIC Directory query and app to import into internal database Added a BIC directory importing command line application Added model and API for BIC Directory information","title":"2014 March"},{"location":"release-notes/changelog-sdk/#2013-september","text":"SRU 2013 update","title":"2013 September"},{"location":"release-notes/changelog-sepa/","text":"Prowide Integrator SEPA - CHANGELOG Model extension for SEPA messages 9.4.0 - July 2023 Version aligned with Prowide Integrator 9.4.x for SRU2023 1.1.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 1.0.8 - December 2022 Switched to semantic versioning 2019v1.0u7 - November 2022 Updated Apache Commons Text dependency to 1.10 to fix reported CVE 2019v1.0u6 - September 2022 Added the current SRU to the version number for consistent SRU based BOM and dependency with other Integrator artifacts 2019v1.0u5 - April 2022 Internal schema compress to reduce jar size 2019v1.0u4 - January 2022 Prowide Integrator SDK and Prowide Core updates 2019v1.0u3 - December 2021 Added com.prowidesoftware.integrator.sepa as automatic module name in the MANIFEST for JPMS support 2019v1.0u2 - October 2020 Removed the CopyableTo implementation from the generated model Added a method to return the MxId and the targetNamespace in the SepaMessageType enumeration 2019v1.0u1 - June 2020 Minor change to removed some unused classes from the SEPA generated dictionary model 2019v1.0 First implementation for the Nov 2019 release","title":"Prowide Integrator SEPA"},{"location":"release-notes/changelog-sepa/#prowide-integrator-sepa-changelog","text":"Model extension for SEPA messages","title":"Prowide Integrator SEPA - CHANGELOG"},{"location":"release-notes/changelog-sepa/#940-july-2023","text":"Version aligned with Prowide Integrator 9.4.x for SRU2023","title":"9.4.0 - July 2023"},{"location":"release-notes/changelog-sepa/#110-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"1.1.0 - May 2023"},{"location":"release-notes/changelog-sepa/#108-december-2022","text":"Switched to semantic versioning","title":"1.0.8 - December 2022"},{"location":"release-notes/changelog-sepa/#2019v10u7-november-2022","text":"Updated Apache Commons Text dependency to 1.10 to fix reported CVE","title":"2019v1.0u7 - November 2022"},{"location":"release-notes/changelog-sepa/#2019v10u6-september-2022","text":"Added the current SRU to the version number for consistent SRU based BOM and dependency with other Integrator artifacts","title":"2019v1.0u6 - September 2022"},{"location":"release-notes/changelog-sepa/#2019v10u5-april-2022","text":"Internal schema compress to reduce jar size","title":"2019v1.0u5 - April 2022"},{"location":"release-notes/changelog-sepa/#2019v10u4-january-2022","text":"Prowide Integrator SDK and Prowide Core updates","title":"2019v1.0u4 - January 2022"},{"location":"release-notes/changelog-sepa/#2019v10u3-december-2021","text":"Added com.prowidesoftware.integrator.sepa as automatic module name in the MANIFEST for JPMS support","title":"2019v1.0u3 - December 2021"},{"location":"release-notes/changelog-sepa/#2019v10u2-october-2020","text":"Removed the CopyableTo implementation from the generated model Added a method to return the MxId and the targetNamespace in the SepaMessageType enumeration","title":"2019v1.0u2 - October 2020"},{"location":"release-notes/changelog-sepa/#2019v10u1-june-2020","text":"Minor change to removed some unused classes from the SEPA generated dictionary model","title":"2019v1.0u1 - June 2020"},{"location":"release-notes/changelog-sepa/#2019v10","text":"First implementation for the Nov 2019 release","title":"2019v1.0"},{"location":"release-notes/changelog-sic/","text":"Prowide Integrator SIC - CHANGELOG Model extension for SIC (Swiss RGTS) messages 9.4.1 - October 2023 Added model for SIC release 4.10 Moved release 4.9 to specific package Deprecated default model.mx.sic package in favor of package per specific SIC releases 9.4.0 - July 2023 Version aligned with Prowide Integrator 9.4.x for SRU2023 4.10.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 4.9.5 - April 2023 Added a SicMessageFactory to autodetect and parse and XML message into the correct Mx SIC model class 4.9.4 - February 2023 Minor javadoc fixes 4.9.3 - February 2023 Prowide dependencies update 4.9.2 - December 2022 Switched to semantic versioning 4.9u1 - November 2022 Updated Apache Commons Text dependency to 1.10 to fix reported CVE 4.9 - November 2022 Model migrated to SIC release 4.9 versions 4.6u6 - September 2022 Added the current SRU to the version number for consistent SRU based BOM and dependency with other Integrator artifacts 4.6u5 - April 2022 Internal schema compress to reduce jar size 4.6u4 - January 2022 Prowide Integrator SDK and Prowide Core updates 4.6u3 - December 2021 Added com.prowidesoftware.integrator.sic as automatic module name in the MANIFEST for JPMS support 4.6u2 - October 2020 Removed the CopyableTo implementation from the generated model Added a method to return the MxId and the targetNamespace in the SicMessageType enumeration 4.6u1 - June 2020 Fixed generated model for the Mx classes to use the restricted SIC elements 4.6 First implementation for the Nov 2019 release","title":"Prowide Integrator SIC"},{"location":"release-notes/changelog-sic/#prowide-integrator-sic-changelog","text":"Model extension for SIC (Swiss RGTS) messages","title":"Prowide Integrator SIC - CHANGELOG"},{"location":"release-notes/changelog-sic/#941-october-2023","text":"Added model for SIC release 4.10 Moved release 4.9 to specific package Deprecated default model.mx.sic package in favor of package per specific SIC releases","title":"9.4.1 - October 2023"},{"location":"release-notes/changelog-sic/#940-july-2023","text":"Version aligned with Prowide Integrator 9.4.x for SRU2023","title":"9.4.0 - July 2023"},{"location":"release-notes/changelog-sic/#4100-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"4.10.0 - May 2023"},{"location":"release-notes/changelog-sic/#495-april-2023","text":"Added a SicMessageFactory to autodetect and parse and XML message into the correct Mx SIC model class","title":"4.9.5 - April 2023"},{"location":"release-notes/changelog-sic/#494-february-2023","text":"Minor javadoc fixes","title":"4.9.4 - February 2023"},{"location":"release-notes/changelog-sic/#493-february-2023","text":"Prowide dependencies update","title":"4.9.3 - February 2023"},{"location":"release-notes/changelog-sic/#492-december-2022","text":"Switched to semantic versioning","title":"4.9.2 - December 2022"},{"location":"release-notes/changelog-sic/#49u1-november-2022","text":"Updated Apache Commons Text dependency to 1.10 to fix reported CVE","title":"4.9u1 - November 2022"},{"location":"release-notes/changelog-sic/#49-november-2022","text":"Model migrated to SIC release 4.9 versions","title":"4.9 - November 2022"},{"location":"release-notes/changelog-sic/#46u6-september-2022","text":"Added the current SRU to the version number for consistent SRU based BOM and dependency with other Integrator artifacts","title":"4.6u6 - September 2022"},{"location":"release-notes/changelog-sic/#46u5-april-2022","text":"Internal schema compress to reduce jar size","title":"4.6u5 - April 2022"},{"location":"release-notes/changelog-sic/#46u4-january-2022","text":"Prowide Integrator SDK and Prowide Core updates","title":"4.6u4 - January 2022"},{"location":"release-notes/changelog-sic/#46u3-december-2021","text":"Added com.prowidesoftware.integrator.sic as automatic module name in the MANIFEST for JPMS support","title":"4.6u3 - December 2021"},{"location":"release-notes/changelog-sic/#46u2-october-2020","text":"Removed the CopyableTo implementation from the generated model Added a method to return the MxId and the targetNamespace in the SicMessageType enumeration","title":"4.6u2 - October 2020"},{"location":"release-notes/changelog-sic/#46u1-june-2020","text":"Fixed generated model for the Mx classes to use the restricted SIC elements","title":"4.6u1 - June 2020"},{"location":"release-notes/changelog-sic/#46","text":"First implementation for the Nov 2019 release","title":"4.6"},{"location":"release-notes/changelog-translations/","text":"Prowide Integrator Translations - CHANGELOG 9.4.40 - June 2024 (PW-1897) CBPR+ camt.052.001.08 -> MT941/942: using account currency for fields 90C and 90D when entry currency is not present (PW-1896) CBPR+ MT200/202/205 -> pacs.009.001.08: create a new UETR for PaymentIdentification\\UETR when block3\\121 is missing pacs.010.001.03 -> MT204: fixed mappings for fields 58A and 58D (PW-1859) Added new ISO translator: pain.001.001.09 -> MT103 9.4.39 - May 2024 CBPR+ MT102/103 -> pacs.008.001.08 and MT200/201/202/205 -> pacs.009.001.08: enhanced and fixed mappings from field 72 codewords CATPURP, SVCLVL and LOCINS 9.4.38 - May 2024 (PW-1878) CBPR+ MT900 and MT910 to camt: set Entry/EntryReference to NOTPROVIDED since field 25 is already mapped to the Notification/Account (PW-1865) Added new flag to TranslatorConfiguration class, in order to force the number formatting to have exactly two decimal places 9.4.37 - May 2024 (PW-1872) CBPR+ MT 950 -> camt.053.001.08: fixed mappings from 60M to Balance\\Type\\Code = OPBD and 62M to Balance\\Type\\Code = CLBD (PW-1863) CBPR+ MT 940 -> camt.053.001.08: fixed mappings from 60M to Balance\\Type\\Code = OPBD and 62M to Balance\\Type\\Code = CLBD (PW-1862) MT to MX: Revamped implementation of Narrative translation functions (PW-1847) Added new ISO translators: MT 564/568 <-> seev.031.002.13 Fixed mapping of Block5/PDE flag into the AppHdr/PossibleDuplicate when PDE exists and is empty CBPR+ MT 102/103 -> pacs.008.001.08: fixed mappings for fields 70 and 72 into InstructionForNextAgent and RemittanceInformation\\Unstructured CBPR+ MT 102/103 -> pacs.008.001.08: removed mapping for codeword PURP in field 72 and fixed use of codeword CATPURP into CategoryPurpose\\Code CBPR+ MT 202.COV/205.COV -> pacs.009.001.08.COV: fixed mappings for fields 70 and 72 into InstructionForNextAgent and RemittanceInformation\\Unstructured CBPR+ MT 202 -> pacs.009.001.08/pacs.009.001.08.ADV: fixed mappings for codeword PURP in field 72 into Purpose\\Code and Purpose\\Proprietary Enhanced the market type factories returned by the TranslatorFactoryProvider to honour the translation mappings configuration 9.4.36 - April 2024 (PW-1857) CBPR+ MT 900/910 -> camt.054.001.08: fixed mappings according to CBPR+ mapping rules (PW-1856) MT 200/202/203/205 -> pacs.009: fixed mappings for 72 Narrative extra codewords to InstructionForNextAgent (PW-1855) CBPR+ MT 202 -> pacs.004.001.09: added extra XT99 narrative to ReturnReasonInformation\\AdditionalInformation (PW-1854) CBPR+ MT 202 -> pacs.004.001.09: added mapping for OriginalInstructionIdentification (PW-1850) CBPR+ MT 202 -> pacs.004.001.09: fixed mapping for ServiceLevel\\Code when there's no Block3\\111 (PW-1852) CBPR+ MT 202 -> pacs.004.001.09: added mapping for ReturnIdentification (PW-1851) CBPR+ MT 202 -> pacs.004.001.09: fixed mapping for CreditorAgent when there's no 57a field (PW-1849) CBPR+ MT 202.COV/205.COV -> pacs.009: preserve line numbers in field 50F mapping as part of value in the MX elements (PW-1848) CBPR+ MT 103 -> pacs.004.001.09: fixed mappings to 'NOTPROVIDED' as instructed by the CBPR+ mapping rules (PW-1848) CBPR+ MT 103 -> pacs.004.001.09: added extra XT99 narrative to ReturnReasonInformation\\AdditionalInformation (PW-1848) Fixed mapping of Block5/PDE flag into the AppHdr/PossibleDuplicate (PW-1848) CBPR+ MT 103 -> pacs.004.001.09: fixed mappings to 'NOTPROVIDED' as instructed by the CBPR+ mapping rules MT 103 -> pacs.008: fixed typo in codeword CATPURP 9.4.35 - April 2024 (PW-1835) CBPR+ camt.054.001.08 -> MT 910/910 : fixed mappings for tag 21 (PW-1832) CBPR translators: fixed mapping to comply with CBPR_Agent_Name_Postal_Address_FormalRule rule MX to MT: Revamped implementation of MxToMtFinancialInstitutionNameAndAddress for translation into fields 52D, 53D, 54D, 55D, 56D & 57D MX to MT: Revamped implementation of MxToMtMTFATFNameAndAddress and MxToMtMTFATFNameAndAddress2 for translation into field 50F and 50K MX to MT: fixed coverage in MxToMt functions Added new ISO translator: seev.008.001.08 -> MT 568 Added new ISO translator: MT 536 -> semt.017.001.12 Added new ISO translator: MT 537 -> semt.018.001.13 Added new ISO translators: sese.028.001.09/10 -> MT 578 9.4.34 - April 2024 (PW-1827) Added new ISO translators: camt.053.001.10/11 <-> MT 940/950 (PW-1814) Removed criteria selection in translations MT196/MT296 -> camt.029.001.11 (PW-1759) TranslationFactory: fixed getTranslator for ACK/NACK messages with a specific MX version Added new ISO translator: seev.001.001.10 -> MT 564 Added new ISO translator: seev.002.001.09 -> MT 564 Added new ISO translator: seev.003.001.09 -> MT 564 Added new ISO translator: seev.004.001.09 -> MT 565 Added new ISO translator: seev.005.001.09 -> MT 565 Added new ISO translator: seev.006.001.09 -> MT 567 Added new ISO translator: seev.007.001.09 -> MT 567 MT to MX: Revamped mapping for fields 50F and 59F into structured postal address node when line 3 (country) is present 9.4.33 - March 2024 (PW-1814) MT 196/296 -> camt.029: fixed mapping from narrative 77A when codeword /UETR/ is used in multiple lines (PW-1635) camt.056 -> MT 192/292: fixed default value for tag 20 when node Underlying\\TransactionInformation\\Case\\Identification is missing T2 Translators: added NONREF as fixed value for GroupHeader\\MessageIdentification node T2 Translators: map field 20 to BusinessMessageIdentifier in header 9.4.32 - March 2024 (PW-1759) TranslatorFactory: Added translator ACK/NAK (service 21 message) -> admi.007.001.01 9.4.31 - March 2024 (PW-1804) sese.025 -> MT 540/541/542/543: fixed mapping for multiple 22F STCO indicators (PW-1635) camt.029 -> MT 196/296: fixed default value for tag 20 when node CancellationStatusIdentification is missing Added new ISO translators: sese.020.001.07 -> MT 540/541/542/543 Added new ISO translators: semt.020.001.07 <-> MT 578 Added new ISO translators: semt.002.001.11 <-> MT 535 Added new ISO translator: semt.017.001.12 -> MT 536 Added new ISO translator: semt.018.001.13 -> MT 537 Enhanced truncation report: added MX source path even when partial element content is truncated 9.4.30 - March 2024 (PW-1800) MT 540/541/542/543 -> sese.023: fixed 36B Quantity of Financial Instrument precondition 9.4.29 - March 2024 (PW-1756) MT 102/103 -> pacs.008: added mapping for field 72 codeword /PURP/ into Purpose/Proprietary Added new ISO translators: sese.024.001.11/12 <-> MT 548 Added new ISO translators: pacs.009.001.10 <-> MT 200 (PW-1787) Added new ISO translators: sese.026.001.10 <-> MT 544/545/546/547 (PW-1790) MT950 -> camt.053: fixed BookingDate and EntryDetails mappings (PW-1790) MT942 -> camt.052: fixed BookingDate mapping 9.4.28 - February 2024 (PW-1759) TranslationFactoryConfiguration - deprecated setEvaluatePreconditions (replaced with withEvaluatePreconditions) 9.4.27 - February 2024 (PW-1764) Added new ISO translators: sese.023.001.11 -> MT 540/541/542/543 (PW-1764) Added new ISO translators: sese.025.001.11 -> MT 544/545/546/547 (PW-1764) ISO sese.023.001. / sese.025.001. <-> MT 54*: added mappings for SecuritiesSubBalanceType <-> 22F SSBT (PW-1762) MT 103 -> pacs.004.001.09 (CBPR+/LYNX/T2): fixed mapping for /CHGS/ codeword into ChargesInformation (PW-1759) Added new translator: ACK/NAK (service 21 message) -> admi.007.001.01 (PW-1756) MT 202 -> pacs.009: added mapping for field 72 codeword /PURP/ into Purpose/Proprietary 9.4.26 - January 2024 Added new translator: MT 097 <-> xsys.001.001.01 Added new CBPR+ translator: MT 104 <- pacs.003.001.08 Added new CBPR+ translator: MT 107 -> pacs.003.001.08 Added new ISO translators: MT 104 <- pacs.003.001.08/09/10 Added new ISO translators: MT 107 <-> pacs.003.001.08/09/10 (PW-1754) ISO seev.036.001.14 -> MT 566: fixed mappings in section 16R:CASHMOVE 9.4.25 - January 2024 (PW-1748/1733) CHATS for pacs message the receiver BIC in the AppHdr is fixed to HKICHKHHXXX (PW-1747) SWIFT GO MT199 <-> trck.001.001.02/trck.002.001.01: Fixed mappings Enhanced the TranslatorFactory with new parameters to specify the prefered MT/MX target type and version (replacing preferLatestVersions flag) Added new ISO translators: MT 103.REMIT -> pacs.008.* Added new CBPR+ translator: MT 104 -> pacs.003.001.08 Added new ISO translators: MT 104 -> pacs.003.001.08/09/10 MT192/292 -> camt.058/056: fixed mapping and added default NOTPROVIDED in CancelationReason/AdditionalInformation Truncated report: added path to source and target truncated fields 9.4.24 - January 2024 MT196/296 -> camt.029: removed UETR existence precondition Added new ISO translators: MT 110 <-> camt.107.001.01 Added new ISO translators: MT 111 <-> camt.108.001.01 Added new ISO translators: MT 112 <-> camt.109.001.01 sese.20/23/33/36.* -> MT541: added precondition to check SettlementAmount or OtherAmounts existence seev.32/34/41.* -> MT567: added default A16S:LINK mandatory section 9.4.23 - January 2024 Added new translator: MT 192 -> camt.058.001.08 Added new CBPR+ translator: MT 292 -> camt.058.001.08 Added new CBPR+ translator: MT 192 -> camt.055.001.08 Added new CBPR+ translator: MT 110 -> camt.107.001.01 Added new CBPR+ translator: MT 111 -> camt.108.001.01 Added new CBPR+ translator: MT 112 -> camt.109.001.01 9.4.22 - December 2023 (PW-1732) sese.020 / sese.023 / sese.033 / sese.036 -> MT 543: added precondition to validate SettlementAmount existence in sese messages ISO MT103 -> pacs.008.*: added mapping for block3/103 to ClearingSystem\\Code Added new translators: MT 540 / MT 541 / MT 542 / MT 543 -> sese.020.001.07 / sese.023.001.11 Added new translators: MT 544 / MT 545 / MT 546 / MT 547 -> sese.025.001.11 9.4.21 - December 2023 (PW-1674) CHATS MT103 / MT202 -> pacs.008 / pacs.009: fixed mapping for field 72 /SPRO/ instruction to InstructionForNextAgent\\InstructionInformation CHATS/LYNX/RITS/SCRIPS/T2 pacs.008.001.* <-> MT 103: added mapping for field 26T to CreditTransferTransactionInformation\\Purpose\\Proprietary T2 MT103 -> pacs.008.001.*: convert 8 digit BIC to 11 digit BIC for FinancialInstrumentIdentification/BICFI 9.4.20 - December 2023 (PW-1674) CHATS/LYNX/RITS/SCRIPS/T2 translation factories: return ISO translators in the getTranslator(AbstractMX mx) method (PW-1674) CBPR/SIC/SWIFTGO translation factories: return ISO translators in the getTranslator(AbstractMX mx) method if no specific translator is found (PW-1674) CHATS MT 202/202.COV -> pacs.009.001.08: added mapping for field 72 /CATPURP/ codeword into PaymentTypeInformation\\CategoryPurpose\\Proprietary 9.4.19 - November 2023 (PW-1674) CHATS MT 202/202.COV -> pacs.009.001.08: added mapping for field 72 /SPRO/ instruction to InstructionForNextAgent\\InstructionInformation (PW-1397) CHATS MT 103 -> pacs.008.001.08: added mapping for field 72 /SPRO/ instruction to InstructionForNextAgent\\InstructionInformation 9.4.18 - November 2023 (PW-1698) MT950 -> camt.053: added mapping block3\\108 to GroupHeader\\MessageIdentification (PW-1674) ISO pacs.004/pacs.008/pacs.009 -> MT102/MT103/MT200/MT202/MT205: added mapping GroupHeader\\SettlementInformation\\ClearingSystem\\Code To Block3\\103 (PW-1674) CHATS MT202.COV -> pacs.009.001.08: removed fixed LocalInstrument\\Proprietary mapping 9.4.17 - November 2023 (PW-1691) CBPR+ Translation: fixed business service value for MT 104 -> pain.008.001.08 (PW-1394) Added translation CBPR+ pacs.003.001.08 -> MT107 Updated the SIC translations and translator factory, to use the SIC 4.10 model and message versions 9.4.16 - November 2023 Reverted RITS translations to set the AppHdr creation datetime to the current local time with UTC offset (not necessarily UTC 0) (PW-1684) MT548 -> sese.024: deprecated preconditions 9.4.15 - November 2023 (PW-1683) MT548 -> sese.024/sese.027: don't use field 23G as criteria to define MX target (PW-1674) CHATS Translations: Added MT 192/292 -> camt.056.001.08 (PW-1674) CHATS Translations: Added MT 202 COV -> pacs.009.001.08.COV (PW-1670) seev.031.001.13 -> MT 564: fixed additional mapping for dates without 98C field Added specific translations for SWIFT GO: MT103 <-> pacs.008.001.08 Added specific translations for SWIFT GO: MT199 <-> trck.001.001.02/trck.002.001.01 Added translation MT292 -> camt.058.001.08 9.4.14 - October 2023 (PW-1670) seev.031.001.13 -> MT 564: fixed mapping for dates without 98C field 9.4.13 - October 2023 (PW-1657) pacs.008.001.08/09/10 -> MT 102/103: added additional mapping for PaymentTypeInformation\\ServiceLevel\\Code to Block3\\111 (PW-1581) Enhanced mapping into field 72 to trim the instruction narratives avoiding pure blanks such as \"/REC/ \" (PW-1394) Added translation CBPR+ camt.055.001.08 -> MT192 (PW-1394) Added translation CBPR+ pain.008.001.08 -> MT104 MT564 -> seev.031.002.06 translation: mapping fixes sese.027.001.05 -> MT548 translation: mapping fixes Added missing entries in the CBPR+ translator factory for the recently added translations 9.4.12 - October 2023 (PW-1644) MT 900/910 -> camt.054.001.06/07/08/09: added additional mapping for 21 to TransactionDetails\\References\\EndToEndIdentification 9.4.11 - September 2023 (PW-1596) MT 540/541/542/543 <-> sese.023.001.09: added a special mapping for 22F::STCO/COEX/PARQ and 22F::STCO/COEX/PARC to/from SttlmParams\\PrtlSttlmInd (PW-1397) CHATS Translations: fixed PaymentTypeInformation/CategoryPurpose/Proprietary code IFT 9.4.10 - September 2023 (PW-1477) MT 540/541/542/543 -> sese.023.001.09: added a special mapping for 22F::STCO BPSS into SttlmParams\\SttlmTxCond\\Prtry using BSSP as identification and T2S as issuer 9.4.9 - September 2023 (PW-1442) MT <-> MX translations: fixed TimeZone handling in date time conversions that might lead to invalid date changes during translation depending on the local offset 9.4.8 - September 2023 (PW-1304) LYNX Translation Factory: pacs.009.001.08 returns MT205 translation by default (PW-1304) RITS/SCRIPS/CHATS/T2 Translation Factories: return generic Mx to Mt ISO translators 9.4.7 - August 2023 (PW-1562/PW-1565) MT 530 <-> sese.030.001.008 : Fixed mapping for 22F::PRTL into ReqDtls\\PrtlSttlmInd (PW-1563/PW-1564) MT 548 -> sese.031.001.08 : Fixed mapping, do not map section ReqDtls in MX (Ref\\AcctOwnrTxId, Ref\\MktInfrstrctrTxId and HldInd) (PW-1557) Added translation CBPR+ MT104 -> pain.008.001.08 (PW-1210) Added specific translations for T2 (T2 RTGS) for MT103, MT202 and MT205 to MX (PW-1210) Added specific translations for Lynx (Canada RTGS) for MT103, MT202 and MT205 to MX RITS Translations: fixed creation time in header (Zulu time) MT to MX: replaced the dummy creation date 9999-12-31 in all translations but the CBPR+ ones with the current date 9.4.6 - August 2023 (PW-1474) CBPR MT 900 / MT 910 -> camt.054.001.08 : Added mapping for field 25 into Entry\\EntryReference (PW-1471) MT 548 -> sese.031.001.08 : Fixed mapping for :25D::TPRC//MODC -> ProcessingStatus/Completed (PW-1469) MT 540 / MT 541 / MT 542 / MT 543 <-> sese.023.001.09 : Fixed mapping for 94a <-> SafekeepingPlace (PW-1469) MT 544 / MT 545 / MT 546 / MT 547 <-> sese.025.001.09 : Fixed mapping for 94a <-> SafekeepingPlace (PW-1469) MT 548 <-> sese.024.001.10 : Fixed mapping for 94a <-> SafekeepingPlace (PW-1469) MT 578 <-> sese.028.001.08 : Fixed mapping for 94a <-> SafekeepingPlace (PW-1465) RITS translators: Generate automatic UETR if it doesn't exist in the MT source (Block3/121) (PW-1459) sese.023 <-> MT 540 / MT 541 / MT 542 / MT 543 : Fixed mapping for HoldIndicator <-> 23G (PW-1459) sese.024 <-> MT 548 : Fixed mapping for HoldIndicator <-> 23G (PW-1455) sese.030 -> MT 530 : Fixed mapping for HoldIndicator into :22F::SETT (PW-1454) MxToMt72FullField fix, accept proprietary codewords with alphanumeric characters (PW-1440) MT 548 -> sese.024.001.10 : Added NOTPROVIDED to ProcessingStatus\\CancellationRequested\\AdditionalReasonInformation when :25D::IPRC equals to CPRC and :70D::REAS don't exist 9.4.5 - July 2023 (PW-1423) RITS: Added automatic message identifier generation for the MX header and group header pacs.004 -> MT 103 : Revamped mappings for tag 70 pacs.008 -> MT 102 / 103 : Revamped mappings for tag 70 pacs.009 -> MT 202 COV / 205 COV : Revamped mappings for tag 70 pacs.008 -> MT 102 / 103 : Revamped mappings for tags 50 and 59 Name and Address component pacs.009 -> MT 202 COV / 205 COV : Revamped mappings for tags 50 and 59 Name and Address component 9.4.4 - July 2023 (PW-1438) Added translation seev.044.001.12 -> MT564 (PW-1437) Added translation seev.039.001.12 -> MT564 (PW-1436) Added translation seev.037.001.14 -> MT566 (PW-1435) Added translation seev.036.001.14 -> MT566 (PW-1434) Added translation seev.035.001.14 -> MT564 (PW-1433) Added translation seev.031.001.13 -> MT564 (PW-1433) Added translation seev.031.001.13 -> MT568 Added specific translations for SCRIPS (MEPS+, Singapore RGTS) for MT103 and MT202 to MX Added specific translations for SCRIPS (MEPS+, Singapore RTGS) for MT103 and MT202 to MX (PW-1397) Added specific translations for CHATS (Hong Kong RTGS) for MT103 and MT202 to MX (PW-1399) MT -> MX: amounts are converted into the MX decimal number with minimal decimal places according to the currency (PW-1397) Added specific translations for CHATS (Hong Kong RGTS) for MT103 and MT202 to MX 9.4.3 - July 2023 (PW-1427) Added translations MT564 <-> seev.031.001.11 (PW-1427) Added translations MT568 <-> seev.031.001.11 (PW-1425) Added translation sese.029.001.04 -> MT578 (PW-1425) Added translation semt.020.001.05 -> MT578 (PW-1417) MT104 -> pain.008.001.08 : added mapping for 53A into RemittanceInformation/Structured/AdditionalRemittanceInformation 9.4.2 - June 2023 (PW-1424) Added translations MT530 <-> sese.030.001.08 (PW-1424) Added translations MT548 <-> sese.031.001.08 (PW-1399) FormatDecimal MT -> MX : added 2 fixed decimal places in all translations (PW-1421) CBPR+ MT910 -> camt.054.001.08 : fixed CreditDebitIndicator from DBIT to CRDT (PW-1412) Added translation sese.028.001.08 -> MT578 9.4.1 - June 2023 (PW-1407) MT548 -> sese.024/032/034 / semt.014 and MT537 -> semt.018 : added pending reason code mapping (PATD to OTHR) (PW-1407) MT548 -> sese.024/034 : added rejected reason code mapping (NARR to OTHR) (PW-1406) CBPR+ MT to MX translations -> trim starting slashes while mapping account numbers into Identification/Other/Identification to be compliant with CBPR+ restricted charset (PW-1394) Added CBPR+ translation camt.058.001.08 -> MT292 (PW-1394) Added CBPR+ translation camt.107.001.01 -> MT110 (PW-1394) Added CBPR+ translation camt.108.001.01 -> MT111 (PW-1394) Added CBPR+ translation camt.109.001.01 -> MT112 MTn92, MTn96 and MT200 to MX: Fixed translation of field 11[R,S] into date time element in MX, adding a dummy time component 9.4.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 9.3.42 - June 2023 (PW-1395) Added translation MT578 -> sese.028.001.08 (PW-1391) pacs.008.001 -> MT102/103: Revamped implementation of MxToMtRemittanceInformation for translation into field 70 (PW-1390) CBPR+ pacs.009.001.08 -> MT200/202/205: Revamped implementation of MxToMtPartyNameAndStructuredAddress and MxToMtPartyNameAndUnstructuredAddress for translation into fields 52D/56D/57D/58D (PW-1388) CBPR+ pacs.008.001.08 -> MT103: minor fix in function MxToMtAddressLineIsStructured (PW-1385) CBPR+ pacs.008.001.08 -> MT103: minor fix in function MxToMtNameAndAddress (7/NIDN information) (PW-1384) CBPR+ pacs.008.001.08 -> MT103: fixed mapping for PaymentTypeInformation/CategoryPurpose/Code into tag 23E (PW-1382) sese.023.001.09 -> MT540/MT541/MT542/MT543: new mapping from OtherBusinessParties/Investor/Nationality to field 95C (PW-1182) Added CBPR+ translation MT201 -> pacs.008.001.08 (PW-1182) Added CBPR+ translation MT203 -> pacs.008.001.08 (PW-1182) Added CBPR+ translations MT102 / MT102.STP <-> pacs.009.001.08 / pacs.009.001.08.STP pacs.008/pacs.004/pain.001 -> MT101/102/103: truncate with evidence last line in field 70 mapping CBPR+ camt.052/camt.053: fixes in fields 20/28C/34F/61 mapping pacs.002 <-> MT199 / MT299: Revamped implementation of MxToMt72Or79REJT for translation into field 79 9.3.41 - May 2023 (PW-1371) pacs.004/pacs.008 -> MT102/MT103: conditional mapping to field 71G only if the amount is different from 0 (PW-1360/PW-1363) CBPR+ pacs.004 -> MT103: Revamped implementation of MxToMtRETN(MT1) for translation into field 72 (PW-1359) CBPR+ pacs.008.001.08.STP -> MT103.STP: use only the last PreviousAgent occurrence for mapping into field 72 pacs.004 -> MT103: implementation of MxToMtRETN(MT1) for translation into field 72 pacs.004 -> MT202/MT205: implementation of MxToMtRETN(MT2) for translation into field 72 9.3.40 - May 2023 Added specific translations for RITS (Australian RTGS) for MT103 and MT202 to MX Added a TranslatorFactoryProvider to allow the creation of a TranslatorFactory for a specific market or clearing type Added accessors for the TranslatorConfiguration in the Translator interface Deprecated the 'translate' call with configuration parameter in favor of modifying the translator instance configuration 9.3.39 - April 2023 (PW-1353/1354) CBPR+ pacs.004/pacs.008/pacs.009 to MT: fixed tags 50/59 letter option logic and added MxToMtAddressLineIsStructured function implementation (PW-1349) Enhanced mapping into field 72 by adding MxToMt72FullField function implementation (PW-1349) Fixed the implementation of the InstructionForNextAgent function (PW-1347) Added translation seev.044.001.11 -> MT564 (PW-1345) Added translation seev.037.001.13 -> MT566 (PW-1344) Added translation seev.036.001.13 -> MT566 (PW-1343) Added translation seev.035.001.13 -> MT564 (PW-1342) Added translations seev.031.001.12 -> MT564 / MT568 9.3.38 - April 2023 (PW-1340) CBPR+ MT210 -> camt.057: strip leading slash (/) while mapping tag 25 into Notification/Account/Identification/Other/Identification (PW-1336) pacs.004.001 -> MT103 / MT202 / MT205: fixed mapping of tag 72, added XT99 code to unmappable reason codes 9.3.37 - April 2023 (PW-1335) MT to MX: fixed MxToMt72FullField for translation into field 72, multiple lines mapping in InstructionForNextAgent node (PW-1334) camt.053 -> MT940 / MT950: fixed preconditions and mapping for 60F/M - 61 (PW-1330) pacs.008 -> MT103: fixed mapping of tag 77B, admit simultaneous /ORDERRES/ and /BENEFRES/ codes (PW-1310/1314/1328/1329) MX to MT: mapping for Name and Address fields 50/52/53/54/56/57/58/59, Revamped implementation of MxToMtNameAndAddress functions (PW-1310/1314/1328/1329) CBPR+ pacs.004/pacs.008/pacs.009 translators, using new MxToMtNameAndAddress functions (PW-1276) MX to MT: MxToMt72FullField for translation into field 72, add ACC code to InstructionForCreditorAgent Added and option in the translator configuration to define the specific version for the AppHdr to generate 9.3.36 - April 2023 (PW-1208) ISO pacs.008 / pacs.004 -> MT103: deprecated preconditions (InstructingAgent and InstructedAgent) 9.3.35 - April 2023 (PW-1325) sese.024 -> MT548: fixed translation of tag 24B:REJT, mapping of code OTHR to NARR 9.3.34 - April 2023 (PW-1319) pacs to MT103: removed mapping of extra content /LOCINS/CRED in field 72 (PW-1317) pacs.008.001 -> MT103: fixed mapping of tag 77B, included CountryOfResidence for Debtor and Creditor (PW-1316) MT to MX: fixed mapping of tag 59F PartyIdentifier (PW-1315) MT to MX: MxToMt72FullField for translation into field 72, excluded Proprietary fields in LOCINS indicator (PW-1312) pacs.004.001 -> MT103 / MT202 / MT205: fixed mapping of tag 72, correct parsing of ReasonCode and AdditionalInformation (PW-1311) CBPR+ pacs.008.001 -> MT103: fixed mapping of tag 59, extra row in Name and Address section (PW-1309) CBPR+ pacs.008.001 -> MT103: fixed mapping of tag 59F, extra row in Name and Address section (PW-1308) CBPR+ pacs.008.001 -> MT103: fixed mapping of tag 23E SDVA and INTC (PW-1301) CBPR+ pacs.008.001 -> MT103: added mapping of tag 23E for HOLD, CHQB, PHOB and TELB codes in CreditTransferTransactionInformation\\InstructionForCreditorAgent (PW-1299) pacs.008.001 -> MT103 / MT102: fixed mapping of tag 70, added /URI/ indicator to RemittanceInformation\\Unstructured mapping (PW-1298) pacs.004.001 -> MT103 / MT202 / MT205: fixed mapping of tag 72, added /XT99/ to reason code (PW-1297) MT to MX: fixed mapping of tag 52D, truncate line 2 when FinancialInstitutionIdentification\\Name is longer than max length (PW-1276) pacs.008.001 -> MT103 / MT102: fixed mapping of tag 70, RemittanceInformation\\Unstructured with /RFB/ indicator 9.3.33 - March 2023 (PW-1296) CBPR+ MT202/205 -> pacs.009 and MT103 -> pacs.008: removed the precondition rejecting 53B in present along 54a CBPR+ MT202/205 -> pacs.009 and MT204 -> pacs.010: fixed mapping of 58D into Name & Address to be compliant with CBPR+ UG rule MT to MX: Removed unnecessary precondition checking the format of /CLSTIME/ in field 72 9.3.32 - March 2023 (PW-1288/1289/1290/1291/1293/1295) pacs.004.001.09/10 -> MT103: minor fixes in mapping for Creditor/Agent to field 59 and Debtor/Agent to field 50 (PW-1285) pacs.008.001 -> MT103: fixed mapping InstructionForCreditorAgent\\Code CHQB to field 23E (PW-1284/1294) minor fixes in MxToMt72FullField and MxToMt72FullField2 for translation into field 72 (PW-1283) pacs.004.001.09/10 -> MT103 / MT202 / MT205: fixed mapping for field 72 added extra TEXT line (PW-1282) pacs.004.001.09/10 -> MT103: added mapping for Creditor/Agent to field 59 and Debtor/Agent to field 50 (PW-1280) pacs.008 -> MT103: fixed mapping of tag 70, remove /RFB/ prefix when EndToEndIdentification is NOTPROVIDED (PW-1280) MX_To_MTAgent: removed Schema/Code prefix when it's different from CUID (PW-1280) MX_To_MTFATFNameAndAddress: replaced last / separator in CountryCode/TownName/PostCode for CountryCode/TownName,PostCode (PW-1278) pacs.009.001 -> MT202.COV: Implementation of MxToMt72FullField and MxToMt72FullField2 for translation into field 72 (PW-1276) CBPR+ pacs.008 -> MT103: Revamped implementation of MxToMt72FullField for translation into field 72 (PW-1275) Added translation semt.002.001.10 -> MT535 (PW-1267) MT103 -> pacs.008: Changed field 23E mapping to avoid InstructionForNextAgent/Code for compatibility with HVPS (PW-1209) MT204 -> pacs.010.001.03: deprecated mandatory Block3/121 precondition and autogenerate new UETR if Block3/121 is missing 9.3.31 - March 2023 (PW-1270) MT535 -> semt.002.002.03 / semt.003.002.03: fixed mapping of tag 94a in Sequence B1 to BalanceForAccount/SafekeepingPlace (PW-1265) ISO pacs.004.001.09/10 -> MT103 / MT202 / MT205: fixed reason code mapping for field 72 (PW-1265) ISO pacs.004.001.09/10 -> MT103 / MT202 / MT205: fixed selector criteria, defaulting to MT202 (PW-1265) ISO pacs.004.001.09/10 -> MT103: fixed mapping field 72, field 50F and field 57D (PW-1208) ISO pacs.009 -> MT202: deprecated preconditions (InstructingAgent and InstructedAgent) 9.3.30 - March 2023 (PW-1271) MT192/MT292 -> camt.056.001.08/10: fixed mappings of fields 20 and 21 into the Underlying message information (PW-1266) Fixed length in field 72 wrapped lines (PW-1265) CBPR+ pacs.004.001.09 -> MT103 / MT202 / MT205: fixed reason code mapping for field 72 (PW-1262) CBPR+ pacs.004 -> MT103 / MT202 / MT205: fixed selector criteria, defaulting to MT202 (PW-1240) pacs.009 -> MT202/MT205: proper generation of the // (continuation of narrative) prefixes in field 72 9.3.29 - March 2023 (PW-1240) pacs.009.001.* -> MT202 / MT205: fixed mapping of RemittanceInformation/Unstructured in MxToMt72FullField2 for translation into field 72 9.3.28 - March 2023 (PW-1258) CBPR+ pacs.004.001.09 -> MT103: fixed mapping field 72, field 50F and field 57D (PW-1257) camt.053.001.02/07/08 -> MT940: fixed mapping of multiple AdditionalEntryInformation to field 86 (PW-1182) Fixed translations MT940 <-> camt.060.001.05 for both generic ISO and CBPR+ versions (PW-1182) Added translations MT940 <-> camt.060.001.06 9.3.27 - March 2023 (PW-1253) camt.056.001.08/10 -> MT192 / MT292: fixed mapping of OriginalGroupInformation\\OriginalCreationDateTime to 11S (PW-1252) camt.053.001.* -> MT950: fixed mapping of Statement\\LegalSequenceNumber and Statement\\ElectronicSequenceNumber to field 28C (PW-1249) pacs.008.001.* -> MT102 / MT103: fixed mapping of RemittanceInformation/Unstructured with ROC prefix to field 70 (PW-1247) MT202 / MT205 to pacs.009: Fixed mapping of TELEBEN code into InstructionForCreditorAgent/Code (PW-1245) CBPR+ pacs.009.001.08.COV -> MT202.COV: removed unnecessary RFB prefix in field 70, fixed field 72 line split (PW-1240) MT103 -> pacs.008.001.*: removed unnecessary defaults 'false' for BatchBooking (PW-1238) MT202 / MT205 -> pacs.009.001.*: fixed 53A mapping to SettlementInformation/SettlementAccount (PW-1237) MT103 / MT103.STP -> pacs.008.001.*: fixed 53A mapping to /FIN53/ in InstructionForNextAgent (PW-1235) CBPR+ pacs.009.001.* -> MT202 / MT205: Revamped implementation of MxToMt72FullField2 for translation into field 72 (PW-1233, PW-1246) CBPR+ pacs/camt -> MT: ignore FinancialInstitutionIdentification\\PostalAddress\\AddressLine containing \"NOTPROVIDED\" (PW-1230) CBPR+ pacs.008.001.08 -> MT103: added mapping for field 26T (PW-1229) Preserve whitespaces in XML element values when parsing the source MX for translation into MT (PW-1229) CBPR+ pacs.008/pacs.009 -> MT103/MT202: fixed mapping of multiple occurrences of InstructionForNextAgent/InstructionInformation to field 72 (PW-1229) camt.053.001.* -> MT940: fixed mapping of EntryDetails/AdditionalEntryInformation to field 86 (PW-1229) TranslationConfiguration: added new attribute preserveWhitespaces to prevent the translator from trimming the node contents in the MX to MT translations 9.3.26 - March 2023 (PW-1251) CBPR+ MT to pacs.009: Fixed mapping of field 72 into repetitive InstructionForNextAgent with proper truncation 9.3.25 - March 2023 (PW-1228) CBPR+ translation: fixed duplicated Member Identification in field 57D when translating from a ClearingSystemMemberIdentification element (PW-1225) CBPR+ pacs.004/pacs.009/pacs.009.COV/pacs.009.ADV -> MT202/MT202COV: removed unnecessary defaults 'NOTPROVIDED' for fields 52D-56D-57D (PW-1219) camt.054.001.06/07/08/09 -> MT900/MT910: fixed AddtlTxInf split into field 72 lines 9.3.24 - March 2023 (PW-1224) Fixed RemittanceInformation\\Unstructured -> tag 70 (code RFB deleted) in CBPR+ translation pacs.008.001.08 -> MT103 (PW-1220) Fixed tag 53B incorrect prefix (INGA = C/INDA = D) in CBPR+ translation pacs.008.001.08 -> MT103 (PW-1217) Fixed InstructionForNextAgent\\InstructionInformation -> tag 72 (multiple occurrences) in CBPR+ translation pacs.008.001.08 -> MT103 (PW-1216) Fixed InstgAgt mapping to 72/INS/ in translation CBPR+ pacs.009.001.08 -> MT202 (PW-1210) Added translations MT102 <-> pacs.008.001.09 (PW-1210) Added translations MT103 / MT103.STP <-> pacs.008.001.09 (PW-1210) Added translations MT103 <-> pacs.004.001.10 (PW-1210) Added translations MT202 <-> pacs.004.001.10 (PW-1210) Added translations MT205 <-> pacs.004.001.10 (PW-1210) Added translations MT200 <-> pacs.009.001.09 (PW-1210) Added translations MT202 / MT202.COV <-> pacs.009.001.09 (PW-1210) Added translations MT205 / MT205.COV <-> pacs.009.001.09 (PW-1196) Fixed field 61/Supplementary Details mapping in the MT940 -> camt.053.001.07/08/09 translators (PW-1182) MT920 to camt.060.001.05: fixed intermediate field 34F repetition mapping (PW-1182) Added translations MT196/296 <-> camt.029.001.11 (PW-1182) Added translations pacs.009.001.08 -> MT205.COV 9.3.23 - February 2023 (PW-1205) Removed criteria selection in translations MT196/MT296 -> camt.029.001.09 (PW-1204) Fixed 22F:STCO repetitive tag in translations sese.024. /sese.034. -> MT548 - semt.017.002.01 -> MT536 - semt.018.002.01 -> MT537 9.3.22 - February 2023 (PW-1196) Enhancements in the MT940 <-> camt.053.001.* translators to enable back-and-forth conversion without data loss (PW-1196) Translator Factory: prefer MT940 over MT950 when both options are available as target MT (PW-1194) Fixed field 50A mapping in pacs.008.001.* to MT translators, it was the wildcard letter option 'a' instead of 'A' (PW-1089) Fixed Field 72 translation in MT103 -> pacs.008.001.* (PW-1089) Internal enhancement of narrative fields content extraction (MTs n99, 103, 200, 202 and 205 to MX) 9.3.21 - February 2023 (PW-1183) Fixed criteria filter in translations pacs.008.001.08/10 -> MT102 9.3.20 - February 2023 (PW-1182) Added translations MT102 <-> pacs.008.001.08 (PW-1182) Added translations MT900 <-> camt.054.001.09 (PW-1182) Added translations MT192/292) <-> camt.056.001.10 (PW-1182) Added translations MT941 <-> camt.052.001.09 (PW-1182) Added translation camt.060.001.06 -> MT920 (PW-1089) pacs.008 to MT103: enhanced field 72 mapping to support and propagate also custom codes (PW-1173) mapped the MX header priority into the target MT also when the direction of the MT is inbound (SwiftBlock2Output) Reviewed preconditions for pacs, semt to meet MT semantic checks restrictions Reviewed MT103 translation preconditions to make sure field 54A used with //RT indicator is followed by data for the member id 9.3.19 - January 2023 (PW-1157) Added translation seev.035.001.11 to MT564 9.3.18 - January 2023 (PW-1148) Added translation MT548 to sese.027.001.05 (PW-1146) Added translations sese.020.001.06 to MT540/MT541/MT542/MT543 (PW-1137) Added translations MT199/MT299 RJCT to pacs.002.001.10 (generic ISO 20022 and CBPR+ versions) 9.3.17 - December 2022 (PW-1138) camt.057.001.06 to MT210: Notification/Item/Account fix (PW-1137) CBPR+ translation issue for pacs.002 (PW-1136) Added translation seev.039.001.10/11 to MT564 (PW-1135) Added translation seev.037.001.11 to MT566 (PW-1134) Added translation seev.036.001.11 to MT566 (PW-1133) Added translation seev.035.001.10 to MT564 (PW-1132) Added translation seev.031.001.10 to MT564 (PW-1131) Added translation seev.031.001.10 to MT568 (PW-1129) CBPR pacs.008.001.08 to MT103: minor fix fin field 72 /REC/ mapping MT300 to fxtr.014.001.03: implementation enhancements 9.3.16 - December 2022 (PW-1125) pacs.009.001 to MT202 precondition SR23 fix 9.3.15 - December 2022 (PW-1123) MT202/MT205 to pacs.009.001: added mapping of account in field 53A into instruction for next agent with /FIN53/ prefix Internal implementation enhancements in MT564/MT568 to seev.031 and MT564 to seev.039 9.3.14 - November 2022 (PW-1112) sese.023.001.09 to MT540, MT541, MT542 and MT543 enhancements 9.3.13 - November 2022 (PW-1111) Added translation sese.023.001.09 to MT541 and MT543 Added translation sese.024.001.09 to MT548 9.3.12 - November 2022 Updated Apache Commons Text dependency to 1.10 to fix reported CVE (PW-1103) MT210 <-> camt.057.001.06: Enhanced mapping of fields 50, 52 and 56 (PW-1100) MT196/296 to camt.029: optional 11R/11S criteria check and added 11S translation (PW-1089) MT103 to pacs.008: Enhanced mapping of fields 70 and 72 into InstructionForNextAgent and RemittanceInformation (PW-1044) MT103 to pacs.008 - added narrative 72 /LOCINS/ /CATPURP/ and Batch Booking node Added translation MT200 to camt.050.001.05 9.3.11 - November 2022 Migrated SIC translations to release 4.9 9.3.10 - October 2022 Added translation camt.050.001.05 to MT200 (PW-1088) MT101 to pain.001 and MT103 to pacs.008: field 23E mapping enhancements 9.3.9 - October 2022 (PW-1077) MT548 to sese.024.001.10 mapping enhancements (PW-1063) MT544/545/546/547 to sese.025.001.09: Fixed partial settlement indicator mapping (PART, NPAR) (PW-1063) MT542 to sese.023.001.09: Fixed partial settlement indicator mapping (PART, NPAR) (PW-1057) MT to pacs.008 and pacs.009 - translate field 72 - added /BNF/ and /REC/ prefix in MX output 9.3.8 - October 2022 (PW-1075) MT548 to sese.024.001.10: MatchingStatus fixes with default if field 70D is not present (PW-1072) pacs to MT103 (and 202): Fixed logic for field 33B mapping to avoid D49 error in semantic check (PW-1057) MT103 to pacs.008: Remittance Unstructured mapped from Field 72 /BNF/ with fallback to mapping from field 70 if /BNF/ is not present (PW-1064) Fallback option to system classloader in resource loading Enhancements in MT party identifier into to MX clearing system identification mappings Added missing new versions for SRU2022 to the translator factory 9.3.7 - September 2022 (PW-1066) Added translations MT545 MT546 MT547 to sese.025.001.09 (PW-1065) Added translation sese.023.001.09 to MT542 (PW-1063) Added translation MT544 to sese.025.001.09 (PW-1062) pacs.008/pacs.009 to MT translates enhancements in field 20 for consistency between CBPR+ and generic ISO 20022 mappings (PW-1061) Revamp of the translation factory in order to enhance defaults and disambiguation (PW-1060) Fixed cast exception in MX to MT translations using explicit Output direction for the target message (PW-1059) MT to MX: Fixes an enhancements in translation of fields 50F and 59F (MTs; 101, 102, 103, 104, 202, 205, 210) (PW-1057) MT to pacs.008/pacs.009 enhanced mapping of REC code in field 72 (PW-955) pain.001 to MT101: copy raw unstructured remittance information to field 70 Added enum classes MtToMxTranslation and MxToMtTranslation will the supported translations 9.3.6 - September 2022 (PW-1043) CBPR+: Minor enhancements in the 192/292 to camt.056 translations (PW-1006) Changed the translation factory, to fall-back into 29 for MT target when both 19 and 29* are feasible Added generic ISO: MT103 to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT196 to camt.029.001.09 (based on CBPR+ translation) Added generic ISO: MT200 to pacs.009.001.08 (based on CBPR+ translation) Added generic ISO: MT202 to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT202 to pacs.004.001.09 (based on CBPR+ translation) Added generic ISO: MT202COV to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT204 to pacs.010.001.03 (based on CBPR+ translation) Added generic ISO: MT205 to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT205 to pacs.004.001.09 (based on CBPR+ translation) Added generic ISO: MT205 to pacs.009.001.08 (based on CBPR+ translation) Added generic ISO: MT205COV to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT205COV to pacs.009.001.08 (based on CBPR+ translation) Added generic ISO: MT296 to camt.029.001.09 (based on CBPR+ translation) Added generic ISO: camt.029.001.09 to MT196 (based on CBPR+ translation) Added generic ISO: camt.029.001.09 to MT296 (based on CBPR+ translation) Added generic ISO: camt.056.001.08 to MT292 (based on CBPR+ translation) Added generic ISO: camt.057.001.06 to MT210 (based on CBPR+ translation) Added generic ISO: camt.060.001.05 to MT920 (based on CBPR+ translation) Added generic ISO: pacs.002.001.10 to MT199 (based on CBPR+ translation) Added generic ISO: pacs.002.001.10 to MT299 (based on CBPR+ translation) Added generic ISO: pacs.004.001.09 to MT202 (based on CBPR+ translation) Added generic ISO: pacs.004.001.09 to MT205 (based on CBPR+ translation) Added generic ISO: pacs.009.001.08 to MT200 (based on CBPR+ translation) Added generic ISO: pacs.009.001.08 to MT205 (based on CBPR+ translation) Added generic ISO: pacs.010.001.03 to MT204 (based on CBPR+ translation) Removed unnecesary unescape in internal extractPattern function 9.3.5 - September 2022 (PW-1031) Added translation MT548 to sese.024.001.10 (PW-1006) MX to MT: Added a translation coverage report to see what source elements have been read during the translation semt.020.002.01 to MT578 mapping fix for REDE/RECE => REAG semantic check compiance in the generated MT 9.3.4 - August 2022 (PW-1012) sese.027.001.05 to MT548 mapping fixes 9.3.3 - August 2022 (PW-955) pain.001 to MT101: added truncation to the text after /RFB in field 70 Added internal loops API to MTs: 110, 201, 203, 210, 410, 412, 420, 422, 450, 456, 604, 605, 801, 920, 973 9.3.2 - July 2022 (PW-958) Enhanced the truncation report to differentiate between truncation regular fields and reference fields (PW-949) MX to MT: enhanced mapping of name & address fields, with truncation with evidence and having the country, when present, always at the last line (PW-948) MX -> MT202, MT204, MT205: enhanced mapping of field 58D (PW-948) MX -> MT202, MT204, MT205: enhanced mapping of field 58D (PW-948) pacs.009.01.10 -> MT202: enhanced mapping of field 58D (PW-943) Added translation: pacs.002.001.10 positive -> MT199/MT299 (PW-943) pacs.002.001.10 positive to MT199/MT299 (PW-935) Added MT-MX translation for latest versions of seev.031, seev.032, seev.033, seev.034, seev.038, seev.039, seev.040, seev.041, seev.042 (PW-932) Added translation: pacs.008.001.08 (ISO and CBPR+) -> MT103.REMIT (PW-932) Added a translation configuration parameter to disable the generation of the PDE flag (PW-932) Added translation: camt.056.001.08 -> MT192 (PW-924) Added translation: camt.052.001.09 <-> MT942 (PW-924) Added translation: camt.053.001.09 <-> MT940 (PW-924) Added translation: camt.053.001.09 <-> MT950 (PW-924) Added translation: camt.054.001.09 <-> MT910 setr.004.001.04 -> MT502: mapped the Holdings Redemption Rate into 36B::ORDR/UNIT to be compliant with semantic 258 check MT102 -> pacs.008.001.10: fixed mapping to be compliant with MX cross element checks Implementation enhancements 9.3.1 - May 2022 (PW-832) Added translation sese.023.001.09 -> MT540 MX to MT: Added truncation with evidence in party identification name fields 9.3.0 - May 2022 SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.2.35 - May 2022 (PW-918) Added translation MT192/MT292 -> camt.056.001.08 (PW-908) Added translation: MT102 -> pacs.008.001.10 (PW-813) Internal enhancement to fix CVE Added getTruncatedContent() to the Translator interface Deprecation API review 9.2.34 - May 2022 (PW-915) Added translation: pacs.009.001.10 <-> MT202 (PW-915) Added translation: pacs.008.001.10 <-> MT103 (PW-908) Added translation: pacs.008.001.10 -> MT102 Mx to MT: Added a post process to sanitize with default values missing components in party fields options D, K and H 9.2.33 - May 2022 (PW-905) MX pain.001 to MT101: Added default values for charges and creditor and removed related preconditions 9.2.32 - May 2022 (PW-899) sese.027.001.05 -> MT548 added the mapping of TxDtls into SETTRAN Added CBPR+ translation: MT950 <-> camt.053.001.08 Added CBPR+ translation: MT941 <-> camt.052.001.08 Added CBPR+ translation: camt.060.001.05 -> MT920 Added CBPR+ translation: pacs.009.001.08 -> MT200 Added CBPR+ translation: MT941 <-> camt.052.001.08 9.2.31 - April 2022 Added CBPR+ translation: MT200 -> pacs.009.001.08 Added CBPR+ translation: MT942 -> camt.052.001.08 Added CBPR+ translation: MT940 -> camt.053.001.08 Added CBPR+ translation: MT204 <-> pacs.010.001.03 Added CBPR+ translation: MT103, MT202, MT205 -> pacs.004.001.09 Added CBPR+ translation: MT900 -> camt.054.001.08 Added CBPR+ translation: MT910 -> camt.054.001.08 Added CBPR+ translation: MT210 -> camt.057.001.06 Added CBPR+ translation: MT101 <-> pain.001.001.09 MT101 to pain.001: fixed mapping of fields 50F and 59F, with preference for structured postal address instead of unstructured address lines CBPR+ MT192 and MT292 to camt.056: Added mapping of mandatory CreationDateTime MT103 STP to CBPR+ pacs.008.001.08.STP: Fixed mapping of mandatory creditor account CBPR+ MT to MX: changed the mapping of GroupHeader/CreationDateTime to have a fixed dummy date instead of the current time (PW-887) MT to MX: fixed the concatenation of narrative, to use space separator or not, depending on the MT value being split by length or words (PW-887) MX to MT: added a postprocess of the created message to sanitize fields with lines starting with '-' or ':' using '.' as replacement 9.2.30 - April 2022 seev.036 and seev.037 to MT566: Fixed mapping of CADETL dates seev.036 to MT566: Fixed mapping of SECMOVE dates, CASHMOVE and 19B::WITF -> 19B::FTCA seev.035 to MT564: FIxed mapping of CADETL Added CBPR+ translation: camt.057.001.06 -> MT210 MX to MT: Fixed mapping of field 50F party identifier using code, country and identifier (no account number) 9.2.29 - April 2022 Added translations: MT196/MT296 -> CBPR+ camt.029.001.09 Added translations xsys.011.001.01 and xsys.001.001.02 -> ACK/NAK (service 21 message) Fixed MIR generation in translations from xsys.012 and xsys.003 to MT019 9.2.28 - March 2022 Added CBPR+ translation camt.029.001.09 to MT196/296 (PW-747) Added translation: MT104 -> pain.008.001.08 9.2.27 - March 2022 (PW-872) Fixed mapping of field 95Q with multiple lines of name & address Added translations: MT566 <-> seev.036.002.12 and seev.036.001.12 Added translations: MT566 <-> seev.037.002.12 and seev.037.001.12 Added translations: MT564 <-> seev.035.002.12 and seev.035.001.12 Added translations: MT564 <-> seev.044.002.10 and seev.044.001.10 9.2.26 - March 2022 Added CBPR+ translation MT103 REJT to pacs.002.001.10 Added CBPR+ translation MT202 REJT and MT202 COV REJT to pacs.002.001.10 Added CBPR+ translation MT205 REJT and MT205 COV REJT to pacs.002.001.10 (PW-865) MT540/541/542/543 to sese.023.001.09: fixed mapping of place of trade 94B Added API to the translation factories to indicate a specific message type/version output 9.2.25 - March 2022 (PW-747) Added CBPR+ translations camt.056 <-> MT192/MT292 9.2.24 - March 2022 Enhanced support for local date time offset in the mappings MX to MT: mapping review for fields 98a, with preference of 98E over 98C when possible From prowide-iso2022 update: changed the default date time serialization to local time with UTC offset 9.2.23 - March 2022 (PW-859) MT54x to sese.020 fixed mapping of fields 20C:SEME, 20C:PCTI and 20C:MITI 9.2.22 - February 2022 Added CBPR+ translation camt.052 to MT942 camt.052 to MT941/MT942 migrated to common translations hierarchy camt.052/053 to MT: Fixed mapping of pagination into 28C CBPR+ fixed translation of 72:/INS to previous instructing agent, added dummy postal address to be compliant with UG 9.2.21 - February 2022 Added translation versions MT566 to seev.036.001.12 and seev.037.001.12 Added CBPR+ translation camt.053 to MT940 Added CBPR+ translation camt.054 to MT900/MT910 Added CBPR+ translation pacs.002 negative to MT199/MT299 REJT CBPR+ MT202 to pacs.009 ADV: fixed mapping of settlement information from fields 53a and 54a in the MT CBPR+ MT103 and MT202 mapping: fixed mapping for default creditor and debtor agents camt.053 to MT940/MT950 migrated to common translations hierarchy 9.2.20 - January 2022 (PW-831) camt.052 and camt.053 to 9xx: Fixed direction toggle by configuration 9.2.19 - January 2022 Added CBPR+ translation pacs.004.001.09 to MT103 RETN Added CBPR+ translation pacs.004.001.09 to MT202 RETN Added CBPR+ translation pacs.004.001.09 to MT205 RETN Added CBPR+ translation pacs.009.001.08.ADV to MT202 Added CBPR+ translation pacs.009.001.08 to MT205 Added CBPR+ translation pacs.009.001.08.COV to MT205COV Added translation version pacs.004.001.09 to MT103 RETN (PW-747) Added translations version for pain.001.001.09 <--> MT101 (PW-831) MT9xx to camt.05x: Versions 6, 7 and 8 migrated to common translations hierarchy MT101 to pain.001.001.08: migrated to common translations hierarchy Migrated CBPR+ translations to release 2.1 9.2.18 - January 2022 (PW-798) Added translations from MT540, MT541, MT542 and MT543 to sese.020.001.06 (PW-798) Added translations from sese.027.001.05 to MT548 Added specific translation implementation classes for CBPR+ (pacs.009 --> MT202) Added a CbprTranslatorFactory to autodetect source CBPR+ messages and provide its corresponding translation implementation MT to seev: Fixed incorrect version at AppHdr/MsgDefIdr in some MT to seev translations MX to MT: Added a translation configuration option to enabled or disabled the conversion of non-SWIFT characters into '.' 9.2.17 - January 2022 Added specific translation implementation classes for CBPR+ (pacs.009 <-- MT202/MT205) MT103 and MT202 to MX: removed redundant mapping for Interbank Settlement Date to meet cross-element rule constraint MT202 to pacs.009: Added criteria selection, field 72 must not indicate message is a rejection or return MT202 to pacs.009: Versions 6, 7 and 8 migrated to common translations hierarchy MT202 to pacs.009: enhanced mapping of SttlmInf in GrpHdr according to the CBPR+ METAFCT002/METAFCT003 9.2.17 - December 2021 Added specific translation implementation classes for CBPR+ (pacs.008 <-> MT103) Added com.prowidesoftware.integrator.translations as automatic module name in the MANIFEST for JPMS support MT103 to pacs.008.001.08: minor mapping enhancements (UETR, field 13C) MT to MX: Changed default ISO date time to local time with offset (for CBPR+ compatibility) MT to MX: Changed default label for missing content from UNKNOWN to NOTPROVIDED (for CBPR+ compatibility) 9.2.16 - December 2021 (PW-781) Added translation sese.025.001.09 to MT545 and MT547 (PW-779) Added translation MT541 and MT543 to sese.023.001.09 MT103 to pacs.008: added criteria check to avoid translating RETURN messages into pacs.008 (pacs.004 should be used instead) MT to MX: BusinessApplicationHeaderV02 is now generated by default instead of BusinessApplicationHeaderV01 Added back and forth mapping between the MT priority and PDE flag and the MX AppHdr 9.2.15 - November 2021 MT103 to pacs.008: enhanced mapping of SttlmInf in GrpHdr according to the CBPR+ METAFCT001 9.2.14 - November 2021 (PW-769): Added mapping for expected trade and settlement dates (from B/98a into NewDetails dates) MT103 to pacs.008: removed redundant IntrBkSttlmDt from GrpHdr (already mapped in CdtTrfTxInf) to be compliant with cross-element rule 9.2.13 - November 2021 (PW-762) Added translation MT542 to sese.023.001.09 9.2.12 - November 2021 (PW-754) camt.054 to MT900 and MT910: fixed mapping of 13D, 32A value date, 52D, 72 and added mapping for 50F option 9.2.11 - October 2021 (PW-643) setr.010.001.04 to MT502: RSET is set from CshSttlmDt (with fallback to ReqdFutrTradDt) 9.2.10 - October 2021 (PW-643) setr.004.001.04 to MT502: RSET is set from CshSttlmDt (with fallback to ReqdFutrTradDt) 9.2.9 - October 2021 (PW-643) MT509 to setr.016.001.04: changed mapping of OrdrDtlsRpt to IndvOrdrDtlsRpt to align with the SMPG spec (PW-663) Added translation MT210 to camt.057.001.06 (PW-663) Added translation MT103 RETURN to pacs.004.001.09 9.2.8 - October 2021 (PW-709) MT54x and 578 to sese: fixed generation of empty Settlement Transaction Condition (PW-709) MT540 to sese.023.001.09: fixed mapping of Partial Settlement Indicator (PW-708) pacs.008 and pacs.004 to MT: Fixed mapping of third reimbursement agent account (PW-643) setr.004.001.04 and setr.010.001.04 to MT502: RSET is set from CshSttlmDt (with fallback to ReqdFutrTradDt) 9.2.7 - September 2021 (JR-613) pacs.009 to MT202: Avoid redundant codewords in field 72 lines 9.2.6 - September 2021 (PW-662) pacs.009.001.08 to MT202[COV]: added mapping for PaymentIdentification/UETR into Block3/121 with fallback to autogenerated UETR (PW-643) MT515 to setr.012 and setr.006: added mapping for 95a::ALTE and removed related precondition check 9.2.5 - August 2021 (PW-643) MT515 into setr.012: enhanced mapping of InvstmtAcctDtls/AcctId to avoid precondition on INVE/BUYR parties (PW-643) MT515 into setr.006.001.04 and setr.012.001.04: fixed mapping of 35B when ISIN is not present (CUSIP, SEDOL, etc...) (PW-643) setr into MT502: TILI indicator defaults to GTCA (good until canceled) License check fix when source MX does not contain AppHdr 9.2.4 - August 2021 (PW-626) sese.024.001 and sese.025.001 to MT: mapped AppHdr/CreDt into 98C:PREP (PW-623) MT566 to seev036: removed unnecessary precondition check and enhanced mapping of the ADDB indicator, amount and rates (PW-613) pacs.009 to MT202 and MT202COV: Enhanced mapping of field 72 Added API to set default amount, unit and currency; when it is mandatory in a target element/field and not present in the source message 9.2.3 - August 2021 (PW-642) sese.025.001.09 to MT: fixed PlcOfTrad into 94B:EXCH mapping, fixed FctvSttlmDt into 98C:ESET mapping (PW-643) setr.004.001.04 and setr.010.001.04 to MT502: multiple mapping enhancements (PW-643) setr.004, setr.006, setr.010, setr.012, setr.015: enhanced mapping into 35B without ISIN, including corresponding prefixes (PW-569) pacs.008 and pacs.009 to MT: enhanced heuristic to attempt mapping into 50F and 59F instead of 50K and 59 pacs.008 and pacs.009 to MT: minor bugfix translating into field 50F when StrtNm and BldgNb concatenation exceeds the line limit in field 50F (PW-605) MT to MX: avoid split of DSS into Issr and SchmeNm elements if the Issr alone in the MX has enough length for the DSS value (PW-591-598, 600-604, 607-612, 614, 616, 618) Mapping fixes in MT564 to seev.031.001.10 9.2.2 - July 2021 (PW-626) sese.024.001.10 to MT548: several mapping fixes (PW-572) pacs.008 to MT103: avoid the /REC/ in field 72 if the InstrForNxtAgt already contains and instruction code (PW-569) pacs.009 to MT202COV: added mapping of structured beneficiary data into field 59F option (PW-567) pacs.008.001.08 to MT103: added mapping for PaymentIdentification/UETR into Block3/121 with fallback to autogenerated UETR Added translation sese.025.001.09 to MT546 (PW-569) pacs.008 to MT103: added mapping of structured beneficiary data into field 59F option (PW-568) pacs.008 to MT103: fixed mapping of CtgyPurp/Cd with \"INTC\" or \"CORT\" into 23E (PW-617) MT502, MT504, MT515, MT564 and MT566 to MX: fixed mapping of 98E with offset into ISO date time (PW-580-582-585-586-588-589-590) Mapping fixes in MT564 to seev.031.001.10 (PW-581) MT to MX: Preserve starting and trailing spaces when narrative field content is mapped into multiple lines of a single XML element (PW-568) pacs.008 to MT103: mapped special use case of CtgyPurp/Prtry with \"INTC CORT\" into respective 23E instances with \"INTC\" and \"CORT\" (PW-567) pacs.008 to MT103: avoid propagation of useless EndToEndId with \"NOTPROVIDED\" to field 70:/ROC/NOTPROVIDED MT856 translations: fixed mapping for sequence B6b Added translation setr.004.001.04 to MT502 Added translation setr.010.001.04 to MT502 (PW-579) MT564 to seev.031 added mapping for 70E::OFFO into Offerr elements (PW-577) MT564 to seev.031.001.10 added mapping for 25D with DSS into processing status sese and semt to MT: fixed mapping for SETPRTY 97A::SAFE when type and name was present besides the account identifier MX to MT: general fix in field 20C mapping that could occasionally generate more than 16 characters Added translation MT540 to sese.023.001.09 Added translation sese.024.001.10 to MT548 Added translation sese.025.001.09 to MT544 9.2.1 - June 2021 Added translation MT509 to setr.016.001.04 Added translation MT515 to setr.006.001.04 Added translation MT515 to setr.012.001.04 Added translation seev.035.001.03 to MT564 Added translation seev.039.001.03 to MT564 Added translation seev.044.001.03 to MT564 setr.017 to MT509: OrdrRef reverted change, mapped back to TRRF instead of RELA MX to MT: preserve line breaks in MT fields when translated from MX narrative content Added translation seev.038.001.03 to MT568 (PW-551) seev.031 to MT564: fixed 90K PRPP and 90L OFFR field mapping into cash movement details (PW-550) MT564 to seev.035, MT565 to seev.033, MT566 to seev.036: fixed mapping of field 90J currency component (PW-549) seev.031.001.10 to MT564: fixed mapping of MACI MICI and MMCI into the corporate action option details (PW-548) seev.031 to MT564: fixed mapping of 90F, 90J and 90L OFFR into the securities movement details (PW-547) seev.031 to MT564: added mapping for 90s option L into the maximum and minimum price details with 'PRCT' as default code (PW-546) seev.031 to MT564: fixed mapping of price details in SctiesMvmntDtls (PW-545) seev.031.001.03 to MT564: fixed mapping of certification breakdown flags (PW-544) MT564 to seev.031: fixed mapping of indicator flags in CADETL and CAOPTN (PW-543) seev.031.001.03 to MT564: fixed ISIN mapping (PW-542) MT564 to seev.031.001.10: fixed mapping of repetitive 70E content (PW-541) MT564 to seev.031.001.10: added missing mapping for 92D:WAPA into WarrantParity (PW-537) MT to MX: fixed mapping of face amount, that in some cases was propagated as 1.0 instead of the actual value (PW-535) MT564 to seev.031.001.10: mapping fixes in the cash movement details (PW-533) Added translation from seev.031.001.09 to MT564 MX pacs.008 and pacs.004 to MT103: fixed calculation of total charges in field 71G when the ChrgsInf is repeated in the MX Mapping fixes in setr.006.001.04, setr.012.001.04 and setr.015.001.04 to MT515 Mapping fix in MT103 to pacs.008 when multiple sender charges are present (PW-521) MT564 to seev.031.001.10: reviewed mapping of rate and amount details setr016 and setr.017 to MT509: OrdrRef is mapped into RELA instead of TRRF 9.2.0 - May 2021 SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.1.12 - April 2021 (PW-518) More flexible check of licensed BIC codes extracted from the translated MT headers xsys.012 to MT019: minor fix in target message fields order 9.1.11 - February 2021 (CR-34) Added seev.031.001.001.03 to MT564 and MT568 translations (CR-34) Added MT564 and MT568 to seev.031.001.10 translations Fixed seev.031 to 564/568 invalid codewords MIEX and MILT in translation into field 36B Fixed generation of 20C:SEME when BAH is not present, in translations from seev.031/033/034/037/038/044 Fixed generation of LINK in translations from: seev.031/032/033/034/035/036/037, semt.016, sese.023/026/033/037 9.1.10 - January 2021 (PW-438) Further enhancements in the setr.016 to MT509 when status is suspended 9.1.9 - January 2021 (PW-438) Fixed setr.016 to MT509 when status is suspended with proprietary reason code 9.1.8 - December 2020 Added translation from camt.053.001.02 to MT940 Added a one to many special translation for camt.053.001.02 to list of MT940 License check review 9.1.7 - November 2020 (PW-368) setr.015.001, setr.006.001 and setr.012.001 to MT515: Fixed mapping of transfer agent into 95Q from RltdPtyDtls with code TRAG (PW-368) setr.015 to MT515: added mapping for :22H::CAOP from Income Preference in the MX (PW-368) setr.015 to MT515: changed the mapping of InvstmtAcctDtls/AcctId into 95Q SELL/BUYR instead of 97A:SAFE setr.015.001 MT515: enhanced mapping for 35B when identification is not an ISIN setr.015.001 to MT515: removed no longer necessary precondition checks 30, 31 and 34 setr.006.001 to MT515: removed no longer necessary precondition checks 25 Fixed option to set sender/receiver from configuration in MX to MT940, MT941, MT942, MT900 and MT910 translations 9.1.6 - November 2020 (PW-368) setr.012.001 to MT515: removed no longer necessary precondition checks 6 (PW-368) setr.015.001 to MT515: removed no longer necessary precondition checks 5 (PW-368) setr.006.001 to MT515: removed no longer necessary precondition checks 5, 19 and 36 (PW-368) setr.006.001 and setr.012.001 to to 515: Mapped amount with codeword SWIT into amount with OTHR in the MT since SWIT is not accepted (PW-368) setr.006.001 and setr.012.001 to MT515: enhanced mapping for 35B when identification is not an ISIN (PW-368) setr.006.001 and setr.012.001 to MT515: fixed mapping for 95P when source message party information contains a BIC code semt, sese and setr into MT: fixed mapping into fields 19A and 90B when source message has too many decimal digits setr into MT: fixed mapping into field 95R from when source uses a proprietary identification 9.1.5 - November 2020 (PW-368) setr.016.001 to MT509: enhanced mapping for /Extension content (PW-368) setr.017.001 to MT509: enhanced mapping for /Extension content (PW-368) setr.017.001 to MT509: references and status mapping review (PW-368) setr.006.001 to MT515: more lenient precondition, and enhanced amounts mapping (PW-368) setr.012.001 to MT515: more lenient precondition, and enhanced amounts mapping (PW-368) setr.015.001 to MT515: more lenient precondition, and enhanced amounts mapping (PW-368) setr.016.001 to MT509: added mapping for the Extension into the Reason narrative 70D (PW-395) Added translation for MT567 to seev.041.001.10 corporate action cancellation status 9.1.4 - October 2020 (PW-368) Enhanced the setr.016.001 to MT509 translation to support all code and reason structures in the source MX (PW-374) Added a one to many special translation for pacs.001 to list of MT101 (PW-374) Added sender, receiver and direction to the optional TranslatorConfiguration (PW-368) Added global preventive check in MX to MT translations to avoid propagating tab characters into MT fields (PW-368) setr to MT515: added fallback mappings for mandatory fields 98a:SETT and 95:SELL or 95:BUYR in MT515 (PW-377) pacs.001 to MT101 added a fallback mapping from CdtTrfTxInf/PmtId/EndToEndId into field 21 when CdtTrfTxInf/PmtId/InstrId is not present (PW-377) pacs.001 to MT101 added a fallback mapping to create the optional field 23E with value OTHR if no other 23E field is created MT to MX: General fix for 35B ISIN mapping into MX identification of security elements 9.1.3 - August 2020 (PW-368) MX to MT: enhanced mapping of references (field 20 or 20C:SEME) with fallback to reference from AppHdr and truncation if necessary setr.016 to MT509: fixed mapping of mandatory field 24B 9.1.2 - August 2020 (PW-320) Replaced legacy default translations DSS name 'STRS' by 'COEX' (Coexistence global DSS from ISO 20022) Added version 8 translation between pacs.009 and MT202 Added version 8 translation between pacs.008 and MT103 Added version 8 translation between camt.053 and MT940 Added version 8 translation between camt.053 and MT950 Added version 8 translation between camt.054 and MT900 Added version 8 translation between camt.054 and MT910 In pacs.009 to 202 fixed precondition check for the CdtTrfTxInf[1]/PrvsInstgAgt Minor Fix in MX to MT time with offset mapping, offset was not propagated properly in some use cases Minor fix in logical criteria exception messages Added pacs.004.001.02 to MT 103 RETURN translation (for both ISO and SIC versions) Added pacs.002.001.03 to ACK/NAK translation (for both ISO and SIC versions) MX to MT: Added a parameter in the TranslatorConfiguration to optionally set a ClearingSystemMemberIdToBic function implementation SIC: MT to MX, trimmed spaces from reference to be compliant with SIC restriction SIC: MT103 to pacs.008 instructed agent mapped from 56A when present in the MT SIC: MT202 to pacs.009 instructed agent mapped from 57A when present in the MT 9.1.1 - Jun 2020 MT103 to pacs.008 fixed mapping of fields 70 and 72 MT101 to pacs.008 fixed mapping of fields 70 and 72 MT202 to pacs.009 fixed mapping of fields 70 and 72 MT202 to pacs.009 fixed precondition checking the format of the CLSTIME MT to MX: general enhancements in mapping of field 50F when line numbers are repeated MT502 to to setr.004 and setr.010: enhanced mapping for fields 70E and 70C MT564 to seev.031 enhanced mapping for field 94G MT565 to seev.033 enhanced mapping for fields 70E and 95G MT568 to seev.031 enhanced mapping for field 70E 9.1.0 - May 2020 SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.0.1 - May 2020 Internal implementation changes to the use the new AppHdr model in the SDK 9.0.0 - May 2020 Translations module extracted to its own jar in the distribution, with its own version from now on (PW-286) Fixed ISO datetime conversions into MT variants 8.0.8 - April 2020 Fixed logical message criteria for camt.054 into 900 or 910 depending on the entry debit/credit indicator Fixed translator factory finder for pacs.008.001.06 to 103 and seev to 566 Change in preconditions from camt.053 to MT to make them more flexible 8.0.7 - March 2020 Added specific translations for SIC (SWISS RTGS): between 202 and pacs.009 Added specific translations for SIC (SWISS RTGS): between 103 and pacs.008 In MX to MT: fixed extra slash when mapping clearing system codes or account numbers into party fields pacs.008 to 103 and pacs.009 to 202: field 20 now is mapped from CdtTrfTxInf/PmtId/TxId instead of GrpHdr/MsgId 103 to pacs.008: when present, the block 3 MUR is mapped into GrpHdr/MsgId instead of the reference field 20 8.0.6 - February 2020 Added translation from setr.006.001.04 redemption order confirmation to MT515 Added translation from setr.012.001.04 subscription order confirmation to MT515 Added translation from setr.016.001.04 order instruction status report to MT509 Added translation from setr.015.001.04 switch order confirmation into MT515 redemption and subscription leg messages Added translation between setr.017.001.04 order cancellation status report and MT509 (back and forth) Added a truncation report in translator classes and a '+' as last character of truncated data in the target message In MT to MX; header data is propagated to the AppHdr, including sender, receiver, reference, message type, and also PDE flag if present in the MT trailer In MX to MT; if the source MX contains an ISO header with the possible duplicate flag set to true, the created MT will have a PDE trailer flag MT103 to pacs.008 added mapping from 32A date into the group header settlement date Added a remove spaces transformation when mapping IBAN numbers from MT to MX 8.0.5 - January 2019 MT202 and MT202COV to MX, added mapping for sender correspondent field 53B location into group header instructing agent postal address (PW-225) MT202 and MT202COV to MX, removed the precondition requiring a mandatory party identifier in the sender correspondent field 53B 8.0.4 - December 2019 MT103 to MX, added mapping for sender correspondent field 53B location into group header instructing agent postal address (PW-225) MT103 to MX, removed the precondition requiring a mandatory party identifier in the sender correspondent field 53B (PW-225) MT103 to MX, removed the precondition requiring the same currency In semt to MT translations when Document/*/Id/Id is not found in MX the 20C:SEME is generated from AppHdr/BizMsgIdr Enhanced mapping of field 35B description of security when the ISIN is not present 8.0.3 - September 2019 Fixed mapping for field 36E in translations from MX to MT Added version 6, 7, 8 and 9 for translations between MT566 and seev.036 and seev.037 8.0.2 - August 2019 Added version 6, 7, 8 and 9 for translations between MT566 and seev.036 and seev.037 Fixed mapping for field 36E in translations from MX to MT Fixed bin/translator CLI app that stopped reading input on the first line break 8.0.1 - July 2019 Added a TranslatorFactory to enable automatic translator selection based on the source message Added a CLI to run automatic translation of files in the command line 8.0.0 - May 2019 JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 7.10.8 - March 2019 Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Fixed obfuscation to keep directories in jar Fixed mapping of Field70 to EndToEndId 7.10.7 - January 2019 Added alternative translate call in translation implementation classes to run the process without precondition checks Added translations between pacs.001.001.08 and MT101 Fixed translations for fields 50F and 77B Fixed precondition check for MX pain.001.001.03 to MT101 translation Fixed translation MX pain.001.001.03 to MT101 when multiple PmtInf and CdtTrfTxInf combinations are present 7.10.0 - April 2018 SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Added 103 and 103 STP to pacs.008.001.07 Added 202 and 202 COV to pacs.009.001.07 Added 900 to camt.054.001.07 Added 910 to camt.054.001.07 Added 940 to camt.053.001.07 Added 941 to camt.052.001.07 Added 942 to camt.052.001.07 Added 950 to camt.053.001.07 Added pacs.008.001.07 to 103 Added pacs.009.001.07 to 202 and 202 COV Added camt.052.001.07 to 941 and 942 Added camt.053.001.07 to 940 and 950 Added camt.054.001.07 to 900 and 910 7.9.8 - April 2018 MT to MX: fixed decimal separator in amount format to avoid locale dependant issues 7.9.7 - January 2018 Changes in the distribution package |-> Command line tools in the bic directory changed from jar files to wrapper scripts |-> Dependencies directory renamed to lib |-> Removed the BUILD id timestamp from the jar files * MT to MX: sender and receiver address from header blocks mapped according to message direction 7.9.6 - December 2017 Added camt.054.001.06 to MT900 and MT910 Added camt.053.001.06 to MT940 and MT950 Added camt.052.001.06 to MT941 and MT942 Added pacs.009.001.06 to MT202 and MT202 COV Added pacs.008.001.06 to MT103 Added xsys.003.001.01 to MT019 Added xsys.012.001.01 to MT019 Added MT300 to fxtr.014.001.03 Performance enhancement: comprehensive use of relative paths to optimize content selection. Performance enhancement: mappings migrated from docname to xml to avoid paths conversion in engine. MX to MT: Fixed generation of fields with letter option D (such as 52D) when only name & address was present as content Added plugable PathAdapter to customize MX paths used in translations 7.9.5 - December 2017 Performance enhancement: static methods for internal processing, reduced path conversion Individual precondition checks made private in favor of the global preconditionsChecks API 7.9.4 - November 2017 JRE requirement backported to Java 1.6 Added xsys.002.001.01 to MT012 7.9.3 - October 2017 Fixed MT548 to MX: fixed mappings for ProcessingStatus Fixed MT586 to MX: mappings with invalid amounts sequence B5c changed to B5b MT564 and 566 to MX: fixed mapping for currency component in field 92J Added MT568 to seev.031.002.06 Added MT564 to seev.031.002.06 and seev.039.002.06 Added MT019 to xsys.003.001.01 and xsys.012.001.01 Added MT012 to xsys.002.001.01 Added MT202 and MT202 COV to pacs.009.001.06 Added MT103 and MT103 STP to pacs.008.001.06 MT to MX: fixed mapping header for sender and receiver addresses in output (incoming) messages MT to MX: replaced fixed data in message creation date time with current ISO time stamp MT940 to camt.053 and MT941/MT942 to camt.052: fixed translation for field 86 repetitions into additional entries information MT101 to pain.001: fixed translation for field 23E repetitions MT900 and MT910 to camt.054: fixed translation for field 72 repetitions Added MT941 and MT942 to camt.052.001.06 Added MT940 and MT950 to camt.053.001.06 Added MT900 and MT910 to camt.054.001.06 7.9.2 - August 2017 semt.020.02.01 to MTs 508, 545, 547, 578: changed default amount XXX99999999999999 to locale currency and 0 sese.020.002.01 and semt.013.002.01 to MT524 fixed generation of LINK sequences seev, semt, sese, setr to MT5xx: fixed generation of field 36B with quantity of financial instrument semt.020.002.01 to MT578: changed translation to generate the alleged instruction indicator (:22H::PAYM) in sequence B with codeword FREE instead of APMT to be compliant with MT semantic 283 pain.001.001.03 to MT101: fixed mapping for multiline field 77B and fixed MX paths when checking the available payment information instances setr.006.002.01 and setr.012.002.01 to MT515: fixed mapping for multiline field 70C semt and sese to MTs 544, 545, 546, 547 and 548: added link sequence with RELA to be compliant with MT semantic rules 73 semt.020.002.01 to MTs 535, 536, 537, 538 and 586: changed translations to set Activity Flag (field :17B:ACTI) to 'N' to be compliant with MT semantic rules 256, 266 and 267 semt.020.002.01 to MT508 and sese.020.002.01 to 524: changed translations to be compliant with MT semantic rule 281 MX to MT: fixed collapsing data in output MT, due to bug in handling repeat predicates from MX path MX to MT: fixed generic bug when creating fieldset with multiple letter options MX to MT: general mappings fixes for MX categories seev, semt, sese and setr Generic fix for proper handling of repetitive fields/elements in target message MX to MT: fixed bug when creating fieldset with multiple letter options MX to MT: fixed mappings translations for seev, semt, sese and setr 7.9 - May 2017 SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX) Removed false positive warning for invalid namespace in header when the header was actually empty 7.8.9 - May 2017 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 7.8.3 - Jul 2016 If GrpHdr is present when converting from MX to MT, header BICs are set from it Internal migration from MxNode to XmlNode from SDK","title":"Prowide Integrator Translations"},{"location":"release-notes/changelog-translations/#prowide-integrator-translations-changelog","text":"","title":"Prowide Integrator Translations - CHANGELOG"},{"location":"release-notes/changelog-translations/#9440-june-2024","text":"(PW-1897) CBPR+ camt.052.001.08 -> MT941/942: using account currency for fields 90C and 90D when entry currency is not present (PW-1896) CBPR+ MT200/202/205 -> pacs.009.001.08: create a new UETR for PaymentIdentification\\UETR when block3\\121 is missing pacs.010.001.03 -> MT204: fixed mappings for fields 58A and 58D (PW-1859) Added new ISO translator: pain.001.001.09 -> MT103","title":"9.4.40 - June 2024"},{"location":"release-notes/changelog-translations/#9439-may-2024","text":"CBPR+ MT102/103 -> pacs.008.001.08 and MT200/201/202/205 -> pacs.009.001.08: enhanced and fixed mappings from field 72 codewords CATPURP, SVCLVL and LOCINS","title":"9.4.39 - May 2024"},{"location":"release-notes/changelog-translations/#9438-may-2024","text":"(PW-1878) CBPR+ MT900 and MT910 to camt: set Entry/EntryReference to NOTPROVIDED since field 25 is already mapped to the Notification/Account (PW-1865) Added new flag to TranslatorConfiguration class, in order to force the number formatting to have exactly two decimal places","title":"9.4.38 - May 2024"},{"location":"release-notes/changelog-translations/#9437-may-2024","text":"(PW-1872) CBPR+ MT 950 -> camt.053.001.08: fixed mappings from 60M to Balance\\Type\\Code = OPBD and 62M to Balance\\Type\\Code = CLBD (PW-1863) CBPR+ MT 940 -> camt.053.001.08: fixed mappings from 60M to Balance\\Type\\Code = OPBD and 62M to Balance\\Type\\Code = CLBD (PW-1862) MT to MX: Revamped implementation of Narrative translation functions (PW-1847) Added new ISO translators: MT 564/568 <-> seev.031.002.13 Fixed mapping of Block5/PDE flag into the AppHdr/PossibleDuplicate when PDE exists and is empty CBPR+ MT 102/103 -> pacs.008.001.08: fixed mappings for fields 70 and 72 into InstructionForNextAgent and RemittanceInformation\\Unstructured CBPR+ MT 102/103 -> pacs.008.001.08: removed mapping for codeword PURP in field 72 and fixed use of codeword CATPURP into CategoryPurpose\\Code CBPR+ MT 202.COV/205.COV -> pacs.009.001.08.COV: fixed mappings for fields 70 and 72 into InstructionForNextAgent and RemittanceInformation\\Unstructured CBPR+ MT 202 -> pacs.009.001.08/pacs.009.001.08.ADV: fixed mappings for codeword PURP in field 72 into Purpose\\Code and Purpose\\Proprietary Enhanced the market type factories returned by the TranslatorFactoryProvider to honour the translation mappings configuration","title":"9.4.37 - May 2024"},{"location":"release-notes/changelog-translations/#9436-april-2024","text":"(PW-1857) CBPR+ MT 900/910 -> camt.054.001.08: fixed mappings according to CBPR+ mapping rules (PW-1856) MT 200/202/203/205 -> pacs.009: fixed mappings for 72 Narrative extra codewords to InstructionForNextAgent (PW-1855) CBPR+ MT 202 -> pacs.004.001.09: added extra XT99 narrative to ReturnReasonInformation\\AdditionalInformation (PW-1854) CBPR+ MT 202 -> pacs.004.001.09: added mapping for OriginalInstructionIdentification (PW-1850) CBPR+ MT 202 -> pacs.004.001.09: fixed mapping for ServiceLevel\\Code when there's no Block3\\111 (PW-1852) CBPR+ MT 202 -> pacs.004.001.09: added mapping for ReturnIdentification (PW-1851) CBPR+ MT 202 -> pacs.004.001.09: fixed mapping for CreditorAgent when there's no 57a field (PW-1849) CBPR+ MT 202.COV/205.COV -> pacs.009: preserve line numbers in field 50F mapping as part of value in the MX elements (PW-1848) CBPR+ MT 103 -> pacs.004.001.09: fixed mappings to 'NOTPROVIDED' as instructed by the CBPR+ mapping rules (PW-1848) CBPR+ MT 103 -> pacs.004.001.09: added extra XT99 narrative to ReturnReasonInformation\\AdditionalInformation (PW-1848) Fixed mapping of Block5/PDE flag into the AppHdr/PossibleDuplicate (PW-1848) CBPR+ MT 103 -> pacs.004.001.09: fixed mappings to 'NOTPROVIDED' as instructed by the CBPR+ mapping rules MT 103 -> pacs.008: fixed typo in codeword CATPURP","title":"9.4.36 - April 2024"},{"location":"release-notes/changelog-translations/#9435-april-2024","text":"(PW-1835) CBPR+ camt.054.001.08 -> MT 910/910 : fixed mappings for tag 21 (PW-1832) CBPR translators: fixed mapping to comply with CBPR_Agent_Name_Postal_Address_FormalRule rule MX to MT: Revamped implementation of MxToMtFinancialInstitutionNameAndAddress for translation into fields 52D, 53D, 54D, 55D, 56D & 57D MX to MT: Revamped implementation of MxToMtMTFATFNameAndAddress and MxToMtMTFATFNameAndAddress2 for translation into field 50F and 50K MX to MT: fixed coverage in MxToMt functions Added new ISO translator: seev.008.001.08 -> MT 568 Added new ISO translator: MT 536 -> semt.017.001.12 Added new ISO translator: MT 537 -> semt.018.001.13 Added new ISO translators: sese.028.001.09/10 -> MT 578","title":"9.4.35 - April 2024"},{"location":"release-notes/changelog-translations/#9434-april-2024","text":"(PW-1827) Added new ISO translators: camt.053.001.10/11 <-> MT 940/950 (PW-1814) Removed criteria selection in translations MT196/MT296 -> camt.029.001.11 (PW-1759) TranslationFactory: fixed getTranslator for ACK/NACK messages with a specific MX version Added new ISO translator: seev.001.001.10 -> MT 564 Added new ISO translator: seev.002.001.09 -> MT 564 Added new ISO translator: seev.003.001.09 -> MT 564 Added new ISO translator: seev.004.001.09 -> MT 565 Added new ISO translator: seev.005.001.09 -> MT 565 Added new ISO translator: seev.006.001.09 -> MT 567 Added new ISO translator: seev.007.001.09 -> MT 567 MT to MX: Revamped mapping for fields 50F and 59F into structured postal address node when line 3 (country) is present","title":"9.4.34 - April 2024"},{"location":"release-notes/changelog-translations/#9433-march-2024","text":"(PW-1814) MT 196/296 -> camt.029: fixed mapping from narrative 77A when codeword /UETR/ is used in multiple lines (PW-1635) camt.056 -> MT 192/292: fixed default value for tag 20 when node Underlying\\TransactionInformation\\Case\\Identification is missing T2 Translators: added NONREF as fixed value for GroupHeader\\MessageIdentification node T2 Translators: map field 20 to BusinessMessageIdentifier in header","title":"9.4.33 - March 2024"},{"location":"release-notes/changelog-translations/#9432-march-2024","text":"(PW-1759) TranslatorFactory: Added translator ACK/NAK (service 21 message) -> admi.007.001.01","title":"9.4.32 - March 2024"},{"location":"release-notes/changelog-translations/#9431-march-2024","text":"(PW-1804) sese.025 -> MT 540/541/542/543: fixed mapping for multiple 22F STCO indicators (PW-1635) camt.029 -> MT 196/296: fixed default value for tag 20 when node CancellationStatusIdentification is missing Added new ISO translators: sese.020.001.07 -> MT 540/541/542/543 Added new ISO translators: semt.020.001.07 <-> MT 578 Added new ISO translators: semt.002.001.11 <-> MT 535 Added new ISO translator: semt.017.001.12 -> MT 536 Added new ISO translator: semt.018.001.13 -> MT 537 Enhanced truncation report: added MX source path even when partial element content is truncated","title":"9.4.31 - March 2024"},{"location":"release-notes/changelog-translations/#9430-march-2024","text":"(PW-1800) MT 540/541/542/543 -> sese.023: fixed 36B Quantity of Financial Instrument precondition","title":"9.4.30 - March 2024"},{"location":"release-notes/changelog-translations/#9429-march-2024","text":"(PW-1756) MT 102/103 -> pacs.008: added mapping for field 72 codeword /PURP/ into Purpose/Proprietary Added new ISO translators: sese.024.001.11/12 <-> MT 548 Added new ISO translators: pacs.009.001.10 <-> MT 200 (PW-1787) Added new ISO translators: sese.026.001.10 <-> MT 544/545/546/547 (PW-1790) MT950 -> camt.053: fixed BookingDate and EntryDetails mappings (PW-1790) MT942 -> camt.052: fixed BookingDate mapping","title":"9.4.29 - March 2024"},{"location":"release-notes/changelog-translations/#9428-february-2024","text":"(PW-1759) TranslationFactoryConfiguration - deprecated setEvaluatePreconditions (replaced with withEvaluatePreconditions)","title":"9.4.28 - February 2024"},{"location":"release-notes/changelog-translations/#9427-february-2024","text":"(PW-1764) Added new ISO translators: sese.023.001.11 -> MT 540/541/542/543 (PW-1764) Added new ISO translators: sese.025.001.11 -> MT 544/545/546/547 (PW-1764) ISO sese.023.001. / sese.025.001. <-> MT 54*: added mappings for SecuritiesSubBalanceType <-> 22F SSBT (PW-1762) MT 103 -> pacs.004.001.09 (CBPR+/LYNX/T2): fixed mapping for /CHGS/ codeword into ChargesInformation (PW-1759) Added new translator: ACK/NAK (service 21 message) -> admi.007.001.01 (PW-1756) MT 202 -> pacs.009: added mapping for field 72 codeword /PURP/ into Purpose/Proprietary","title":"9.4.27 - February 2024"},{"location":"release-notes/changelog-translations/#9426-january-2024","text":"Added new translator: MT 097 <-> xsys.001.001.01 Added new CBPR+ translator: MT 104 <- pacs.003.001.08 Added new CBPR+ translator: MT 107 -> pacs.003.001.08 Added new ISO translators: MT 104 <- pacs.003.001.08/09/10 Added new ISO translators: MT 107 <-> pacs.003.001.08/09/10 (PW-1754) ISO seev.036.001.14 -> MT 566: fixed mappings in section 16R:CASHMOVE","title":"9.4.26 - January 2024"},{"location":"release-notes/changelog-translations/#9425-january-2024","text":"(PW-1748/1733) CHATS for pacs message the receiver BIC in the AppHdr is fixed to HKICHKHHXXX (PW-1747) SWIFT GO MT199 <-> trck.001.001.02/trck.002.001.01: Fixed mappings Enhanced the TranslatorFactory with new parameters to specify the prefered MT/MX target type and version (replacing preferLatestVersions flag) Added new ISO translators: MT 103.REMIT -> pacs.008.* Added new CBPR+ translator: MT 104 -> pacs.003.001.08 Added new ISO translators: MT 104 -> pacs.003.001.08/09/10 MT192/292 -> camt.058/056: fixed mapping and added default NOTPROVIDED in CancelationReason/AdditionalInformation Truncated report: added path to source and target truncated fields","title":"9.4.25 - January 2024"},{"location":"release-notes/changelog-translations/#9424-january-2024","text":"MT196/296 -> camt.029: removed UETR existence precondition Added new ISO translators: MT 110 <-> camt.107.001.01 Added new ISO translators: MT 111 <-> camt.108.001.01 Added new ISO translators: MT 112 <-> camt.109.001.01 sese.20/23/33/36.* -> MT541: added precondition to check SettlementAmount or OtherAmounts existence seev.32/34/41.* -> MT567: added default A16S:LINK mandatory section","title":"9.4.24 - January 2024"},{"location":"release-notes/changelog-translations/#9423-january-2024","text":"Added new translator: MT 192 -> camt.058.001.08 Added new CBPR+ translator: MT 292 -> camt.058.001.08 Added new CBPR+ translator: MT 192 -> camt.055.001.08 Added new CBPR+ translator: MT 110 -> camt.107.001.01 Added new CBPR+ translator: MT 111 -> camt.108.001.01 Added new CBPR+ translator: MT 112 -> camt.109.001.01","title":"9.4.23 - January 2024"},{"location":"release-notes/changelog-translations/#9422-december-2023","text":"(PW-1732) sese.020 / sese.023 / sese.033 / sese.036 -> MT 543: added precondition to validate SettlementAmount existence in sese messages ISO MT103 -> pacs.008.*: added mapping for block3/103 to ClearingSystem\\Code Added new translators: MT 540 / MT 541 / MT 542 / MT 543 -> sese.020.001.07 / sese.023.001.11 Added new translators: MT 544 / MT 545 / MT 546 / MT 547 -> sese.025.001.11","title":"9.4.22 - December 2023"},{"location":"release-notes/changelog-translations/#9421-december-2023","text":"(PW-1674) CHATS MT103 / MT202 -> pacs.008 / pacs.009: fixed mapping for field 72 /SPRO/ instruction to InstructionForNextAgent\\InstructionInformation CHATS/LYNX/RITS/SCRIPS/T2 pacs.008.001.* <-> MT 103: added mapping for field 26T to CreditTransferTransactionInformation\\Purpose\\Proprietary T2 MT103 -> pacs.008.001.*: convert 8 digit BIC to 11 digit BIC for FinancialInstrumentIdentification/BICFI","title":"9.4.21 - December 2023"},{"location":"release-notes/changelog-translations/#9420-december-2023","text":"(PW-1674) CHATS/LYNX/RITS/SCRIPS/T2 translation factories: return ISO translators in the getTranslator(AbstractMX mx) method (PW-1674) CBPR/SIC/SWIFTGO translation factories: return ISO translators in the getTranslator(AbstractMX mx) method if no specific translator is found (PW-1674) CHATS MT 202/202.COV -> pacs.009.001.08: added mapping for field 72 /CATPURP/ codeword into PaymentTypeInformation\\CategoryPurpose\\Proprietary","title":"9.4.20 - December 2023"},{"location":"release-notes/changelog-translations/#9419-november-2023","text":"(PW-1674) CHATS MT 202/202.COV -> pacs.009.001.08: added mapping for field 72 /SPRO/ instruction to InstructionForNextAgent\\InstructionInformation (PW-1397) CHATS MT 103 -> pacs.008.001.08: added mapping for field 72 /SPRO/ instruction to InstructionForNextAgent\\InstructionInformation","title":"9.4.19 - November 2023"},{"location":"release-notes/changelog-translations/#9418-november-2023","text":"(PW-1698) MT950 -> camt.053: added mapping block3\\108 to GroupHeader\\MessageIdentification (PW-1674) ISO pacs.004/pacs.008/pacs.009 -> MT102/MT103/MT200/MT202/MT205: added mapping GroupHeader\\SettlementInformation\\ClearingSystem\\Code To Block3\\103 (PW-1674) CHATS MT202.COV -> pacs.009.001.08: removed fixed LocalInstrument\\Proprietary mapping","title":"9.4.18 - November 2023"},{"location":"release-notes/changelog-translations/#9417-november-2023","text":"(PW-1691) CBPR+ Translation: fixed business service value for MT 104 -> pain.008.001.08 (PW-1394) Added translation CBPR+ pacs.003.001.08 -> MT107 Updated the SIC translations and translator factory, to use the SIC 4.10 model and message versions","title":"9.4.17 - November 2023"},{"location":"release-notes/changelog-translations/#9416-november-2023","text":"Reverted RITS translations to set the AppHdr creation datetime to the current local time with UTC offset (not necessarily UTC 0) (PW-1684) MT548 -> sese.024: deprecated preconditions","title":"9.4.16 - November 2023"},{"location":"release-notes/changelog-translations/#9415-november-2023","text":"(PW-1683) MT548 -> sese.024/sese.027: don't use field 23G as criteria to define MX target (PW-1674) CHATS Translations: Added MT 192/292 -> camt.056.001.08 (PW-1674) CHATS Translations: Added MT 202 COV -> pacs.009.001.08.COV (PW-1670) seev.031.001.13 -> MT 564: fixed additional mapping for dates without 98C field Added specific translations for SWIFT GO: MT103 <-> pacs.008.001.08 Added specific translations for SWIFT GO: MT199 <-> trck.001.001.02/trck.002.001.01 Added translation MT292 -> camt.058.001.08","title":"9.4.15 - November 2023"},{"location":"release-notes/changelog-translations/#9414-october-2023","text":"(PW-1670) seev.031.001.13 -> MT 564: fixed mapping for dates without 98C field","title":"9.4.14 - October 2023"},{"location":"release-notes/changelog-translations/#9413-october-2023","text":"(PW-1657) pacs.008.001.08/09/10 -> MT 102/103: added additional mapping for PaymentTypeInformation\\ServiceLevel\\Code to Block3\\111 (PW-1581) Enhanced mapping into field 72 to trim the instruction narratives avoiding pure blanks such as \"/REC/ \" (PW-1394) Added translation CBPR+ camt.055.001.08 -> MT192 (PW-1394) Added translation CBPR+ pain.008.001.08 -> MT104 MT564 -> seev.031.002.06 translation: mapping fixes sese.027.001.05 -> MT548 translation: mapping fixes Added missing entries in the CBPR+ translator factory for the recently added translations","title":"9.4.13 - October 2023"},{"location":"release-notes/changelog-translations/#9412-october-2023","text":"(PW-1644) MT 900/910 -> camt.054.001.06/07/08/09: added additional mapping for 21 to TransactionDetails\\References\\EndToEndIdentification","title":"9.4.12 - October 2023"},{"location":"release-notes/changelog-translations/#9411-september-2023","text":"(PW-1596) MT 540/541/542/543 <-> sese.023.001.09: added a special mapping for 22F::STCO/COEX/PARQ and 22F::STCO/COEX/PARC to/from SttlmParams\\PrtlSttlmInd (PW-1397) CHATS Translations: fixed PaymentTypeInformation/CategoryPurpose/Proprietary code IFT","title":"9.4.11 - September 2023"},{"location":"release-notes/changelog-translations/#9410-september-2023","text":"(PW-1477) MT 540/541/542/543 -> sese.023.001.09: added a special mapping for 22F::STCO BPSS into SttlmParams\\SttlmTxCond\\Prtry using BSSP as identification and T2S as issuer","title":"9.4.10 - September 2023"},{"location":"release-notes/changelog-translations/#949-september-2023","text":"(PW-1442) MT <-> MX translations: fixed TimeZone handling in date time conversions that might lead to invalid date changes during translation depending on the local offset","title":"9.4.9 - September 2023"},{"location":"release-notes/changelog-translations/#948-september-2023","text":"(PW-1304) LYNX Translation Factory: pacs.009.001.08 returns MT205 translation by default (PW-1304) RITS/SCRIPS/CHATS/T2 Translation Factories: return generic Mx to Mt ISO translators","title":"9.4.8 - September 2023"},{"location":"release-notes/changelog-translations/#947-august-2023","text":"(PW-1562/PW-1565) MT 530 <-> sese.030.001.008 : Fixed mapping for 22F::PRTL into ReqDtls\\PrtlSttlmInd (PW-1563/PW-1564) MT 548 -> sese.031.001.08 : Fixed mapping, do not map section ReqDtls in MX (Ref\\AcctOwnrTxId, Ref\\MktInfrstrctrTxId and HldInd) (PW-1557) Added translation CBPR+ MT104 -> pain.008.001.08 (PW-1210) Added specific translations for T2 (T2 RTGS) for MT103, MT202 and MT205 to MX (PW-1210) Added specific translations for Lynx (Canada RTGS) for MT103, MT202 and MT205 to MX RITS Translations: fixed creation time in header (Zulu time) MT to MX: replaced the dummy creation date 9999-12-31 in all translations but the CBPR+ ones with the current date","title":"9.4.7 - August 2023"},{"location":"release-notes/changelog-translations/#946-august-2023","text":"(PW-1474) CBPR MT 900 / MT 910 -> camt.054.001.08 : Added mapping for field 25 into Entry\\EntryReference (PW-1471) MT 548 -> sese.031.001.08 : Fixed mapping for :25D::TPRC//MODC -> ProcessingStatus/Completed (PW-1469) MT 540 / MT 541 / MT 542 / MT 543 <-> sese.023.001.09 : Fixed mapping for 94a <-> SafekeepingPlace (PW-1469) MT 544 / MT 545 / MT 546 / MT 547 <-> sese.025.001.09 : Fixed mapping for 94a <-> SafekeepingPlace (PW-1469) MT 548 <-> sese.024.001.10 : Fixed mapping for 94a <-> SafekeepingPlace (PW-1469) MT 578 <-> sese.028.001.08 : Fixed mapping for 94a <-> SafekeepingPlace (PW-1465) RITS translators: Generate automatic UETR if it doesn't exist in the MT source (Block3/121) (PW-1459) sese.023 <-> MT 540 / MT 541 / MT 542 / MT 543 : Fixed mapping for HoldIndicator <-> 23G (PW-1459) sese.024 <-> MT 548 : Fixed mapping for HoldIndicator <-> 23G (PW-1455) sese.030 -> MT 530 : Fixed mapping for HoldIndicator into :22F::SETT (PW-1454) MxToMt72FullField fix, accept proprietary codewords with alphanumeric characters (PW-1440) MT 548 -> sese.024.001.10 : Added NOTPROVIDED to ProcessingStatus\\CancellationRequested\\AdditionalReasonInformation when :25D::IPRC equals to CPRC and :70D::REAS don't exist","title":"9.4.6 - August 2023"},{"location":"release-notes/changelog-translations/#945-july-2023","text":"(PW-1423) RITS: Added automatic message identifier generation for the MX header and group header pacs.004 -> MT 103 : Revamped mappings for tag 70 pacs.008 -> MT 102 / 103 : Revamped mappings for tag 70 pacs.009 -> MT 202 COV / 205 COV : Revamped mappings for tag 70 pacs.008 -> MT 102 / 103 : Revamped mappings for tags 50 and 59 Name and Address component pacs.009 -> MT 202 COV / 205 COV : Revamped mappings for tags 50 and 59 Name and Address component","title":"9.4.5 - July 2023"},{"location":"release-notes/changelog-translations/#944-july-2023","text":"(PW-1438) Added translation seev.044.001.12 -> MT564 (PW-1437) Added translation seev.039.001.12 -> MT564 (PW-1436) Added translation seev.037.001.14 -> MT566 (PW-1435) Added translation seev.036.001.14 -> MT566 (PW-1434) Added translation seev.035.001.14 -> MT564 (PW-1433) Added translation seev.031.001.13 -> MT564 (PW-1433) Added translation seev.031.001.13 -> MT568 Added specific translations for SCRIPS (MEPS+, Singapore RGTS) for MT103 and MT202 to MX Added specific translations for SCRIPS (MEPS+, Singapore RTGS) for MT103 and MT202 to MX (PW-1397) Added specific translations for CHATS (Hong Kong RTGS) for MT103 and MT202 to MX (PW-1399) MT -> MX: amounts are converted into the MX decimal number with minimal decimal places according to the currency (PW-1397) Added specific translations for CHATS (Hong Kong RGTS) for MT103 and MT202 to MX","title":"9.4.4 - July 2023"},{"location":"release-notes/changelog-translations/#943-july-2023","text":"(PW-1427) Added translations MT564 <-> seev.031.001.11 (PW-1427) Added translations MT568 <-> seev.031.001.11 (PW-1425) Added translation sese.029.001.04 -> MT578 (PW-1425) Added translation semt.020.001.05 -> MT578 (PW-1417) MT104 -> pain.008.001.08 : added mapping for 53A into RemittanceInformation/Structured/AdditionalRemittanceInformation","title":"9.4.3 - July 2023"},{"location":"release-notes/changelog-translations/#942-june-2023","text":"(PW-1424) Added translations MT530 <-> sese.030.001.08 (PW-1424) Added translations MT548 <-> sese.031.001.08 (PW-1399) FormatDecimal MT -> MX : added 2 fixed decimal places in all translations (PW-1421) CBPR+ MT910 -> camt.054.001.08 : fixed CreditDebitIndicator from DBIT to CRDT (PW-1412) Added translation sese.028.001.08 -> MT578","title":"9.4.2 - June 2023"},{"location":"release-notes/changelog-translations/#941-june-2023","text":"(PW-1407) MT548 -> sese.024/032/034 / semt.014 and MT537 -> semt.018 : added pending reason code mapping (PATD to OTHR) (PW-1407) MT548 -> sese.024/034 : added rejected reason code mapping (NARR to OTHR) (PW-1406) CBPR+ MT to MX translations -> trim starting slashes while mapping account numbers into Identification/Other/Identification to be compliant with CBPR+ restricted charset (PW-1394) Added CBPR+ translation camt.058.001.08 -> MT292 (PW-1394) Added CBPR+ translation camt.107.001.01 -> MT110 (PW-1394) Added CBPR+ translation camt.108.001.01 -> MT111 (PW-1394) Added CBPR+ translation camt.109.001.01 -> MT112 MTn92, MTn96 and MT200 to MX: Fixed translation of field 11[R,S] into date time element in MX, adding a dummy time component","title":"9.4.1 - June 2023"},{"location":"release-notes/changelog-translations/#940-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"9.4.0 - May 2023"},{"location":"release-notes/changelog-translations/#9342-june-2023","text":"(PW-1395) Added translation MT578 -> sese.028.001.08 (PW-1391) pacs.008.001 -> MT102/103: Revamped implementation of MxToMtRemittanceInformation for translation into field 70 (PW-1390) CBPR+ pacs.009.001.08 -> MT200/202/205: Revamped implementation of MxToMtPartyNameAndStructuredAddress and MxToMtPartyNameAndUnstructuredAddress for translation into fields 52D/56D/57D/58D (PW-1388) CBPR+ pacs.008.001.08 -> MT103: minor fix in function MxToMtAddressLineIsStructured (PW-1385) CBPR+ pacs.008.001.08 -> MT103: minor fix in function MxToMtNameAndAddress (7/NIDN information) (PW-1384) CBPR+ pacs.008.001.08 -> MT103: fixed mapping for PaymentTypeInformation/CategoryPurpose/Code into tag 23E (PW-1382) sese.023.001.09 -> MT540/MT541/MT542/MT543: new mapping from OtherBusinessParties/Investor/Nationality to field 95C (PW-1182) Added CBPR+ translation MT201 -> pacs.008.001.08 (PW-1182) Added CBPR+ translation MT203 -> pacs.008.001.08 (PW-1182) Added CBPR+ translations MT102 / MT102.STP <-> pacs.009.001.08 / pacs.009.001.08.STP pacs.008/pacs.004/pain.001 -> MT101/102/103: truncate with evidence last line in field 70 mapping CBPR+ camt.052/camt.053: fixes in fields 20/28C/34F/61 mapping pacs.002 <-> MT199 / MT299: Revamped implementation of MxToMt72Or79REJT for translation into field 79","title":"9.3.42 - June 2023"},{"location":"release-notes/changelog-translations/#9341-may-2023","text":"(PW-1371) pacs.004/pacs.008 -> MT102/MT103: conditional mapping to field 71G only if the amount is different from 0 (PW-1360/PW-1363) CBPR+ pacs.004 -> MT103: Revamped implementation of MxToMtRETN(MT1) for translation into field 72 (PW-1359) CBPR+ pacs.008.001.08.STP -> MT103.STP: use only the last PreviousAgent occurrence for mapping into field 72 pacs.004 -> MT103: implementation of MxToMtRETN(MT1) for translation into field 72 pacs.004 -> MT202/MT205: implementation of MxToMtRETN(MT2) for translation into field 72","title":"9.3.41 - May 2023"},{"location":"release-notes/changelog-translations/#9340-may-2023","text":"Added specific translations for RITS (Australian RTGS) for MT103 and MT202 to MX Added a TranslatorFactoryProvider to allow the creation of a TranslatorFactory for a specific market or clearing type Added accessors for the TranslatorConfiguration in the Translator interface Deprecated the 'translate' call with configuration parameter in favor of modifying the translator instance configuration","title":"9.3.40 - May 2023"},{"location":"release-notes/changelog-translations/#9339-april-2023","text":"(PW-1353/1354) CBPR+ pacs.004/pacs.008/pacs.009 to MT: fixed tags 50/59 letter option logic and added MxToMtAddressLineIsStructured function implementation (PW-1349) Enhanced mapping into field 72 by adding MxToMt72FullField function implementation (PW-1349) Fixed the implementation of the InstructionForNextAgent function (PW-1347) Added translation seev.044.001.11 -> MT564 (PW-1345) Added translation seev.037.001.13 -> MT566 (PW-1344) Added translation seev.036.001.13 -> MT566 (PW-1343) Added translation seev.035.001.13 -> MT564 (PW-1342) Added translations seev.031.001.12 -> MT564 / MT568","title":"9.3.39 - April 2023"},{"location":"release-notes/changelog-translations/#9338-april-2023","text":"(PW-1340) CBPR+ MT210 -> camt.057: strip leading slash (/) while mapping tag 25 into Notification/Account/Identification/Other/Identification (PW-1336) pacs.004.001 -> MT103 / MT202 / MT205: fixed mapping of tag 72, added XT99 code to unmappable reason codes","title":"9.3.38 - April 2023"},{"location":"release-notes/changelog-translations/#9337-april-2023","text":"(PW-1335) MT to MX: fixed MxToMt72FullField for translation into field 72, multiple lines mapping in InstructionForNextAgent node (PW-1334) camt.053 -> MT940 / MT950: fixed preconditions and mapping for 60F/M - 61 (PW-1330) pacs.008 -> MT103: fixed mapping of tag 77B, admit simultaneous /ORDERRES/ and /BENEFRES/ codes (PW-1310/1314/1328/1329) MX to MT: mapping for Name and Address fields 50/52/53/54/56/57/58/59, Revamped implementation of MxToMtNameAndAddress functions (PW-1310/1314/1328/1329) CBPR+ pacs.004/pacs.008/pacs.009 translators, using new MxToMtNameAndAddress functions (PW-1276) MX to MT: MxToMt72FullField for translation into field 72, add ACC code to InstructionForCreditorAgent Added and option in the translator configuration to define the specific version for the AppHdr to generate","title":"9.3.37 - April 2023"},{"location":"release-notes/changelog-translations/#9336-april-2023","text":"(PW-1208) ISO pacs.008 / pacs.004 -> MT103: deprecated preconditions (InstructingAgent and InstructedAgent)","title":"9.3.36 - April 2023"},{"location":"release-notes/changelog-translations/#9335-april-2023","text":"(PW-1325) sese.024 -> MT548: fixed translation of tag 24B:REJT, mapping of code OTHR to NARR","title":"9.3.35 - April 2023"},{"location":"release-notes/changelog-translations/#9334-april-2023","text":"(PW-1319) pacs to MT103: removed mapping of extra content /LOCINS/CRED in field 72 (PW-1317) pacs.008.001 -> MT103: fixed mapping of tag 77B, included CountryOfResidence for Debtor and Creditor (PW-1316) MT to MX: fixed mapping of tag 59F PartyIdentifier (PW-1315) MT to MX: MxToMt72FullField for translation into field 72, excluded Proprietary fields in LOCINS indicator (PW-1312) pacs.004.001 -> MT103 / MT202 / MT205: fixed mapping of tag 72, correct parsing of ReasonCode and AdditionalInformation (PW-1311) CBPR+ pacs.008.001 -> MT103: fixed mapping of tag 59, extra row in Name and Address section (PW-1309) CBPR+ pacs.008.001 -> MT103: fixed mapping of tag 59F, extra row in Name and Address section (PW-1308) CBPR+ pacs.008.001 -> MT103: fixed mapping of tag 23E SDVA and INTC (PW-1301) CBPR+ pacs.008.001 -> MT103: added mapping of tag 23E for HOLD, CHQB, PHOB and TELB codes in CreditTransferTransactionInformation\\InstructionForCreditorAgent (PW-1299) pacs.008.001 -> MT103 / MT102: fixed mapping of tag 70, added /URI/ indicator to RemittanceInformation\\Unstructured mapping (PW-1298) pacs.004.001 -> MT103 / MT202 / MT205: fixed mapping of tag 72, added /XT99/ to reason code (PW-1297) MT to MX: fixed mapping of tag 52D, truncate line 2 when FinancialInstitutionIdentification\\Name is longer than max length (PW-1276) pacs.008.001 -> MT103 / MT102: fixed mapping of tag 70, RemittanceInformation\\Unstructured with /RFB/ indicator","title":"9.3.34 - April 2023"},{"location":"release-notes/changelog-translations/#9333-march-2023","text":"(PW-1296) CBPR+ MT202/205 -> pacs.009 and MT103 -> pacs.008: removed the precondition rejecting 53B in present along 54a CBPR+ MT202/205 -> pacs.009 and MT204 -> pacs.010: fixed mapping of 58D into Name & Address to be compliant with CBPR+ UG rule MT to MX: Removed unnecessary precondition checking the format of /CLSTIME/ in field 72","title":"9.3.33 - March 2023"},{"location":"release-notes/changelog-translations/#9332-march-2023","text":"(PW-1288/1289/1290/1291/1293/1295) pacs.004.001.09/10 -> MT103: minor fixes in mapping for Creditor/Agent to field 59 and Debtor/Agent to field 50 (PW-1285) pacs.008.001 -> MT103: fixed mapping InstructionForCreditorAgent\\Code CHQB to field 23E (PW-1284/1294) minor fixes in MxToMt72FullField and MxToMt72FullField2 for translation into field 72 (PW-1283) pacs.004.001.09/10 -> MT103 / MT202 / MT205: fixed mapping for field 72 added extra TEXT line (PW-1282) pacs.004.001.09/10 -> MT103: added mapping for Creditor/Agent to field 59 and Debtor/Agent to field 50 (PW-1280) pacs.008 -> MT103: fixed mapping of tag 70, remove /RFB/ prefix when EndToEndIdentification is NOTPROVIDED (PW-1280) MX_To_MTAgent: removed Schema/Code prefix when it's different from CUID (PW-1280) MX_To_MTFATFNameAndAddress: replaced last / separator in CountryCode/TownName/PostCode for CountryCode/TownName,PostCode (PW-1278) pacs.009.001 -> MT202.COV: Implementation of MxToMt72FullField and MxToMt72FullField2 for translation into field 72 (PW-1276) CBPR+ pacs.008 -> MT103: Revamped implementation of MxToMt72FullField for translation into field 72 (PW-1275) Added translation semt.002.001.10 -> MT535 (PW-1267) MT103 -> pacs.008: Changed field 23E mapping to avoid InstructionForNextAgent/Code for compatibility with HVPS (PW-1209) MT204 -> pacs.010.001.03: deprecated mandatory Block3/121 precondition and autogenerate new UETR if Block3/121 is missing","title":"9.3.32 - March 2023"},{"location":"release-notes/changelog-translations/#9331-march-2023","text":"(PW-1270) MT535 -> semt.002.002.03 / semt.003.002.03: fixed mapping of tag 94a in Sequence B1 to BalanceForAccount/SafekeepingPlace (PW-1265) ISO pacs.004.001.09/10 -> MT103 / MT202 / MT205: fixed reason code mapping for field 72 (PW-1265) ISO pacs.004.001.09/10 -> MT103 / MT202 / MT205: fixed selector criteria, defaulting to MT202 (PW-1265) ISO pacs.004.001.09/10 -> MT103: fixed mapping field 72, field 50F and field 57D (PW-1208) ISO pacs.009 -> MT202: deprecated preconditions (InstructingAgent and InstructedAgent)","title":"9.3.31 - March 2023"},{"location":"release-notes/changelog-translations/#9330-march-2023","text":"(PW-1271) MT192/MT292 -> camt.056.001.08/10: fixed mappings of fields 20 and 21 into the Underlying message information (PW-1266) Fixed length in field 72 wrapped lines (PW-1265) CBPR+ pacs.004.001.09 -> MT103 / MT202 / MT205: fixed reason code mapping for field 72 (PW-1262) CBPR+ pacs.004 -> MT103 / MT202 / MT205: fixed selector criteria, defaulting to MT202 (PW-1240) pacs.009 -> MT202/MT205: proper generation of the // (continuation of narrative) prefixes in field 72","title":"9.3.30 - March 2023"},{"location":"release-notes/changelog-translations/#9329-march-2023","text":"(PW-1240) pacs.009.001.* -> MT202 / MT205: fixed mapping of RemittanceInformation/Unstructured in MxToMt72FullField2 for translation into field 72","title":"9.3.29 - March 2023"},{"location":"release-notes/changelog-translations/#9328-march-2023","text":"(PW-1258) CBPR+ pacs.004.001.09 -> MT103: fixed mapping field 72, field 50F and field 57D (PW-1257) camt.053.001.02/07/08 -> MT940: fixed mapping of multiple AdditionalEntryInformation to field 86 (PW-1182) Fixed translations MT940 <-> camt.060.001.05 for both generic ISO and CBPR+ versions (PW-1182) Added translations MT940 <-> camt.060.001.06","title":"9.3.28 - March 2023"},{"location":"release-notes/changelog-translations/#9327-march-2023","text":"(PW-1253) camt.056.001.08/10 -> MT192 / MT292: fixed mapping of OriginalGroupInformation\\OriginalCreationDateTime to 11S (PW-1252) camt.053.001.* -> MT950: fixed mapping of Statement\\LegalSequenceNumber and Statement\\ElectronicSequenceNumber to field 28C (PW-1249) pacs.008.001.* -> MT102 / MT103: fixed mapping of RemittanceInformation/Unstructured with ROC prefix to field 70 (PW-1247) MT202 / MT205 to pacs.009: Fixed mapping of TELEBEN code into InstructionForCreditorAgent/Code (PW-1245) CBPR+ pacs.009.001.08.COV -> MT202.COV: removed unnecessary RFB prefix in field 70, fixed field 72 line split (PW-1240) MT103 -> pacs.008.001.*: removed unnecessary defaults 'false' for BatchBooking (PW-1238) MT202 / MT205 -> pacs.009.001.*: fixed 53A mapping to SettlementInformation/SettlementAccount (PW-1237) MT103 / MT103.STP -> pacs.008.001.*: fixed 53A mapping to /FIN53/ in InstructionForNextAgent (PW-1235) CBPR+ pacs.009.001.* -> MT202 / MT205: Revamped implementation of MxToMt72FullField2 for translation into field 72 (PW-1233, PW-1246) CBPR+ pacs/camt -> MT: ignore FinancialInstitutionIdentification\\PostalAddress\\AddressLine containing \"NOTPROVIDED\" (PW-1230) CBPR+ pacs.008.001.08 -> MT103: added mapping for field 26T (PW-1229) Preserve whitespaces in XML element values when parsing the source MX for translation into MT (PW-1229) CBPR+ pacs.008/pacs.009 -> MT103/MT202: fixed mapping of multiple occurrences of InstructionForNextAgent/InstructionInformation to field 72 (PW-1229) camt.053.001.* -> MT940: fixed mapping of EntryDetails/AdditionalEntryInformation to field 86 (PW-1229) TranslationConfiguration: added new attribute preserveWhitespaces to prevent the translator from trimming the node contents in the MX to MT translations","title":"9.3.27 - March 2023"},{"location":"release-notes/changelog-translations/#9326-march-2023","text":"(PW-1251) CBPR+ MT to pacs.009: Fixed mapping of field 72 into repetitive InstructionForNextAgent with proper truncation","title":"9.3.26 - March 2023"},{"location":"release-notes/changelog-translations/#9325-march-2023","text":"(PW-1228) CBPR+ translation: fixed duplicated Member Identification in field 57D when translating from a ClearingSystemMemberIdentification element (PW-1225) CBPR+ pacs.004/pacs.009/pacs.009.COV/pacs.009.ADV -> MT202/MT202COV: removed unnecessary defaults 'NOTPROVIDED' for fields 52D-56D-57D (PW-1219) camt.054.001.06/07/08/09 -> MT900/MT910: fixed AddtlTxInf split into field 72 lines","title":"9.3.25 - March 2023"},{"location":"release-notes/changelog-translations/#9324-march-2023","text":"(PW-1224) Fixed RemittanceInformation\\Unstructured -> tag 70 (code RFB deleted) in CBPR+ translation pacs.008.001.08 -> MT103 (PW-1220) Fixed tag 53B incorrect prefix (INGA = C/INDA = D) in CBPR+ translation pacs.008.001.08 -> MT103 (PW-1217) Fixed InstructionForNextAgent\\InstructionInformation -> tag 72 (multiple occurrences) in CBPR+ translation pacs.008.001.08 -> MT103 (PW-1216) Fixed InstgAgt mapping to 72/INS/ in translation CBPR+ pacs.009.001.08 -> MT202 (PW-1210) Added translations MT102 <-> pacs.008.001.09 (PW-1210) Added translations MT103 / MT103.STP <-> pacs.008.001.09 (PW-1210) Added translations MT103 <-> pacs.004.001.10 (PW-1210) Added translations MT202 <-> pacs.004.001.10 (PW-1210) Added translations MT205 <-> pacs.004.001.10 (PW-1210) Added translations MT200 <-> pacs.009.001.09 (PW-1210) Added translations MT202 / MT202.COV <-> pacs.009.001.09 (PW-1210) Added translations MT205 / MT205.COV <-> pacs.009.001.09 (PW-1196) Fixed field 61/Supplementary Details mapping in the MT940 -> camt.053.001.07/08/09 translators (PW-1182) MT920 to camt.060.001.05: fixed intermediate field 34F repetition mapping (PW-1182) Added translations MT196/296 <-> camt.029.001.11 (PW-1182) Added translations pacs.009.001.08 -> MT205.COV","title":"9.3.24 - March 2023"},{"location":"release-notes/changelog-translations/#9323-february-2023","text":"(PW-1205) Removed criteria selection in translations MT196/MT296 -> camt.029.001.09 (PW-1204) Fixed 22F:STCO repetitive tag in translations sese.024. /sese.034. -> MT548 - semt.017.002.01 -> MT536 - semt.018.002.01 -> MT537","title":"9.3.23 - February 2023"},{"location":"release-notes/changelog-translations/#9322-february-2023","text":"(PW-1196) Enhancements in the MT940 <-> camt.053.001.* translators to enable back-and-forth conversion without data loss (PW-1196) Translator Factory: prefer MT940 over MT950 when both options are available as target MT (PW-1194) Fixed field 50A mapping in pacs.008.001.* to MT translators, it was the wildcard letter option 'a' instead of 'A' (PW-1089) Fixed Field 72 translation in MT103 -> pacs.008.001.* (PW-1089) Internal enhancement of narrative fields content extraction (MTs n99, 103, 200, 202 and 205 to MX)","title":"9.3.22 - February 2023"},{"location":"release-notes/changelog-translations/#9321-february-2023","text":"(PW-1183) Fixed criteria filter in translations pacs.008.001.08/10 -> MT102","title":"9.3.21 - February 2023"},{"location":"release-notes/changelog-translations/#9320-february-2023","text":"(PW-1182) Added translations MT102 <-> pacs.008.001.08 (PW-1182) Added translations MT900 <-> camt.054.001.09 (PW-1182) Added translations MT192/292) <-> camt.056.001.10 (PW-1182) Added translations MT941 <-> camt.052.001.09 (PW-1182) Added translation camt.060.001.06 -> MT920 (PW-1089) pacs.008 to MT103: enhanced field 72 mapping to support and propagate also custom codes (PW-1173) mapped the MX header priority into the target MT also when the direction of the MT is inbound (SwiftBlock2Output) Reviewed preconditions for pacs, semt to meet MT semantic checks restrictions Reviewed MT103 translation preconditions to make sure field 54A used with //RT indicator is followed by data for the member id","title":"9.3.20 - February 2023"},{"location":"release-notes/changelog-translations/#9319-january-2023","text":"(PW-1157) Added translation seev.035.001.11 to MT564","title":"9.3.19 - January 2023"},{"location":"release-notes/changelog-translations/#9318-january-2023","text":"(PW-1148) Added translation MT548 to sese.027.001.05 (PW-1146) Added translations sese.020.001.06 to MT540/MT541/MT542/MT543 (PW-1137) Added translations MT199/MT299 RJCT to pacs.002.001.10 (generic ISO 20022 and CBPR+ versions)","title":"9.3.18 - January 2023"},{"location":"release-notes/changelog-translations/#9317-december-2022","text":"(PW-1138) camt.057.001.06 to MT210: Notification/Item/Account fix (PW-1137) CBPR+ translation issue for pacs.002 (PW-1136) Added translation seev.039.001.10/11 to MT564 (PW-1135) Added translation seev.037.001.11 to MT566 (PW-1134) Added translation seev.036.001.11 to MT566 (PW-1133) Added translation seev.035.001.10 to MT564 (PW-1132) Added translation seev.031.001.10 to MT564 (PW-1131) Added translation seev.031.001.10 to MT568 (PW-1129) CBPR pacs.008.001.08 to MT103: minor fix fin field 72 /REC/ mapping MT300 to fxtr.014.001.03: implementation enhancements","title":"9.3.17 - December 2022"},{"location":"release-notes/changelog-translations/#9316-december-2022","text":"(PW-1125) pacs.009.001 to MT202 precondition SR23 fix","title":"9.3.16 - December 2022"},{"location":"release-notes/changelog-translations/#9315-december-2022","text":"(PW-1123) MT202/MT205 to pacs.009.001: added mapping of account in field 53A into instruction for next agent with /FIN53/ prefix Internal implementation enhancements in MT564/MT568 to seev.031 and MT564 to seev.039","title":"9.3.15 - December 2022"},{"location":"release-notes/changelog-translations/#9314-november-2022","text":"(PW-1112) sese.023.001.09 to MT540, MT541, MT542 and MT543 enhancements","title":"9.3.14 - November 2022"},{"location":"release-notes/changelog-translations/#9313-november-2022","text":"(PW-1111) Added translation sese.023.001.09 to MT541 and MT543 Added translation sese.024.001.09 to MT548","title":"9.3.13 - November 2022"},{"location":"release-notes/changelog-translations/#9312-november-2022","text":"Updated Apache Commons Text dependency to 1.10 to fix reported CVE (PW-1103) MT210 <-> camt.057.001.06: Enhanced mapping of fields 50, 52 and 56 (PW-1100) MT196/296 to camt.029: optional 11R/11S criteria check and added 11S translation (PW-1089) MT103 to pacs.008: Enhanced mapping of fields 70 and 72 into InstructionForNextAgent and RemittanceInformation (PW-1044) MT103 to pacs.008 - added narrative 72 /LOCINS/ /CATPURP/ and Batch Booking node Added translation MT200 to camt.050.001.05","title":"9.3.12 - November 2022"},{"location":"release-notes/changelog-translations/#9311-november-2022","text":"Migrated SIC translations to release 4.9","title":"9.3.11 - November 2022"},{"location":"release-notes/changelog-translations/#9310-october-2022","text":"Added translation camt.050.001.05 to MT200 (PW-1088) MT101 to pain.001 and MT103 to pacs.008: field 23E mapping enhancements","title":"9.3.10 - October 2022"},{"location":"release-notes/changelog-translations/#939-october-2022","text":"(PW-1077) MT548 to sese.024.001.10 mapping enhancements (PW-1063) MT544/545/546/547 to sese.025.001.09: Fixed partial settlement indicator mapping (PART, NPAR) (PW-1063) MT542 to sese.023.001.09: Fixed partial settlement indicator mapping (PART, NPAR) (PW-1057) MT to pacs.008 and pacs.009 - translate field 72 - added /BNF/ and /REC/ prefix in MX output","title":"9.3.9 - October 2022"},{"location":"release-notes/changelog-translations/#938-october-2022","text":"(PW-1075) MT548 to sese.024.001.10: MatchingStatus fixes with default if field 70D is not present (PW-1072) pacs to MT103 (and 202): Fixed logic for field 33B mapping to avoid D49 error in semantic check (PW-1057) MT103 to pacs.008: Remittance Unstructured mapped from Field 72 /BNF/ with fallback to mapping from field 70 if /BNF/ is not present (PW-1064) Fallback option to system classloader in resource loading Enhancements in MT party identifier into to MX clearing system identification mappings Added missing new versions for SRU2022 to the translator factory","title":"9.3.8 - October 2022"},{"location":"release-notes/changelog-translations/#937-september-2022","text":"(PW-1066) Added translations MT545 MT546 MT547 to sese.025.001.09 (PW-1065) Added translation sese.023.001.09 to MT542 (PW-1063) Added translation MT544 to sese.025.001.09 (PW-1062) pacs.008/pacs.009 to MT translates enhancements in field 20 for consistency between CBPR+ and generic ISO 20022 mappings (PW-1061) Revamp of the translation factory in order to enhance defaults and disambiguation (PW-1060) Fixed cast exception in MX to MT translations using explicit Output direction for the target message (PW-1059) MT to MX: Fixes an enhancements in translation of fields 50F and 59F (MTs; 101, 102, 103, 104, 202, 205, 210) (PW-1057) MT to pacs.008/pacs.009 enhanced mapping of REC code in field 72 (PW-955) pain.001 to MT101: copy raw unstructured remittance information to field 70 Added enum classes MtToMxTranslation and MxToMtTranslation will the supported translations","title":"9.3.7 - September 2022"},{"location":"release-notes/changelog-translations/#936-september-2022","text":"(PW-1043) CBPR+: Minor enhancements in the 192/292 to camt.056 translations (PW-1006) Changed the translation factory, to fall-back into 29 for MT target when both 19 and 29* are feasible Added generic ISO: MT103 to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT196 to camt.029.001.09 (based on CBPR+ translation) Added generic ISO: MT200 to pacs.009.001.08 (based on CBPR+ translation) Added generic ISO: MT202 to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT202 to pacs.004.001.09 (based on CBPR+ translation) Added generic ISO: MT202COV to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT204 to pacs.010.001.03 (based on CBPR+ translation) Added generic ISO: MT205 to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT205 to pacs.004.001.09 (based on CBPR+ translation) Added generic ISO: MT205 to pacs.009.001.08 (based on CBPR+ translation) Added generic ISO: MT205COV to pacs.002.001.10 (based on CBPR+ translation) Added generic ISO: MT205COV to pacs.009.001.08 (based on CBPR+ translation) Added generic ISO: MT296 to camt.029.001.09 (based on CBPR+ translation) Added generic ISO: camt.029.001.09 to MT196 (based on CBPR+ translation) Added generic ISO: camt.029.001.09 to MT296 (based on CBPR+ translation) Added generic ISO: camt.056.001.08 to MT292 (based on CBPR+ translation) Added generic ISO: camt.057.001.06 to MT210 (based on CBPR+ translation) Added generic ISO: camt.060.001.05 to MT920 (based on CBPR+ translation) Added generic ISO: pacs.002.001.10 to MT199 (based on CBPR+ translation) Added generic ISO: pacs.002.001.10 to MT299 (based on CBPR+ translation) Added generic ISO: pacs.004.001.09 to MT202 (based on CBPR+ translation) Added generic ISO: pacs.004.001.09 to MT205 (based on CBPR+ translation) Added generic ISO: pacs.009.001.08 to MT200 (based on CBPR+ translation) Added generic ISO: pacs.009.001.08 to MT205 (based on CBPR+ translation) Added generic ISO: pacs.010.001.03 to MT204 (based on CBPR+ translation) Removed unnecesary unescape in internal extractPattern function","title":"9.3.6 - September 2022"},{"location":"release-notes/changelog-translations/#935-september-2022","text":"(PW-1031) Added translation MT548 to sese.024.001.10 (PW-1006) MX to MT: Added a translation coverage report to see what source elements have been read during the translation semt.020.002.01 to MT578 mapping fix for REDE/RECE => REAG semantic check compiance in the generated MT","title":"9.3.5 - September 2022"},{"location":"release-notes/changelog-translations/#934-august-2022","text":"(PW-1012) sese.027.001.05 to MT548 mapping fixes","title":"9.3.4 - August 2022"},{"location":"release-notes/changelog-translations/#933-august-2022","text":"(PW-955) pain.001 to MT101: added truncation to the text after /RFB in field 70 Added internal loops API to MTs: 110, 201, 203, 210, 410, 412, 420, 422, 450, 456, 604, 605, 801, 920, 973","title":"9.3.3 - August 2022"},{"location":"release-notes/changelog-translations/#932-july-2022","text":"(PW-958) Enhanced the truncation report to differentiate between truncation regular fields and reference fields (PW-949) MX to MT: enhanced mapping of name & address fields, with truncation with evidence and having the country, when present, always at the last line (PW-948) MX -> MT202, MT204, MT205: enhanced mapping of field 58D (PW-948) MX -> MT202, MT204, MT205: enhanced mapping of field 58D (PW-948) pacs.009.01.10 -> MT202: enhanced mapping of field 58D (PW-943) Added translation: pacs.002.001.10 positive -> MT199/MT299 (PW-943) pacs.002.001.10 positive to MT199/MT299 (PW-935) Added MT-MX translation for latest versions of seev.031, seev.032, seev.033, seev.034, seev.038, seev.039, seev.040, seev.041, seev.042 (PW-932) Added translation: pacs.008.001.08 (ISO and CBPR+) -> MT103.REMIT (PW-932) Added a translation configuration parameter to disable the generation of the PDE flag (PW-932) Added translation: camt.056.001.08 -> MT192 (PW-924) Added translation: camt.052.001.09 <-> MT942 (PW-924) Added translation: camt.053.001.09 <-> MT940 (PW-924) Added translation: camt.053.001.09 <-> MT950 (PW-924) Added translation: camt.054.001.09 <-> MT910 setr.004.001.04 -> MT502: mapped the Holdings Redemption Rate into 36B::ORDR/UNIT to be compliant with semantic 258 check MT102 -> pacs.008.001.10: fixed mapping to be compliant with MX cross element checks Implementation enhancements","title":"9.3.2 - July 2022"},{"location":"release-notes/changelog-translations/#931-may-2022","text":"(PW-832) Added translation sese.023.001.09 -> MT540 MX to MT: Added truncation with evidence in party identification name fields","title":"9.3.1 - May 2022"},{"location":"release-notes/changelog-translations/#930-may-2022","text":"SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.3.0 - May 2022"},{"location":"release-notes/changelog-translations/#9235-may-2022","text":"(PW-918) Added translation MT192/MT292 -> camt.056.001.08 (PW-908) Added translation: MT102 -> pacs.008.001.10 (PW-813) Internal enhancement to fix CVE Added getTruncatedContent() to the Translator interface Deprecation API review","title":"9.2.35 - May 2022"},{"location":"release-notes/changelog-translations/#9234-may-2022","text":"(PW-915) Added translation: pacs.009.001.10 <-> MT202 (PW-915) Added translation: pacs.008.001.10 <-> MT103 (PW-908) Added translation: pacs.008.001.10 -> MT102 Mx to MT: Added a post process to sanitize with default values missing components in party fields options D, K and H","title":"9.2.34 - May 2022"},{"location":"release-notes/changelog-translations/#9233-may-2022","text":"(PW-905) MX pain.001 to MT101: Added default values for charges and creditor and removed related preconditions","title":"9.2.33 - May 2022"},{"location":"release-notes/changelog-translations/#9232-may-2022","text":"(PW-899) sese.027.001.05 -> MT548 added the mapping of TxDtls into SETTRAN Added CBPR+ translation: MT950 <-> camt.053.001.08 Added CBPR+ translation: MT941 <-> camt.052.001.08 Added CBPR+ translation: camt.060.001.05 -> MT920 Added CBPR+ translation: pacs.009.001.08 -> MT200 Added CBPR+ translation: MT941 <-> camt.052.001.08","title":"9.2.32 - May 2022"},{"location":"release-notes/changelog-translations/#9231-april-2022","text":"Added CBPR+ translation: MT200 -> pacs.009.001.08 Added CBPR+ translation: MT942 -> camt.052.001.08 Added CBPR+ translation: MT940 -> camt.053.001.08 Added CBPR+ translation: MT204 <-> pacs.010.001.03 Added CBPR+ translation: MT103, MT202, MT205 -> pacs.004.001.09 Added CBPR+ translation: MT900 -> camt.054.001.08 Added CBPR+ translation: MT910 -> camt.054.001.08 Added CBPR+ translation: MT210 -> camt.057.001.06 Added CBPR+ translation: MT101 <-> pain.001.001.09 MT101 to pain.001: fixed mapping of fields 50F and 59F, with preference for structured postal address instead of unstructured address lines CBPR+ MT192 and MT292 to camt.056: Added mapping of mandatory CreationDateTime MT103 STP to CBPR+ pacs.008.001.08.STP: Fixed mapping of mandatory creditor account CBPR+ MT to MX: changed the mapping of GroupHeader/CreationDateTime to have a fixed dummy date instead of the current time (PW-887) MT to MX: fixed the concatenation of narrative, to use space separator or not, depending on the MT value being split by length or words (PW-887) MX to MT: added a postprocess of the created message to sanitize fields with lines starting with '-' or ':' using '.' as replacement","title":"9.2.31 - April 2022"},{"location":"release-notes/changelog-translations/#9230-april-2022","text":"seev.036 and seev.037 to MT566: Fixed mapping of CADETL dates seev.036 to MT566: Fixed mapping of SECMOVE dates, CASHMOVE and 19B::WITF -> 19B::FTCA seev.035 to MT564: FIxed mapping of CADETL Added CBPR+ translation: camt.057.001.06 -> MT210 MX to MT: Fixed mapping of field 50F party identifier using code, country and identifier (no account number)","title":"9.2.30 - April 2022"},{"location":"release-notes/changelog-translations/#9229-april-2022","text":"Added translations: MT196/MT296 -> CBPR+ camt.029.001.09 Added translations xsys.011.001.01 and xsys.001.001.02 -> ACK/NAK (service 21 message) Fixed MIR generation in translations from xsys.012 and xsys.003 to MT019","title":"9.2.29 - April 2022"},{"location":"release-notes/changelog-translations/#9228-march-2022","text":"Added CBPR+ translation camt.029.001.09 to MT196/296 (PW-747) Added translation: MT104 -> pain.008.001.08","title":"9.2.28 - March 2022"},{"location":"release-notes/changelog-translations/#9227-march-2022","text":"(PW-872) Fixed mapping of field 95Q with multiple lines of name & address Added translations: MT566 <-> seev.036.002.12 and seev.036.001.12 Added translations: MT566 <-> seev.037.002.12 and seev.037.001.12 Added translations: MT564 <-> seev.035.002.12 and seev.035.001.12 Added translations: MT564 <-> seev.044.002.10 and seev.044.001.10","title":"9.2.27 - March 2022"},{"location":"release-notes/changelog-translations/#9226-march-2022","text":"Added CBPR+ translation MT103 REJT to pacs.002.001.10 Added CBPR+ translation MT202 REJT and MT202 COV REJT to pacs.002.001.10 Added CBPR+ translation MT205 REJT and MT205 COV REJT to pacs.002.001.10 (PW-865) MT540/541/542/543 to sese.023.001.09: fixed mapping of place of trade 94B Added API to the translation factories to indicate a specific message type/version output","title":"9.2.26 - March 2022"},{"location":"release-notes/changelog-translations/#9225-march-2022","text":"(PW-747) Added CBPR+ translations camt.056 <-> MT192/MT292","title":"9.2.25 - March 2022"},{"location":"release-notes/changelog-translations/#9224-march-2022","text":"Enhanced support for local date time offset in the mappings MX to MT: mapping review for fields 98a, with preference of 98E over 98C when possible From prowide-iso2022 update: changed the default date time serialization to local time with UTC offset","title":"9.2.24 - March 2022"},{"location":"release-notes/changelog-translations/#9223-march-2022","text":"(PW-859) MT54x to sese.020 fixed mapping of fields 20C:SEME, 20C:PCTI and 20C:MITI","title":"9.2.23 - March 2022"},{"location":"release-notes/changelog-translations/#9222-february-2022","text":"Added CBPR+ translation camt.052 to MT942 camt.052 to MT941/MT942 migrated to common translations hierarchy camt.052/053 to MT: Fixed mapping of pagination into 28C CBPR+ fixed translation of 72:/INS to previous instructing agent, added dummy postal address to be compliant with UG","title":"9.2.22 - February 2022"},{"location":"release-notes/changelog-translations/#9221-february-2022","text":"Added translation versions MT566 to seev.036.001.12 and seev.037.001.12 Added CBPR+ translation camt.053 to MT940 Added CBPR+ translation camt.054 to MT900/MT910 Added CBPR+ translation pacs.002 negative to MT199/MT299 REJT CBPR+ MT202 to pacs.009 ADV: fixed mapping of settlement information from fields 53a and 54a in the MT CBPR+ MT103 and MT202 mapping: fixed mapping for default creditor and debtor agents camt.053 to MT940/MT950 migrated to common translations hierarchy","title":"9.2.21 - February 2022"},{"location":"release-notes/changelog-translations/#9220-january-2022","text":"(PW-831) camt.052 and camt.053 to 9xx: Fixed direction toggle by configuration","title":"9.2.20 - January 2022"},{"location":"release-notes/changelog-translations/#9219-january-2022","text":"Added CBPR+ translation pacs.004.001.09 to MT103 RETN Added CBPR+ translation pacs.004.001.09 to MT202 RETN Added CBPR+ translation pacs.004.001.09 to MT205 RETN Added CBPR+ translation pacs.009.001.08.ADV to MT202 Added CBPR+ translation pacs.009.001.08 to MT205 Added CBPR+ translation pacs.009.001.08.COV to MT205COV Added translation version pacs.004.001.09 to MT103 RETN (PW-747) Added translations version for pain.001.001.09 <--> MT101 (PW-831) MT9xx to camt.05x: Versions 6, 7 and 8 migrated to common translations hierarchy MT101 to pain.001.001.08: migrated to common translations hierarchy Migrated CBPR+ translations to release 2.1","title":"9.2.19 - January 2022"},{"location":"release-notes/changelog-translations/#9218-january-2022","text":"(PW-798) Added translations from MT540, MT541, MT542 and MT543 to sese.020.001.06 (PW-798) Added translations from sese.027.001.05 to MT548 Added specific translation implementation classes for CBPR+ (pacs.009 --> MT202) Added a CbprTranslatorFactory to autodetect source CBPR+ messages and provide its corresponding translation implementation MT to seev: Fixed incorrect version at AppHdr/MsgDefIdr in some MT to seev translations MX to MT: Added a translation configuration option to enabled or disabled the conversion of non-SWIFT characters into '.'","title":"9.2.18 - January 2022"},{"location":"release-notes/changelog-translations/#9217-january-2022","text":"Added specific translation implementation classes for CBPR+ (pacs.009 <-- MT202/MT205) MT103 and MT202 to MX: removed redundant mapping for Interbank Settlement Date to meet cross-element rule constraint MT202 to pacs.009: Added criteria selection, field 72 must not indicate message is a rejection or return MT202 to pacs.009: Versions 6, 7 and 8 migrated to common translations hierarchy MT202 to pacs.009: enhanced mapping of SttlmInf in GrpHdr according to the CBPR+ METAFCT002/METAFCT003","title":"9.2.17 - January 2022"},{"location":"release-notes/changelog-translations/#9217-december-2021","text":"Added specific translation implementation classes for CBPR+ (pacs.008 <-> MT103) Added com.prowidesoftware.integrator.translations as automatic module name in the MANIFEST for JPMS support MT103 to pacs.008.001.08: minor mapping enhancements (UETR, field 13C) MT to MX: Changed default ISO date time to local time with offset (for CBPR+ compatibility) MT to MX: Changed default label for missing content from UNKNOWN to NOTPROVIDED (for CBPR+ compatibility)","title":"9.2.17 - December 2021"},{"location":"release-notes/changelog-translations/#9216-december-2021","text":"(PW-781) Added translation sese.025.001.09 to MT545 and MT547 (PW-779) Added translation MT541 and MT543 to sese.023.001.09 MT103 to pacs.008: added criteria check to avoid translating RETURN messages into pacs.008 (pacs.004 should be used instead) MT to MX: BusinessApplicationHeaderV02 is now generated by default instead of BusinessApplicationHeaderV01 Added back and forth mapping between the MT priority and PDE flag and the MX AppHdr","title":"9.2.16 - December 2021"},{"location":"release-notes/changelog-translations/#9215-november-2021","text":"MT103 to pacs.008: enhanced mapping of SttlmInf in GrpHdr according to the CBPR+ METAFCT001","title":"9.2.15 - November 2021"},{"location":"release-notes/changelog-translations/#9214-november-2021","text":"(PW-769): Added mapping for expected trade and settlement dates (from B/98a into NewDetails dates) MT103 to pacs.008: removed redundant IntrBkSttlmDt from GrpHdr (already mapped in CdtTrfTxInf) to be compliant with cross-element rule","title":"9.2.14 - November 2021"},{"location":"release-notes/changelog-translations/#9213-november-2021","text":"(PW-762) Added translation MT542 to sese.023.001.09","title":"9.2.13 - November 2021"},{"location":"release-notes/changelog-translations/#9212-november-2021","text":"(PW-754) camt.054 to MT900 and MT910: fixed mapping of 13D, 32A value date, 52D, 72 and added mapping for 50F option","title":"9.2.12 - November 2021"},{"location":"release-notes/changelog-translations/#9211-october-2021","text":"(PW-643) setr.010.001.04 to MT502: RSET is set from CshSttlmDt (with fallback to ReqdFutrTradDt)","title":"9.2.11 - October 2021"},{"location":"release-notes/changelog-translations/#9210-october-2021","text":"(PW-643) setr.004.001.04 to MT502: RSET is set from CshSttlmDt (with fallback to ReqdFutrTradDt)","title":"9.2.10 - October 2021"},{"location":"release-notes/changelog-translations/#929-october-2021","text":"(PW-643) MT509 to setr.016.001.04: changed mapping of OrdrDtlsRpt to IndvOrdrDtlsRpt to align with the SMPG spec (PW-663) Added translation MT210 to camt.057.001.06 (PW-663) Added translation MT103 RETURN to pacs.004.001.09","title":"9.2.9 - October 2021"},{"location":"release-notes/changelog-translations/#928-october-2021","text":"(PW-709) MT54x and 578 to sese: fixed generation of empty Settlement Transaction Condition (PW-709) MT540 to sese.023.001.09: fixed mapping of Partial Settlement Indicator (PW-708) pacs.008 and pacs.004 to MT: Fixed mapping of third reimbursement agent account (PW-643) setr.004.001.04 and setr.010.001.04 to MT502: RSET is set from CshSttlmDt (with fallback to ReqdFutrTradDt)","title":"9.2.8 - October 2021"},{"location":"release-notes/changelog-translations/#927-september-2021","text":"(JR-613) pacs.009 to MT202: Avoid redundant codewords in field 72 lines","title":"9.2.7 - September 2021"},{"location":"release-notes/changelog-translations/#926-september-2021","text":"(PW-662) pacs.009.001.08 to MT202[COV]: added mapping for PaymentIdentification/UETR into Block3/121 with fallback to autogenerated UETR (PW-643) MT515 to setr.012 and setr.006: added mapping for 95a::ALTE and removed related precondition check","title":"9.2.6 - September 2021"},{"location":"release-notes/changelog-translations/#925-august-2021","text":"(PW-643) MT515 into setr.012: enhanced mapping of InvstmtAcctDtls/AcctId to avoid precondition on INVE/BUYR parties (PW-643) MT515 into setr.006.001.04 and setr.012.001.04: fixed mapping of 35B when ISIN is not present (CUSIP, SEDOL, etc...) (PW-643) setr into MT502: TILI indicator defaults to GTCA (good until canceled) License check fix when source MX does not contain AppHdr","title":"9.2.5 - August 2021"},{"location":"release-notes/changelog-translations/#924-august-2021","text":"(PW-626) sese.024.001 and sese.025.001 to MT: mapped AppHdr/CreDt into 98C:PREP (PW-623) MT566 to seev036: removed unnecessary precondition check and enhanced mapping of the ADDB indicator, amount and rates (PW-613) pacs.009 to MT202 and MT202COV: Enhanced mapping of field 72 Added API to set default amount, unit and currency; when it is mandatory in a target element/field and not present in the source message","title":"9.2.4 - August 2021"},{"location":"release-notes/changelog-translations/#923-august-2021","text":"(PW-642) sese.025.001.09 to MT: fixed PlcOfTrad into 94B:EXCH mapping, fixed FctvSttlmDt into 98C:ESET mapping (PW-643) setr.004.001.04 and setr.010.001.04 to MT502: multiple mapping enhancements (PW-643) setr.004, setr.006, setr.010, setr.012, setr.015: enhanced mapping into 35B without ISIN, including corresponding prefixes (PW-569) pacs.008 and pacs.009 to MT: enhanced heuristic to attempt mapping into 50F and 59F instead of 50K and 59 pacs.008 and pacs.009 to MT: minor bugfix translating into field 50F when StrtNm and BldgNb concatenation exceeds the line limit in field 50F (PW-605) MT to MX: avoid split of DSS into Issr and SchmeNm elements if the Issr alone in the MX has enough length for the DSS value (PW-591-598, 600-604, 607-612, 614, 616, 618) Mapping fixes in MT564 to seev.031.001.10","title":"9.2.3 - August 2021"},{"location":"release-notes/changelog-translations/#922-july-2021","text":"(PW-626) sese.024.001.10 to MT548: several mapping fixes (PW-572) pacs.008 to MT103: avoid the /REC/ in field 72 if the InstrForNxtAgt already contains and instruction code (PW-569) pacs.009 to MT202COV: added mapping of structured beneficiary data into field 59F option (PW-567) pacs.008.001.08 to MT103: added mapping for PaymentIdentification/UETR into Block3/121 with fallback to autogenerated UETR Added translation sese.025.001.09 to MT546 (PW-569) pacs.008 to MT103: added mapping of structured beneficiary data into field 59F option (PW-568) pacs.008 to MT103: fixed mapping of CtgyPurp/Cd with \"INTC\" or \"CORT\" into 23E (PW-617) MT502, MT504, MT515, MT564 and MT566 to MX: fixed mapping of 98E with offset into ISO date time (PW-580-582-585-586-588-589-590) Mapping fixes in MT564 to seev.031.001.10 (PW-581) MT to MX: Preserve starting and trailing spaces when narrative field content is mapped into multiple lines of a single XML element (PW-568) pacs.008 to MT103: mapped special use case of CtgyPurp/Prtry with \"INTC CORT\" into respective 23E instances with \"INTC\" and \"CORT\" (PW-567) pacs.008 to MT103: avoid propagation of useless EndToEndId with \"NOTPROVIDED\" to field 70:/ROC/NOTPROVIDED MT856 translations: fixed mapping for sequence B6b Added translation setr.004.001.04 to MT502 Added translation setr.010.001.04 to MT502 (PW-579) MT564 to seev.031 added mapping for 70E::OFFO into Offerr elements (PW-577) MT564 to seev.031.001.10 added mapping for 25D with DSS into processing status sese and semt to MT: fixed mapping for SETPRTY 97A::SAFE when type and name was present besides the account identifier MX to MT: general fix in field 20C mapping that could occasionally generate more than 16 characters Added translation MT540 to sese.023.001.09 Added translation sese.024.001.10 to MT548 Added translation sese.025.001.09 to MT544","title":"9.2.2 - July 2021"},{"location":"release-notes/changelog-translations/#921-june-2021","text":"Added translation MT509 to setr.016.001.04 Added translation MT515 to setr.006.001.04 Added translation MT515 to setr.012.001.04 Added translation seev.035.001.03 to MT564 Added translation seev.039.001.03 to MT564 Added translation seev.044.001.03 to MT564 setr.017 to MT509: OrdrRef reverted change, mapped back to TRRF instead of RELA MX to MT: preserve line breaks in MT fields when translated from MX narrative content Added translation seev.038.001.03 to MT568 (PW-551) seev.031 to MT564: fixed 90K PRPP and 90L OFFR field mapping into cash movement details (PW-550) MT564 to seev.035, MT565 to seev.033, MT566 to seev.036: fixed mapping of field 90J currency component (PW-549) seev.031.001.10 to MT564: fixed mapping of MACI MICI and MMCI into the corporate action option details (PW-548) seev.031 to MT564: fixed mapping of 90F, 90J and 90L OFFR into the securities movement details (PW-547) seev.031 to MT564: added mapping for 90s option L into the maximum and minimum price details with 'PRCT' as default code (PW-546) seev.031 to MT564: fixed mapping of price details in SctiesMvmntDtls (PW-545) seev.031.001.03 to MT564: fixed mapping of certification breakdown flags (PW-544) MT564 to seev.031: fixed mapping of indicator flags in CADETL and CAOPTN (PW-543) seev.031.001.03 to MT564: fixed ISIN mapping (PW-542) MT564 to seev.031.001.10: fixed mapping of repetitive 70E content (PW-541) MT564 to seev.031.001.10: added missing mapping for 92D:WAPA into WarrantParity (PW-537) MT to MX: fixed mapping of face amount, that in some cases was propagated as 1.0 instead of the actual value (PW-535) MT564 to seev.031.001.10: mapping fixes in the cash movement details (PW-533) Added translation from seev.031.001.09 to MT564 MX pacs.008 and pacs.004 to MT103: fixed calculation of total charges in field 71G when the ChrgsInf is repeated in the MX Mapping fixes in setr.006.001.04, setr.012.001.04 and setr.015.001.04 to MT515 Mapping fix in MT103 to pacs.008 when multiple sender charges are present (PW-521) MT564 to seev.031.001.10: reviewed mapping of rate and amount details setr016 and setr.017 to MT509: OrdrRef is mapped into RELA instead of TRRF","title":"9.2.1 - June 2021"},{"location":"release-notes/changelog-translations/#920-may-2021","text":"SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.2.0 - May 2021"},{"location":"release-notes/changelog-translations/#9112-april-2021","text":"(PW-518) More flexible check of licensed BIC codes extracted from the translated MT headers xsys.012 to MT019: minor fix in target message fields order","title":"9.1.12 - April 2021"},{"location":"release-notes/changelog-translations/#9111-february-2021","text":"(CR-34) Added seev.031.001.001.03 to MT564 and MT568 translations (CR-34) Added MT564 and MT568 to seev.031.001.10 translations Fixed seev.031 to 564/568 invalid codewords MIEX and MILT in translation into field 36B Fixed generation of 20C:SEME when BAH is not present, in translations from seev.031/033/034/037/038/044 Fixed generation of LINK in translations from: seev.031/032/033/034/035/036/037, semt.016, sese.023/026/033/037","title":"9.1.11 - February 2021"},{"location":"release-notes/changelog-translations/#9110-january-2021","text":"(PW-438) Further enhancements in the setr.016 to MT509 when status is suspended","title":"9.1.10 - January 2021"},{"location":"release-notes/changelog-translations/#919-january-2021","text":"(PW-438) Fixed setr.016 to MT509 when status is suspended with proprietary reason code","title":"9.1.9 - January 2021"},{"location":"release-notes/changelog-translations/#918-december-2020","text":"Added translation from camt.053.001.02 to MT940 Added a one to many special translation for camt.053.001.02 to list of MT940 License check review","title":"9.1.8 - December 2020"},{"location":"release-notes/changelog-translations/#917-november-2020","text":"(PW-368) setr.015.001, setr.006.001 and setr.012.001 to MT515: Fixed mapping of transfer agent into 95Q from RltdPtyDtls with code TRAG (PW-368) setr.015 to MT515: added mapping for :22H::CAOP from Income Preference in the MX (PW-368) setr.015 to MT515: changed the mapping of InvstmtAcctDtls/AcctId into 95Q SELL/BUYR instead of 97A:SAFE setr.015.001 MT515: enhanced mapping for 35B when identification is not an ISIN setr.015.001 to MT515: removed no longer necessary precondition checks 30, 31 and 34 setr.006.001 to MT515: removed no longer necessary precondition checks 25 Fixed option to set sender/receiver from configuration in MX to MT940, MT941, MT942, MT900 and MT910 translations","title":"9.1.7 - November 2020"},{"location":"release-notes/changelog-translations/#916-november-2020","text":"(PW-368) setr.012.001 to MT515: removed no longer necessary precondition checks 6 (PW-368) setr.015.001 to MT515: removed no longer necessary precondition checks 5 (PW-368) setr.006.001 to MT515: removed no longer necessary precondition checks 5, 19 and 36 (PW-368) setr.006.001 and setr.012.001 to to 515: Mapped amount with codeword SWIT into amount with OTHR in the MT since SWIT is not accepted (PW-368) setr.006.001 and setr.012.001 to MT515: enhanced mapping for 35B when identification is not an ISIN (PW-368) setr.006.001 and setr.012.001 to MT515: fixed mapping for 95P when source message party information contains a BIC code semt, sese and setr into MT: fixed mapping into fields 19A and 90B when source message has too many decimal digits setr into MT: fixed mapping into field 95R from when source uses a proprietary identification","title":"9.1.6 - November 2020"},{"location":"release-notes/changelog-translations/#915-november-2020","text":"(PW-368) setr.016.001 to MT509: enhanced mapping for /Extension content (PW-368) setr.017.001 to MT509: enhanced mapping for /Extension content (PW-368) setr.017.001 to MT509: references and status mapping review (PW-368) setr.006.001 to MT515: more lenient precondition, and enhanced amounts mapping (PW-368) setr.012.001 to MT515: more lenient precondition, and enhanced amounts mapping (PW-368) setr.015.001 to MT515: more lenient precondition, and enhanced amounts mapping (PW-368) setr.016.001 to MT509: added mapping for the Extension into the Reason narrative 70D (PW-395) Added translation for MT567 to seev.041.001.10 corporate action cancellation status","title":"9.1.5 - November 2020"},{"location":"release-notes/changelog-translations/#914-october-2020","text":"(PW-368) Enhanced the setr.016.001 to MT509 translation to support all code and reason structures in the source MX (PW-374) Added a one to many special translation for pacs.001 to list of MT101 (PW-374) Added sender, receiver and direction to the optional TranslatorConfiguration (PW-368) Added global preventive check in MX to MT translations to avoid propagating tab characters into MT fields (PW-368) setr to MT515: added fallback mappings for mandatory fields 98a:SETT and 95:SELL or 95:BUYR in MT515 (PW-377) pacs.001 to MT101 added a fallback mapping from CdtTrfTxInf/PmtId/EndToEndId into field 21 when CdtTrfTxInf/PmtId/InstrId is not present (PW-377) pacs.001 to MT101 added a fallback mapping to create the optional field 23E with value OTHR if no other 23E field is created MT to MX: General fix for 35B ISIN mapping into MX identification of security elements","title":"9.1.4 - October 2020"},{"location":"release-notes/changelog-translations/#913-august-2020","text":"(PW-368) MX to MT: enhanced mapping of references (field 20 or 20C:SEME) with fallback to reference from AppHdr and truncation if necessary setr.016 to MT509: fixed mapping of mandatory field 24B","title":"9.1.3 - August 2020"},{"location":"release-notes/changelog-translations/#912-august-2020","text":"(PW-320) Replaced legacy default translations DSS name 'STRS' by 'COEX' (Coexistence global DSS from ISO 20022) Added version 8 translation between pacs.009 and MT202 Added version 8 translation between pacs.008 and MT103 Added version 8 translation between camt.053 and MT940 Added version 8 translation between camt.053 and MT950 Added version 8 translation between camt.054 and MT900 Added version 8 translation between camt.054 and MT910 In pacs.009 to 202 fixed precondition check for the CdtTrfTxInf[1]/PrvsInstgAgt Minor Fix in MX to MT time with offset mapping, offset was not propagated properly in some use cases Minor fix in logical criteria exception messages Added pacs.004.001.02 to MT 103 RETURN translation (for both ISO and SIC versions) Added pacs.002.001.03 to ACK/NAK translation (for both ISO and SIC versions) MX to MT: Added a parameter in the TranslatorConfiguration to optionally set a ClearingSystemMemberIdToBic function implementation SIC: MT to MX, trimmed spaces from reference to be compliant with SIC restriction SIC: MT103 to pacs.008 instructed agent mapped from 56A when present in the MT SIC: MT202 to pacs.009 instructed agent mapped from 57A when present in the MT","title":"9.1.2 - August 2020"},{"location":"release-notes/changelog-translations/#911-jun-2020","text":"MT103 to pacs.008 fixed mapping of fields 70 and 72 MT101 to pacs.008 fixed mapping of fields 70 and 72 MT202 to pacs.009 fixed mapping of fields 70 and 72 MT202 to pacs.009 fixed precondition checking the format of the CLSTIME MT to MX: general enhancements in mapping of field 50F when line numbers are repeated MT502 to to setr.004 and setr.010: enhanced mapping for fields 70E and 70C MT564 to seev.031 enhanced mapping for field 94G MT565 to seev.033 enhanced mapping for fields 70E and 95G MT568 to seev.031 enhanced mapping for field 70E","title":"9.1.1 - Jun 2020"},{"location":"release-notes/changelog-translations/#910-may-2020","text":"SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.1.0 - May 2020"},{"location":"release-notes/changelog-translations/#901-may-2020","text":"Internal implementation changes to the use the new AppHdr model in the SDK","title":"9.0.1 - May 2020"},{"location":"release-notes/changelog-translations/#900-may-2020","text":"Translations module extracted to its own jar in the distribution, with its own version from now on (PW-286) Fixed ISO datetime conversions into MT variants","title":"9.0.0 - May 2020"},{"location":"release-notes/changelog-translations/#808-april-2020","text":"Fixed logical message criteria for camt.054 into 900 or 910 depending on the entry debit/credit indicator Fixed translator factory finder for pacs.008.001.06 to 103 and seev to 566 Change in preconditions from camt.053 to MT to make them more flexible","title":"8.0.8 - April 2020"},{"location":"release-notes/changelog-translations/#807-march-2020","text":"Added specific translations for SIC (SWISS RTGS): between 202 and pacs.009 Added specific translations for SIC (SWISS RTGS): between 103 and pacs.008 In MX to MT: fixed extra slash when mapping clearing system codes or account numbers into party fields pacs.008 to 103 and pacs.009 to 202: field 20 now is mapped from CdtTrfTxInf/PmtId/TxId instead of GrpHdr/MsgId 103 to pacs.008: when present, the block 3 MUR is mapped into GrpHdr/MsgId instead of the reference field 20","title":"8.0.7 - March 2020"},{"location":"release-notes/changelog-translations/#806-february-2020","text":"Added translation from setr.006.001.04 redemption order confirmation to MT515 Added translation from setr.012.001.04 subscription order confirmation to MT515 Added translation from setr.016.001.04 order instruction status report to MT509 Added translation from setr.015.001.04 switch order confirmation into MT515 redemption and subscription leg messages Added translation between setr.017.001.04 order cancellation status report and MT509 (back and forth) Added a truncation report in translator classes and a '+' as last character of truncated data in the target message In MT to MX; header data is propagated to the AppHdr, including sender, receiver, reference, message type, and also PDE flag if present in the MT trailer In MX to MT; if the source MX contains an ISO header with the possible duplicate flag set to true, the created MT will have a PDE trailer flag MT103 to pacs.008 added mapping from 32A date into the group header settlement date Added a remove spaces transformation when mapping IBAN numbers from MT to MX","title":"8.0.6 - February 2020"},{"location":"release-notes/changelog-translations/#805-january-2019","text":"MT202 and MT202COV to MX, added mapping for sender correspondent field 53B location into group header instructing agent postal address (PW-225) MT202 and MT202COV to MX, removed the precondition requiring a mandatory party identifier in the sender correspondent field 53B","title":"8.0.5 - January 2019"},{"location":"release-notes/changelog-translations/#804-december-2019","text":"MT103 to MX, added mapping for sender correspondent field 53B location into group header instructing agent postal address (PW-225) MT103 to MX, removed the precondition requiring a mandatory party identifier in the sender correspondent field 53B (PW-225) MT103 to MX, removed the precondition requiring the same currency In semt to MT translations when Document/*/Id/Id is not found in MX the 20C:SEME is generated from AppHdr/BizMsgIdr Enhanced mapping of field 35B description of security when the ISIN is not present","title":"8.0.4 - December 2019"},{"location":"release-notes/changelog-translations/#803-september-2019","text":"Fixed mapping for field 36E in translations from MX to MT Added version 6, 7, 8 and 9 for translations between MT566 and seev.036 and seev.037","title":"8.0.3 - September 2019"},{"location":"release-notes/changelog-translations/#802-august-2019","text":"Added version 6, 7, 8 and 9 for translations between MT566 and seev.036 and seev.037 Fixed mapping for field 36E in translations from MX to MT Fixed bin/translator CLI app that stopped reading input on the first line break","title":"8.0.2 - August 2019"},{"location":"release-notes/changelog-translations/#801-july-2019","text":"Added a TranslatorFactory to enable automatic translator selection based on the source message Added a CLI to run automatic translation of files in the command line","title":"8.0.1 - July 2019"},{"location":"release-notes/changelog-translations/#800-may-2019","text":"JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"8.0.0 - May 2019"},{"location":"release-notes/changelog-translations/#7108-march-2019","text":"Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Fixed obfuscation to keep directories in jar Fixed mapping of Field70 to EndToEndId","title":"7.10.8 - March 2019"},{"location":"release-notes/changelog-translations/#7107-january-2019","text":"Added alternative translate call in translation implementation classes to run the process without precondition checks Added translations between pacs.001.001.08 and MT101 Fixed translations for fields 50F and 77B Fixed precondition check for MX pain.001.001.03 to MT101 translation Fixed translation MX pain.001.001.03 to MT101 when multiple PmtInf and CdtTrfTxInf combinations are present","title":"7.10.7 - January 2019"},{"location":"release-notes/changelog-translations/#7100-april-2018","text":"SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Added 103 and 103 STP to pacs.008.001.07 Added 202 and 202 COV to pacs.009.001.07 Added 900 to camt.054.001.07 Added 910 to camt.054.001.07 Added 940 to camt.053.001.07 Added 941 to camt.052.001.07 Added 942 to camt.052.001.07 Added 950 to camt.053.001.07 Added pacs.008.001.07 to 103 Added pacs.009.001.07 to 202 and 202 COV Added camt.052.001.07 to 941 and 942 Added camt.053.001.07 to 940 and 950 Added camt.054.001.07 to 900 and 910","title":"7.10.0 - April 2018"},{"location":"release-notes/changelog-translations/#798-april-2018","text":"MT to MX: fixed decimal separator in amount format to avoid locale dependant issues","title":"7.9.8 - April 2018"},{"location":"release-notes/changelog-translations/#797-january-2018","text":"Changes in the distribution package |-> Command line tools in the bic directory changed from jar files to wrapper scripts |-> Dependencies directory renamed to lib |-> Removed the BUILD id timestamp from the jar files * MT to MX: sender and receiver address from header blocks mapped according to message direction","title":"7.9.7 - January 2018"},{"location":"release-notes/changelog-translations/#796-december-2017","text":"Added camt.054.001.06 to MT900 and MT910 Added camt.053.001.06 to MT940 and MT950 Added camt.052.001.06 to MT941 and MT942 Added pacs.009.001.06 to MT202 and MT202 COV Added pacs.008.001.06 to MT103 Added xsys.003.001.01 to MT019 Added xsys.012.001.01 to MT019 Added MT300 to fxtr.014.001.03 Performance enhancement: comprehensive use of relative paths to optimize content selection. Performance enhancement: mappings migrated from docname to xml to avoid paths conversion in engine. MX to MT: Fixed generation of fields with letter option D (such as 52D) when only name & address was present as content Added plugable PathAdapter to customize MX paths used in translations","title":"7.9.6 - December 2017"},{"location":"release-notes/changelog-translations/#795-december-2017","text":"Performance enhancement: static methods for internal processing, reduced path conversion Individual precondition checks made private in favor of the global preconditionsChecks API","title":"7.9.5 - December 2017"},{"location":"release-notes/changelog-translations/#794-november-2017","text":"JRE requirement backported to Java 1.6 Added xsys.002.001.01 to MT012","title":"7.9.4 - November 2017"},{"location":"release-notes/changelog-translations/#793-october-2017","text":"Fixed MT548 to MX: fixed mappings for ProcessingStatus Fixed MT586 to MX: mappings with invalid amounts sequence B5c changed to B5b MT564 and 566 to MX: fixed mapping for currency component in field 92J Added MT568 to seev.031.002.06 Added MT564 to seev.031.002.06 and seev.039.002.06 Added MT019 to xsys.003.001.01 and xsys.012.001.01 Added MT012 to xsys.002.001.01 Added MT202 and MT202 COV to pacs.009.001.06 Added MT103 and MT103 STP to pacs.008.001.06 MT to MX: fixed mapping header for sender and receiver addresses in output (incoming) messages MT to MX: replaced fixed data in message creation date time with current ISO time stamp MT940 to camt.053 and MT941/MT942 to camt.052: fixed translation for field 86 repetitions into additional entries information MT101 to pain.001: fixed translation for field 23E repetitions MT900 and MT910 to camt.054: fixed translation for field 72 repetitions Added MT941 and MT942 to camt.052.001.06 Added MT940 and MT950 to camt.053.001.06 Added MT900 and MT910 to camt.054.001.06","title":"7.9.3 - October 2017"},{"location":"release-notes/changelog-translations/#792-august-2017","text":"semt.020.02.01 to MTs 508, 545, 547, 578: changed default amount XXX99999999999999 to locale currency and 0 sese.020.002.01 and semt.013.002.01 to MT524 fixed generation of LINK sequences seev, semt, sese, setr to MT5xx: fixed generation of field 36B with quantity of financial instrument semt.020.002.01 to MT578: changed translation to generate the alleged instruction indicator (:22H::PAYM) in sequence B with codeword FREE instead of APMT to be compliant with MT semantic 283 pain.001.001.03 to MT101: fixed mapping for multiline field 77B and fixed MX paths when checking the available payment information instances setr.006.002.01 and setr.012.002.01 to MT515: fixed mapping for multiline field 70C semt and sese to MTs 544, 545, 546, 547 and 548: added link sequence with RELA to be compliant with MT semantic rules 73 semt.020.002.01 to MTs 535, 536, 537, 538 and 586: changed translations to set Activity Flag (field :17B:ACTI) to 'N' to be compliant with MT semantic rules 256, 266 and 267 semt.020.002.01 to MT508 and sese.020.002.01 to 524: changed translations to be compliant with MT semantic rule 281 MX to MT: fixed collapsing data in output MT, due to bug in handling repeat predicates from MX path MX to MT: fixed generic bug when creating fieldset with multiple letter options MX to MT: general mappings fixes for MX categories seev, semt, sese and setr Generic fix for proper handling of repetitive fields/elements in target message MX to MT: fixed bug when creating fieldset with multiple letter options MX to MT: fixed mappings translations for seev, semt, sese and setr","title":"7.9.2 - August 2017"},{"location":"release-notes/changelog-translations/#79-may-2017","text":"SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX) Removed false positive warning for invalid namespace in header when the header was actually empty","title":"7.9 - May 2017"},{"location":"release-notes/changelog-translations/#789-may-2017","text":"Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"7.8.9 - May 2017"},{"location":"release-notes/changelog-translations/#783-jul-2016","text":"If GrpHdr is present when converting from MX to MT, header BICs are set from it Internal migration from MxNode to XmlNode from SDK","title":"7.8.3 - Jul 2016"},{"location":"release-notes/changelog-validation/","text":"Prowide Integrator Validation - CHANGELOG 9.4.24 - June 2024 (PW-1845) Added an option in the RITS (HVCS) validation engine to opt-in strict mode validation (rules not checked by the HVCS portal) 9.4.23 - May 2024 (PW-1845) Added new RITS (HVCS) validator for pacs.004 9.4.22 - April 2024 (PW-1809) Added a new optional SchemaCache to the validation engine configuration to optimize the MX validation process 9.4.21 - April 2024 (PW-1842) Remove System.exit() call from deprecated class to avoid false positive vulnerability report 9.4.20 - February 2024 (PW-1761) Fixed error message for E92 on MT 545 and 547 Replaced generic KNN errors with specific codeword errors for designated fields such as T03, T04, T20, T35, etc... 9.4.19 - January 2024 (PW-1752) Added new API method 'validateTag' in order to allow to validate singe tags/fields without the need to build a full message (PW-1743) Remove usage of deprecated SafeXMLUtils methods Added field validation rule for pattern used in MT 097 field 109 9.4.18 - January 2024 (PW-1739) Modified the validation of field 23 in order to match the specification for MT102/MT103/MT305/MT601 9.4.17 - January 2024 Disabled 'Missing checksum field CHK (Z04)' block 5 validation because the checksum algorithm is proprietary by SWIFT and not available in the library API 9.4.16 - December 2023 (PW-1732) Enhanced the semantic 292 to also report the error for MT541 when the sequence E3 is missing 9.4.15 - December 2023 (PW-1666) Updated T13 validation logic in order to avoid false positives when validating MTs n92/n95/n96 9.4.14 - December 2023 (PW-1708) Fix concurrency issue with BICDirectory in semantic 257 and 5 implementations Added missing implementation for SCORE UG rules in MT798<700> 9.4.13 - November 2023 (PW-1697) Changed field 29O validation to be compatible with the field model changes 9.4.12 - November 2023 (PW-1691) CBPR+: NPE fix in the validation of the specific business service for each message type Minor fix in the validation of field 29O 9.4.11 - November 2023 (PW-1691) CBPR+ fixed validation of specific business service for each message type (version could vary depending on the specific message type) 9.4.10 - November 2023 (PW-1675) Fixed specific validations for SCORE messages in SRU2023 9.4.9 - October 2023 Updated the default ISO 20022 external code set XSD resource to the 2Q2023_ExternalCodeSets_v1.xsd release 9.4.8 - October 2023 MT370 and MT670 messages are now verified to have a size less than 10,000 9.4.7 - October 2023 (PW-1653) MT671 message is now verified to have a size less than 10,000 9.4.6 - September 2023 (PW-1613) fixed validation of field 44J narrative to enable 65 characters after the mandatory starting slash 9.4.5 - September 2023 (PW-1628) fixed validation of new Field 44A, 44B, 44E and 44F enabling multilines since they now use character 'z' 9.4.4 - September 2023 (PW-1478) fixed validation of new Field 44J 9.4.3 - September 2023 (PW-1480) More accurate implementation of semantic rule C25 (MTn92): field 79 or at least any fields from the original message (or both) must be present 9.4.2 - August 2023 (PW-1472) Fixed validation of 23X in MT767 (PW-1431) CBPR+: Implemented UG validation for CBPR+ 2023 messages (PW-1448) Fixed size validation for field 24G (PW-1431) CBPR+: Implemented UG validation for CBPR+ 2023 messages Added CROSS RULES validation for new CBPR+ 2023 messages 9.4.1 - June 2023 ValidationEngine add explicit API to validate the MX Business Application Header version 3 9.4.0 - May 2023 SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/) 9.3.18 - June 2023 Fixed field 79 /REJT/ or /RETN/ validation of lines containing /TEXT/ narrative 9.3.17 - May 2023 (PW-1373) Minor fix in semantic validation for MT 798<720> 9.3.16 - May 2023 (PW-1377) Fixed NPE validating semantic rule 2 in MT 798_750 9.3.15 - May 2023 (PW-1373) MT SCORE 798<720>: Fixed codewords and rules for fields 40B and 41a (PW-1367) Added MT SCORE 798 sub-message types: 722_LC_C2B, 726_LC_C2B, 735_LC_C2B, 770_LC_C2B, 772_LC_C2B (PW-1359) Added missing T47 problem properties 9.3.14 - April 2023 MX validation: Added a general rule to check the maximum bytes allowed for the message 9.3.13 - February 2023 (PW-1206) Added message model for the MT SCORE subtypes 707/708/710/711/720/721/732/734/750 (PW-1198) Added validation for MT SCORE subtype 767 - Sequence B optional for 22A ISCA or ICCA 9.3.12 - January 2023 (PW-1154) Enhanced block 2 input validation; when priority is \"S\" (System) delivery monitoring and obsolesce period are not allowed (PW-1150) Added validation for MT SCORE subtypes 731/736/748/753/755/757/771/773 9.3.11 - December 2022 Removed the org.mozilla:rhino dependency 9.3.10 - November 2022 Minor backward compatibility fix in the ValidationConfiguration IBICDirectory initialization 9.3.9 - November 2022 Updated Apache Commons Text dependency to 1.10 to fix reported CVE (PW-1097) Fixed BIC validation against directory in CBPR+ messages (PW-1090) Enhanced validation of field 11T in SCORE messages, with specific check for the allowed sub-message type (PW-1085) Moved the custom BIC directory implementation setter from the SDK singleton configuration to the ValidationConfiguration 9.3.8 - October 2022 Code enhancements review 9.3.7 - October 2022 (PW-1074) MT568: fixed typo in qualifier name \"PTNI\" (PW-1071) MX cross-element rules are not applied when validating a custom schema, such as SIC4 (PW-1064) Fallback option to system classloader in resource loading SRU2022 update review: MT540 Removed field 99C SRU2022 update review: MT548 Added field 98C::SCTS SRU2022 update review: Field 35C changed validation to 9.3.6 - September 2022 Added support for MUG validations (CLSB and AU/PDS) 9.3.5 - September 2022 MT structure validation: enhanced report of missing required fields, adding the path of sequences when applicable MT structure validation: enhanced report of unexpected fields, when the possible cause is the fields ordering 9.3.4 - August 2022 Permanently replaced the legacy ValidationEngine.Configuration inner class by the ValidationConfiguration MT structure validation refactor to decommission the need for the Rhino dependency 9.3.3 - August 2022 (PW-1015) Added validation for sub-message types 700, 701 and 774 (SCORE) (PW-1007) Changed the AppHdr message definition against Document namespace validation to be more flexible, allowing subtypes such as \"CORE\" 9.3.2 - August 2022 PW-1007: Changed the AppHdr message definition against Document namespace validation to be more flexible, allowing subtypes such as \"CORE\" Implemented cross-element rules for pacs.004.001.10 and 11 Implemented cross-element rules for pain.001.001.10 and 11 Implemented cross-element rules for pain.002.001.10, 11 and 12 Implemented cross-element rules for camt.029.001.10 and 11 Added internal loops API to MTs: 110, 201, 203, 210, 410, 412, 420, 422, 450, 456, 604, 605, 801, 920, 973 (PW-968) Field 72: fixed validation of optional text after INSTR codes, that cannot be a complete set of blanks 9.3.1 - July 2022 (PW-968) Field 72: fixed validation of optional text after INSTR codes, that cannot be a complete set of blanks (PW-963) Fixes message length validation rule to compute also CRLF characters (PW-931) Added a field check for unexpected slash separator, in fields having an optional second component separated by slash (PW-867) Enhanced validation of party fields starting with /C/ or /D/ to avoid false negative errors on /D /C prefixes in the account Fixed SRU2022 changes in semantic rules 258 and 267 MT semantic validations minor fixes and enhancements Implemented cross-element rules for newer versions of camt.052 Implemented cross-element rules for newer versions of camt.053 Implemented cross-element rules for newer versions of camt.054 Implemented cross-element rules for newer versions of camt.056 Implemented cross-element rules for newer versions of camt.057 Implemented cross-element rules for newer versions of camt.060 Implemented cross-element rules for newer versions of pacs.010 Implemented cross-element rules for: Pacs.008 v9 & v10 (standard and STP), pacs.009 v9 & v10 9.3.0 - May 2022 SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.2.31 - May 2022 (PW-813) Internal enhancement to fix CVE Deprecation API review 9.2.30 - May 2022 MT semantic rules review and minor fixes MX cross-element checks review and enhancements 9.2.29 - May 2022 MX cross-element checks review and enhancements 9.2.28 - April 2022 Fixed MX cross-element checks Changed the ValidationResult to have the valid flag as transient field, set dynamically depending on the problems list size Added missing validations for CBPR+ pacs.009 9.2.27 - April 2022 CBPR+ UG validation fixes 9.2.26 - March 2022 (PW-882) SCORE 798_760 fixed validation of sequence B which is optional if purpose of message is ICCO or ISCO MT104: Fixed validation problem description in semantic rule 96 9.2.25 - March 2022 CBPR+ validation: apply schema from Document namespace when AppHdr message type does not match pacs.002.001.10: Implemented cross-element rules, and CBPR+ UG rules pain.002.001.10: Implemented cross-element rules, and CBPR+ UG rules 9.2.24 - March 2022 pacs.010.001.03: Implemented cross-element rules, and CBPR+ UG rules camt.060.001.05: Implemented cross-element rules, and CBPR+ UG rules pain.001.001.09: Implemented cross-element rules, and CBPR+ UG rules 9.2.23 - March 2022 Fixed error description in MX validation (cross element checks and CBPR+ rules) MX cross element validation fixes (X00420) 9.2.22 - March 2022 Enhanced the CBPR+ AppHdr validation with constraints from CBPR+ restricted BAH v2 schema 9.2.21 - March 2022 (PW-861) Fixed validation of fields 23X, 21H, 77B (MT734) and 98K that was too strict; slash character is allowed in the component using x character set 9.2.20 - February 2022 (PW-856) GPI: Fixed misleading error description in field 111 validation (PW-835) GPI: Field 111 is optional in MT199 even for GPI members Fixed inconsistency in the ValidationResult valid flag returned by the CbprValidationEngine Fixed MX cross-element validations when too elements cannot be present together, but may both be absent 9.2.19 - February 2022 Updated the default ISO 20022 external code set XSD to the February 2022 update camt.029.001.09: Implemented cross-element rules, and CBPR+ UG rules camt.052.001.08: Implemented cross-element rules, and CBPR+ UG rules camt.053._001.08: Implemented cross-element rules, and CBPR+ UG rules camt.056.001.08: Implemented cross-element rules, and CBPR+ UG rules camt.057.001.06: Implemented cross-element rules, and CBPR+ UG rules pacs.002.001.10: Implemented cross-element rules, and CBPR+ UG rules pacs.004.001.09: Implemented cross-element rules, and CBPR+ UG rules Completed UG rules for CBPR+ pacs.008 and pacs.009 variants (COV, STP, ADV) 9.2.18 - February 2022 (PW-837) In MT message length validation, remove line CRLF when computing the message size 9.2.17 - January 2022 (PW-835) Fixed validation of GPI field 111 (block3) expected values per message type 9.2.16 - January 2022 (PW-833) Fixed mandatory field 77E in MTn98 Added UG implementation for CBPR+ pacs.008 STP and pacs.009 ADV/COV 9.2.15 - January 2022 SCORE messages semantic validations review 9.2.14 - January 2022 (PW-819-820) SCORE message MT798_760 validation fixes Added UG implementation for CBPR+ camt.054 Implemented cross-element rules for camt.054.001.08 Added validation for MX match between AppHdr message identifier and Document namespace 9.2.13 - January 2022 (PW-815) Fixed validation of field 12H (SCORE) where narrative is optional MT530 validation: Fixed semantic 237 rule, where subsequence C1 is repetitive Added UG implementation for CBPR+ pacs.009 Implemented cross-element rules for pacs.009.001.08 9.2.12 - December 2021 Added a specific CbprValidationEngine class to validate CBPR+ messages Added UG implementation for CBPR+ pacs.008 Implemented cross-element rules for pacs.008.001.08 Added com.prowidesoftware.integrator.validation as automatic module name in the MANIFEST for JPMS support 9.2.11 - December 2021 (PW-799) fixed validation of semantic rule 199 in MT564 9.2.10 - December 2021 (PW-780) Added ValidationConfiguration#setGpiMember to override the general static SdkConfiguration#setGpiMember (PW-764) Fixed error description in field 119 (block 3) validation 9.2.9 - November 2021 (PW-772) Enable empty lines in MT568 field 70F as it is exceptionally allowed in the ISO 15022 usage guidelines In Mx IBAN validation added specific error code D00003 9.2.8 - November 2021 (PW-764) Reviewed validation of field 119 (block 3) (PW-703) Clearer validation results for MT block 2 with invalid identifier Added IBAN validation (including local account format) for MX elements containing IBAN numbers Added optional IBAN validation for MT messages, for specific fields where IBAN validation is explicitly requested by configuration MX validation: renamed proprietary error codes for invalid currency and country codes by standard codes D00004 and D00005 Fixed validation of letter options in B/98a 9.2.7 - October 2021 Added validation of block 2 Output (only Input was validated before, while Output was ignored) Fixed validation of value for Field 26A ( ) 9.2.6 - October 2021 (PW-705) Added validation of mandatory CHK in block 5 when the trailer block is present (PW-703) More verbose MT headers validation (PW-677) MT670, MT671: fixed implementation of semantic check 112 (D12) 9.2.4 - September 2021 (PW-664) Parser enhancement to detect LF before block identifier as validation problem (not exception) 9.2.3 - August 2021 Added german translation for validation problems 9.2.2 - August 2021 (PW-599) MT564: Minor scheme fix, 92a TAXR and WITL can be repeated in CASHMOVE (E2) MT548: Minor scheme fix, added letter option \"C\" in field \"98C:SCTS\" in sequence \"C1a1B1\" (PW-578) Fixed SAX logging with misleading parse errors 9.2.1 - June 2021 (PW-536) Replaced deprecated API in the MX validation (PW-536) Fixed misleading typo in semantic E94 error description (PW-517) Removed the actual licensed BICs information from the unlicensed error description in the validator 9.2.0 - May 2021 SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) More accurate structure problems reporting, with a customizable lookahead for sequence resynchronization after a field partial match Enhanced unexpected fields problem reporting, in some situations it used to trigger also misleading errors about the unexpected field repetitions 9.1.16 - April 2021 Added support for ISO 20022 external code set validations Externalized the validation engine configuration into a ValidationConfiguration class (PW-517) Removed the actual licensed BICs information from the unlicensed error description in the validator 9.1.15 - April 2021 (PW-460) Divided the internal schemas package into packages by category to allow trimming the jar by use 9.1.14 - April 2021 (PW-500) Fixed validation of qualifiers when the component is optional Fixed qualifier error reporting in fields 41A and 41D Replaced generic error code KNN with specific code for each field, such as K41, K23, K92 9.1.13 - April 2021 (PW-508) Fixed validator pattern in field 98K 9.1.12 - April 2021 Enhanced MT structure error detection and reporting (missing and unexpected fields) Fixed validation of fields 12 and 27A in MT SCORE messages 9.1.11 - March 2021 Added semantic validation for available SCORE messages (PW-499) Fixed schemes for MT513, MT564 and MT566: invalid qualifier in field 69D 9.1.10 - March 2021 (PW-494) Fixed schemes for MT565 (sequence B can be repeated up to 1) and MT568 (sequence B is optional, not mandatory) 9.1.9 - March 2021 (PW-493) Fixed scheme for MT671, missing :22H::PRCD//PREF in Other Details sequence Added mtInSequenceResyncLookAhead parameter in the ValidationEngine#Configuration to control the error reporting accuracy Added mtEnhancedRepetitionProblemReportingMode parameter in the ValidationEngine#Configuration to switch off redundant field repetition related errors Removed T13 rule from MTn98 proprietary messages validation (only kept for n92, n95 and n96) Changed default toString in ValidationProblem to use the human-friendly error description 9.1.8 - December 2020 (PW-424) Fixed validation of mandatory field 111 (PW-398) Added check for expected values in field 111 (U14 error code) 9.1.7 - December 2020 License check review 9.1.6 - November 2020 Field validation changes in 83J, 86J, 50F and 59F are now parked until SRU2021 (only cat 5 changes are in force in SRU2020) 9.1.5 - November 2020 (PW-413) 564 added qualifier option SRDC in field 17B in sequence D 530 added qualifiers options BYIY and BDEF in field 22 in sequence B 530 added optional fields 90[A,B] and 19A BCAM in sequence C 565 minor fix in conditional qualifier check in field 92K in sequence C 9.1.4 - September 2020 In MTs 300, 305, 306, 320, 330, 340, 341 and 350 added a missing network rule validating the reference number in fields 22 and 22C against the message rate field Added internal BIC validation skip for SWIFT special BIC codes such as: TRCKCHZZ (GPI) and TRGTXEPM (Target) Fixed semantic check 254 to handle 23E field repetitions properly 9.1.3 - September 2020 Minor fix in semantic 204, 209 and 210 checks when the party identifier is only slashes 9.1.2 - August 2020 (PW-325) Added ValidationEngine.Configuration#addRegisteredBic to programmatically register valid BICs not available in the embedded BIC directory (PW-325) Enhanced de BIC directory validation to avoid false error for Test & Training BIC codes (query will match any equivalent production BIC) 9.1.1 - Jun 2020 Removed a false positive deprecation warning when configuring ignored validation codes 9.1.0 - May 2020 SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 9.0.2 - May 2020 Added validation of ISO business header version 2 (head.001.001.02) when found in a message Added a configuration in the ValidationEngine.Configuration to optionally disable ERI validation Added validation for ERI in fields 61, 72, 77A, 79 and 86, when ERI is present and depending on the message type Fixed amount validation when the whole number part is not present 9.0.1 - May 2020 Fixed validation of field 72 in MT760 9.0.0 - May 2020 Validation module extracted to its own jar in the distribution, with its own version from now on 8.0.9 - May 2020 Fixed scheme for 564, typo in MET2 and MET3 qualifiers 8.0.8 - April 2020 Fixed validation of field 50F party line, was accepting up to 34 characters instead of the 35 allowed limit for the field Enabled presence of field 121 in all payment messages (category 1 and 2) Added support to validate restricted ISO20022 for CBPR+ (PW-259) Fixed semantic 157 check, when amount is zero with decimals Fixed schemes for MT537 adn 458, in sequence PENDET required field is 99A and not 99B Enhanced error reporting for semantic checks: 41, 131, 132, 146 and 147 8.0.7 - March 2020 Added support to validate restricted ISO20022 for SIC (Swiss RTGS) MT548: Fixed repetitions of field 94 in sequence C1a1A1 MT537: Fixed structure for D1a1A1 MT537: Fixed sequence B2b where field 98 option EXSE is mandatory Fixed semantic check 256 affecting validation for message 535 and 536 8.0.6 - February 2020 Fixed T96 check in SB-LC function (affecting fields 22 and 22C) where alphanumeric order must give precedence to letters over numbers 8.0.4 - December 2019 Fixed resource bundle for MX messages when retrieved for specific locale Added convenient toJson with preformatted validaiton problem messages, to the ValidationResult DTO Fixed detection of invalid trailing empty lines in MT field values 8.0.3 - September 2019 (PW-185) Replaced custom error codes with SWIFT standard FIN error codes such as Hnn and Tnn Added new validation entry points for MX messages to use specific XSD schemas (useful to validate SEPA messages) Added missing field validations: T14, T49, T70, T75, T88 Fixed validation of conditional qualifier in field 93C in MT566 8.0.2 - August 2019 Fixed validation of conditional qualifier in field 93C in MT566 Fixed bin/validator CLI app that stopped reading input on the first line break Fixed occasional BIC truncation validating large MX messages 8.0.1 - July 2019 Enhanced the configuration to enable ignoring validation problems by specific key, by name or by type Fixed validation of BIC codes in MX when the BIC directory is disabled Fixed BIC not registered error reporting when validating MX messages Fixed semantic check 196 affecting MTs 362 8.0.0 - May 2019 JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Fixed semantic check 157 affecting MTs 320, 330 adn 620 7.10.9 - May 2019 Fixed SB-LC validation, affecting fields 22 and 22C (common reference); added the missing alphabetic sort check in the parties code and location Fixed lines count check in multiline fields with optional party identifier in first line (ex: 58D) 7.10.8 - March 2019 Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Fixed obfuscation to keep directories in jar 7.10.7 - January 2019 Added missing path when reporting invalid country code in MX Fixed duplicated error reporting when validating MX messages Added the XsdRegistry interface to allow overwriting the default schemas when validating MX messages Enhanced the MX error reporting to include the repetitive element index in the validation problem xPath Added support for custom MX validation rules Enhanced validation and error reporting for fields 50F and 59F Minor performance enhancement for validation process with exit on first error Added support in MX validation to optionally ignore XSD ERROR 7.10.6 - November 2018 Added ISO country code validation for CountryCode elements in MX messages Fixed GPI validation to NAK non-GPI messages with fields 121 or 111 Fixed GPI validation to NAK GPI-message with field 111 when the institution is not a GPI member Fixed error description for structure validation problem TOO_BIG Enabled the UETR validation for any message type, it is still mandatory for GPI messages only though (PW-103) Activated the UETR format validation also for output messages (received from SWIFT) Fixed semantic validation 201 affecting MT564 7.10.4 - September 2018 Bugfix validating empty first line in fields value Enhanced error reporting in BIC validation, including details of the BIC subfield where the validation problem is found Enhanced the BIC validation checking the country code within the BIC is a valid ISO country MX: Added BIC validation using the BIC directory (optional by configuration) for elements containing BIC codes MT: Added BIC validation using the BIC directory (optional by configuration) for the sender and receiver address in the headers 7.10.3 - July 2018 Added a specific PARSE_ERROR validation problem to report when the message has an invalid block structure Prevention of IllegalArgumentException when the hyphen is missing in the closing bracket of block 4 Added MX currency validation using ISO currencies from ISOUtils 7.10.2 - July 2018 Fixed spanish description of semantic E45 check Fixed component size check in validation of Field 59F 7.10.1 - May 2018 Added field 434 in block 3 validation 7.10.0 - April 2018 SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) 7.9.8 - April 2018 Enhanced validation of IBAN numbers verifying the check digits and the custom account number per country (BBAN) MT306: message scheme fix, added the missing 57 ADJ optional field at the end of sequence L Minor fixes in semantic validation rule 40 and rule 122 7.9.7 - January 2018 Changes in the distribution package: Command line tools in the bic directory changed from jar files to wrapper scripts Dependencies directory renamed to lib Removed the BUILD id timestamp from the jar files Removed the BaseTestCase class from the public API to avoid Junit dependency Added ValidationProblem#printout to generate a human friendly printout of a validation problem list Updated dependency: org.mozilla 1.7R4 -> org.mozilla 1.7.7.2 7.9.6 - December 2017 Minor fix in semantic27 affecting malformed MT942 7.9.4 - November 2017 JRE requirement backported to Java 1.6 Fixed validation for field 77J: 50x[\u2019CRLF\u201950x]0-69 7.9.3 - October 2017 Added support to validate MX system messages (xsys category) Fixed currency validation (T52) in fields 60F, 62F, 64, 65 and 33B 7.9.2 - August 2017 Fixed T26 validation in fields 13B, 22W, 94B, 95a and 98K MT537 fixed qualifier validation for field 98a in transaction details sequence (C2) MT524 fixed implementation for rule 208 when several LINK sequences are present in the message MT545 and MT547: fixed validation for field set 98a in Trade Details sequence (B), qualifier ESET is mandatory while SETT is optional Fixed error code and message throw by semantic rule 267 Added more details when reporting semantic rule 266 errors. Added IsoUtils singleton to allow customization and exceptions for currency and country codes validation Currency and Country codes validation is now implemented using data from Java Currency and Locale Validation of maximum fraction digits per currency (semantic rule 3) is now implemented using data from Java Currency 7.9.1 - June 2017 Fixed semantic 167 for MT103 plan (not STP and not REMIT) MT801 first loop can be repeated Fixed semantic 282 affecting MT535 Fixed scheme for MT940 field 60[F,M] is now required 7.9 - May 2017 SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX) MT536: fixed false positive semantic 252 check, fixed qualifiers check in field 98a (sequence B1a2) MT575: transaction details sequence C2, field 98 with SETT or TRAD set as optional MT537: fixed false positive semantic 285 check MT576: additional information sequence C set as optional Fixed semantic rule 259 affecting MT517 link sequence check MT569: fixed incorrect definitions in sequence C1a1 (valuation details) MT506, 569 and 575: field 28E mandatory MT513; sequence A added TRAD qualifier to field 22F, sequence B1 (partial fill details) fields 98 and 94 are optional MT513 and 514: fixed letter option from H to F in field 22F:SETR in settlement details 7.8.9 - May 2017 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Fixed validation of fields 72 and 79 of a Rejected/Return message Renamed FieldProblem.REJT_RETN_0n to more specific errors: REJT_RETN_LINE_n, REJT_RETN_REASON_CODE, REJT_RETN_MREF, REJT_RETN_TREF, REJT_RETN_CHGS, REJT_RETN_TEXT Enhanced validation of user block 3, checking all fields are expected for the message type and checking fields order. Fixed NPE in semantic 119 affecting MTs 102 and 103 STP when IBAN component was not present Added a common type ValidationProblemKey implemented by all problem key enumerations Fixed false positive error validating field 59F when multiple address lines (line label 2) are defined Fixed false positive restriction field 37a second component Fixed scheme for MT505, added missing field 98A:AGRE in sequence A1 Enhanced MX validation to allow MX messages with bank-to-bank namespace declaration Fixed false positive semantic 293 validation for MT507 when sequence B1a1 was not present Fixed letter option in scheme for MT506, sequence D (Collateral Details) field 19 A -> B Fixed qualifier in scheme for MT506, sequence D (Collateral Details) DEAL-> COLL Fixed scheme for MT506, sequence B (Summary) field 95 is mandatory and field 19B only mandatory with qualifier COVA Fixed Semantic 82 implementation affecting MT104 and MT107 Fixed false positive case in Semantic 75, affecting MT104 Fixed validation of leading characters, colon (':') not allowed in second and subsequent lines except for fields 77E and 77T Fixed semantic 103 affecting MT535 7.8.8 - March 2017 Added support for nested Document elements when validating MX messages Removed invalid fields following linkages in GENL sequence Cleaner log in semantic rule 3 validation 7.8.7 - December 2016 Added check for validation flag (STP, REMIT, COV) in user header block Fixed missing semantic associations to MTs 700, 705, 707, 710, 720, 730, 732, 734, 740, 742, 747, 750, 752, 754, 756, 768, 768, 769, 800, 801, 802, 824 MT518 fixed fieldset for Field 70 MT330 fixed qualifier in Field 22 MT513 and MT514 Field 11 moved outside previous fieldset MT541 to MT547 Field 90[A,B] changed to fieldset. MT564 fixed fieldset items in Field93[B,C] MT565 to MT567 Sequence D, fixed field 13 MT609 and MT798_763 fixed qualifiers in Field 29 7.8.6 - November 2016 JRE requirement increased to Java 1.7 (only for Integrator SDK and modules, Core still works on 1.5) semantic 175 minnor fix affecting MT104 and MT107 when multiple sequence B are present 7.8.5 - October 2016 Minor fixes in semantic validations: 206 (used in MTs: 103, 564, 566), 279 (used in MTs: 549, 564, 565) MT564: Minor fixes in semantic validations: 199, 211, 224 MT564: field 93 UNBA instead of UMBA MT564: CAOPT sequence, field 92 INTP, missing conditional qualifier NILP MT564: SECMOVE sequence, field 90 PRPP, missing letter option K MT564: SECMOVE sequence, field 92 NEWO, missing letter option M MT564: CASHMOVE sequence, field 92 ESOF, missing letter options F and M MT564: CASHMOVE sequence, field 92 TXIN, missing letter option F MT564: CASHMOVE sequence, field 92 WITL, missing letter option R and its conditional qualifier eval MT564: fixed field 92J subfield ACTU INDI validation MT565: CAINST sequence, field 90 OFFR, missing letter option L MT566: CADETL sequence, field 92 BIDI missing letter option P MT566:CACONF sequence, field 69, removed invalid letter option J MT566: Fixed qualifier in field 13a to allow UNS MT566:SECMOVE sequence, field 90 OFFR, missing letter option L MT566:SECMOVE sequence, field 90 PRPP, missing letter option K MT566:SECMOVE sequence, field 92 NEWO, missing letter option M MT566:SECMOVE sequence, field 92 TAXC, removed invalid letter option K MT566:CASHMOVE sequence, field 92 TXIN, missing letter option F MT566:CASHMOVE sequence, field 90 PRPP, missing letter option K MT566:fixed field 92J subfield ACTU INDI validation MT567: CADETL sequence, field 35B, removed invalid qualifier check SAFE MT567: field19 changed to fieldset 7.8.4 - Oct 2016 Fixed JS expression in schemes for 564, 565, 566 and 620 Important enhancement in MX validation problem reporting, including full XPATH, line and column of errors. Fixed semantic 291 (affecting 540, 541, 544, 545) Fixed semantic 112 (affecting MTs 670 and 671) Fixed semantic 113 (affecting MTs 380, 381, 503, 504, 506, 670, 671) 7.8.3 - Jul 2016 Added support for changed currency in Belorussia from 974 (BYR) to 933 (BYN). Fixed semantic 210 affecting messages 103, 102, 104 and 107 7.8.2 - Jul 2016 Fixed schemes: definition of field 12A in FIA subsequences of MTs 54x Semantic 283 bugfix (used in MTs 307,503,504,505,506,536,537,548,578,586) 2016 June Added field repetition validation in block 3 2016 April Added detection of extra data in message content or blocks when validating a message 2016 February Fixed validation of min and max repetition in fieldsets, when the attributes are set only in the items 2016 January Fixed scheme 307, typo in semantic rules attribute Added API in SchemeField to retrieve qualifiers information from parsed scripting expressions 2015 December Fixed schemes for 600, 601, 604, 605, 606, 607, 608, 609, 620, wrong qualifier for field 26C 2015 November Fixed validation of repetitive sequence in MT940 2015 October Fixed validation for fields 129, 12A, 13B, 20E, 23A, 26N, 26P, 92C and 94D; removed restriction on amount of slashes because components use charset x where slash is allowed Fixed validation for fields 14G, 27A, 27, 28[D,E], 29[L,N], 38[G,H], 39[A,P], 68C, 69C, 70[C,D,E,G], 90F, 92R, 93B, 94E, 94G 95[Q,T,U,V] and 98F; added restriction on amount of slashes 2015 September Fixed scheme for MT567, removed invalid 25D field in sequence A 2015 August Fixed qualifiers validation scripting in xml schemas for MTs: 306, 360, 361, 362, 364, 365, 500, 501, 535, 564, 565, 566 Enhanced validation patterns naming for better consistency 2015 April Enhanced structure validation error reporting, when JS expressions are used to check conditional qualifiers. The new scheme validation rule generates a proper message indicating the expected and found qualifiers instead of a generic fail expression error. 2015 March Bugfix Field validations, new restriction, start of line character cannot be '-'. Bugfix MT535 subsequence B1a, it can be at most one and the scheme was allowing multiple repetitions 2015 February ValidationEngine enhancement in the default scheme to use, detecting automatically if a 102/103 is STP or if a 202/205 is COV Fixed validation for field 22S, was requiring a 35 characters fixed length for component 2, while the correct validation is up to 35 characters (not fixed) Added more restrictive party field validation when a slash is followed by a blank content, affecting fields 42a, 50a, 51a, 52a, 53a, 54a, 55a, 56a, 57a, 58a, 59a, 81a, 82a 83a, 84a, 85a, 86a, 87a, 88a, 89a, 91a, 96a SchemeValidationRule version 2: new version of structure validation for MT, with several enhancements and bug fixes over the previous version. Important performance enhancement in MT structure validation (30% in average, reaching a 60% for some message structures). Important enhancement in structure error reporting, errors are now more specific and detailed with more details. Better error localization, avoiding duplicated error field validation in some situations. Improvement in scheme's scripting validations, isolating script compile errors from unsatisfied logic conditions. Fixed scheme validation for MT300 that was throwing a false problems for some combination of subsequences E, E1 and E1a. 2015 January RuleManager: fixed loading of field rules, that was skipping incorrectly field validation to fields derived from fieldsets 2014 December Better error message format in BaseTestCase Fixed error message for E73 Review of semantic rules 85,86,198 ValidationEngine: Added API to validate from AbstractMT ValidationEngine: Added exclusive API to use when validating messages in strings or files (with swift format, not parsed objects) therefore detecting more error conditions AbstractTagValidationRule: Fixed validation that had a bug in special conditions, Output messages (received from swift) and with sender and receiver within the same institution 2014 November Bugfix in schemas 515, 536 Enhanced MT expression validation reporting, diferenciating invalid expressions, from runtime errors or failed expression evaluation. Bugfix. Fixed expressions in schemes xml for MT576 and MT568, replacing deprecated function call addQuaifiers by qualifier Bugfix. Added validation of T13 rule to MTs n98 2014 September Bugfix. Missing resource bundle for invalid BIC validation problem Added addVariable method to ValidationProblem Bugfix. Fields 95Q and 70C were restricted to maximum 3 lines, while 4 lines are compliant as well. Bugfix. Fixed XML for MT537, field 22H conditional qualifier STAN changed to STAT 2014 July Enhanced structure validation incorporating special field exceptions and required code words (standard PIII Fields Chapter 4) directly into the xml schemes configurations. Affected MTs: 102 STP, 103, 103 STP, 300, 303, 304, 305, 306, 320, 340, 341, 350, 360, 361, 362, 364, 365, 600, 601, 620, 920, 973 Enhanced structure validation error messages to separate unexpected fields problems reporting, from field qualifier problems or expression evaluation problems Enhanced field validation to avoid repetitive checks for empty content and/or empty lines Bugfix. MT306 optional field 12G changed to 12D and added missing field class Bugfix. SchemeXmlReader to properly set fieldset items' qualifiers and letter options when inherited from container fieldset Bugfix. Added null controls to several semantic validations to prevent NPE that would previously arise when applying semantic checks to messages with specific invalid structures Bugfix. Fixed XML for MT540, field 90 changed to fieldset 90 to allow qualifier validation for items Review and code clean of semantic rule 24, 52 SRU 2014. Affected MTs: 300, 304, 305, 306, 340, 341, 360, 361, 380, 381, 502, 506, 508, 509, 513, 514, 515, 518, 527, 530, 536, 537, 538, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 558, 564, 565, 566, 567, 568, 569, 575, 600, 601, 942 Added description and release attributes to Scheme Minor fix in MT300 sequences structure, B1 and B2 inside B, and named D's subsequence as D1 Bugfix. MT300 optional field 17A changed to optional field 77A (field number was wrong) Bugfix. MT514 fixed missing mandatory fields 36B and 35B between end of sequence B1 and start of sequence B2 Bugfix. MT515 fixed field 90[A,B] with qualifier DEAL at sequence C, changed from optional to mandatory (minRepetition was wrong) 2014 May Review and code clean of semantic rule 184 Review and code clean of semantic rule 176 Review and code clean of semantic rule 152, 153, 154 Performance enhancements: execution speed reduced by approx 71% measured in global test suite 2014 April Review and code clean of semantic rule 131, 253, 133, 135 Fixed semantic 116 rule incorrectly interpreting sequence C absence for MT306 2014 March MT564: Added missing option K to field 90 in sequence E2 cash movements Review and code clean of semantic rule 92, 95 Review and code clean of semantic rule 66, 67, 68 ,78, 84, 93 Review and code clean of semantic rule 61, 57, 58, 62 Added validation problems translation to Italian. Bugfix. Fixed invalid check for X in 8th position for logical terminals without A, B, C identifier Bugfix. Fixed Block1 validation, allowing Logical terminal without the A, B, C identifier (11 characters length) Bugfix. Field validation was not accepting 999 as a valid MT number (example field 11R) 2014 February Bugfix. Affected MTs:n92, n95, n96, n98. Fixed isolation of fields copied from original message from the fields of the message being validated Bugfix semantic rule 31 that was throwing false positives when field 79 was included in the appended original message's fields Initial addition of FieldFilter and FieldFilterUtils API Maintenance review of semantic rule 71 Review and code clean of semantic rule 211, 221, 262 Added API to BaseTestCase Review and code clean of semantic rule 209 Review and code clean of semantic rule 201, 202, 206 Bugfix. Affected MTs: 564. Fixed semantic rule 71 that was throwing IOB exceptions for some valid combinations of fields 93B Bugfix. Affected MTs: 568, 569, 574, 575, 576, 578, 586, 670, 671. Fixed xml schemes, changing the invalid scripting method conditionalQualifiers to conditionalQualifier Review and code clean of semantic rule 203, 206, 209, 221 Review and code clean of semantic rule 201, 202 Bugfix. Affected MTs: 305. Fixed false positive missing field errors when the message ends with nested optional subsequences with inner mandatory fields Review and code clean of semantic rule 192, 72, 199 Review and code clean of semantic rule 71 Review and code clean of semantic rules impacting MT305 Added a code generation tool that can be run from command line to create custom version of Field and MT classes Added a command line application to use the messages validation in standalone mode, validating messages from file system 2014 January Added validation rules for fields belonging to system messages (i.e. 451) Adding constants to Literals class to avoid usage of hardcoded strings and cleaner code with static imports Bugfix. Affected MTs: 207. Fixed maximum repetitions of sequence B from 1 to unlimited Maintenance(Review and performance updates) semantic rule #167, #54, #55 Maintenance(Review and performance updates) semantic rule #161 Maintenance(Review and performance updates) semantic rule #168, #246, #254 Added filter() to AbstractSemanticValidationRule Maintenance(Review and performance updates) semantic rule #162, #166 Added BaseTestCase.assertValid(String) Fixed issue in semantic rule 154 which did not consider properly B sequences Maintenance(Review and performance updates) semantic rule #160, #164 2014-01-15 Fixed issue in semantic rule 77 affecting MTs 730, 768 and 769 2013 October Maintenance(Review and performance updates) semantic rule #44, #45, #46, $47, #48, #51, #53 Maintenance(Review and performance updates) semantic rule #106, #108, #30, #40, #42 Review and performance updates on S102 Refactored max msg length validation to use enum in structure problem for reporting errors Review and performance updates on S79 2013 September SRU 2013 update Fixed incomplete validation for field 77E 2013 March Bugfix: fixed typo at field 22H in MT380, BUYI->BUY1 2012 June Added API to specify locale on ValidationProblem.getMessage method","title":"Prowide Integrator Validation"},{"location":"release-notes/changelog-validation/#prowide-integrator-validation-changelog","text":"","title":"Prowide Integrator Validation - CHANGELOG"},{"location":"release-notes/changelog-validation/#9424-june-2024","text":"(PW-1845) Added an option in the RITS (HVCS) validation engine to opt-in strict mode validation (rules not checked by the HVCS portal)","title":"9.4.24 - June 2024"},{"location":"release-notes/changelog-validation/#9423-may-2024","text":"(PW-1845) Added new RITS (HVCS) validator for pacs.004","title":"9.4.23 - May 2024"},{"location":"release-notes/changelog-validation/#9422-april-2024","text":"(PW-1809) Added a new optional SchemaCache to the validation engine configuration to optimize the MX validation process","title":"9.4.22 - April 2024"},{"location":"release-notes/changelog-validation/#9421-april-2024","text":"(PW-1842) Remove System.exit() call from deprecated class to avoid false positive vulnerability report","title":"9.4.21 - April 2024"},{"location":"release-notes/changelog-validation/#9420-february-2024","text":"(PW-1761) Fixed error message for E92 on MT 545 and 547 Replaced generic KNN errors with specific codeword errors for designated fields such as T03, T04, T20, T35, etc...","title":"9.4.20 - February 2024"},{"location":"release-notes/changelog-validation/#9419-january-2024","text":"(PW-1752) Added new API method 'validateTag' in order to allow to validate singe tags/fields without the need to build a full message (PW-1743) Remove usage of deprecated SafeXMLUtils methods Added field validation rule for pattern used in MT 097 field 109","title":"9.4.19 - January 2024"},{"location":"release-notes/changelog-validation/#9418-january-2024","text":"(PW-1739) Modified the validation of field 23 in order to match the specification for MT102/MT103/MT305/MT601","title":"9.4.18 - January 2024"},{"location":"release-notes/changelog-validation/#9417-january-2024","text":"Disabled 'Missing checksum field CHK (Z04)' block 5 validation because the checksum algorithm is proprietary by SWIFT and not available in the library API","title":"9.4.17 - January 2024"},{"location":"release-notes/changelog-validation/#9416-december-2023","text":"(PW-1732) Enhanced the semantic 292 to also report the error for MT541 when the sequence E3 is missing","title":"9.4.16 - December 2023"},{"location":"release-notes/changelog-validation/#9415-december-2023","text":"(PW-1666) Updated T13 validation logic in order to avoid false positives when validating MTs n92/n95/n96","title":"9.4.15 - December 2023"},{"location":"release-notes/changelog-validation/#9414-december-2023","text":"(PW-1708) Fix concurrency issue with BICDirectory in semantic 257 and 5 implementations Added missing implementation for SCORE UG rules in MT798<700>","title":"9.4.14 - December 2023"},{"location":"release-notes/changelog-validation/#9413-november-2023","text":"(PW-1697) Changed field 29O validation to be compatible with the field model changes","title":"9.4.13 - November 2023"},{"location":"release-notes/changelog-validation/#9412-november-2023","text":"(PW-1691) CBPR+: NPE fix in the validation of the specific business service for each message type Minor fix in the validation of field 29O","title":"9.4.12 - November 2023"},{"location":"release-notes/changelog-validation/#9411-november-2023","text":"(PW-1691) CBPR+ fixed validation of specific business service for each message type (version could vary depending on the specific message type)","title":"9.4.11 - November 2023"},{"location":"release-notes/changelog-validation/#9410-november-2023","text":"(PW-1675) Fixed specific validations for SCORE messages in SRU2023","title":"9.4.10 - November 2023"},{"location":"release-notes/changelog-validation/#949-october-2023","text":"Updated the default ISO 20022 external code set XSD resource to the 2Q2023_ExternalCodeSets_v1.xsd release","title":"9.4.9 - October 2023"},{"location":"release-notes/changelog-validation/#948-october-2023","text":"MT370 and MT670 messages are now verified to have a size less than 10,000","title":"9.4.8 - October 2023"},{"location":"release-notes/changelog-validation/#947-october-2023","text":"(PW-1653) MT671 message is now verified to have a size less than 10,000","title":"9.4.7 - October 2023"},{"location":"release-notes/changelog-validation/#946-september-2023","text":"(PW-1613) fixed validation of field 44J narrative to enable 65 characters after the mandatory starting slash","title":"9.4.6 - September 2023"},{"location":"release-notes/changelog-validation/#945-september-2023","text":"(PW-1628) fixed validation of new Field 44A, 44B, 44E and 44F enabling multilines since they now use character 'z'","title":"9.4.5 - September 2023"},{"location":"release-notes/changelog-validation/#944-september-2023","text":"(PW-1478) fixed validation of new Field 44J","title":"9.4.4 - September 2023"},{"location":"release-notes/changelog-validation/#943-september-2023","text":"(PW-1480) More accurate implementation of semantic rule C25 (MTn92): field 79 or at least any fields from the original message (or both) must be present","title":"9.4.3 - September 2023"},{"location":"release-notes/changelog-validation/#942-august-2023","text":"(PW-1472) Fixed validation of 23X in MT767 (PW-1431) CBPR+: Implemented UG validation for CBPR+ 2023 messages (PW-1448) Fixed size validation for field 24G (PW-1431) CBPR+: Implemented UG validation for CBPR+ 2023 messages Added CROSS RULES validation for new CBPR+ 2023 messages","title":"9.4.2 - August 2023"},{"location":"release-notes/changelog-validation/#941-june-2023","text":"ValidationEngine add explicit API to validate the MX Business Application Header version 3","title":"9.4.1 - June 2023"},{"location":"release-notes/changelog-validation/#940-may-2023","text":"SWIFT Standard release update 2023 (live 19 November 2023) Yearly revision of deprecation phase (see https://dev.prowidesoftware.com/SRU2022/getting-started/deprecation/)","title":"9.4.0 - May 2023"},{"location":"release-notes/changelog-validation/#9318-june-2023","text":"Fixed field 79 /REJT/ or /RETN/ validation of lines containing /TEXT/ narrative","title":"9.3.18 - June 2023"},{"location":"release-notes/changelog-validation/#9317-may-2023","text":"(PW-1373) Minor fix in semantic validation for MT 798<720>","title":"9.3.17 - May 2023"},{"location":"release-notes/changelog-validation/#9316-may-2023","text":"(PW-1377) Fixed NPE validating semantic rule 2 in MT 798_750","title":"9.3.16 - May 2023"},{"location":"release-notes/changelog-validation/#9315-may-2023","text":"(PW-1373) MT SCORE 798<720>: Fixed codewords and rules for fields 40B and 41a (PW-1367) Added MT SCORE 798 sub-message types: 722_LC_C2B, 726_LC_C2B, 735_LC_C2B, 770_LC_C2B, 772_LC_C2B (PW-1359) Added missing T47 problem properties","title":"9.3.15 - May 2023"},{"location":"release-notes/changelog-validation/#9314-april-2023","text":"MX validation: Added a general rule to check the maximum bytes allowed for the message","title":"9.3.14 - April 2023"},{"location":"release-notes/changelog-validation/#9313-february-2023","text":"(PW-1206) Added message model for the MT SCORE subtypes 707/708/710/711/720/721/732/734/750 (PW-1198) Added validation for MT SCORE subtype 767 - Sequence B optional for 22A ISCA or ICCA","title":"9.3.13 - February 2023"},{"location":"release-notes/changelog-validation/#9312-january-2023","text":"(PW-1154) Enhanced block 2 input validation; when priority is \"S\" (System) delivery monitoring and obsolesce period are not allowed (PW-1150) Added validation for MT SCORE subtypes 731/736/748/753/755/757/771/773","title":"9.3.12 - January 2023"},{"location":"release-notes/changelog-validation/#9311-december-2022","text":"Removed the org.mozilla:rhino dependency","title":"9.3.11 - December 2022"},{"location":"release-notes/changelog-validation/#9310-november-2022","text":"Minor backward compatibility fix in the ValidationConfiguration IBICDirectory initialization","title":"9.3.10 - November 2022"},{"location":"release-notes/changelog-validation/#939-november-2022","text":"Updated Apache Commons Text dependency to 1.10 to fix reported CVE (PW-1097) Fixed BIC validation against directory in CBPR+ messages (PW-1090) Enhanced validation of field 11T in SCORE messages, with specific check for the allowed sub-message type (PW-1085) Moved the custom BIC directory implementation setter from the SDK singleton configuration to the ValidationConfiguration","title":"9.3.9 - November 2022"},{"location":"release-notes/changelog-validation/#938-october-2022","text":"Code enhancements review","title":"9.3.8 - October 2022"},{"location":"release-notes/changelog-validation/#937-october-2022","text":"(PW-1074) MT568: fixed typo in qualifier name \"PTNI\" (PW-1071) MX cross-element rules are not applied when validating a custom schema, such as SIC4 (PW-1064) Fallback option to system classloader in resource loading SRU2022 update review: MT540 Removed field 99C SRU2022 update review: MT548 Added field 98C::SCTS SRU2022 update review: Field 35C changed validation to","title":"9.3.7 - October 2022"},{"location":"release-notes/changelog-validation/#936-september-2022","text":"Added support for MUG validations (CLSB and AU/PDS)","title":"9.3.6 - September 2022"},{"location":"release-notes/changelog-validation/#935-september-2022","text":"MT structure validation: enhanced report of missing required fields, adding the path of sequences when applicable MT structure validation: enhanced report of unexpected fields, when the possible cause is the fields ordering","title":"9.3.5 - September 2022"},{"location":"release-notes/changelog-validation/#934-august-2022","text":"Permanently replaced the legacy ValidationEngine.Configuration inner class by the ValidationConfiguration MT structure validation refactor to decommission the need for the Rhino dependency","title":"9.3.4 - August 2022"},{"location":"release-notes/changelog-validation/#933-august-2022","text":"(PW-1015) Added validation for sub-message types 700, 701 and 774 (SCORE) (PW-1007) Changed the AppHdr message definition against Document namespace validation to be more flexible, allowing subtypes such as \"CORE\"","title":"9.3.3 - August 2022"},{"location":"release-notes/changelog-validation/#932-august-2022","text":"PW-1007: Changed the AppHdr message definition against Document namespace validation to be more flexible, allowing subtypes such as \"CORE\" Implemented cross-element rules for pacs.004.001.10 and 11 Implemented cross-element rules for pain.001.001.10 and 11 Implemented cross-element rules for pain.002.001.10, 11 and 12 Implemented cross-element rules for camt.029.001.10 and 11 Added internal loops API to MTs: 110, 201, 203, 210, 410, 412, 420, 422, 450, 456, 604, 605, 801, 920, 973 (PW-968) Field 72: fixed validation of optional text after INSTR codes, that cannot be a complete set of blanks","title":"9.3.2 - August 2022"},{"location":"release-notes/changelog-validation/#931-july-2022","text":"(PW-968) Field 72: fixed validation of optional text after INSTR codes, that cannot be a complete set of blanks (PW-963) Fixes message length validation rule to compute also CRLF characters (PW-931) Added a field check for unexpected slash separator, in fields having an optional second component separated by slash (PW-867) Enhanced validation of party fields starting with /C/ or /D/ to avoid false negative errors on /D /C prefixes in the account Fixed SRU2022 changes in semantic rules 258 and 267 MT semantic validations minor fixes and enhancements Implemented cross-element rules for newer versions of camt.052 Implemented cross-element rules for newer versions of camt.053 Implemented cross-element rules for newer versions of camt.054 Implemented cross-element rules for newer versions of camt.056 Implemented cross-element rules for newer versions of camt.057 Implemented cross-element rules for newer versions of camt.060 Implemented cross-element rules for newer versions of pacs.010 Implemented cross-element rules for: Pacs.008 v9 & v10 (standard and STP), pacs.009 v9 & v10","title":"9.3.1 - July 2022"},{"location":"release-notes/changelog-validation/#930-may-2022","text":"SWIFT Standard release update 2022 (live 20 November 2022) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.3.0 - May 2022"},{"location":"release-notes/changelog-validation/#9231-may-2022","text":"(PW-813) Internal enhancement to fix CVE Deprecation API review","title":"9.2.31 - May 2022"},{"location":"release-notes/changelog-validation/#9230-may-2022","text":"MT semantic rules review and minor fixes MX cross-element checks review and enhancements","title":"9.2.30 - May 2022"},{"location":"release-notes/changelog-validation/#9229-may-2022","text":"MX cross-element checks review and enhancements","title":"9.2.29 - May 2022"},{"location":"release-notes/changelog-validation/#9228-april-2022","text":"Fixed MX cross-element checks Changed the ValidationResult to have the valid flag as transient field, set dynamically depending on the problems list size Added missing validations for CBPR+ pacs.009","title":"9.2.28 - April 2022"},{"location":"release-notes/changelog-validation/#9227-april-2022","text":"CBPR+ UG validation fixes","title":"9.2.27 - April 2022"},{"location":"release-notes/changelog-validation/#9226-march-2022","text":"(PW-882) SCORE 798_760 fixed validation of sequence B which is optional if purpose of message is ICCO or ISCO MT104: Fixed validation problem description in semantic rule 96","title":"9.2.26 - March 2022"},{"location":"release-notes/changelog-validation/#9225-march-2022","text":"CBPR+ validation: apply schema from Document namespace when AppHdr message type does not match pacs.002.001.10: Implemented cross-element rules, and CBPR+ UG rules pain.002.001.10: Implemented cross-element rules, and CBPR+ UG rules","title":"9.2.25 - March 2022"},{"location":"release-notes/changelog-validation/#9224-march-2022","text":"pacs.010.001.03: Implemented cross-element rules, and CBPR+ UG rules camt.060.001.05: Implemented cross-element rules, and CBPR+ UG rules pain.001.001.09: Implemented cross-element rules, and CBPR+ UG rules","title":"9.2.24 - March 2022"},{"location":"release-notes/changelog-validation/#9223-march-2022","text":"Fixed error description in MX validation (cross element checks and CBPR+ rules) MX cross element validation fixes (X00420)","title":"9.2.23 - March 2022"},{"location":"release-notes/changelog-validation/#9222-march-2022","text":"Enhanced the CBPR+ AppHdr validation with constraints from CBPR+ restricted BAH v2 schema","title":"9.2.22 - March 2022"},{"location":"release-notes/changelog-validation/#9221-march-2022","text":"(PW-861) Fixed validation of fields 23X, 21H, 77B (MT734) and 98K that was too strict; slash character is allowed in the component using x character set","title":"9.2.21 - March 2022"},{"location":"release-notes/changelog-validation/#9220-february-2022","text":"(PW-856) GPI: Fixed misleading error description in field 111 validation (PW-835) GPI: Field 111 is optional in MT199 even for GPI members Fixed inconsistency in the ValidationResult valid flag returned by the CbprValidationEngine Fixed MX cross-element validations when too elements cannot be present together, but may both be absent","title":"9.2.20 - February 2022"},{"location":"release-notes/changelog-validation/#9219-february-2022","text":"Updated the default ISO 20022 external code set XSD to the February 2022 update camt.029.001.09: Implemented cross-element rules, and CBPR+ UG rules camt.052.001.08: Implemented cross-element rules, and CBPR+ UG rules camt.053._001.08: Implemented cross-element rules, and CBPR+ UG rules camt.056.001.08: Implemented cross-element rules, and CBPR+ UG rules camt.057.001.06: Implemented cross-element rules, and CBPR+ UG rules pacs.002.001.10: Implemented cross-element rules, and CBPR+ UG rules pacs.004.001.09: Implemented cross-element rules, and CBPR+ UG rules Completed UG rules for CBPR+ pacs.008 and pacs.009 variants (COV, STP, ADV)","title":"9.2.19 - February 2022"},{"location":"release-notes/changelog-validation/#9218-february-2022","text":"(PW-837) In MT message length validation, remove line CRLF when computing the message size","title":"9.2.18 - February 2022"},{"location":"release-notes/changelog-validation/#9217-january-2022","text":"(PW-835) Fixed validation of GPI field 111 (block3) expected values per message type","title":"9.2.17 - January 2022"},{"location":"release-notes/changelog-validation/#9216-january-2022","text":"(PW-833) Fixed mandatory field 77E in MTn98 Added UG implementation for CBPR+ pacs.008 STP and pacs.009 ADV/COV","title":"9.2.16 - January 2022"},{"location":"release-notes/changelog-validation/#9215-january-2022","text":"SCORE messages semantic validations review","title":"9.2.15 - January 2022"},{"location":"release-notes/changelog-validation/#9214-january-2022","text":"(PW-819-820) SCORE message MT798_760 validation fixes Added UG implementation for CBPR+ camt.054 Implemented cross-element rules for camt.054.001.08 Added validation for MX match between AppHdr message identifier and Document namespace","title":"9.2.14 - January 2022"},{"location":"release-notes/changelog-validation/#9213-january-2022","text":"(PW-815) Fixed validation of field 12H (SCORE) where narrative is optional MT530 validation: Fixed semantic 237 rule, where subsequence C1 is repetitive Added UG implementation for CBPR+ pacs.009 Implemented cross-element rules for pacs.009.001.08","title":"9.2.13 - January 2022"},{"location":"release-notes/changelog-validation/#9212-december-2021","text":"Added a specific CbprValidationEngine class to validate CBPR+ messages Added UG implementation for CBPR+ pacs.008 Implemented cross-element rules for pacs.008.001.08 Added com.prowidesoftware.integrator.validation as automatic module name in the MANIFEST for JPMS support","title":"9.2.12 - December 2021"},{"location":"release-notes/changelog-validation/#9211-december-2021","text":"(PW-799) fixed validation of semantic rule 199 in MT564","title":"9.2.11 - December 2021"},{"location":"release-notes/changelog-validation/#9210-december-2021","text":"(PW-780) Added ValidationConfiguration#setGpiMember to override the general static SdkConfiguration#setGpiMember (PW-764) Fixed error description in field 119 (block 3) validation","title":"9.2.10 - December 2021"},{"location":"release-notes/changelog-validation/#929-november-2021","text":"(PW-772) Enable empty lines in MT568 field 70F as it is exceptionally allowed in the ISO 15022 usage guidelines In Mx IBAN validation added specific error code D00003","title":"9.2.9 - November 2021"},{"location":"release-notes/changelog-validation/#928-november-2021","text":"(PW-764) Reviewed validation of field 119 (block 3) (PW-703) Clearer validation results for MT block 2 with invalid identifier Added IBAN validation (including local account format) for MX elements containing IBAN numbers Added optional IBAN validation for MT messages, for specific fields where IBAN validation is explicitly requested by configuration MX validation: renamed proprietary error codes for invalid currency and country codes by standard codes D00004 and D00005 Fixed validation of letter options in B/98a","title":"9.2.8 - November 2021"},{"location":"release-notes/changelog-validation/#927-october-2021","text":"Added validation of block 2 Output (only Input was validated before, while Output was ignored) Fixed validation of value for Field 26A ( )","title":"9.2.7 - October 2021"},{"location":"release-notes/changelog-validation/#926-october-2021","text":"(PW-705) Added validation of mandatory CHK in block 5 when the trailer block is present (PW-703) More verbose MT headers validation (PW-677) MT670, MT671: fixed implementation of semantic check 112 (D12)","title":"9.2.6 - October 2021"},{"location":"release-notes/changelog-validation/#924-september-2021","text":"(PW-664) Parser enhancement to detect LF before block identifier as validation problem (not exception)","title":"9.2.4 - September 2021"},{"location":"release-notes/changelog-validation/#923-august-2021","text":"Added german translation for validation problems","title":"9.2.3 - August 2021"},{"location":"release-notes/changelog-validation/#922-august-2021","text":"(PW-599) MT564: Minor scheme fix, 92a TAXR and WITL can be repeated in CASHMOVE (E2) MT548: Minor scheme fix, added letter option \"C\" in field \"98C:SCTS\" in sequence \"C1a1B1\" (PW-578) Fixed SAX logging with misleading parse errors","title":"9.2.2 - August 2021"},{"location":"release-notes/changelog-validation/#921-june-2021","text":"(PW-536) Replaced deprecated API in the MX validation (PW-536) Fixed misleading typo in semantic E94 error description (PW-517) Removed the actual licensed BICs information from the unlicensed error description in the validator","title":"9.2.1 - June 2021"},{"location":"release-notes/changelog-validation/#920-may-2021","text":"SWIFT Standard release update 2021 (live 21 November 2021) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) More accurate structure problems reporting, with a customizable lookahead for sequence resynchronization after a field partial match Enhanced unexpected fields problem reporting, in some situations it used to trigger also misleading errors about the unexpected field repetitions","title":"9.2.0 - May 2021"},{"location":"release-notes/changelog-validation/#9116-april-2021","text":"Added support for ISO 20022 external code set validations Externalized the validation engine configuration into a ValidationConfiguration class (PW-517) Removed the actual licensed BICs information from the unlicensed error description in the validator","title":"9.1.16 - April 2021"},{"location":"release-notes/changelog-validation/#9115-april-2021","text":"(PW-460) Divided the internal schemas package into packages by category to allow trimming the jar by use","title":"9.1.15 - April 2021"},{"location":"release-notes/changelog-validation/#9114-april-2021","text":"(PW-500) Fixed validation of qualifiers when the component is optional Fixed qualifier error reporting in fields 41A and 41D Replaced generic error code KNN with specific code for each field, such as K41, K23, K92","title":"9.1.14 - April 2021"},{"location":"release-notes/changelog-validation/#9113-april-2021","text":"(PW-508) Fixed validator pattern in field 98K","title":"9.1.13 - April 2021"},{"location":"release-notes/changelog-validation/#9112-april-2021","text":"Enhanced MT structure error detection and reporting (missing and unexpected fields) Fixed validation of fields 12 and 27A in MT SCORE messages","title":"9.1.12 - April 2021"},{"location":"release-notes/changelog-validation/#9111-march-2021","text":"Added semantic validation for available SCORE messages (PW-499) Fixed schemes for MT513, MT564 and MT566: invalid qualifier in field 69D","title":"9.1.11 - March 2021"},{"location":"release-notes/changelog-validation/#9110-march-2021","text":"(PW-494) Fixed schemes for MT565 (sequence B can be repeated up to 1) and MT568 (sequence B is optional, not mandatory)","title":"9.1.10 - March 2021"},{"location":"release-notes/changelog-validation/#919-march-2021","text":"(PW-493) Fixed scheme for MT671, missing :22H::PRCD//PREF in Other Details sequence Added mtInSequenceResyncLookAhead parameter in the ValidationEngine#Configuration to control the error reporting accuracy Added mtEnhancedRepetitionProblemReportingMode parameter in the ValidationEngine#Configuration to switch off redundant field repetition related errors Removed T13 rule from MTn98 proprietary messages validation (only kept for n92, n95 and n96) Changed default toString in ValidationProblem to use the human-friendly error description","title":"9.1.9 - March 2021"},{"location":"release-notes/changelog-validation/#918-december-2020","text":"(PW-424) Fixed validation of mandatory field 111 (PW-398) Added check for expected values in field 111 (U14 error code)","title":"9.1.8 - December 2020"},{"location":"release-notes/changelog-validation/#917-december-2020","text":"License check review","title":"9.1.7 - December 2020"},{"location":"release-notes/changelog-validation/#916-november-2020","text":"Field validation changes in 83J, 86J, 50F and 59F are now parked until SRU2021 (only cat 5 changes are in force in SRU2020)","title":"9.1.6 - November 2020"},{"location":"release-notes/changelog-validation/#915-november-2020","text":"(PW-413) 564 added qualifier option SRDC in field 17B in sequence D 530 added qualifiers options BYIY and BDEF in field 22 in sequence B 530 added optional fields 90[A,B] and 19A BCAM in sequence C 565 minor fix in conditional qualifier check in field 92K in sequence C","title":"9.1.5 - November 2020"},{"location":"release-notes/changelog-validation/#914-september-2020","text":"In MTs 300, 305, 306, 320, 330, 340, 341 and 350 added a missing network rule validating the reference number in fields 22 and 22C against the message rate field Added internal BIC validation skip for SWIFT special BIC codes such as: TRCKCHZZ (GPI) and TRGTXEPM (Target) Fixed semantic check 254 to handle 23E field repetitions properly","title":"9.1.4 - September 2020"},{"location":"release-notes/changelog-validation/#913-september-2020","text":"Minor fix in semantic 204, 209 and 210 checks when the party identifier is only slashes","title":"9.1.3 - September 2020"},{"location":"release-notes/changelog-validation/#912-august-2020","text":"(PW-325) Added ValidationEngine.Configuration#addRegisteredBic to programmatically register valid BICs not available in the embedded BIC directory (PW-325) Enhanced de BIC directory validation to avoid false error for Test & Training BIC codes (query will match any equivalent production BIC)","title":"9.1.2 - August 2020"},{"location":"release-notes/changelog-validation/#911-jun-2020","text":"Removed a false positive deprecation warning when configuring ignored validation codes","title":"9.1.1 - Jun 2020"},{"location":"release-notes/changelog-validation/#910-may-2020","text":"SWIFT Standard release update 2020 (live 22 November 2020) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"9.1.0 - May 2020"},{"location":"release-notes/changelog-validation/#902-may-2020","text":"Added validation of ISO business header version 2 (head.001.001.02) when found in a message Added a configuration in the ValidationEngine.Configuration to optionally disable ERI validation Added validation for ERI in fields 61, 72, 77A, 79 and 86, when ERI is present and depending on the message type Fixed amount validation when the whole number part is not present","title":"9.0.2 - May 2020"},{"location":"release-notes/changelog-validation/#901-may-2020","text":"Fixed validation of field 72 in MT760","title":"9.0.1 - May 2020"},{"location":"release-notes/changelog-validation/#900-may-2020","text":"Validation module extracted to its own jar in the distribution, with its own version from now on","title":"9.0.0 - May 2020"},{"location":"release-notes/changelog-validation/#809-may-2020","text":"Fixed scheme for 564, typo in MET2 and MET3 qualifiers","title":"8.0.9 - May 2020"},{"location":"release-notes/changelog-validation/#808-april-2020","text":"Fixed validation of field 50F party line, was accepting up to 34 characters instead of the 35 allowed limit for the field Enabled presence of field 121 in all payment messages (category 1 and 2) Added support to validate restricted ISO20022 for CBPR+ (PW-259) Fixed semantic 157 check, when amount is zero with decimals Fixed schemes for MT537 adn 458, in sequence PENDET required field is 99A and not 99B Enhanced error reporting for semantic checks: 41, 131, 132, 146 and 147","title":"8.0.8 - April 2020"},{"location":"release-notes/changelog-validation/#807-march-2020","text":"Added support to validate restricted ISO20022 for SIC (Swiss RTGS) MT548: Fixed repetitions of field 94 in sequence C1a1A1 MT537: Fixed structure for D1a1A1 MT537: Fixed sequence B2b where field 98 option EXSE is mandatory Fixed semantic check 256 affecting validation for message 535 and 536","title":"8.0.7 - March 2020"},{"location":"release-notes/changelog-validation/#806-february-2020","text":"Fixed T96 check in SB-LC function (affecting fields 22 and 22C) where alphanumeric order must give precedence to letters over numbers","title":"8.0.6 - February 2020"},{"location":"release-notes/changelog-validation/#804-december-2019","text":"Fixed resource bundle for MX messages when retrieved for specific locale Added convenient toJson with preformatted validaiton problem messages, to the ValidationResult DTO Fixed detection of invalid trailing empty lines in MT field values","title":"8.0.4 - December 2019"},{"location":"release-notes/changelog-validation/#803-september-2019","text":"(PW-185) Replaced custom error codes with SWIFT standard FIN error codes such as Hnn and Tnn Added new validation entry points for MX messages to use specific XSD schemas (useful to validate SEPA messages) Added missing field validations: T14, T49, T70, T75, T88 Fixed validation of conditional qualifier in field 93C in MT566","title":"8.0.3 - September 2019"},{"location":"release-notes/changelog-validation/#802-august-2019","text":"Fixed validation of conditional qualifier in field 93C in MT566 Fixed bin/validator CLI app that stopped reading input on the first line break Fixed occasional BIC truncation validating large MX messages","title":"8.0.2 - August 2019"},{"location":"release-notes/changelog-validation/#801-july-2019","text":"Enhanced the configuration to enable ignoring validation problems by specific key, by name or by type Fixed validation of BIC codes in MX when the BIC directory is disabled Fixed BIC not registered error reporting when validating MX messages Fixed semantic check 196 affecting MTs 362","title":"8.0.1 - July 2019"},{"location":"release-notes/changelog-validation/#800-may-2019","text":"JRE requirement increased to Java 1.8 SWIFT Standard release update 2019 (live 17 November 2019) Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Fixed semantic check 157 affecting MTs 320, 330 adn 620","title":"8.0.0 - May 2019"},{"location":"release-notes/changelog-validation/#7109-may-2019","text":"Fixed SB-LC validation, affecting fields 22 and 22C (common reference); added the missing alphabetic sort check in the parties code and location Fixed lines count check in multiline fields with optional party identifier in first line (ex: 58D)","title":"7.10.9 - May 2019"},{"location":"release-notes/changelog-validation/#7108-march-2019","text":"Updated dependencies: apache-commons-lang 3.7 -> 3.8.1 Updated dependencies: apache-text 1.3 -> 1.6 Fixed obfuscation to keep directories in jar","title":"7.10.8 - March 2019"},{"location":"release-notes/changelog-validation/#7107-january-2019","text":"Added missing path when reporting invalid country code in MX Fixed duplicated error reporting when validating MX messages Added the XsdRegistry interface to allow overwriting the default schemas when validating MX messages Enhanced the MX error reporting to include the repetitive element index in the validation problem xPath Added support for custom MX validation rules Enhanced validation and error reporting for fields 50F and 59F Minor performance enhancement for validation process with exit on first error Added support in MX validation to optionally ignore XSD ERROR","title":"7.10.7 - January 2019"},{"location":"release-notes/changelog-validation/#7106-november-2018","text":"Added ISO country code validation for CountryCode elements in MX messages Fixed GPI validation to NAK non-GPI messages with fields 121 or 111 Fixed GPI validation to NAK GPI-message with field 111 when the institution is not a GPI member Fixed error description for structure validation problem TOO_BIG Enabled the UETR validation for any message type, it is still mandatory for GPI messages only though (PW-103) Activated the UETR format validation also for output messages (received from SWIFT) Fixed semantic validation 201 affecting MT564","title":"7.10.6 - November 2018"},{"location":"release-notes/changelog-validation/#7104-september-2018","text":"Bugfix validating empty first line in fields value Enhanced error reporting in BIC validation, including details of the BIC subfield where the validation problem is found Enhanced the BIC validation checking the country code within the BIC is a valid ISO country MX: Added BIC validation using the BIC directory (optional by configuration) for elements containing BIC codes MT: Added BIC validation using the BIC directory (optional by configuration) for the sender and receiver address in the headers","title":"7.10.4 - September 2018"},{"location":"release-notes/changelog-validation/#7103-july-2018","text":"Added a specific PARSE_ERROR validation problem to report when the message has an invalid block structure Prevention of IllegalArgumentException when the hyphen is missing in the closing bracket of block 4 Added MX currency validation using ISO currencies from ISOUtils","title":"7.10.3 - July 2018"},{"location":"release-notes/changelog-validation/#7102-july-2018","text":"Fixed spanish description of semantic E45 check Fixed component size check in validation of Field 59F","title":"7.10.2 - July 2018"},{"location":"release-notes/changelog-validation/#7101-may-2018","text":"Added field 434 in block 3 validation","title":"7.10.1 - May 2018"},{"location":"release-notes/changelog-validation/#7100-april-2018","text":"SWIFT Standard release update 2018 JRE requirement increased to Java 1.7 Dependencies: updated apache commons-lang from 2.6 to 3.7 Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy)","title":"7.10.0 - April 2018"},{"location":"release-notes/changelog-validation/#798-april-2018","text":"Enhanced validation of IBAN numbers verifying the check digits and the custom account number per country (BBAN) MT306: message scheme fix, added the missing 57 ADJ optional field at the end of sequence L Minor fixes in semantic validation rule 40 and rule 122","title":"7.9.8 - April 2018"},{"location":"release-notes/changelog-validation/#797-january-2018","text":"Changes in the distribution package: Command line tools in the bic directory changed from jar files to wrapper scripts Dependencies directory renamed to lib Removed the BUILD id timestamp from the jar files Removed the BaseTestCase class from the public API to avoid Junit dependency Added ValidationProblem#printout to generate a human friendly printout of a validation problem list Updated dependency: org.mozilla 1.7R4 -> org.mozilla 1.7.7.2","title":"7.9.7 - January 2018"},{"location":"release-notes/changelog-validation/#796-december-2017","text":"Minor fix in semantic27 affecting malformed MT942","title":"7.9.6 - December 2017"},{"location":"release-notes/changelog-validation/#794-november-2017","text":"JRE requirement backported to Java 1.6 Fixed validation for field 77J: 50x[\u2019CRLF\u201950x]0-69","title":"7.9.4 - November 2017"},{"location":"release-notes/changelog-validation/#793-october-2017","text":"Added support to validate MX system messages (xsys category) Fixed currency validation (T52) in fields 60F, 62F, 64, 65 and 33B","title":"7.9.3 - October 2017"},{"location":"release-notes/changelog-validation/#792-august-2017","text":"Fixed T26 validation in fields 13B, 22W, 94B, 95a and 98K MT537 fixed qualifier validation for field 98a in transaction details sequence (C2) MT524 fixed implementation for rule 208 when several LINK sequences are present in the message MT545 and MT547: fixed validation for field set 98a in Trade Details sequence (B), qualifier ESET is mandatory while SETT is optional Fixed error code and message throw by semantic rule 267 Added more details when reporting semantic rule 266 errors. Added IsoUtils singleton to allow customization and exceptions for currency and country codes validation Currency and Country codes validation is now implemented using data from Java Currency and Locale Validation of maximum fraction digits per currency (semantic rule 3) is now implemented using data from Java Currency","title":"7.9.2 - August 2017"},{"location":"release-notes/changelog-validation/#791-june-2017","text":"Fixed semantic 167 for MT103 plan (not STP and not REMIT) MT801 first loop can be repeated Fixed semantic 282 affecting MT535 Fixed scheme for MT940 field 60[F,M] is now required","title":"7.9.1 - June 2017"},{"location":"release-notes/changelog-validation/#79-may-2017","text":"SWIFT Standard release update 2017 (live 19 November 2017 for MT and 18 November for MX) MT536: fixed false positive semantic 252 check, fixed qualifiers check in field 98a (sequence B1a2) MT575: transaction details sequence C2, field 98 with SETT or TRAD set as optional MT537: fixed false positive semantic 285 check MT576: additional information sequence C set as optional Fixed semantic rule 259 affecting MT517 link sequence check MT569: fixed incorrect definitions in sequence C1a1 (valuation details) MT506, 569 and 575: field 28E mandatory MT513; sequence A added TRAD qualifier to field 22F, sequence B1 (partial fill details) fields 98 and 94 are optional MT513 and 514: fixed letter option from H to F in field 22F:SETR in settlement details","title":"7.9 - May 2017"},{"location":"release-notes/changelog-validation/#789-may-2017","text":"Yearly revision of deprecation phase (see http://www.prowidesoftware.com/resources/deprecation-policy) Fixed validation of fields 72 and 79 of a Rejected/Return message Renamed FieldProblem.REJT_RETN_0n to more specific errors: REJT_RETN_LINE_n, REJT_RETN_REASON_CODE, REJT_RETN_MREF, REJT_RETN_TREF, REJT_RETN_CHGS, REJT_RETN_TEXT Enhanced validation of user block 3, checking all fields are expected for the message type and checking fields order. Fixed NPE in semantic 119 affecting MTs 102 and 103 STP when IBAN component was not present Added a common type ValidationProblemKey implemented by all problem key enumerations Fixed false positive error validating field 59F when multiple address lines (line label 2) are defined Fixed false positive restriction field 37a second component Fixed scheme for MT505, added missing field 98A:AGRE in sequence A1 Enhanced MX validation to allow MX messages with bank-to-bank namespace declaration Fixed false positive semantic 293 validation for MT507 when sequence B1a1 was not present Fixed letter option in scheme for MT506, sequence D (Collateral Details) field 19 A -> B Fixed qualifier in scheme for MT506, sequence D (Collateral Details) DEAL-> COLL Fixed scheme for MT506, sequence B (Summary) field 95 is mandatory and field 19B only mandatory with qualifier COVA Fixed Semantic 82 implementation affecting MT104 and MT107 Fixed false positive case in Semantic 75, affecting MT104 Fixed validation of leading characters, colon (':') not allowed in second and subsequent lines except for fields 77E and 77T Fixed semantic 103 affecting MT535","title":"7.8.9 - May 2017"},{"location":"release-notes/changelog-validation/#788-march-2017","text":"Added support for nested Document elements when validating MX messages Removed invalid fields following linkages in GENL sequence Cleaner log in semantic rule 3 validation","title":"7.8.8 - March 2017"},{"location":"release-notes/changelog-validation/#787-december-2016","text":"Added check for validation flag (STP, REMIT, COV) in user header block Fixed missing semantic associations to MTs 700, 705, 707, 710, 720, 730, 732, 734, 740, 742, 747, 750, 752, 754, 756, 768, 768, 769, 800, 801, 802, 824 MT518 fixed fieldset for Field 70 MT330 fixed qualifier in Field 22 MT513 and MT514 Field 11 moved outside previous fieldset MT541 to MT547 Field 90[A,B] changed to fieldset. MT564 fixed fieldset items in Field93[B,C] MT565 to MT567 Sequence D, fixed field 13 MT609 and MT798_763 fixed qualifiers in Field 29","title":"7.8.7 - December 2016"},{"location":"release-notes/changelog-validation/#786-november-2016","text":"JRE requirement increased to Java 1.7 (only for Integrator SDK and modules, Core still works on 1.5) semantic 175 minnor fix affecting MT104 and MT107 when multiple sequence B are present","title":"7.8.6 - November 2016"},{"location":"release-notes/changelog-validation/#785-october-2016","text":"Minor fixes in semantic validations: 206 (used in MTs: 103, 564, 566), 279 (used in MTs: 549, 564, 565) MT564: Minor fixes in semantic validations: 199, 211, 224 MT564: field 93 UNBA instead of UMBA MT564: CAOPT sequence, field 92 INTP, missing conditional qualifier NILP MT564: SECMOVE sequence, field 90 PRPP, missing letter option K MT564: SECMOVE sequence, field 92 NEWO, missing letter option M MT564: CASHMOVE sequence, field 92 ESOF, missing letter options F and M MT564: CASHMOVE sequence, field 92 TXIN, missing letter option F MT564: CASHMOVE sequence, field 92 WITL, missing letter option R and its conditional qualifier eval MT564: fixed field 92J subfield ACTU INDI validation MT565: CAINST sequence, field 90 OFFR, missing letter option L MT566: CADETL sequence, field 92 BIDI missing letter option P MT566:CACONF sequence, field 69, removed invalid letter option J MT566: Fixed qualifier in field 13a to allow UNS MT566:SECMOVE sequence, field 90 OFFR, missing letter option L MT566:SECMOVE sequence, field 90 PRPP, missing letter option K MT566:SECMOVE sequence, field 92 NEWO, missing letter option M MT566:SECMOVE sequence, field 92 TAXC, removed invalid letter option K MT566:CASHMOVE sequence, field 92 TXIN, missing letter option F MT566:CASHMOVE sequence, field 90 PRPP, missing letter option K MT566:fixed field 92J subfield ACTU INDI validation MT567: CADETL sequence, field 35B, removed invalid qualifier check SAFE MT567: field19 changed to fieldset","title":"7.8.5 - October 2016"},{"location":"release-notes/changelog-validation/#784-oct-2016","text":"Fixed JS expression in schemes for 564, 565, 566 and 620 Important enhancement in MX validation problem reporting, including full XPATH, line and column of errors. Fixed semantic 291 (affecting 540, 541, 544, 545) Fixed semantic 112 (affecting MTs 670 and 671) Fixed semantic 113 (affecting MTs 380, 381, 503, 504, 506, 670, 671)","title":"7.8.4 - Oct 2016"},{"location":"release-notes/changelog-validation/#783-jul-2016","text":"Added support for changed currency in Belorussia from 974 (BYR) to 933 (BYN). Fixed semantic 210 affecting messages 103, 102, 104 and 107","title":"7.8.3 - Jul 2016"},{"location":"release-notes/changelog-validation/#782-jul-2016","text":"Fixed schemes: definition of field 12A in FIA subsequences of MTs 54x Semantic 283 bugfix (used in MTs 307,503,504,505,506,536,537,548,578,586)","title":"7.8.2 - Jul 2016"},{"location":"release-notes/changelog-validation/#2016-june","text":"Added field repetition validation in block 3","title":"2016 June"},{"location":"release-notes/changelog-validation/#2016-april","text":"Added detection of extra data in message content or blocks when validating a message","title":"2016 April"},{"location":"release-notes/changelog-validation/#2016-february","text":"Fixed validation of min and max repetition in fieldsets, when the attributes are set only in the items","title":"2016 February"},{"location":"release-notes/changelog-validation/#2016-january","text":"Fixed scheme 307, typo in semantic rules attribute Added API in SchemeField to retrieve qualifiers information from parsed scripting expressions","title":"2016 January"},{"location":"release-notes/changelog-validation/#2015-december","text":"Fixed schemes for 600, 601, 604, 605, 606, 607, 608, 609, 620, wrong qualifier for field 26C","title":"2015 December"},{"location":"release-notes/changelog-validation/#2015-november","text":"Fixed validation of repetitive sequence in MT940","title":"2015 November"},{"location":"release-notes/changelog-validation/#2015-october","text":"Fixed validation for fields 129, 12A, 13B, 20E, 23A, 26N, 26P, 92C and 94D; removed restriction on amount of slashes because components use charset x where slash is allowed Fixed validation for fields 14G, 27A, 27, 28[D,E], 29[L,N], 38[G,H], 39[A,P], 68C, 69C, 70[C,D,E,G], 90F, 92R, 93B, 94E, 94G 95[Q,T,U,V] and 98F; added restriction on amount of slashes","title":"2015 October"},{"location":"release-notes/changelog-validation/#2015-september","text":"Fixed scheme for MT567, removed invalid 25D field in sequence A","title":"2015 September"},{"location":"release-notes/changelog-validation/#2015-august","text":"Fixed qualifiers validation scripting in xml schemas for MTs: 306, 360, 361, 362, 364, 365, 500, 501, 535, 564, 565, 566 Enhanced validation patterns naming for better consistency","title":"2015 August"},{"location":"release-notes/changelog-validation/#2015-april","text":"Enhanced structure validation error reporting, when JS expressions are used to check conditional qualifiers. The new scheme validation rule generates a proper message indicating the expected and found qualifiers instead of a generic fail expression error.","title":"2015 April"},{"location":"release-notes/changelog-validation/#2015-march","text":"Bugfix Field validations, new restriction, start of line character cannot be '-'. Bugfix MT535 subsequence B1a, it can be at most one and the scheme was allowing multiple repetitions","title":"2015 March"},{"location":"release-notes/changelog-validation/#2015-february","text":"ValidationEngine enhancement in the default scheme to use, detecting automatically if a 102/103 is STP or if a 202/205 is COV Fixed validation for field 22S, was requiring a 35 characters fixed length for component 2, while the correct validation is up to 35 characters (not fixed) Added more restrictive party field validation when a slash is followed by a blank content, affecting fields 42a, 50a, 51a, 52a, 53a, 54a, 55a, 56a, 57a, 58a, 59a, 81a, 82a 83a, 84a, 85a, 86a, 87a, 88a, 89a, 91a, 96a SchemeValidationRule version 2: new version of structure validation for MT, with several enhancements and bug fixes over the previous version. Important performance enhancement in MT structure validation (30% in average, reaching a 60% for some message structures). Important enhancement in structure error reporting, errors are now more specific and detailed with more details. Better error localization, avoiding duplicated error field validation in some situations. Improvement in scheme's scripting validations, isolating script compile errors from unsatisfied logic conditions. Fixed scheme validation for MT300 that was throwing a false problems for some combination of subsequences E, E1 and E1a.","title":"2015 February"},{"location":"release-notes/changelog-validation/#2015-january","text":"RuleManager: fixed loading of field rules, that was skipping incorrectly field validation to fields derived from fieldsets","title":"2015 January"},{"location":"release-notes/changelog-validation/#2014-december","text":"Better error message format in BaseTestCase Fixed error message for E73 Review of semantic rules 85,86,198 ValidationEngine: Added API to validate from AbstractMT ValidationEngine: Added exclusive API to use when validating messages in strings or files (with swift format, not parsed objects) therefore detecting more error conditions AbstractTagValidationRule: Fixed validation that had a bug in special conditions, Output messages (received from swift) and with sender and receiver within the same institution","title":"2014 December"},{"location":"release-notes/changelog-validation/#2014-november","text":"Bugfix in schemas 515, 536 Enhanced MT expression validation reporting, diferenciating invalid expressions, from runtime errors or failed expression evaluation. Bugfix. Fixed expressions in schemes xml for MT576 and MT568, replacing deprecated function call addQuaifiers by qualifier Bugfix. Added validation of T13 rule to MTs n98","title":"2014 November"},{"location":"release-notes/changelog-validation/#2014-september","text":"Bugfix. Missing resource bundle for invalid BIC validation problem Added addVariable method to ValidationProblem Bugfix. Fields 95Q and 70C were restricted to maximum 3 lines, while 4 lines are compliant as well. Bugfix. Fixed XML for MT537, field 22H conditional qualifier STAN changed to STAT","title":"2014 September"},{"location":"release-notes/changelog-validation/#2014-july","text":"Enhanced structure validation incorporating special field exceptions and required code words (standard PIII Fields Chapter 4) directly into the xml schemes configurations. Affected MTs: 102 STP, 103, 103 STP, 300, 303, 304, 305, 306, 320, 340, 341, 350, 360, 361, 362, 364, 365, 600, 601, 620, 920, 973 Enhanced structure validation error messages to separate unexpected fields problems reporting, from field qualifier problems or expression evaluation problems Enhanced field validation to avoid repetitive checks for empty content and/or empty lines Bugfix. MT306 optional field 12G changed to 12D and added missing field class Bugfix. SchemeXmlReader to properly set fieldset items' qualifiers and letter options when inherited from container fieldset Bugfix. Added null controls to several semantic validations to prevent NPE that would previously arise when applying semantic checks to messages with specific invalid structures Bugfix. Fixed XML for MT540, field 90 changed to fieldset 90 to allow qualifier validation for items Review and code clean of semantic rule 24, 52 SRU 2014. Affected MTs: 300, 304, 305, 306, 340, 341, 360, 361, 380, 381, 502, 506, 508, 509, 513, 514, 515, 518, 527, 530, 536, 537, 538, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 558, 564, 565, 566, 567, 568, 569, 575, 600, 601, 942 Added description and release attributes to Scheme Minor fix in MT300 sequences structure, B1 and B2 inside B, and named D's subsequence as D1 Bugfix. MT300 optional field 17A changed to optional field 77A (field number was wrong) Bugfix. MT514 fixed missing mandatory fields 36B and 35B between end of sequence B1 and start of sequence B2 Bugfix. MT515 fixed field 90[A,B] with qualifier DEAL at sequence C, changed from optional to mandatory (minRepetition was wrong)","title":"2014 July"},{"location":"release-notes/changelog-validation/#2014-may","text":"Review and code clean of semantic rule 184 Review and code clean of semantic rule 176 Review and code clean of semantic rule 152, 153, 154 Performance enhancements: execution speed reduced by approx 71% measured in global test suite","title":"2014 May"},{"location":"release-notes/changelog-validation/#2014-april","text":"Review and code clean of semantic rule 131, 253, 133, 135 Fixed semantic 116 rule incorrectly interpreting sequence C absence for MT306","title":"2014 April"},{"location":"release-notes/changelog-validation/#2014-march","text":"MT564: Added missing option K to field 90 in sequence E2 cash movements Review and code clean of semantic rule 92, 95 Review and code clean of semantic rule 66, 67, 68 ,78, 84, 93 Review and code clean of semantic rule 61, 57, 58, 62 Added validation problems translation to Italian. Bugfix. Fixed invalid check for X in 8th position for logical terminals without A, B, C identifier Bugfix. Fixed Block1 validation, allowing Logical terminal without the A, B, C identifier (11 characters length) Bugfix. Field validation was not accepting 999 as a valid MT number (example field 11R)","title":"2014 March"},{"location":"release-notes/changelog-validation/#2014-february","text":"Bugfix. Affected MTs:n92, n95, n96, n98. Fixed isolation of fields copied from original message from the fields of the message being validated Bugfix semantic rule 31 that was throwing false positives when field 79 was included in the appended original message's fields Initial addition of FieldFilter and FieldFilterUtils API Maintenance review of semantic rule 71 Review and code clean of semantic rule 211, 221, 262 Added API to BaseTestCase Review and code clean of semantic rule 209 Review and code clean of semantic rule 201, 202, 206 Bugfix. Affected MTs: 564. Fixed semantic rule 71 that was throwing IOB exceptions for some valid combinations of fields 93B Bugfix. Affected MTs: 568, 569, 574, 575, 576, 578, 586, 670, 671. Fixed xml schemes, changing the invalid scripting method conditionalQualifiers to conditionalQualifier Review and code clean of semantic rule 203, 206, 209, 221 Review and code clean of semantic rule 201, 202 Bugfix. Affected MTs: 305. Fixed false positive missing field errors when the message ends with nested optional subsequences with inner mandatory fields Review and code clean of semantic rule 192, 72, 199 Review and code clean of semantic rule 71 Review and code clean of semantic rules impacting MT305 Added a code generation tool that can be run from command line to create custom version of Field and MT classes Added a command line application to use the messages validation in standalone mode, validating messages from file system","title":"2014 February"},{"location":"release-notes/changelog-validation/#2014-january","text":"Added validation rules for fields belonging to system messages (i.e. 451) Adding constants to Literals class to avoid usage of hardcoded strings and cleaner code with static imports Bugfix. Affected MTs: 207. Fixed maximum repetitions of sequence B from 1 to unlimited Maintenance(Review and performance updates) semantic rule #167, #54, #55 Maintenance(Review and performance updates) semantic rule #161 Maintenance(Review and performance updates) semantic rule #168, #246, #254 Added filter() to AbstractSemanticValidationRule Maintenance(Review and performance updates) semantic rule #162, #166 Added BaseTestCase.assertValid(String) Fixed issue in semantic rule 154 which did not consider properly B sequences Maintenance(Review and performance updates) semantic rule #160, #164","title":"2014 January"},{"location":"release-notes/changelog-validation/#2014-01-15","text":"Fixed issue in semantic rule 77 affecting MTs 730, 768 and 769","title":"2014-01-15"},{"location":"release-notes/changelog-validation/#2013-october","text":"Maintenance(Review and performance updates) semantic rule #44, #45, #46, $47, #48, #51, #53 Maintenance(Review and performance updates) semantic rule #106, #108, #30, #40, #42 Review and performance updates on S102 Refactored max msg length validation to use enum in structure problem for reporting errors Review and performance updates on S79","title":"2013 October"},{"location":"release-notes/changelog-validation/#2013-september","text":"SRU 2013 update Fixed incomplete validation for field 77E","title":"2013 September"},{"location":"release-notes/changelog-validation/#2013-march","text":"Bugfix: fixed typo at field 22H in MT380, BUYI->BUY1","title":"2013 March"},{"location":"release-notes/changelog-validation/#2012-june","text":"Added API to specify locale on ValidationProblem.getMessage method","title":"2012 June"},{"location":"release-notes/mule/","text":"Prowide MULE connector The Prowide Mule connector is hosted in Mule Exchange and facilitates the integration and usage of the Prowide libraries for MT, ISO 20022 and CBPR+ in Mule applications. https://www.anypoint.mulesoft.com/exchange/ 1.0.0 - September 2020 (Not released yet) Mule Runtime compatibility: 4.1.0+ Initial version including operations for validation and translation for MT, ISO 20022 and CBPR+","title":"Prowide Mule connector"},{"location":"release-notes/mule/#prowide-mule-connector","text":"The Prowide Mule connector is hosted in Mule Exchange and facilitates the integration and usage of the Prowide libraries for MT, ISO 20022 and CBPR+ in Mule applications. https://www.anypoint.mulesoft.com/exchange/","title":"Prowide MULE connector"},{"location":"release-notes/mule/#100-september-2020-not-released-yet","text":"Mule Runtime compatibility: 4.1.0+ Initial version including operations for validation and translation for MT, ISO 20022 and CBPR+","title":"1.0.0 - September 2020 (Not released yet)"}]} \ No newline at end of file diff --git a/SRU2023-9/sitemap.xml b/SRU2023-9/sitemap.xml index 5f049917f..83540604f 100644 --- a/SRU2023-9/sitemap.xml +++ b/SRU2023-9/sitemap.xml @@ -2,377 +2,377 @@ https://www.prowidesoftware.com/SRU2023-9/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/getting-started/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/getting-started/deprecation/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/getting-started/download-core/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/getting-started/download-iso20022/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/getting-started/versioning/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/getting-started/swift/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/getting-started/swift/swift-mt/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/getting-started/swift/swift-mx/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/cbpr/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/mule/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/score/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/sepa/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/sic/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/myformat/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/myformat/myformat-config/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/myformat/myformat-csv/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/myformat/myformat-engine/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/myformat/myformat-fin/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/myformat/myformat-fixed/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/myformat/myformat-json/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/myformat/myformat-rule/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/myformat/myformat-setup-commands/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/myformat/myformat-sql-table/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/myformat/myformat-transformations/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/myformat/myformat-xml/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/sdk/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/sdk/sdk-bicdirectory/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/sdk/sdk-datapdu/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/sdk/sdk-lau/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/sdk/sdk-mtpath/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/sdk/sdk-printout/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/sdk/sdk-schemes/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/translations/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/translations/translations-avail/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/translations/translations-factory/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/translations/translations-general/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/translations/translations-mt2mx/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/translations/translations-mx2mt/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/validation/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/validation/validation-bic/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/validation/validation-mt/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/validation/validation-mx/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/integrator/validation/validation-process/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/open-source/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/open-source/core/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/open-source/core/mt-ack/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/open-source/core/mt-build/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/open-source/core/mt-json/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/open-source/core/mt-model/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/open-source/core/mt-modify/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/open-source/core/mt-parser/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/open-source/core/mt-rje/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/open-source/core/mt-xml/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/open-source/core/safexmlutils/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/open-source/iso20022/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/open-source/iso20022/iso20022-adapters/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/open-source/iso20022/iso20022-build/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/open-source/iso20022/iso20022-model/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/open-source/iso20022/iso20022-parser/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/release-notes/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/release-notes/changelog-cbpr/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/release-notes/changelog-consolidated/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/release-notes/changelog-core/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/release-notes/changelog-guitools/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/release-notes/changelog-iso20022/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/release-notes/changelog-myformat/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/release-notes/changelog-score/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/release-notes/changelog-sdk/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/release-notes/changelog-sepa/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/release-notes/changelog-sic/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/release-notes/changelog-translations/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/release-notes/changelog-validation/ - 2024-06-12 + 2024-06-18 daily https://www.prowidesoftware.com/SRU2023-9/release-notes/mule/ - 2024-06-12 + 2024-06-18 daily \ No newline at end of file diff --git a/SRU2023-9/sitemap.xml.gz b/SRU2023-9/sitemap.xml.gz index b79acd10d..e1375d2f0 100644 Binary files a/SRU2023-9/sitemap.xml.gz and b/SRU2023-9/sitemap.xml.gz differ