From 34f602afeb29f7126fc953be8d38626ee3b0ff48 Mon Sep 17 00:00:00 2001 From: elominp Date: Wed, 2 Jun 2021 10:44:40 +0200 Subject: [PATCH 1/6] issue #16 fix proposal for apphdr json deserialization --- .../swift/model/mx/AbstractMX.java | 3 + .../swift/model/mx/AppHdrAdapter.java | 40 ++++++ .../swift/model/mx/AbstractMxJsonTest.java | 114 +++++++++++++++++- 3 files changed, 153 insertions(+), 4 deletions(-) create mode 100644 iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrAdapter.java diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AbstractMX.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AbstractMX.java index 0518790ee..2c4bf33ca 100644 --- a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AbstractMX.java +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AbstractMX.java @@ -193,6 +193,7 @@ protected static T fromJson(String json, Class classOfT) { final Gson gson = new GsonBuilder() .registerTypeAdapter(AbstractMX.class, new AbstractMXAdapter()) .registerTypeAdapter(XMLGregorianCalendar.class, new XMLGregorianCalendarAdapter()) + .registerTypeAdapter(AppHdr.class, new AppHdrAdapter()) .create(); return gson.fromJson(json, classOfT); } @@ -208,6 +209,7 @@ public static AbstractMX fromJson(String json) { final Gson gson = new GsonBuilder() .registerTypeAdapter(AbstractMX.class, new AbstractMXAdapter()) .registerTypeAdapter(XMLGregorianCalendar.class, new XMLGregorianCalendarAdapter()) + .registerTypeAdapter(AppHdr.class, new AppHdrAdapter()) .create(); return gson.fromJson(json, AbstractMX.class); } @@ -519,6 +521,7 @@ public String toJson() { final Gson gson = new GsonBuilder() .registerTypeAdapter(AbstractMX.class, new AbstractMXAdapter()) .registerTypeAdapter(XMLGregorianCalendar.class, new XMLGregorianCalendarAdapter()) + .registerTypeAdapter(AppHdr.class, new AppHdrAdapter()) .setPrettyPrinting() .create(); // we use AbstractMX and not this.getClass() in order to force usage of the adapter diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrAdapter.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrAdapter.java new file mode 100644 index 000000000..45f69bbe8 --- /dev/null +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrAdapter.java @@ -0,0 +1,40 @@ +package com.prowidesoftware.swift.model.mx; + +import com.google.gson.*; + +import java.lang.reflect.Type; + +public class AppHdrAdapter implements JsonSerializer, JsonDeserializer { + + private static final String HDR_TYPE = "hdrType"; + + @Override + public JsonElement serialize(AppHdr hdr, Type typeOfSrc, JsonSerializationContext context) { + try { + String[] hdrType = hdr.getClass().getCanonicalName().split("[.]"); + JsonObject json = context.serialize(hdr).getAsJsonObject(); + json.addProperty(HDR_TYPE, hdrType[hdrType.length - 1]); + return json; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + @Override + public AppHdr deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + try { + Class type = LegacyAppHdr.class; + JsonElement identifier = json.getAsJsonObject().get(HDR_TYPE); + if (identifier != null) { + try { + type = Class.forName("com.prowidesoftware.swift.model.mx." + identifier.getAsString()); + } catch (ClassNotFoundException ignored) {} + } + return context.deserialize(json, type); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java index 9eaafed12..2e2ecd85f 100644 --- a/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java +++ b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java @@ -15,7 +15,6 @@ */ package com.prowidesoftware.swift.model.mx; -import com.prowidesoftware.swift.model.mx.dic.*; import org.junit.jupiter.api.Test; import javax.xml.datatype.DatatypeFactory; @@ -25,10 +24,22 @@ import static org.junit.jupiter.api.Assertions.assertEquals; +import com.prowidesoftware.swift.model.mx.dic.AccountStatement6; +import com.prowidesoftware.swift.model.mx.dic.BankToCustomerStatementV06; +import com.prowidesoftware.swift.model.mx.dic.BranchAndFinancialInstitutionIdentification5; +import com.prowidesoftware.swift.model.mx.dic.BranchData2; +import com.prowidesoftware.swift.model.mx.dic.CashAccount25; +import com.prowidesoftware.swift.model.mx.dic.CustomerCreditTransferInitiationV08; +import com.prowidesoftware.swift.model.mx.dic.GroupHeader48; +import com.prowidesoftware.swift.model.mx.dic.OrganisationIdentification8; +import com.prowidesoftware.swift.model.mx.dic.Party11Choice; +import com.prowidesoftware.swift.model.mx.dic.PartyIdentification43; + +import static org.junit.jupiter.api.Assertions.*; + /** * Test for JSON conversion in the MX model (AbstractMX and subclasses). - * - * @since 7.10.2 + * * @since 7.10.2 */ public class AbstractMxJsonTest { @@ -187,4 +198,99 @@ public void testMxDateJsonSerializeAndParse() { assertEquals(json, json2); } -} + @Test + public void parseMxWithAppHdr() { + final String json = "{\n" + + " \"fiCdtTrf\": {\n" + + " \"grpHdr\": {\n" + + " \"msgId\": \"A2P76703\",\n" + + " \"creDtTm\": {\n" + + " \"year\": 2021,\n" + + " \"month\": 4,\n" + + " \"day\": 28,\n" + + " \"timezone\": 0,\n" + + " \"hour\": 9,\n" + + " \"minute\": 22,\n" + + " \"second\": 56\n" + + " },\n" + + " \"nbOfTxs\": \"1\"\n" + + " }\n" + + " },\n" + + " \"appHdr\": {\n" + + " \"from\": {\n" + + " \"type\": \"BIC\",\n" + + " \"id\": \"ABNANL20606\"\n" + + " },\n" + + " \"to\": {\n" + + " \"type\": \"BIC\",\n" + + " \"id\": \"GIISIT2TXXX\"\n" + + " },\n" + + " \"msgName\": \"pacs.009.001.07\",\n" + + " \"msgRef\": \"CPTE190421113270\",\n" + + " \"crDate\": {\n" + + " \"year\": 2021,\n" + + " \"month\": 4,\n" + + " \"day\": 28,\n" + + " \"timezone\": 0,\n" + + " \"hour\": 9,\n" + + " \"minute\": 22,\n" + + " \"second\": 56\n" + + " }\n" + + " },\n" + + " \"type\": \"MX\",\n" + + " \"@xmlns\": \"urn:iso:std:iso:20022:tech:xsd:pacs.009.001.07\",\n" + + " \"identifier\": \"pacs.009.001.07\"\n" + + "}"; + assertDoesNotThrow(() -> AbstractMX.fromJson(json)); + } + + @Test + public void parseSerializedMxWithAppHdr() { + final String json = "{\n" + + " \"fiCdtTrf\": {\n" + + " \"grpHdr\": {\n" + + " \"msgId\": \"A2P76703\",\n" + + " \"creDtTm\": {\n" + + " \"year\": 2021,\n" + + " \"month\": 4,\n" + + " \"day\": 28,\n" + + " \"timezone\": 0,\n" + + " \"hour\": 9,\n" + + " \"minute\": 22,\n" + + " \"second\": 56\n" + + " },\n" + + " \"nbOfTxs\": \"1\"\n" + + " }\n" + + " },\n" + + " \"appHdr\": {\n" + + " \"from\": {\n" + + " \"type\": \"BIC\",\n" + + " \"id\": \"ABNANL20606\"\n" + + " },\n" + + " \"to\": {\n" + + " \"type\": \"BIC\",\n" + + " \"id\": \"GIISIT2TXXX\"\n" + + " },\n" + + " \"msgName\": \"pacs.009.001.07\",\n" + + " \"msgRef\": \"CPTE190421113270\",\n" + + " \"crDate\": {\n" + + " \"year\": 2021,\n" + + " \"month\": 4,\n" + + " \"day\": 28,\n" + + " \"timezone\": 0,\n" + + " \"hour\": 9,\n" + + " \"minute\": 22,\n" + + " \"second\": 56\n" + + " }\n" + + " },\n" + + " \"type\": \"MX\",\n" + + " \"@xmlns\": \"urn:iso:std:iso:20022:tech:xsd:pacs.009.001.07\",\n" + + " \"identifier\": \"pacs.009.001.07\"\n" + + "}"; + AbstractMX source = AbstractMX.fromJson(json); + AbstractMX mx = AbstractMX.fromJson(source.toJson()); + AbstractMX mx2 = AbstractMX.fromJson(mx.toJson()); + assertEquals(mx, mx2); + } + +} \ No newline at end of file From 48e77153875897a73293c4e8c52b1bc319647579 Mon Sep 17 00:00:00 2001 From: elominp Date: Wed, 2 Jun 2021 10:48:54 +0200 Subject: [PATCH 2/6] issue #16 fix proposal for apphdr json deserialization --- .../com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java index 2e2ecd85f..9cd24af65 100644 --- a/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java +++ b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java @@ -15,6 +15,7 @@ */ package com.prowidesoftware.swift.model.mx; +import com.prowidesoftware.swift.model.mx.dic.*; import org.junit.jupiter.api.Test; import javax.xml.datatype.DatatypeFactory; @@ -39,7 +40,7 @@ /** * Test for JSON conversion in the MX model (AbstractMX and subclasses). - * * @since 7.10.2 + * @since 7.10.2 */ public class AbstractMxJsonTest { From daf4452a008e6b6b12bce834a49268f3f420b58c Mon Sep 17 00:00:00 2001 From: fernando-prowide Date: Wed, 2 Jun 2021 21:21:48 -0300 Subject: [PATCH 3/6] Fix Issue #16 apphdr json deserialization with namespace --- .../swift/model/mx/AppHdr.java | 6 + .../swift/model/mx/AppHdrAdapter.java | 15 +- .../swift/model/mx/AppHdrType.java | 32 +++- .../swift/model/mx/BusinessAppHdrV01.java | 11 +- .../swift/model/mx/BusinessAppHdrV02.java | 8 + .../swift/model/mx/LegacyAppHdr.java | 9 + .../swift/model/mx/AbstractMxJsonTest.java | 157 ++++++++++++++++++ 7 files changed, 225 insertions(+), 13 deletions(-) diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdr.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdr.java index a109b95d3..41ae5070c 100644 --- a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdr.java +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdr.java @@ -133,4 +133,10 @@ default String xml() { */ Element element(); + /** + * @return The specific namespace of the Header + * @since 9.1.7 + */ + default String namespace() {return null;} + } diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrAdapter.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrAdapter.java index 45f69bbe8..cda909bd0 100644 --- a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrAdapter.java +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrAdapter.java @@ -1,19 +1,20 @@ package com.prowidesoftware.swift.model.mx; import com.google.gson.*; +import org.apache.commons.lang3.StringUtils; import java.lang.reflect.Type; public class AppHdrAdapter implements JsonSerializer, JsonDeserializer { - private static final String HDR_TYPE = "hdrType"; + private static final String NAMESPACE = "namespace"; @Override public JsonElement serialize(AppHdr hdr, Type typeOfSrc, JsonSerializationContext context) { try { - String[] hdrType = hdr.getClass().getCanonicalName().split("[.]"); + String namespace = hdr.namespace(); JsonObject json = context.serialize(hdr).getAsJsonObject(); - json.addProperty(HDR_TYPE, hdrType[hdrType.length - 1]); + json.addProperty(NAMESPACE, namespace); return json; } catch (Exception e) { e.printStackTrace(); @@ -25,11 +26,9 @@ public JsonElement serialize(AppHdr hdr, Type typeOfSrc, JsonSerializationContex public AppHdr deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { try { Class type = LegacyAppHdr.class; - JsonElement identifier = json.getAsJsonObject().get(HDR_TYPE); - if (identifier != null) { - try { - type = Class.forName("com.prowidesoftware.swift.model.mx." + identifier.getAsString()); - } catch (ClassNotFoundException ignored) {} + JsonElement namespace = json.getAsJsonObject().get(NAMESPACE); + if (namespace != null && !namespace.equals(AppHdrType.LEGACY.getNamespace())) { + type = AppHdrType.of(namespace.getAsString()); } return context.deserialize(json, type); } catch (Exception e) { diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrType.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrType.java index 38531e734..ee88a9338 100644 --- a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrType.java +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrType.java @@ -15,22 +15,46 @@ */ package com.prowidesoftware.swift.model.mx; +import org.apache.commons.lang3.StringUtils; + /** * @since 9.1.2 */ public enum AppHdrType { - LEGACY(LegacyAppHdr.NAMESPACE), - BAH_V1(BusinessAppHdrV01.NAMESPACE), - BAH_V2(BusinessAppHdrV02.NAMESPACE); + LEGACY(LegacyAppHdr.NAMESPACE, LegacyAppHdr.class), + BAH_V1(BusinessAppHdrV01.NAMESPACE, BusinessAppHdrV01.class), + BAH_V2(BusinessAppHdrV02.NAMESPACE, BusinessAppHdrV02.class); private String namespace; + private Class headerClass; - AppHdrType(String namespace) { + AppHdrType(String namespace, Class headerClass) { this.namespace = namespace; + this.headerClass = headerClass; + } + + /** + * @param namespace of the Header + * @return a Class of the Header Implementation + * @since 9.1.7 + */ + public static Class of(String namespace) { + if (StringUtils.isNotBlank(namespace)) { + for (AppHdrType appHdrType : AppHdrType.values()) { + if (appHdrType.getNamespace().equals(namespace)) { + return appHdrType.headerClass; + } + } + } + return LegacyAppHdr.class; } public String getNamespace() { return this.namespace; } + public Class getHeaderClass() { + return this.headerClass; + } + } \ No newline at end of file diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/BusinessAppHdrV01.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/BusinessAppHdrV01.java index 7d37c2b4a..9bc0d13d0 100644 --- a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/BusinessAppHdrV01.java +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/BusinessAppHdrV01.java @@ -220,4 +220,13 @@ public Element element() { return null; } -} + /** + * @since 9.1.7 + * @return NAMESPACE + */ + @Override + public String namespace() { + return NAMESPACE; + } + +} \ No newline at end of file diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/BusinessAppHdrV02.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/BusinessAppHdrV02.java index 93cfaa9ca..2792ea58e 100644 --- a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/BusinessAppHdrV02.java +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/BusinessAppHdrV02.java @@ -220,4 +220,12 @@ public Element element() { return null; } + /** + * @since 9.1.7 + * @return NAMESPACE + */ + @Override + public String namespace(){ + return NAMESPACE; + } } diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/LegacyAppHdr.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/LegacyAppHdr.java index 8ad307798..b36d1faa6 100644 --- a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/LegacyAppHdr.java +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/LegacyAppHdr.java @@ -210,4 +210,13 @@ public Element element() { return null; } + /** + * @since 9.1.7 + * @return NAMESPACE + */ + @Override + public String namespace(){ + return NAMESPACE; + } + } diff --git a/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java index 9cd24af65..4585a71a9 100644 --- a/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java +++ b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java @@ -294,4 +294,161 @@ public void parseSerializedMxWithAppHdr() { assertEquals(mx, mx2); } + + @Test + public void parseSerializedMxWithAppHdrBAH_V1() { + final String json = "{\n" + + " \"fiCdtTrf\": {\n" + + " \"grpHdr\": {\n" + + " \"msgId\": \"A2P76703\",\n" + + " \"creDtTm\": {\n" + + " \"year\": 2021,\n" + + " \"month\": 4,\n" + + " \"day\": 28,\n" + + " \"timezone\": 0,\n" + + " \"hour\": 9,\n" + + " \"minute\": 22,\n" + + " \"second\": 56\n" + + " },\n" + + " \"nbOfTxs\": \"1\"\n" + + " }\n" + + " },\n" + + " \"appHdr\": {\n" + + " \"namespace\": \"urn:iso:std:iso:20022:tech:xsd:head.001.001.01\",\n" + + " \"fr\": {\n" + + " \"type\": \"BIC\",\n" + + " \"id\": \"ABNANL20606\"\n" + + " },\n" + + " \"to\": {\n" + + " \"type\": \"BIC\",\n" + + " \"id\": \"GIISIT2TXXX\"\n" + + " },\n" + + " \"msgName\": \"pacs.009.001.07\",\n" + + " \"msgRef\": \"CPTE190421113270\",\n" + + " \"crDate\": {\n" + + " \"year\": 2021,\n" + + " \"month\": 4,\n" + + " \"day\": 28,\n" + + " \"timezone\": 0,\n" + + " \"hour\": 9,\n" + + " \"minute\": 22,\n" + + " \"second\": 56\n" + + " }\n" + + " },\n" + + " \"type\": \"MX\",\n" + + " \"@xmlns\": \"urn:iso:std:iso:20022:tech:xsd:pacs.009.001.07\",\n" + + " \"identifier\": \"pacs.009.001.07\"\n" + + "}"; + AbstractMX source = AbstractMX.fromJson(json); + AbstractMX mx = AbstractMX.fromJson(source.toJson()); + AbstractMX mx2 = AbstractMX.fromJson(mx.toJson()); + BusinessAppHdrV01 BAH_V1 = (BusinessAppHdrV01) mx.getAppHdr(); + assertNotNull(BAH_V1); + } + + + @Test + public void parseSerializedMxWithAppHdrBAH_V2() { + final String json = "{\n" + + " \"fiCdtTrf\": {\n" + + " \"grpHdr\": {\n" + + " \"msgId\": \"A2P76703\",\n" + + " \"creDtTm\": {\n" + + " \"year\": 2021,\n" + + " \"month\": 4,\n" + + " \"day\": 28,\n" + + " \"timezone\": 0,\n" + + " \"hour\": 9,\n" + + " \"minute\": 22,\n" + + " \"second\": 56\n" + + " },\n" + + " \"nbOfTxs\": \"1\"\n" + + " }\n" + + " },\n" + + " \"appHdr\": {\n" + + " \"namespace\": \"urn:iso:std:iso:20022:tech:xsd:head.001.001.02\",\n" + + " \"fr\": {\n" + + " \"type\": \"BIC\",\n" + + " \"id\": \"ABNANL20606\"\n" + + " },\n" + + " \"to\": {\n" + + " \"type\": \"BIC\",\n" + + " \"id\": \"GIISIT2TXXX\"\n" + + " },\n" + + " \"msgName\": \"pacs.009.001.07\",\n" + + " \"msgRef\": \"CPTE190421113270\",\n" + + " \"crDate\": {\n" + + " \"year\": 2021,\n" + + " \"month\": 4,\n" + + " \"day\": 28,\n" + + " \"timezone\": 0,\n" + + " \"hour\": 9,\n" + + " \"minute\": 22,\n" + + " \"second\": 56\n" + + " }\n" + + " },\n" + + " \"type\": \"MX\",\n" + + " \"@xmlns\": \"urn:iso:std:iso:20022:tech:xsd:pacs.009.001.07\",\n" + + " \"identifier\": \"pacs.009.001.07\"\n" + + "}"; + AbstractMX source = AbstractMX.fromJson(json); + AbstractMX mx = AbstractMX.fromJson(source.toJson()); + AbstractMX mx2 = AbstractMX.fromJson(mx.toJson()); + assertEquals(mx,mx2); + BusinessAppHdrV02 BAH_V2 = (BusinessAppHdrV02) mx.getAppHdr(); + assertNotNull(BAH_V2); + } + + + @Test + public void parseSerializedMxWithAppHdrNoNameSpace() { + final String json = "{\n" + + " \"fiCdtTrf\": {\n" + + " \"grpHdr\": {\n" + + " \"msgId\": \"A2P76703\",\n" + + " \"creDtTm\": {\n" + + " \"year\": 2021,\n" + + " \"month\": 4,\n" + + " \"day\": 28,\n" + + " \"timezone\": 0,\n" + + " \"hour\": 9,\n" + + " \"minute\": 22,\n" + + " \"second\": 56\n" + + " },\n" + + " \"nbOfTxs\": \"1\"\n" + + " }\n" + + " },\n" + + " \"appHdr\": {\n" + + " \"fr\": {\n" + + " \"type\": \"BIC\",\n" + + " \"id\": \"ABNANL20606\"\n" + + " },\n" + + " \"to\": {\n" + + " \"type\": \"BIC\",\n" + + " \"id\": \"GIISIT2TXXX\"\n" + + " },\n" + + " \"msgName\": \"pacs.009.001.07\",\n" + + " \"msgRef\": \"CPTE190421113270\",\n" + + " \"crDate\": {\n" + + " \"year\": 2021,\n" + + " \"month\": 4,\n" + + " \"day\": 28,\n" + + " \"timezone\": 0,\n" + + " \"hour\": 9,\n" + + " \"minute\": 22,\n" + + " \"second\": 56\n" + + " }\n" + + " },\n" + + " \"type\": \"MX\",\n" + + " \"@xmlns\": \"urn:iso:std:iso:20022:tech:xsd:pacs.009.001.07\",\n" + + " \"identifier\": \"pacs.009.001.07\"\n" + + "}"; + AbstractMX source = AbstractMX.fromJson(json); + AbstractMX mx = AbstractMX.fromJson(source.toJson()); + AbstractMX mx2 = AbstractMX.fromJson(mx.toJson()); + assertEquals(mx, mx2); + + BusinessAppHdrV01 legacyAppHdr = (BusinessAppHdrV01) mx.getAppHdr(); + assertNotNull(legacyAppHdr); + } } \ No newline at end of file From 0cd9d4ceffad05af0d1c6054bcce7f73b6b43a31 Mon Sep 17 00:00:00 2001 From: fernando-prowide Date: Wed, 2 Jun 2021 21:33:00 -0300 Subject: [PATCH 4/6] Add invalid namespace --- .../swift/model/mx/AbstractMxJsonTest.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java index 4585a71a9..c707f13c1 100644 --- a/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java +++ b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java @@ -451,4 +451,58 @@ public void parseSerializedMxWithAppHdrNoNameSpace() { BusinessAppHdrV01 legacyAppHdr = (BusinessAppHdrV01) mx.getAppHdr(); assertNotNull(legacyAppHdr); } + + + @Test + public void parseSerializedMxWithAppHdrInvalidNamespace() { + final String json = "{\n" + + " \"fiCdtTrf\": {\n" + + " \"grpHdr\": {\n" + + " \"msgId\": \"A2P76703\",\n" + + " \"creDtTm\": {\n" + + " \"year\": 2021,\n" + + " \"month\": 4,\n" + + " \"day\": 28,\n" + + " \"timezone\": 0,\n" + + " \"hour\": 9,\n" + + " \"minute\": 22,\n" + + " \"second\": 56\n" + + " },\n" + + " \"nbOfTxs\": \"1\"\n" + + " }\n" + + " },\n" + + " \"appHdr\": {\n" + + " \"namespace\": \"urn:iso:std:iso:00000:tech:xsd:head.000.000.00\",\n" + + " \"fr\": {\n" + + " \"type\": \"BIC\",\n" + + " \"id\": \"ABNANL20606\"\n" + + " },\n" + + " \"to\": {\n" + + " \"type\": \"BIC\",\n" + + " \"id\": \"GIISIT2TXXX\"\n" + + " },\n" + + " \"msgName\": \"pacs.009.001.07\",\n" + + " \"msgRef\": \"CPTE190421113270\",\n" + + " \"crDate\": {\n" + + " \"year\": 2021,\n" + + " \"month\": 4,\n" + + " \"day\": 28,\n" + + " \"timezone\": 0,\n" + + " \"hour\": 9,\n" + + " \"minute\": 22,\n" + + " \"second\": 56\n" + + " }\n" + + " },\n" + + " \"type\": \"MX\",\n" + + " \"@xmlns\": \"urn:iso:std:iso:20022:tech:xsd:pacs.009.001.07\",\n" + + " \"identifier\": \"pacs.009.001.07\"\n" + + "}"; + AbstractMX source = AbstractMX.fromJson(json); + AbstractMX mx = AbstractMX.fromJson(source.toJson()); + AbstractMX mx2 = AbstractMX.fromJson(mx.toJson()); + assertEquals(mx, mx2); + + LegacyAppHdr legacyAppHdr = (LegacyAppHdr) mx.getAppHdr(); + assertNotNull(legacyAppHdr); + } } \ No newline at end of file From fd3c33ad8457de858179e5470445a65469766581 Mon Sep 17 00:00:00 2001 From: fernando-prowide Date: Thu, 3 Jun 2021 09:59:24 -0300 Subject: [PATCH 5/6] Remove unsued method --- .../java/com/prowidesoftware/swift/model/mx/AppHdrType.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrType.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrType.java index ee88a9338..4012159d5 100644 --- a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrType.java +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrType.java @@ -52,9 +52,5 @@ public static Class of(String namespace) { public String getNamespace() { return this.namespace; } - - public Class getHeaderClass() { - return this.headerClass; - } - + } \ No newline at end of file From 52a19daa53af0a1ff42b5052602a66f440245c2f Mon Sep 17 00:00:00 2001 From: zubri Date: Fri, 4 Jun 2021 13:03:30 -0300 Subject: [PATCH 6/6] code review and fixed test --- CHANGELOG.txt | 3 ++ .../swift/io/parser/MxParser.java | 2 +- .../swift/model/mx/AppHdr.java | 7 +++- .../swift/model/mx/AppHdrAdapter.java | 42 +++++++++---------- .../swift/model/mx/AppHdrType.java | 10 ++--- .../swift/model/mx/BusinessAppHdrV01.java | 2 +- .../swift/model/mx/BusinessAppHdrV02.java | 4 +- .../swift/model/mx/LegacyAppHdr.java | 4 +- .../swift/model/mx/AbstractMxJsonTest.java | 26 ++++-------- 9 files changed, 47 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 94f0ff9a1..8820bccd6 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -2,6 +2,9 @@ Prowide ISO 20022 - CHANGELOG ----------------------------------------------------------------------------------------------------------------------- +RELEASE 9.1.7 - June 2021 + * (GH-26) Fixed AppHdr JSON conversion with explicit new namespace field as discriminator + RELEASE 9.1.6 - April 2021 * (GH-17|JIRA-506) Enhanced the XML format in the serializing, spaces and line breaks * (GH-18) Fixed NPE in json serialization/deserialization of XMLGregorianCalendar fractional second diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/io/parser/MxParser.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/io/parser/MxParser.java index 64acb2ac2..4a750b0d0 100644 --- a/iso20022-core/src/main/java/com/prowidesoftware/swift/io/parser/MxParser.java +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/io/parser/MxParser.java @@ -336,7 +336,7 @@ private String readNamespace(final javax.xml.stream.XMLStreamReader reader) { *

