From dcda52d65f45d9bf8385a62863e4a0b7b514ab98 Mon Sep 17 00:00:00 2001 From: dankl Date: Sun, 6 Oct 2019 15:37:11 +0200 Subject: [PATCH] Implemented replacing empty data element group separators at end of segment (so that segment doesn't end with e.g. ...+DE+++') --- .../fints/messages/segmente/Segment.kt | 22 ++++++++- .../implementierte/Verschluesselungskopf.kt | 3 +- .../fints/messages/MessageBuilderTest.kt | 2 +- .../fints/messages/segmente/SegmentTest.kt | 46 +++++++++++++++++++ .../VerschluesselungskopfTest.kt | 2 +- 5 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 fints4javaLib/src/test/kotlin/net/dankito/fints/messages/segmente/SegmentTest.kt diff --git a/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/Segment.kt b/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/Segment.kt index d5666daf..f9783ccb 100644 --- a/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/Segment.kt +++ b/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/Segment.kt @@ -3,13 +3,33 @@ package net.dankito.fints.messages.segmente import net.dankito.fints.messages.Existenzstatus import net.dankito.fints.messages.Separators import net.dankito.fints.messages.datenelemente.DatenelementBase +import java.util.regex.Pattern abstract class Segment(val dataElementsAndGroups: List, existenzstatus: Existenzstatus) : DatenelementBase(existenzstatus) { + companion object { + val ReplaceEmptyDataElementGroupSeparatorsAtEndPattern = + Pattern.compile("\\${Separators.DataElementGroupsSeparator}*\$") + } + + override fun format(): String { - return dataElementsAndGroups.joinToString(Separators.DataElementGroupsSeparator) { it.format() } + val formattedSegment = dataElementsAndGroups.joinToString(Separators.DataElementGroupsSeparator) { it.format() } + + return cutEmptyDataElementGroupsAtEndOfSegment(formattedSegment) + } + + /** + * Auslassen von Datenelementen durch Abschneiden + * Ist für DE, die am Ende eines Segments stehen, kein Inhalt vorhanden, können sie ausgelassen werden. + * In diesem Fall wird das Segmentende-Zeichen unmittelbar nach dem letzten mit Inhalt belegten DE angegeben. + */ + protected open fun cutEmptyDataElementGroupsAtEndOfSegment(formattedSegment: String): String { + val matcher = ReplaceEmptyDataElementGroupSeparatorsAtEndPattern.matcher(formattedSegment) + + return matcher.replaceFirst("") } } \ No newline at end of file diff --git a/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/implementierte/Verschluesselungskopf.kt b/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/implementierte/Verschluesselungskopf.kt index 6ebff293..73e34695 100644 --- a/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/implementierte/Verschluesselungskopf.kt +++ b/fints4javaLib/src/main/kotlin/net/dankito/fints/messages/segmente/implementierte/Verschluesselungskopf.kt @@ -54,6 +54,5 @@ open class Verschluesselungskopf( VerschluesselungsalgorithmusDatenelementgruppe(mode), Schluesselname(bank.countryCode, bank.bankCode, customer.customerId, key, keyNumber, keyVersion), KomprimierungsfunktionDatenelement(algorithm), - // Certificate not applicapable for PIN/TAN; it should be also fine to write nothing at all and therefore leave NotAllowedDatenelement away - NotAllowedDatenelement() // Zertifikat is actually a Datenelementgruppe, not a Datenelement + NotAllowedDatenelement() // Certificate not applicapable for PIN/TAN ), Existenzstatus.Mandatory) \ No newline at end of file diff --git a/fints4javaLib/src/test/kotlin/net/dankito/fints/messages/MessageBuilderTest.kt b/fints4javaLib/src/test/kotlin/net/dankito/fints/messages/MessageBuilderTest.kt index e6a1685a..7e1bd9a6 100644 --- a/fints4javaLib/src/test/kotlin/net/dankito/fints/messages/MessageBuilderTest.kt +++ b/fints4javaLib/src/test/kotlin/net/dankito/fints/messages/MessageBuilderTest.kt @@ -64,7 +64,7 @@ class MessageBuilderTest : FinTsTestBase() { // then assertThat(normalizeBinaryData(result)).isEqualTo(normalizeBinaryData( "HNHBK:1:3+000000000386+300+0+1'" + - "HNVSK:998:3+PIN:2+998+1+1::0+1:$Date:$Time+2:16:14:@8@ :5:1+280:$BankCode:$CustomerId:V:0:0+0+'" + + "HNVSK:998:3+PIN:2+998+1+1::0+1:$Date:$Time+2:16:14:@8@ :5:1+280:$BankCode:$CustomerId:V:0:0+0'" + "HNVSD:999:1+@221@" + "HNSHK:2:4+PIN:2+${SecurityFunction.code}+$ControlReference+1+1+1::0+1+1:$Date:$Time+1:999:1+6:10:16+280:$BankCode:$CustomerId:S:0:0'" + "HKIDN:3:2+280:$BankCode+$CustomerId+0+1'" + "HKVVB:4:3+0+0+${Language.code}+$ProductName+$ProductVersion'" + diff --git a/fints4javaLib/src/test/kotlin/net/dankito/fints/messages/segmente/SegmentTest.kt b/fints4javaLib/src/test/kotlin/net/dankito/fints/messages/segmente/SegmentTest.kt new file mode 100644 index 00000000..e584dc13 --- /dev/null +++ b/fints4javaLib/src/test/kotlin/net/dankito/fints/messages/segmente/SegmentTest.kt @@ -0,0 +1,46 @@ +package net.dankito.fints.messages.segmente + +import net.dankito.fints.messages.Existenzstatus +import net.dankito.fints.messages.datenelemente.DatenelementBase +import net.dankito.fints.messages.datenelemente.basisformate.TextDatenelement +import org.assertj.core.api.Assertions.assertThat +import org.junit.Test + +class SegmentTest { + + @Test + fun format_CutEmptyDataElementGroupsAtSegmentEnd() { + + // given + val underTest = object : Segment(listOf( + createTextDataElement("DE1"), + createTextDataElement("DE2"), + createEmptyTextDataElement(), + createEmptyTextDataElement(), + createEmptyTextDataElement(), + createTextDataElement("DE6"), + createEmptyTextDataElement(), + createTextDataElement("DE8"), + createEmptyTextDataElement(), + createEmptyTextDataElement() + ), Existenzstatus.Mandatory) { } + + + // when + val result = underTest.format() + + // then + // assert that empty data elements at end get cut but that the empty ones in the middle remain + assertThat(result).isEqualTo("DE1+DE2++++DE6++DE8") + } + + + private fun createEmptyTextDataElement(): DatenelementBase { + return createTextDataElement("") + } + + private fun createTextDataElement(text: String): DatenelementBase { + return object : TextDatenelement(text, Existenzstatus.Optional) { } + } + +} \ No newline at end of file diff --git a/fints4javaLib/src/test/kotlin/net/dankito/fints/messages/segmente/implementierte/VerschluesselungskopfTest.kt b/fints4javaLib/src/test/kotlin/net/dankito/fints/messages/segmente/implementierte/VerschluesselungskopfTest.kt index f8d614b5..d3417852 100644 --- a/fints4javaLib/src/test/kotlin/net/dankito/fints/messages/segmente/implementierte/VerschluesselungskopfTest.kt +++ b/fints4javaLib/src/test/kotlin/net/dankito/fints/messages/segmente/implementierte/VerschluesselungskopfTest.kt @@ -18,7 +18,7 @@ class VerschluesselungskopfTest : FinTsTestBase() { val result = underTest.format() // then - assertThat(normalizeBinaryData(result)).isEqualTo("HNVSK:998:3+PIN:2+998+1+1::0+1:$Date:$Time+2:16:14:@8@ :5:1+280:$BankCode:$CustomerId:V:0:0+0+") + assertThat(normalizeBinaryData(result)).isEqualTo("HNVSK:998:3+PIN:2+998+1+1::0+1:$Date:$Time+2:16:14:@8@ :5:1+280:$BankCode:$CustomerId:V:0:0+0") } } \ No newline at end of file