Started FinTsClientSwift but which results due Kotlin/Native's shared XOR mutable in very ugly code
This commit is contained in:
parent
7e19930742
commit
fa6fdd0800
|
@ -0,0 +1,32 @@
|
|||
import com.soywiz.klock.Date
|
||||
import kotlinx.cinterop.addressOf
|
||||
import kotlinx.cinterop.convert
|
||||
import kotlinx.cinterop.usePinned
|
||||
import platform.Foundation.*
|
||||
|
||||
|
||||
fun String.toNsData(): NSData {
|
||||
return this.encodeToByteArray().toNSData()
|
||||
}
|
||||
|
||||
fun ByteArray.toNSData(): NSData = NSMutableData().apply {
|
||||
if (isEmpty()) return@apply
|
||||
this@toNSData.usePinned {
|
||||
appendBytes(it.addressOf(0), size.convert())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun NSDate?.toDate(): Date? {
|
||||
return this?.toDate()
|
||||
}
|
||||
|
||||
fun NSDate.toDate(): Date {
|
||||
val calendar = NSCalendar.currentCalendar()
|
||||
|
||||
return Date.invoke(
|
||||
calendar.component(NSCalendarUnitYear, this).toInt(),
|
||||
calendar.component(NSCalendarUnitMonth, this).toInt(),
|
||||
calendar.component(NSCalendarUnitDay, this).toInt()
|
||||
)
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
import net.dankito.banking.fints.FinTsClient
|
||||
import net.dankito.banking.fints.callback.FinTsClientCallback
|
||||
import net.dankito.banking.fints.model.AccountData
|
||||
import net.dankito.banking.fints.model.AccountFeature
|
||||
import net.dankito.banking.fints.model.BankData
|
||||
import net.dankito.banking.fints.model.CustomerData
|
||||
import net.dankito.banking.fints.response.client.AddAccountResponse
|
||||
import net.dankito.banking.fints.response.client.FinTsClientResponse
|
||||
import net.dankito.banking.fints.response.client.GetTransactionsResponse
|
||||
import net.dankito.banking.fints.util.log.LoggerFactory
|
||||
import net.dankito.banking.fints.webclient.IWebClient
|
||||
import kotlin.native.concurrent.TransferMode
|
||||
import kotlin.native.concurrent.Worker
|
||||
import kotlin.native.concurrent.freeze
|
||||
|
||||
|
||||
open class FinTsClientWorkerArgument(val bank: BankData, val customer: CustomerData, val webClient: IWebClient, val callback: FinTsClientCallback)
|
||||
|
||||
class GetTransactionsWorkerArgument(val parameter: GetTransactionsParameter, val account: AccountData,
|
||||
bank: BankData, customer: CustomerData, webClient: IWebClient, callback: FinTsClientCallback)
|
||||
: FinTsClientWorkerArgument(bank, customer, webClient, callback)
|
||||
|
||||
data class FinTsClientWorkerResult<T : FinTsClientResponse>(
|
||||
val bank: BankData, val customer: CustomerData, val response: T)
|
||||
|
||||
|
||||
open class FinTsClientSwift(
|
||||
protected val bank: BankData,
|
||||
protected val customer: CustomerData,
|
||||
protected val webClient: IWebClient,
|
||||
protected val callback: FinTsClientCallback
|
||||
) {
|
||||
|
||||
init {
|
||||
webClient.freeze()
|
||||
callback.freeze()
|
||||
}
|
||||
|
||||
|
||||
protected val worker = Worker.start(name = "FinTsClient worker for $customer")
|
||||
|
||||
|
||||
open fun addAccountAsync(callback: (AddAccountResponse) -> Unit) {
|
||||
val future = worker.execute(TransferMode.SAFE, { createWorkerArgument() }) { arg ->
|
||||
val client = FinTsClient(arg.callback, arg.webClient)
|
||||
|
||||
// unbelievable, i am not allowed to use the createCopy() methods
|
||||
val bank = BankData(
|
||||
arg.bank.bankCode, arg.bank.countryCode, arg.bank.finTs3ServerAddress, arg.bank.bic, arg.bank.bpdVersion,
|
||||
arg.bank.name, arg.bank.countMaxJobsPerMessage, arg.bank.supportedHbciVersions, arg.bank.supportedTanProcedures,
|
||||
arg.bank.changeTanMediumParameters, arg.bank.pinInfo, arg.bank.supportedLanguages, arg.bank.supportedJobs
|
||||
)
|
||||
val customer = CustomerData(
|
||||
arg.customer.customerId, arg.customer.pin, arg.customer.userId, arg.customer.name, arg.customer.updVersion,
|
||||
arg.customer.supportedTanProcedures, arg.customer.selectedTanProcedure, arg.customer.tanMedia,
|
||||
arg.customer.selectedLanguage, arg.customer.customerSystemId, arg.customer.customerSystemStatus
|
||||
)
|
||||
|
||||
val response = client.addAccount(bank, customer)
|
||||
|
||||
FinTsClientWorkerResult(bank.freeze(), customer.freeze(), response.freeze())
|
||||
}
|
||||
|
||||
future.consume { result ->
|
||||
map(bank, result.bank)
|
||||
map(customer, result.customer)
|
||||
|
||||
callback(result.response)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
open fun getTransactionsAsync(parameter: GetTransactionsParameter, account: AccountData, callback: (GetTransactionsResponse) -> Unit) {
|
||||
val future = worker.execute(TransferMode.SAFE, { createWorkerArgument(parameter, account) }) { arg ->
|
||||
val client = FinTsClient(arg.callback, arg.webClient)
|
||||
|
||||
// unbelievable, i am not allowed to use the createCopy() methods
|
||||
val bank = BankData(
|
||||
arg.bank.bankCode, arg.bank.countryCode, arg.bank.finTs3ServerAddress, arg.bank.bic, arg.bank.bpdVersion,
|
||||
arg.bank.name, arg.bank.countMaxJobsPerMessage, arg.bank.supportedHbciVersions, arg.bank.supportedTanProcedures,
|
||||
arg.bank.changeTanMediumParameters, arg.bank.pinInfo, arg.bank.supportedLanguages, arg.bank.supportedJobs
|
||||
)
|
||||
val customer = CustomerData(
|
||||
arg.customer.customerId, arg.customer.pin, arg.customer.userId, arg.customer.name, arg.customer.updVersion,
|
||||
arg.customer.supportedTanProcedures, arg.customer.selectedTanProcedure, arg.customer.tanMedia,
|
||||
arg.customer.selectedLanguage, arg.customer.customerSystemId, arg.customer.customerSystemStatus
|
||||
)
|
||||
|
||||
val parameter = net.dankito.banking.fints.model.GetTransactionsParameter(
|
||||
arg.parameter.alsoRetrieveBalance, arg.parameter.fromDate.toDate(), arg.parameter.toDate.toDate(),
|
||||
arg.parameter.maxCountEntries, arg.parameter.abortIfTanIsRequired, arg.parameter.retrievedChunkListener
|
||||
)
|
||||
|
||||
val response = client.getTransactions(parameter, bank, customer, arg.account) // TODO: map account
|
||||
|
||||
FinTsClientWorkerResult(bank.freeze(), customer.freeze(), response.freeze())
|
||||
}
|
||||
|
||||
future.consume { result ->
|
||||
map(bank, result.bank)
|
||||
map(customer, result.customer)
|
||||
|
||||
callback(result.response)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected open fun createWorkerArgument(): FinTsClientWorkerArgument {
|
||||
val bank = createImmutableCopy(this.bank)
|
||||
val customer = createImmutableCopy(this.customer)
|
||||
|
||||
return FinTsClientWorkerArgument(bank, customer, webClient, callback)
|
||||
}
|
||||
|
||||
protected open fun createWorkerArgument(parameter: GetTransactionsParameter, account: AccountData): GetTransactionsWorkerArgument {
|
||||
val bank = createImmutableCopy(this.bank)
|
||||
val customer = createImmutableCopy(this.customer)
|
||||
val frozenAccount = createImmutableCopy(account)
|
||||
|
||||
return GetTransactionsWorkerArgument(parameter.freeze(), frozenAccount, bank, customer, webClient, callback)
|
||||
}
|
||||
|
||||
|
||||
protected open fun createCopy(bank: BankData): BankData {
|
||||
return BankData(
|
||||
bank.bankCode, bank.countryCode, bank.finTs3ServerAddress, bank.bic, bank.bpdVersion,
|
||||
bank.name, bank.countMaxJobsPerMessage, bank.supportedHbciVersions, bank.supportedTanProcedures,
|
||||
bank.changeTanMediumParameters, bank.pinInfo, bank.supportedLanguages, bank.supportedJobs
|
||||
)
|
||||
}
|
||||
|
||||
protected open fun createImmutableCopy(bank: BankData): BankData {
|
||||
return createCopy(bank).freeze()
|
||||
}
|
||||
|
||||
protected open fun createCopy(customer: CustomerData): CustomerData {
|
||||
return CustomerData(
|
||||
customer.customerId, customer.pin, customer.userId, customer.name, customer.updVersion,
|
||||
customer.supportedTanProcedures, customer.selectedTanProcedure, customer.tanMedia,
|
||||
customer.selectedLanguage, customer.customerSystemId, customer.customerSystemStatus
|
||||
)
|
||||
}
|
||||
|
||||
protected open fun createImmutableCopy(customer: CustomerData): CustomerData {
|
||||
return createCopy(customer).freeze()
|
||||
}
|
||||
|
||||
protected open fun createCopy(account: AccountData): AccountData {
|
||||
val copy = AccountData(
|
||||
account.accountIdentifier, account.subAccountAttribute, account.bankCountryCode,
|
||||
account.bankCode, account.iban, account.customerId, account.accountType, account.currency,
|
||||
account.accountHolderName, account.productName, account.accountLimit, account.allowedJobNames,
|
||||
account.allowedJobs, account.supportsRetrievingTransactionsOfLast90DaysWithoutTan,
|
||||
account.triedToRetrieveTransactionsOfLast90DaysWithoutTan
|
||||
)
|
||||
|
||||
AccountFeature.values().forEach { feature ->
|
||||
copy.setSupportsFeature(feature, account.supportsFeature(feature))
|
||||
}
|
||||
|
||||
return copy
|
||||
}
|
||||
|
||||
protected open fun createImmutableCopy(account: AccountData): AccountData {
|
||||
return createCopy(account).freeze()
|
||||
}
|
||||
|
||||
|
||||
protected open fun map(to: BankData, from: BankData) {
|
||||
to.bankCode = from.bankCode
|
||||
to.countryCode = from.countryCode
|
||||
to.finTs3ServerAddress = from.finTs3ServerAddress
|
||||
to.bic = from.bic
|
||||
to.bpdVersion = from.bpdVersion
|
||||
to.name = from.name
|
||||
to.countMaxJobsPerMessage = from.countMaxJobsPerMessage
|
||||
to.supportedHbciVersions = from.supportedHbciVersions
|
||||
to.supportedTanProcedures = from.supportedTanProcedures
|
||||
to.changeTanMediumParameters = from.changeTanMediumParameters
|
||||
to.pinInfo = from.pinInfo
|
||||
to.supportedLanguages = from.supportedLanguages
|
||||
to.supportedJobs = from.supportedJobs
|
||||
}
|
||||
|
||||
protected open fun map(to: CustomerData, from: CustomerData) {
|
||||
to.customerId = from.customerId
|
||||
to.pin = from.pin
|
||||
to.userId = from.userId
|
||||
to.name = from.name
|
||||
to.updVersion = from.updVersion
|
||||
to.supportedTanProcedures = from.supportedTanProcedures
|
||||
to.selectedTanProcedure = from.selectedTanProcedure
|
||||
to.tanMedia = from.tanMedia
|
||||
to.selectedLanguage = from.selectedLanguage
|
||||
to.customerSystemId = from.customerSystemId
|
||||
to.customerSystemStatus = from.customerSystemStatus
|
||||
|
||||
// TODO: create convenience method to set accounts
|
||||
to.accounts.forEach { account ->
|
||||
to.removeAccount(account)
|
||||
}
|
||||
from.accounts.forEach { account ->
|
||||
to.addAccount(account) // TODO: also map account?
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import net.dankito.banking.fints.model.AccountTransaction
|
||||
import platform.Foundation.NSDate
|
||||
|
||||
|
||||
class GetTransactionsParameter(
|
||||
val alsoRetrieveBalance: Boolean = true,
|
||||
val fromDate: NSDate? = null,
|
||||
val toDate: NSDate? = null,
|
||||
val maxCountEntries: Int? = null,
|
||||
val abortIfTanIsRequired: Boolean = false,
|
||||
val retrievedChunkListener: ((List<AccountTransaction>) -> Unit)? = null
|
||||
) {
|
||||
|
||||
constructor() : this(true, null, null, null, false, null)
|
||||
|
||||
}
|
Loading…
Reference in New Issue