This implementation is intended to be lightweight and efficient so it actually does a simple substring * operation on the XML using information provided by the result of {@link #analyzeMessage()}. The XML is not * converted into DOM on purpose because we want to strip the content event when the XML is not totally well-formed. - * + *< *

If the message contains more than one Document element the expected result is as follows: *

    *
  • If the documents are nested (this can happen for example when an additional MX message is provided diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdr.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdr.java index 41ae5070c..3fba81e41 100644 --- a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdr.java +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdr.java @@ -134,9 +134,12 @@ default String xml() { Element element(); /** - * @return The specific namespace of the Header + * Gets the specific namespace of the header + * @return default implementation returns null * @since 9.1.7 */ - default String namespace() {return null;} + default String namespace() { + return null; + } } diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrAdapter.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrAdapter.java index cda909bd0..ffa05ed69 100644 --- a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrAdapter.java +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrAdapter.java @@ -1,39 +1,39 @@ package com.prowidesoftware.swift.model.mx; import com.google.gson.*; -import org.apache.commons.lang3.StringUtils; import java.lang.reflect.Type; +/** + * @since 9.1.7 + */ public class AppHdrAdapter implements JsonSerializer, JsonDeserializer { private static final String NAMESPACE = "namespace"; @Override public JsonElement serialize(AppHdr hdr, Type typeOfSrc, JsonSerializationContext context) { - try { - String namespace = hdr.namespace(); - JsonObject json = context.serialize(hdr).getAsJsonObject(); - json.addProperty(NAMESPACE, namespace); - return json; - } catch (Exception e) { - e.printStackTrace(); - } - return null; + JsonObject json = context.serialize(hdr).getAsJsonObject(); + json.addProperty(NAMESPACE, hdr.namespace()); + return json; } @Override public AppHdr deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - try { - Class type = LegacyAppHdr.class; - JsonElement namespace = json.getAsJsonObject().get(NAMESPACE); - if (namespace != null && !namespace.equals(AppHdrType.LEGACY.getNamespace())) { - type = AppHdrType.of(namespace.getAsString()); - } - return context.deserialize(json, type); - } catch (Exception e) { - e.printStackTrace(); + + // resolve header implementation class + JsonElement namespace = json.getAsJsonObject().get(NAMESPACE); + Class type = null; + if (namespace != null) { + type = AppHdrType.of(namespace.getAsString()); + } + + if (type == null) { + // default to legacy header + type = LegacyAppHdr.class; } - return null; + + return context.deserialize(json, type); } -} + +} \ No newline at end of file diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrType.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrType.java index 4012159d5..b57558feb 100644 --- a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrType.java +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/AppHdrType.java @@ -34,23 +34,23 @@ public enum AppHdrType { } /** - * @param namespace of the Header - * @return a Class of the Header Implementation + * @param namespace the namespace of the header + * @return the header implementation class or null if namespace is invalid or cannot be matched * @since 9.1.7 */ public static Class of(String namespace) { if (StringUtils.isNotBlank(namespace)) { for (AppHdrType appHdrType : AppHdrType.values()) { - if (appHdrType.getNamespace().equals(namespace)) { + if (namespace.equals(appHdrType.getNamespace())) { return appHdrType.headerClass; } } } - return LegacyAppHdr.class; + return null; } public String getNamespace() { return this.namespace; } - + } \ No newline at end of file diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/BusinessAppHdrV01.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/BusinessAppHdrV01.java index 9bc0d13d0..96171d432 100644 --- a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/BusinessAppHdrV01.java +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/BusinessAppHdrV01.java @@ -221,8 +221,8 @@ public Element element() { } /** - * @since 9.1.7 * @return NAMESPACE + * @since 9.1.7 */ @Override public String namespace() { diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/BusinessAppHdrV02.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/BusinessAppHdrV02.java index 2792ea58e..8b5ccbd24 100644 --- a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/BusinessAppHdrV02.java +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/BusinessAppHdrV02.java @@ -221,11 +221,11 @@ public Element element() { } /** - * @since 9.1.7 * @return NAMESPACE + * @since 9.1.7 */ @Override - public String namespace(){ + public String namespace() { return NAMESPACE; } } diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/LegacyAppHdr.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/LegacyAppHdr.java index b36d1faa6..9e6002735 100644 --- a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/LegacyAppHdr.java +++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/LegacyAppHdr.java @@ -211,11 +211,11 @@ public Element element() { } /** - * @since 9.1.7 * @return NAMESPACE + * @since 9.1.7 */ @Override - public String namespace(){ + public String namespace() { return NAMESPACE; } diff --git a/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java index c707f13c1..c9f7e237a 100644 --- a/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java +++ b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/AbstractMxJsonTest.java @@ -23,23 +23,11 @@ import java.math.BigDecimal; import java.util.GregorianCalendar; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import com.prowidesoftware.swift.model.mx.dic.AccountStatement6; -import com.prowidesoftware.swift.model.mx.dic.BankToCustomerStatementV06; -import com.prowidesoftware.swift.model.mx.dic.BranchAndFinancialInstitutionIdentification5; -import com.prowidesoftware.swift.model.mx.dic.BranchData2; -import com.prowidesoftware.swift.model.mx.dic.CashAccount25; -import com.prowidesoftware.swift.model.mx.dic.CustomerCreditTransferInitiationV08; -import com.prowidesoftware.swift.model.mx.dic.GroupHeader48; -import com.prowidesoftware.swift.model.mx.dic.OrganisationIdentification8; -import com.prowidesoftware.swift.model.mx.dic.Party11Choice; -import com.prowidesoftware.swift.model.mx.dic.PartyIdentification43; - import static org.junit.jupiter.api.Assertions.*; /** * Test for JSON conversion in the MX model (AbstractMX and subclasses). + * * @since 7.10.2 */ public class AbstractMxJsonTest { @@ -294,7 +282,6 @@ public void parseSerializedMxWithAppHdr() { assertEquals(mx, mx2); } - @Test public void parseSerializedMxWithAppHdrBAH_V1() { final String json = "{\n" + @@ -342,11 +329,12 @@ public void parseSerializedMxWithAppHdrBAH_V1() { AbstractMX source = AbstractMX.fromJson(json); AbstractMX mx = AbstractMX.fromJson(source.toJson()); AbstractMX mx2 = AbstractMX.fromJson(mx.toJson()); + assertEquals(mx, mx2); + BusinessAppHdrV01 BAH_V1 = (BusinessAppHdrV01) mx.getAppHdr(); assertNotNull(BAH_V1); } - @Test public void parseSerializedMxWithAppHdrBAH_V2() { final String json = "{\n" + @@ -394,12 +382,12 @@ public void parseSerializedMxWithAppHdrBAH_V2() { AbstractMX source = AbstractMX.fromJson(json); AbstractMX mx = AbstractMX.fromJson(source.toJson()); AbstractMX mx2 = AbstractMX.fromJson(mx.toJson()); - assertEquals(mx,mx2); + assertEquals(mx, mx2); + BusinessAppHdrV02 BAH_V2 = (BusinessAppHdrV02) mx.getAppHdr(); assertNotNull(BAH_V2); } - @Test public void parseSerializedMxWithAppHdrNoNameSpace() { final String json = "{\n" + @@ -448,11 +436,10 @@ public void parseSerializedMxWithAppHdrNoNameSpace() { AbstractMX mx2 = AbstractMX.fromJson(mx.toJson()); assertEquals(mx, mx2); - BusinessAppHdrV01 legacyAppHdr = (BusinessAppHdrV01) mx.getAppHdr(); + LegacyAppHdr legacyAppHdr = (LegacyAppHdr) mx.getAppHdr(); assertNotNull(legacyAppHdr); } - @Test public void parseSerializedMxWithAppHdrInvalidNamespace() { final String json = "{\n" + @@ -505,4 +492,5 @@ public void parseSerializedMxWithAppHdrInvalidNamespace() { LegacyAppHdr legacyAppHdr = (LegacyAppHdr) mx.getAppHdr(); assertNotNull(legacyAppHdr); } + } \ No newline at end of file