Implemented masking data elements' values (required for SEPA descriptor URNs)

This commit is contained in:
dankl 2019-10-20 19:29:28 +02:00 committed by dankito
parent 9b2e4100f3
commit af0e4e923b
4 changed files with 48 additions and 2 deletions

View File

@ -1,8 +1,28 @@
package net.dankito.fints.messages
import net.dankito.fints.util.MessageUtils
abstract class Nachrichtenteil {
abstract class Nachrichtenteil(protected val messageUtils: MessageUtils = MessageUtils()) {
abstract fun format(): String
open fun maskMessagePart(messagePart: String, separator: String): String {
var maskedMessagePart = messagePart
val binaryDataRanges = messageUtils.findBinaryDataRanges(messagePart)
val unmaskedMaskingCharacterIndices = messageUtils.findSeparatorIndices(maskedMessagePart, Separators.MaskingCharacter, binaryDataRanges)
.filter { messageUtils.doesNotMaskSeparatorOrMaskingCharacter(it, maskedMessagePart) }
maskedMessagePart = messageUtils
.maskCharacterAtIndices(maskedMessagePart, Separators.MaskingCharacter, unmaskedMaskingCharacterIndices)
val separatorIndices = messageUtils.findSeparatorIndices(maskedMessagePart, separator, binaryDataRanges)
return messageUtils.maskCharacterAtIndices(maskedMessagePart, separator, separatorIndices)
}
}

View File

@ -11,6 +11,10 @@ class Separators {
const val DataElementsSeparator = ":"
const val MaskingCharacter = "?"
val AllSeparators = listOf(DataElementsSeparator, DataElementGroupsSeparator, SegmentSeparator)
val AllSeparatorsAndMaskingCharacter = listOf(*AllSeparators.toTypedArray(), MaskingCharacter)
}
}

View File

@ -2,6 +2,7 @@ package net.dankito.fints.messages.datenelemente.basisformate
import net.dankito.fints.messages.Existenzstatus
import net.dankito.fints.messages.HbciCharset
import net.dankito.fints.messages.Separators
import net.dankito.fints.messages.datenelemente.Datenelement
@ -24,7 +25,7 @@ abstract class TextDatenelement(val value: String?, existenzstatus: Existenzstat
}
protected open fun formatValue(value: String): String {
return value // may overwritten in sub classes
return maskMessagePart(value, Separators.DataElementsSeparator) // may overwritten in sub classes
}

View File

@ -63,6 +63,16 @@ open class MessageUtils {
return false
}
open fun doesNotMaskSeparatorOrMaskingCharacter(maskingCharacterIndex: Int, messagePart: String): Boolean {
if (maskingCharacterIndex < messagePart.length - 1) {
val nextCharacter = messagePart[maskingCharacterIndex + 1]
return Separators.AllSeparatorsAndMaskingCharacter.contains(nextCharacter.toString()) == false
}
return true
}
open fun isInRange(index: Int, ranges: List<IntRange>): Boolean {
for (range in ranges) {
if (range.contains(index)) {
@ -73,4 +83,15 @@ open class MessageUtils {
return false
}
open fun maskCharacterAtIndices(unmaskedString: String, unmaskedCharacter: String, indices: List<Int>): String {
var maskedString = unmaskedString
indices.sortedDescending().forEach { index ->
maskedString = maskedString.replaceRange(index, index + 1, Separators.MaskingCharacter + unmaskedCharacter
)
}
return maskedString
}
}