From 9b2e4100f32914cf0839706a9dbada269a810428 Mon Sep 17 00:00:00 2001 From: dankl Date: Sun, 20 Oct 2019 19:23:19 +0200 Subject: [PATCH] Extracted MessageUtils --- .../dankito/fints/response/ResponseParser.kt | 60 ++------------- .../net/dankito/fints/util/MessageUtils.kt | 76 +++++++++++++++++++ 2 files changed, 81 insertions(+), 55 deletions(-) create mode 100644 fints4javaLib/src/main/kotlin/net/dankito/fints/util/MessageUtils.kt diff --git a/fints4javaLib/src/main/kotlin/net/dankito/fints/response/ResponseParser.kt b/fints4javaLib/src/main/kotlin/net/dankito/fints/response/ResponseParser.kt index 8d2f3214..827bcce6 100644 --- a/fints4javaLib/src/main/kotlin/net/dankito/fints/response/ResponseParser.kt +++ b/fints4javaLib/src/main/kotlin/net/dankito/fints/response/ResponseParser.kt @@ -1,6 +1,5 @@ package net.dankito.fints.response -import net.dankito.fints.extensions.allIndicesOf import net.dankito.fints.messages.Separators import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Datum import net.dankito.fints.messages.datenelemente.abgeleiteteformate.Uhrzeit @@ -17,20 +16,19 @@ import net.dankito.fints.messages.segmente.id.MessageSegmentId import net.dankito.fints.response.segments.* import net.dankito.fints.transactions.IAccountTransactionsParser import net.dankito.fints.transactions.Mt940AccountTransactionsParser +import net.dankito.fints.util.MessageUtils import org.slf4j.LoggerFactory import java.math.BigDecimal import java.util.* -import java.util.regex.Matcher import java.util.regex.Pattern open class ResponseParser @JvmOverloads constructor( - protected val mt940Parser: IAccountTransactionsParser = Mt940AccountTransactionsParser() + protected val mt940Parser: IAccountTransactionsParser = Mt940AccountTransactionsParser(), + protected val messageUtils: MessageUtils = MessageUtils() ) { companion object { - val BinaryDataHeaderPattern = Pattern.compile("@\\d+@") - val EncryptionDataSegmentHeaderPattern = Pattern.compile("${MessageSegmentId.EncryptionData.id}:\\d{1,3}:\\d{1,3}\\+") val JobParametersSegmentPattern = Pattern.compile("HI[A-Z]{3}S") @@ -495,24 +493,10 @@ open class ResponseParser @JvmOverloads constructor( * * After string is split, unmask separator * - * Also binary data shouldn't be taken into account (TODO: really?). + * Also binary data shouldn't be taken into account. */ protected open fun splitIntoPartsAndUnmask(dataString: String, separator: String): List { - val binaryDataRanges = mutableListOf() - val binaryDataMatcher = BinaryDataHeaderPattern.matcher(dataString) - - while (binaryDataMatcher.find()) { - if (isEncryptionDataSegment(dataString, binaryDataMatcher) == false) { - val startIndex = binaryDataMatcher.end() - val length = binaryDataMatcher.group().replace("@", "").toInt() - - binaryDataRanges.add(IntRange(startIndex, startIndex + length - 1)) - } - } - - val separatorIndices = dataString.allIndicesOf(separator) - .filter { isCharacterMasked(it, dataString) == false } - .filter { isInRange(it, binaryDataRanges) == false } + val separatorIndices = messageUtils.findSeparatorIndices(dataString, separator) var startIndex = 0 val elements = separatorIndices.map { endIndex -> @@ -528,40 +512,6 @@ open class ResponseParser @JvmOverloads constructor( return elements.map { it.replace(Separators.MaskingCharacter + separator, separator) } } - protected open fun isEncryptionDataSegment(dataString: String, binaryDataMatcher: Matcher): Boolean { - val binaryDataHeaderStartIndex = binaryDataMatcher.start() - - if (binaryDataHeaderStartIndex > 15) { - val encryptionDataSegmentMatcher = EncryptionDataSegmentHeaderPattern.matcher(dataString) - - if (encryptionDataSegmentMatcher.find(binaryDataHeaderStartIndex - 15)) { - return encryptionDataSegmentMatcher.start() < binaryDataHeaderStartIndex - } - } - - return false - } - - protected open fun isCharacterMasked(characterIndex: Int, wholeString: String): Boolean { - if (characterIndex > 0) { - val previousChar = wholeString[characterIndex - 1] - - return previousChar.toString() == Separators.MaskingCharacter - } - - return false - } - - protected open fun isInRange(index: Int, ranges: List): Boolean { - for (range in ranges) { - if (range.contains(index)) { - return true - } - } - - return false - } - protected open fun parseStringToNullIfEmpty(string: String): String? { val parsedString = parseString(string) diff --git a/fints4javaLib/src/main/kotlin/net/dankito/fints/util/MessageUtils.kt b/fints4javaLib/src/main/kotlin/net/dankito/fints/util/MessageUtils.kt new file mode 100644 index 00000000..e28182c9 --- /dev/null +++ b/fints4javaLib/src/main/kotlin/net/dankito/fints/util/MessageUtils.kt @@ -0,0 +1,76 @@ +package net.dankito.fints.util + +import net.dankito.fints.extensions.allIndicesOf +import net.dankito.fints.messages.Separators +import net.dankito.fints.response.ResponseParser +import java.util.regex.Matcher +import java.util.regex.Pattern + + +open class MessageUtils { + + companion object { + val BinaryDataHeaderPattern = Pattern.compile("@\\d+@") + } + + + open fun findSeparatorIndices(dataString: String, separator: String): List { + return findSeparatorIndices(dataString, separator, findBinaryDataRanges(dataString)) + } + + open fun findSeparatorIndices(dataString: String, separator: String, binaryDataRanges: List): List { + return dataString.allIndicesOf(separator) + .filter { isCharacterMasked(it, dataString) == false } + .filter { isInRange(it, binaryDataRanges) == false } + } + + open fun findBinaryDataRanges(dataString: String): List { + val binaryDataRanges = mutableListOf() + val binaryDataMatcher = BinaryDataHeaderPattern.matcher(dataString) + + while (binaryDataMatcher.find()) { + if (isEncryptionDataSegment(dataString, binaryDataMatcher) == false) { + val startIndex = binaryDataMatcher.end() + val length = binaryDataMatcher.group().replace("@", "").toInt() + + binaryDataRanges.add(IntRange(startIndex, startIndex + length - 1)) + } + } + return binaryDataRanges + } + + open fun isEncryptionDataSegment(dataString: String, binaryDataMatcher: Matcher): Boolean { + val binaryDataHeaderStartIndex = binaryDataMatcher.start() + + if (binaryDataHeaderStartIndex > 15) { + val encryptionDataSegmentMatcher = ResponseParser.EncryptionDataSegmentHeaderPattern.matcher(dataString) + + if (encryptionDataSegmentMatcher.find(binaryDataHeaderStartIndex - 15)) { + return encryptionDataSegmentMatcher.start() < binaryDataHeaderStartIndex + } + } + + return false + } + + open fun isCharacterMasked(characterIndex: Int, wholeString: String): Boolean { + if (characterIndex > 0) { + val previousChar = wholeString[characterIndex - 1] + + return previousChar.toString() == Separators.MaskingCharacter + } + + return false + } + + open fun isInRange(index: Int, ranges: List): Boolean { + for (range in ranges) { + if (range.contains(index)) { + return true + } + } + + return false + } + +} \ No newline at end of file