Made BankingUiCommon a multi platform project

This commit is contained in:
dankito 2020-07-12 19:31:18 +02:00
parent 588877cb20
commit 52d3b49baa
76 changed files with 478 additions and 326 deletions

View File

@ -1,16 +1,17 @@
package net.dankito.banking.persistence
import net.dankito.utils.multiplatform.File
import net.dankito.banking.ui.model.Customer
import net.dankito.banking.ui.model.AccountTransaction
import net.dankito.banking.ui.model.BankAccount
import net.dankito.banking.util.ISerializer
import net.dankito.banking.util.JacksonJsonSerializer
import java.io.File
import java.io.FileOutputStream
import java.net.URL
open class BankingPersistenceJson(
protected val jsonFile: File,
protected val serializer: ISerializer = JacksonJsonSerializer()
protected val serializer: ISerializer
) : IBankingPersistence {
@ -28,7 +29,7 @@ open class BankingPersistenceJson(
}
override fun readPersistedAccounts(): List<Customer> {
return serializer.deserializeListOr(jsonFile, Customer::class.java, listOf())
return serializer.deserializeListOr(jsonFile, Customer::class, listOf())
}
@ -36,4 +37,13 @@ open class BankingPersistenceJson(
// done when called saveOrUpdateAccount()
}
override fun saveUrlToFile(url: String, file: File) {
URL(url).openConnection().getInputStream().buffered().use { iconInputStream ->
FileOutputStream(file).use { fileOutputStream ->
iconInputStream.copyTo(fileOutputStream)
}
}
}
}

View File

@ -78,9 +78,7 @@ android {
}
dependencies {
implementation project(":fints4k"), {
exclude group: "com.soywiz.korlibs.klock", module: "klock-android" // klock-jvm already adds required extensions, to avoid duplicates
}
implementation project(":fints4k")
implementation project(':BankingUiCommon')

View File

@ -4,9 +4,9 @@ import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import dagger.Module
import dagger.Provides
import net.dankito.utils.multiplatform.File
import net.dankito.banking.ui.android.RouterAndroid
import net.dankito.banking.ui.android.util.CurrentActivityTracker
import net.dankito.banking.ui.android.util.Base64ServiceAndroid
import net.dankito.banking.fints4kBankingClientCreator
import net.dankito.banking.persistence.IBankingPersistence
import net.dankito.banking.persistence.LuceneBankingPersistence
@ -17,6 +17,7 @@ import net.dankito.banking.ui.IRouter
import net.dankito.banking.ui.presenter.BankingPresenter
import net.dankito.banking.bankfinder.IBankFinder
import net.dankito.banking.bankfinder.LuceneBankFinder
import net.dankito.utils.multiplatform.toFile
import net.dankito.banking.util.*
import net.dankito.banking.util.extraction.IInvoiceDataExtractor
import net.dankito.banking.util.extraction.ITextExtractorRegistry
@ -28,7 +29,6 @@ import net.dankito.text.extraction.pdf.iText2PdfTextExtractor
import net.dankito.utils.ThreadPool
import net.dankito.utils.web.client.IWebClient
import net.dankito.utils.web.client.OkHttpWebClient
import java.io.File
import javax.inject.Named
import javax.inject.Singleton
@ -59,7 +59,7 @@ class BankingModule(private val applicationContext: Context) {
@Singleton
@Named(DataFolderKey)
fun provideDataFolder(applicationContext: Context) : File {
return ensureFolderExists(applicationContext.filesDir, "data")
return ensureFolderExists(applicationContext.filesDir.toFile(), "data")
}
@Provides
@ -93,7 +93,7 @@ class BankingModule(private val applicationContext: Context) {
textExtractorRegistry: ITextExtractorRegistry, router: IRouter, invoiceDataExtractor: IInvoiceDataExtractor,
serializer: ISerializer, asyncRunner: IAsyncRunner) : BankingPresenter {
return BankingPresenter(bankingClientCreator, bankFinder, dataFolder, persister,
remitteeSearcher, bankIconFinder, textExtractorRegistry, router, invoiceDataExtractor, serializer, asyncRunner)
router, remitteeSearcher, bankIconFinder, textExtractorRegistry, invoiceDataExtractor, serializer, asyncRunner)
}
@Provides
@ -110,8 +110,8 @@ class BankingModule(private val applicationContext: Context) {
@Provides
@Singleton
fun provideBankingClientCreator() : IBankingClientCreator {
return fints4kBankingClientCreator()
fun provideBankingClientCreator(serializer: ISerializer) : IBankingClientCreator {
return fints4kBankingClientCreator(serializer)
}
@Provides

View File

@ -24,7 +24,6 @@ import net.dankito.banking.ui.android.extensions.closePopupOnBackButtonPress
import net.dankito.banking.ui.android.listener.ListItemSelectedListener
import net.dankito.banking.ui.android.util.StandardAutocompleteCallback
import net.dankito.banking.ui.android.util.StandardTextWatcher
import net.dankito.banking.search.IRemitteeSearcher
import net.dankito.banking.search.Remittee
import net.dankito.banking.ui.model.BankAccount
import net.dankito.banking.ui.model.parameters.TransferMoneyData
@ -32,6 +31,7 @@ import net.dankito.banking.ui.model.responses.BankingClientResponse
import net.dankito.banking.ui.presenter.BankingPresenter
import net.dankito.banking.util.InputValidator
import net.dankito.banking.bankfinder.BankInfo
import net.dankito.utils.multiplatform.toBigDecimal
import net.dankito.utils.android.extensions.asActivity
import java.math.BigDecimal
import java.text.DecimalFormatSymbols
@ -242,7 +242,7 @@ open class TransferMoneyDialog : DialogFragment() {
inputValidator.convertToAllowedSepaCharacters(edtxtRemitteeName.text.toString()),
edtxtRemitteeIban.text.toString().replace(" ", ""),
edtxtRemitteeBic.text.toString().replace(" ", ""),
amount,
amount.toBigDecimal(),
inputValidator.convertToAllowedSepaCharacters(edtxtUsage.text.toString()),
chkbxInstantPayment.isChecked
)

View File

@ -1,22 +0,0 @@
package net.dankito.banking.ui.android.util
import android.util.Base64
import net.dankito.banking.util.IBase64Service
import java.nio.charset.Charset
open class Base64ServiceAndroid : IBase64Service {
override fun encode(text: String, charset: Charset): String {
val bytes = text.toByteArray(charset)
return Base64.encodeToString(bytes, Base64.NO_WRAP)
}
override fun decode(base64: String, charset: Charset): String {
val decoded = Base64.decode(base64, Base64.NO_WRAP)
return String(decoded, charset)
}
}

View File

@ -7,6 +7,7 @@ import androidx.fragment.app.FragmentActivity
import com.github.clans.fab.FloatingActionButton
import com.github.clans.fab.FloatingActionMenu
import kotlinx.android.synthetic.main.view_floating_action_button_main.view.*
import net.dankito.utils.multiplatform.toFile
import net.dankito.banking.ui.android.R
import net.dankito.banking.ui.model.moneytransfer.ExtractTransferMoneyDataFromPdfResult
import net.dankito.banking.ui.model.moneytransfer.ExtractTransferMoneyDataFromPdfResultType
@ -78,7 +79,7 @@ open class MainActivityFloatingActionMenuButton(
selectedFile?.let {
lastSelectedFolder = selectedFile.parentFile
val result = presenter.transferMoneyWithDataFromPdf(selectedFile)
val result = presenter.transferMoneyWithDataFromPdf(selectedFile.toFile())
if (result.type != ExtractTransferMoneyDataFromPdfResultType.Success) {
showTransferMoneyWithDataFromPdfError(activity, selectedFile, result)

View File

@ -1,17 +1,18 @@
package net.dankito.banking.ui.javafx.dialogs.mainwindow
import javafx.scene.control.SplitPane
import net.dankito.utils.multiplatform.File
import net.dankito.banking.fints4kBankingClientCreator
import net.dankito.banking.ui.javafx.RouterJavaFx
import net.dankito.banking.ui.javafx.controls.AccountTransactionsView
import net.dankito.banking.ui.javafx.controls.AccountsView
import net.dankito.banking.ui.javafx.dialogs.mainwindow.controls.MainMenuBar
import net.dankito.banking.ui.javafx.util.Base64ServiceJava8
import net.dankito.banking.ui.presenter.BankingPresenter
import net.dankito.banking.util.BankIconFinder
import net.dankito.banking.bankfinder.LuceneBankFinder
import net.dankito.banking.persistence.LuceneBankingPersistence
import net.dankito.banking.search.LuceneRemitteeSearcher
import net.dankito.banking.util.JacksonJsonSerializer
import net.dankito.banking.util.extraction.JavaTextExtractorRegistry
import net.dankito.text.extraction.TextExtractorRegistry
import net.dankito.text.extraction.TikaTextExtractor
@ -19,10 +20,8 @@ import net.dankito.text.extraction.image.Tesseract4CommandlineImageTextExtractor
import net.dankito.text.extraction.image.model.OcrLanguage
import net.dankito.text.extraction.image.model.TesseractConfig
import net.dankito.text.extraction.pdf.*
import net.dankito.utils.web.client.OkHttpWebClient
import tornadofx.*
import tornadofx.FX.Companion.messages
import java.io.File
class MainWindow : View(messages["application.title"]) {
@ -33,6 +32,8 @@ class MainWindow : View(messages["application.title"]) {
private val indexFolder = ensureFolderExists(dataFolder, "index")
private val serializer = JacksonJsonSerializer()
private val tesseractTextExtractor = Tesseract4CommandlineImageTextExtractor(TesseractConfig(listOf(OcrLanguage.English, OcrLanguage.German)))
private val textExtractorRegistry = JavaTextExtractorRegistry(TextExtractorRegistry(pdffontsPdfTypeDetector(), listOf(
@ -41,12 +42,12 @@ class MainWindow : View(messages["application.title"]) {
tesseractTextExtractor, TikaTextExtractor()
)))
private val presenter = BankingPresenter(fints4kBankingClientCreator(),
private val presenter = BankingPresenter(fints4kBankingClientCreator(serializer),
LuceneBankFinder(indexFolder), dataFolder, LuceneBankingPersistence(indexFolder, databaseFolder),
LuceneRemitteeSearcher(indexFolder), BankIconFinder(), textExtractorRegistry, RouterJavaFx())
RouterJavaFx(), LuceneRemitteeSearcher(indexFolder), BankIconFinder(), textExtractorRegistry)
// private val presenter = BankingPresenter(hbci4jBankingClientCreator(), LuceneBankFinder(indexFolder),
// dataFolder, LuceneBankingPersistence(indexFolder, databaseFolder), LuceneRemitteeSearcher(indexFolder),
// BankIconFinder(), textExtractorRegistry, RouterJavaFx())
// dataFolder, LuceneBankingPersistence(indexFolder, databaseFolder), RouterJavaFx(), LuceneRemitteeSearcher(indexFolder),
// BankIconFinder(), textExtractorRegistry)

View File

@ -5,6 +5,7 @@ import javafx.scene.input.KeyCode
import javafx.scene.input.KeyCodeCombination
import javafx.scene.input.KeyCombination
import javafx.stage.FileChooser
import net.dankito.utils.multiplatform.toFile
import net.dankito.banking.ui.model.moneytransfer.ExtractTransferMoneyDataFromPdfResult
import net.dankito.banking.ui.model.moneytransfer.ExtractTransferMoneyDataFromPdfResultType
import net.dankito.banking.ui.presenter.BankingPresenter
@ -79,7 +80,7 @@ open class MainMenuBar(protected val presenter: BankingPresenter) : View() {
fileChooser.showOpenDialog(currentStage)?.let { pdfFile ->
lastSelectedFolder = pdfFile.parentFile
val result = presenter.transferMoneyWithDataFromPdf(pdfFile)
val result = presenter.transferMoneyWithDataFromPdf(pdfFile.toFile())
if (result.type != ExtractTransferMoneyDataFromPdfResultType.Success) {
showTransferMoneyWithDataFromPdfError(pdfFile, result)

View File

@ -19,6 +19,7 @@ import net.dankito.banking.ui.presenter.BankingPresenter
import net.dankito.banking.util.InputValidator
import net.dankito.banking.bankfinder.BankInfo
import net.dankito.banking.search.Remittee
import net.dankito.utils.multiplatform.toBigDecimal
import net.dankito.banking.ui.javafx.extensions.focusNextControl
import net.dankito.utils.javafx.ui.controls.AutoCompletionSearchTextField
import net.dankito.utils.javafx.ui.controls.autocompletionsearchtextfield
@ -352,7 +353,7 @@ open class TransferMoneyDialog @JvmOverloads constructor(
inputValidator.convertToAllowedSepaCharacters(remitteeName.value),
remitteeIban.value.replace(" ", ""),
remitteeBic.value.replace(" ", ""),
amount.value.toBigDecimal(),
amount.value.toBigDecimal().toBigDecimal(),
inputValidator.convertToAllowedSepaCharacters(usage.value),
instantPayment.value
)

View File

@ -1,27 +1,62 @@
apply plugin: 'java-library'
apply plugin: 'kotlin'
plugins {
id "org.jetbrains.kotlin.multiplatform"
id "com.android.library"
id "maven-publish"
}
ext.artifactName = "banking-ui-common"
sourceCompatibility = "1.7"
targetCompatibility = "1.7"
kotlin {
jvm {
compilations.main.kotlinOptions {
jvmTarget = "1.6"
}
}
compileKotlin {
kotlinOptions.jvmTarget = "1.6"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.6"
}
targets {
// Select iOS target for real device or emulator.
final def iOSIsRealDevice = System.getenv('SDK_NAME')?.startsWith("iphoneos")
final def iOSTarget = iOSIsRealDevice ? presets.iosArm64 : presets.iosX64
// iOS target.
fromPreset(iOSTarget, 'ios') {
binaries {
framework {
baseName = "BankingUiCommon"
}
}
}
}
dependencies {
api "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
sourceSets {
commonMain {
dependencies {
api kotlin("stdlib-common")
api "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$kotlinCoroutinesVersion"
api "net.dankito.utils:java-utils:$javaUtilsVersion"
// TODO: try to get rid of this import
api project(":fints4k")
api project(":BankFinder")
}
}
commonTest {
dependencies {
implementation kotlin("test-common")
implementation kotlin("test-annotations-common")
implementation "ch.tutteli.atrium:atrium-fluent-en_GB:$atriumVersion"
}
}
jvmMain {
dependencies {
api "net.dankito.utils:java-utils:$javaUtilsVersion"
api "net.dankito.text.extraction:text-extractor-common:$textExtractorVersion"
api "net.dankito.text.extraction:text-info-extractor:$textInfoExtractorVersion"
@ -29,13 +64,102 @@ dependencies {
implementation "net.dankito.utils:favicon-finder:1.0.0-SNAPSHOT"
implementation "org.jsoup:jsoup:1.13.1"
}
}
// TODO: try to get rid of this import
api project(':fints4k')
jvmTest {
dependencies {
implementation kotlin("test-junit")
implementation "junit:junit:$junitVersion"
// implementation "org.junit.jupiter:junit-jupiter:$junit5Version"
// runtimeOnly "org.junit.jupiter:junit-jupiter-engine:$junit5Version"
implementation "org.assertj:assertj-core:$assertJVersion"
implementation "org.mockito:mockito-core:$mockitoVersion"
implementation "ch.tutteli.atrium:atrium-api-fluent-en_GB-jdk8:$atriumVersion"
implementation "org.slf4j:slf4j-simple:$slf4jVersion"
}
}
testImplementation "junit:junit:$junitVersion"
testImplementation "org.assertj:assertj-core:$assertJVersion"
iosMain {
dependencies {
api "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlinVersion"
api "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:$kotlinCoroutinesVersion"
}
}
}
}
// Task to generate iOS framework for xcode projects.
task packForXCode(type: Sync) {
final File frameworkDir = new File(buildDir, "xcode-frameworks")
final String mode = project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG'
final def framework = kotlin.targets.ios.binaries.getFramework("", mode)
inputs.property "mode", mode
dependsOn framework.linkTask
from { framework.outputFile.parentFile }
into frameworkDir
doLast {
new File(frameworkDir, 'gradlew').with {
text = "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n"
setExecutable(true)
}
}
}
// Run packForXCode when building.
tasks.build.dependsOn packForXCode
android {
compileSdkVersion androidCompileSdkVersion
defaultConfig {
minSdkVersion androidMinSdkVersion
targetSdkVersion androidTargetSdkVersion
versionName version
versionCode appVersionCode
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
packagingOptions {
pickFirst 'META-INF/ktor-http.kotlin_module'
pickFirst 'META-INF/kotlinx-io.kotlin_module'
pickFirst 'META-INF/atomicfu.kotlin_module'
pickFirst 'META-INF/ktor-utils.kotlin_module'
pickFirst 'META-INF/kotlinx-coroutines-io.kotlin_module'
pickFirst 'META-INF/ktor-client-core.kotlin_module'
pickFirst 'META-INF/DEPENDENCIES'
pickFirst 'META-INF/NOTICE'
pickFirst 'META-INF/LICENSE'
pickFirst 'META-INF/LICENSE.txt'
pickFirst 'META-INF/NOTICE.txt'
}
lintOptions {
abortOnError false
}
testImplementation "org.slf4j:slf4j-simple:$slf4jVersion"
}

View File

@ -1,5 +1,6 @@
package net.dankito.banking.persistence
import net.dankito.utils.multiplatform.File
import net.dankito.banking.ui.model.Customer
import net.dankito.banking.ui.model.AccountTransaction
import net.dankito.banking.ui.model.BankAccount
@ -16,4 +17,6 @@ interface IBankingPersistence {
fun saveOrUpdateAccountTransactions(bankAccount: BankAccount, transactions: List<AccountTransaction>)
fun saveUrlToFile(url: String, file: File)
}

View File

@ -0,0 +1,33 @@
package net.dankito.banking.persistence
import net.dankito.banking.ui.model.AccountTransaction
import net.dankito.banking.ui.model.BankAccount
import net.dankito.banking.ui.model.Customer
import net.dankito.utils.multiplatform.File
open class NoOpBankingPersistence : IBankingPersistence {
override fun saveOrUpdateAccount(customer: Customer, allCustomers: List<Customer>) {
}
override fun deleteAccount(customer: Customer, allCustomers: List<Customer>) {
}
override fun readPersistedAccounts(): List<Customer> {
return listOf()
}
override fun saveOrUpdateAccountTransactions(bankAccount: BankAccount, transactions: List<AccountTransaction>) {
}
override fun saveUrlToFile(url: String, file: File) {
}
}

View File

@ -0,0 +1,10 @@
package net.dankito.banking.search
open class NoOpRemitteeSearcher : IRemitteeSearcher {
override fun findRemittees(query: String): List<Remittee> {
return listOf()
}
}

View File

@ -1,8 +1,8 @@
package net.dankito.banking.ui
import net.dankito.utils.multiplatform.File
import net.dankito.banking.bankfinder.BankInfo
import net.dankito.banking.util.IAsyncRunner
import java.io.File
interface IBankingClientCreator {

View File

@ -1,14 +1,14 @@
package net.dankito.banking.ui.model
import com.fasterxml.jackson.annotation.JsonIdentityInfo
import com.fasterxml.jackson.annotation.ObjectIdGenerators
import java.math.BigDecimal
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*
//import com.fasterxml.jackson.annotation.JsonIdentityInfo
//import com.fasterxml.jackson.annotation.ObjectIdGenerators
import net.dankito.utils.multiplatform.BigDecimal
import net.dankito.utils.multiplatform.Date
import net.dankito.utils.multiplatform.DateFormatStyle
import net.dankito.utils.multiplatform.DateFormatter
@JsonIdentityInfo(property = "id", generator = ObjectIdGenerators.PropertyGenerator::class) // to avoid stack overflow due to circular references
//@JsonIdentityInfo(property = "id", generator = ObjectIdGenerators.PropertyGenerator::class) // to avoid stack overflow due to circular references
open class AccountTransaction(
open val bankAccount: BankAccount,
open val amount: BigDecimal,
@ -50,7 +50,7 @@ open class AccountTransaction(
) {
companion object {
val IdDateFormat = SimpleDateFormat("yyyy.MM.dd")
val IdDateFormat = DateFormatter("yyyy.MM.dd")
}
@ -62,7 +62,7 @@ open class AccountTransaction(
0, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "", "", null, null, "", null)
// for object deserializers
internal constructor() : this(BankAccount(), BigDecimal.ZERO, "","", Date(), null, null, null, null, Date(), 0, null, BigDecimal.ZERO, BigDecimal.ZERO,
internal constructor() : this(BankAccount(), BigDecimal.Zero, "","", Date(), null, null, null, null, Date(), 0, null, BigDecimal.Zero, BigDecimal.Zero,
null, null, null, null, null, null, null, null, null, null, null, null, null,
null, "", "", null, null, "", null)
@ -79,7 +79,7 @@ open class AccountTransaction(
if (other !is AccountTransaction) return false
if (bankAccount != other.bankAccount) return false
if (amount.compareTo(other.amount) != 0) return false
if (amount != other) return false // TODO: does this work?
if (currency != other.currency) return false
if (unparsedUsage != other.unparsedUsage) return false
if (bookingDate != other.bookingDate) return false
@ -108,7 +108,7 @@ open class AccountTransaction(
override fun toString(): String {
return "${DateFormat.getDateInstance(DateFormat.MEDIUM).format(valueDate)} $amount $otherPartyName: $usage"
return "${DateFormatter(DateFormatStyle.Medium).format(valueDate)} $amount $otherPartyName: $usage"
}
}

View File

@ -1,12 +1,14 @@
package net.dankito.banking.ui.model
import com.fasterxml.jackson.annotation.JsonIdentityInfo
import com.fasterxml.jackson.annotation.ObjectIdGenerators
import java.math.BigDecimal
import java.util.*
//import com.fasterxml.jackson.annotation.JsonIdentityInfo
//import com.fasterxml.jackson.annotation.ObjectIdGenerators
import net.dankito.utils.multiplatform.BigDecimal
import net.dankito.utils.multiplatform.Date
import net.dankito.utils.multiplatform.UUID
import kotlin.jvm.JvmOverloads
@JsonIdentityInfo(property = "id", generator = ObjectIdGenerators.PropertyGenerator::class) // to avoid stack overflow due to circular references
//@JsonIdentityInfo(property = "id", generator = ObjectIdGenerators.PropertyGenerator::class) // to avoid stack overflow due to circular references
open class BankAccount @JvmOverloads constructor(
open val customer: Customer,
open val identifier: String,
@ -14,7 +16,7 @@ open class BankAccount @JvmOverloads constructor(
open var iban: String?,
open var subAccountNumber: String?,
open val customerId: String,
open var balance: BigDecimal = BigDecimal.ZERO,
open var balance: BigDecimal = BigDecimal.Zero,
open var currency: String = "EUR",
open var type: BankAccountType = BankAccountType.Girokonto,
open val productName: String? = null,
@ -30,7 +32,7 @@ open class BankAccount @JvmOverloads constructor(
internal constructor() : this(Customer(), "", "", null, null, "") // for object deserializers
open var id: String = UUID.randomUUID().toString()
open var id: String = UUID.random()
open val displayName: String

View File

@ -1,15 +1,16 @@
package net.dankito.banking.ui.model
import com.fasterxml.jackson.annotation.JsonIdentityInfo
import com.fasterxml.jackson.annotation.ObjectIdGenerators
//import com.fasterxml.jackson.annotation.JsonIdentityInfo
//import com.fasterxml.jackson.annotation.ObjectIdGenerators
import net.dankito.utils.multiplatform.BigDecimal
import net.dankito.utils.multiplatform.UUID
import net.dankito.utils.multiplatform.sum
import net.dankito.banking.ui.model.tan.TanMedium
import net.dankito.banking.ui.model.tan.TanMediumStatus
import net.dankito.banking.ui.model.tan.TanProcedure
import java.math.BigDecimal
import java.util.*
@JsonIdentityInfo(property = "id", generator = ObjectIdGenerators.PropertyGenerator::class) // to avoid stack overflow due to circular references
//@JsonIdentityInfo(property = "id", generator = ObjectIdGenerators.PropertyGenerator::class) // to avoid stack overflow due to circular references
open class Customer(
val bankCode: String,
val customerId: String,
@ -27,7 +28,7 @@ open class Customer(
internal constructor() : this("", "", "", "", "", "", "") // for object deserializers
var id: String = UUID.randomUUID().toString()
var id: String = UUID.random()
var supportedTanProcedures: List<TanProcedure> = listOf()
@ -44,7 +45,7 @@ open class Customer(
get() = bankName
val balance: BigDecimal
get() = accounts.map { it.balance }.fold(BigDecimal.ZERO) { acc, e -> acc + e }
get() = accounts.map { it.balance }.sum()
val transactions: List<AccountTransaction>
get() = accounts.flatMap { it.bookedTransactions }

View File

@ -1,6 +1,6 @@
package net.dankito.banking.ui.model
import java.util.*
import net.dankito.utils.multiplatform.Date
open class MessageLogEntry(

View File

@ -1,7 +1,7 @@
package net.dankito.banking.ui.model.parameters
import net.dankito.utils.multiplatform.Date
import net.dankito.banking.ui.model.AccountTransaction
import java.util.*
open class GetTransactionsParameter(

View File

@ -1,7 +1,7 @@
package net.dankito.banking.ui.model.parameters
import net.dankito.utils.multiplatform.BigDecimal
import net.dankito.banking.ui.model.AccountTransaction
import java.math.BigDecimal
open class TransferMoneyData(
@ -20,7 +20,7 @@ open class TransferMoneyData(
transaction.otherPartyName ?: "",
transaction.otherPartyAccountId ?: "",
transaction.otherPartyBankCode ?: "",
BigDecimal.ZERO,
BigDecimal.Zero,
""
)
}

View File

@ -1,9 +1,9 @@
package net.dankito.banking.ui.model.responses
import net.dankito.utils.multiplatform.BigDecimal
import net.dankito.banking.ui.model.Customer
import net.dankito.banking.ui.model.AccountTransaction
import net.dankito.banking.ui.model.BankAccount
import java.math.BigDecimal
open class AddAccountResponse(

View File

@ -1,8 +1,8 @@
package net.dankito.banking.ui.model.responses
import net.dankito.utils.multiplatform.BigDecimal
import net.dankito.banking.ui.model.AccountTransaction
import net.dankito.banking.ui.model.BankAccount
import java.math.BigDecimal
open class GetTransactionsResponse(

View File

@ -17,6 +17,7 @@ import net.dankito.banking.ui.model.tan.TanGeneratorTanMedium
import net.dankito.banking.bankfinder.IBankFinder
import net.dankito.banking.bankfinder.BankInfo
import net.dankito.banking.search.IRemitteeSearcher
import net.dankito.banking.search.NoOpRemitteeSearcher
import net.dankito.banking.search.Remittee
import net.dankito.banking.ui.model.moneytransfer.ExtractTransferMoneyDataFromPdfResult
import net.dankito.banking.ui.model.moneytransfer.ExtractTransferMoneyDataFromPdfResultType
@ -25,14 +26,10 @@ import net.dankito.banking.ui.model.settings.AppSettings
import net.dankito.banking.util.*
import net.dankito.banking.util.extraction.IInvoiceDataExtractor
import net.dankito.banking.util.extraction.ITextExtractorRegistry
import net.dankito.banking.util.extraction.JavaInvoiceDataExtractor
import org.slf4j.LoggerFactory
import java.io.File
import java.io.FileOutputStream
import java.math.BigDecimal
import java.net.URL
import java.text.SimpleDateFormat
import java.util.*
import net.dankito.banking.util.extraction.NoOpInvoiceDataExtractor
import net.dankito.banking.util.extraction.NoOpTextExtractorRegistry
import net.dankito.utils.multiplatform.*
import net.dankito.utils.multiplatform.log.LoggerFactory
import kotlin.collections.ArrayList
@ -41,21 +38,21 @@ open class BankingPresenter(
protected val bankFinder: IBankFinder,
protected val dataFolder: File,
protected val persister: IBankingPersistence,
protected val remitteeSearcher: IRemitteeSearcher,
protected val bankIconFinder: IBankIconFinder,
protected val textExtractorRegistry: ITextExtractorRegistry,
protected val router: IRouter,
protected val invoiceDataExtractor: IInvoiceDataExtractor = JavaInvoiceDataExtractor(),
protected val serializer: ISerializer = JacksonJsonSerializer(),
protected val remitteeSearcher: IRemitteeSearcher = NoOpRemitteeSearcher(),
protected val bankIconFinder: IBankIconFinder = NoOpBankIconFinder(),
protected val textExtractorRegistry: ITextExtractorRegistry = NoOpTextExtractorRegistry(),
protected val invoiceDataExtractor: IInvoiceDataExtractor = NoOpInvoiceDataExtractor(),
protected val serializer: ISerializer = NoOpSerializer(),
protected val asyncRunner: IAsyncRunner = CoroutinesAsyncRunner()
) {
companion object {
protected const val OneDayMillis = 24 * 60 * 60 * 1000
protected val MessageLogEntryDateFormat = SimpleDateFormat("yyyy.MM.dd HH:mm:ss.SSS")
protected val MessageLogEntryDateFormatter = DateFormatter("yyyy.MM.dd HH:mm:ss.SSS")
private val log = LoggerFactory.getLogger(BankingPresenter::class.java)
private val log = LoggerFactory.getLogger(BankingPresenter::class)
}
@ -127,7 +124,7 @@ open class BankingPresenter(
try {
newClient.restoreData()
} catch (e: Exception) {
log.error("Could not deserialize customer data of $customer", e)
log.error(e) { "Could not deserialize customer data of $customer" }
// TODO: show error message to user
}
@ -138,7 +135,7 @@ open class BankingPresenter(
selectedAllBankAccounts() // TODO: save last selected bank account(s)
} catch (e: Exception) {
log.error("Could not deserialize persisted accounts with persister $persister", e)
log.error(e) { "Could not deserialize persisted accounts with persister $persister" }
}
}
@ -194,14 +191,14 @@ open class BankingPresenter(
bankIconFinder.findIconForBank(customer.bankName)?.let { bankIconUrl ->
val bankIconFile = saveBankIconToDisk(customer, bankIconUrl)
customer.iconUrl = "file://" + bankIconFile.absolutePath // without 'file://' Android will not find it
customer.iconUrl = "file://" + bankIconFile.getAbsolutePath() // without 'file://' Android will not find it
persistAccount(customer)
callAccountsChangedListeners()
}
} catch (e: Exception) {
log.error("Could not get icon for bank ${customer.bankName}", e)
log.error(e) { "Could not get icon for bank ${customer.bankName}" }
}
}
@ -212,28 +209,24 @@ open class BankingPresenter(
val extension = getIconFileExtension(bankIconUrl)
val bankIconFile = File(bankIconsDir, customer.bankCode + if (extension != null) (".$extension") else "")
URL(bankIconUrl).openConnection().getInputStream().buffered().use { iconInputStream ->
FileOutputStream(bankIconFile).use { fileOutputStream ->
iconInputStream.copyTo(fileOutputStream)
}
}
persister.saveUrlToFile(bankIconUrl, bankIconFile)
return bankIconFile
}
protected open fun getIconFileExtension(bankIconUrl: String): String? {
try {
var iconFilename = File(bankIconUrl).name
var iconFilename = File(bankIconUrl).filename
if (iconFilename.contains('?')) {
iconFilename = iconFilename.substring(0, iconFilename.indexOf('?'))
}
val extension = File(iconFilename).extension
val extension = File(iconFilename).fileExtension
if (extension.isNotBlank()) {
return extension
}
} catch (e: Exception) {
log.info("Could not get icon file extension from url '$bankIconUrl'", e)
log.info(e) { "Could not get icon file extension from url '$bankIconUrl'" }
}
return null
@ -308,7 +301,7 @@ open class BankingPresenter(
}
protected open fun updateBankAccountTransactionsAsync(bankAccount: BankAccount, abortIfTanIsRequired: Boolean, callback: (GetTransactionsResponse) -> Unit) {
val fromDate = bankAccount.lastRetrievedTransactionsTimestamp?.let { Date(it.time - OneDayMillis) } // one day before last received transactions
val fromDate = bankAccount.lastRetrievedTransactionsTimestamp?.let { Date(it.millisSinceEpoch - OneDayMillis) } // one day before last received transactions
fetchAccountTransactionsAsync(bankAccount, fromDate, abortIfTanIsRequired, callback)
}
@ -348,7 +341,7 @@ open class BankingPresenter(
}
open fun formatAmount(amount: BigDecimal): String {
return String.format("%.02f", amount)
return amount.format("%.02f")
}
@ -391,7 +384,7 @@ open class BankingPresenter(
val transferMoneyData = TransferMoneyData("",
invoiceData.potentialIban ?: "",
invoiceData.potentialBic ?: "",
invoiceData.potentialTotalAmount ?: BigDecimal.ZERO, "")
invoiceData.potentialTotalAmount ?: BigDecimal.Zero, "")
showTransferMoneyDialog(null, transferMoneyData)
}
else {
@ -481,7 +474,7 @@ open class BankingPresenter(
}
return logEntries.map { entry ->
MessageLogEntryDateFormat.format(entry.time) + " " + entry.customer.bankCode + " " + entry.message
MessageLogEntryDateFormatter.format(entry.time) + " " + entry.customer.bankCode + " " + entry.message
}
}
@ -608,15 +601,15 @@ open class BankingPresenter(
protected open fun getAccountTransactionsForBankAccounts(bankAccounts: Collection<BankAccount>): List<AccountTransaction> {
return bankAccounts.flatMap { it.bookedTransactions }.sortedByDescending { it.valueDate } // TODO: someday add unbooked transactions
return bankAccounts.flatMap { it.bookedTransactions }.sortedByDescending { it.valueDate.millisSinceEpoch } // TODO: someday add unbooked transactions
}
protected open fun getBalanceForAccounts(customers: Collection<Customer>): BigDecimal {
return customers.map { it.balance }.fold(BigDecimal.ZERO) { acc, e -> acc + e }
return customers.map { it.balance }.sum()
}
protected open fun sumBalance(singleBalances: Collection<BigDecimal>): BigDecimal {
return singleBalances.fold(BigDecimal.ZERO) { acc, e -> acc + e }
return singleBalances.sum()
}
@ -631,17 +624,17 @@ open class BankingPresenter(
try {
serializer.serializeObject(appSettings, getAppSettingsFile())
} catch (e: Exception) {
log.error("Could not persist AppSettings to file ${getAppSettingsFile()}", e)
log.error(e) { "Could not persist AppSettings to file ${getAppSettingsFile()}" }
}
}
protected open fun readAppSettings() {
try {
serializer.deserializeObject(getAppSettingsFile(), AppSettings::class.java)?.let {
serializer.deserializeObject(getAppSettingsFile(), AppSettings::class)?.let {
appSettings = it
}
} catch (e: Exception) {
log.error("Could not read AppSettings from file ${getAppSettingsFile()}", e)
log.error(e) { "Could not read AppSettings from file ${getAppSettingsFile()}" }
}
}

View File

@ -0,0 +1,95 @@
package net.dankito.banking.ui.util
import net.dankito.banking.ui.model.tan.FlickerCode
import net.dankito.banking.fints.tan.Bit
import net.dankito.banking.fints.tan.FlickerCanvas
import net.dankito.utils.multiplatform.log.LoggerFactory
import kotlin.jvm.JvmOverloads
import kotlin.jvm.Volatile
open class FlickerCodeAnimator {
companion object {
const val MinFrequency = 2
const val MaxFrequency = 40
const val DefaultFrequency = 20
private val log = LoggerFactory.getLogger(FlickerCodeAnimator::class)
}
protected var currentFrequency: Int = DefaultFrequency
protected var currentStepIndex = 0
@Volatile
protected var isPaused = false
// protected var calculateAnimationThread: Thread? = null
@JvmOverloads
open fun animateFlickerCode(flickerCode: FlickerCode, frequency: Int = DefaultFrequency, showStep: (Array<Bit>) -> Unit) {
currentFrequency = frequency
currentStepIndex = 0
val steps = FlickerCanvas(flickerCode.parsedDataSet).steps
stop() // stop may still running previous animation
// calculateAnimationThread = Thread({ calculateAnimation(steps, showStep) }, "CalculateFlickerCodeAnimation")
//
// calculateAnimationThread?.start()
}
// protected open fun calculateAnimation(steps: List<Array<Bit>>, showStep: (Array<Bit>) -> Unit) {
// while (Thread.currentThread().isInterrupted == false) {
// if (isPaused == false) {
// val nextStep = steps[currentStepIndex]
//
// showStep(nextStep)
//
// currentStepIndex++
// if (currentStepIndex >= steps.size) {
// currentStepIndex = 0 // all steps shown, start again from beginning
// }
// }
//
// try {
// TimeUnit.MILLISECONDS.sleep(1000L / currentFrequency)
// } catch (ignored: Exception) {
// Thread.currentThread().interrupt()
// }
// }
// }
open fun pause() {
this.isPaused = true
}
open fun resume() {
this.isPaused = false
}
open fun stop() {
try {
// if (calculateAnimationThread?.isInterrupted == false) {
// calculateAnimationThread?.interrupt()
// calculateAnimationThread?.join(500)
//
// calculateAnimationThread = null
// }
} catch (e: Exception) {
log.warn(e) { "Could not stop calculateAnimationThread" }
}
}
open fun setFrequency(frequency: Int) {
if (frequency in MinFrequency..MaxFrequency) {
currentFrequency = frequency
}
}
}

View File

@ -1,14 +1,13 @@
package net.dankito.banking.util
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
open class CoroutinesAsyncRunner : IAsyncRunner {
open class CoroutinesAsyncRunner : IAsyncRunner { // TODO: remove (coroutines in common)
override fun runAsync(runnable: () -> Unit) {
GlobalScope.launch(Dispatchers.IO) {
GlobalScope.launch {
runnable()
}
}

View File

@ -0,0 +1,16 @@
package net.dankito.banking.util
import net.dankito.utils.multiplatform.File
import kotlin.reflect.KClass
interface ISerializer {
fun serializeObject(obj: Any, outputFile: File)
fun <T : Any> deserializeObject(serializedObjectFile: File, objectClass: KClass<T>, vararg genericParameterTypes: KClass<*>): T?
fun <T : Any> deserializeListOr(serializedObjectFile: File, genericListParameterType: KClass<T>,
defaultValue: List<T> = listOf()) : List<T>
}

View File

@ -2,7 +2,6 @@ package net.dankito.banking.util
import net.dankito.banking.fints.messages.segmente.implementierte.sepa.ISepaMessageCreator
import net.dankito.banking.fints.messages.segmente.implementierte.sepa.SepaMessageCreator
import java.util.regex.Pattern
open class InputValidator {
@ -22,7 +21,7 @@ open class InputValidator {
* (https://en.wikipedia.org/wiki/International_Bank_Account_Number#Structure)
*/
const val IbanPatternString = "[A-Z]{2}\\d{2}[A-Z0-9]{10,30}"
val IbanPattern = Pattern.compile("^" + IbanPatternString + "\$")
val IbanPattern = Regex("^" + IbanPatternString + "\$")
/**
* The IBAN should not contain spaces when transmitted electronically. When printed it is expressed in groups
@ -30,9 +29,9 @@ open class InputValidator {
* (https://en.wikipedia.org/wiki/International_Bank_Account_Number#Structure)
*/
const val IbanWithSpacesPatternString = "[A-Z]{2}\\d{2}\\s([A-Z0-9]{4}\\s){3}[A-Z0-9\\s]{1,18}"
val IbanWithSpacesPattern = Pattern.compile("^" + IbanWithSpacesPatternString + "\$")
val IbanWithSpacesPattern = Regex("^" + IbanWithSpacesPatternString + "\$")
val InvalidIbanCharactersPattern = Pattern.compile("[^A-Z0-9 ]")
val InvalidIbanCharactersPattern = Regex("[^A-Z0-9 ]")
/**
@ -47,12 +46,12 @@ open class InputValidator {
* Where an eight digit code is given, it may be assumed that it refers to the primary office.
*/
const val BicPatternString = "[A-Z]{4}[A-Z]{2}[A-Z0-9]{2}(?:\\b|[A-Z0-9]{03})"
val BicPattern = Pattern.compile("^" + BicPatternString + "$")
val BicPattern = Regex("^" + BicPatternString + "$")
val InvalidBicCharactersPattern = Pattern.compile("[^A-Z0-9]")
val InvalidBicCharactersPattern = Regex("[^A-Z0-9]")
val InvalidSepaCharactersPattern = Pattern.compile("[^${SepaMessageCreator.AllowedSepaCharacters}]+")
val InvalidSepaCharactersPattern = Regex("[^${SepaMessageCreator.AllowedSepaCharacters}]+")
}
@ -60,7 +59,7 @@ open class InputValidator {
open fun isValidIban(stringToTest: String): Boolean {
return IbanPattern.matcher(stringToTest.replace(" ", "")).matches()
return IbanPattern.matches(stringToTest.replace(" ", ""))
}
open fun getInvalidIbanCharacters(string: String): String {
@ -69,7 +68,7 @@ open class InputValidator {
open fun isValidBic(stringToTest: String): Boolean {
return BicPattern.matcher(stringToTest).matches()
return BicPattern.matches(stringToTest)
}
open fun getInvalidBicCharacters(string: String): String {
@ -114,16 +113,8 @@ open class InputValidator {
}
open fun getInvalidCharacters(string: String, pattern: Pattern): String {
val illegalCharacters = mutableSetOf<String>()
val matcher = pattern.matcher(string)
while (matcher.find()) {
illegalCharacters.add(matcher.group())
}
return illegalCharacters.joinToString("")
open fun getInvalidCharacters(string: String, pattern: Regex): String {
return pattern.findAll(string).joinToString("")
}
}

View File

@ -0,0 +1,21 @@
package net.dankito.banking.util
import net.dankito.utils.multiplatform.File
import kotlin.reflect.KClass
open class NoOpSerializer : ISerializer {
override fun serializeObject(obj: Any, outputFile: File) {
}
override fun <T : Any> deserializeObject(serializedObjectFile: File, objectClass: KClass<T>, vararg genericParameterTypes: KClass<*>): T? {
return null
}
override fun <T : Any> deserializeListOr(serializedObjectFile: File, genericListParameterType: KClass<T>, defaultValue: List<T>): List<T> {
return defaultValue
}
}

View File

@ -1,7 +1,5 @@
package net.dankito.banking.util.extraction
import java.lang.Exception
open class ExtractionResult(
open val couldExtractText: Boolean,

View File

@ -1,6 +1,6 @@
package net.dankito.banking.util.extraction
import java.io.File
import net.dankito.utils.multiplatform.File
interface ITextExtractorRegistry {

View File

@ -1,6 +1,6 @@
package net.dankito.banking.util.extraction
import java.math.BigDecimal
import net.dankito.utils.multiplatform.BigDecimal
open class InvoiceData(

View File

@ -1,6 +1,6 @@
package net.dankito.banking.util.extraction
import java.io.File
import net.dankito.utils.multiplatform.File
open class NoOpTextExtractorRegistry : ITextExtractorRegistry {

View File

@ -0,0 +1,24 @@
package net.dankito.banking.util
import net.dankito.utils.multiplatform.File
import kotlin.reflect.KClass
open class JacksonJsonSerializer(
protected val serializer: net.dankito.utils.serialization.ISerializer = net.dankito.utils.serialization.JacksonJsonSerializer()
) : ISerializer {
override fun serializeObject(obj: Any, outputFile: File) {
return serializer.serializeObject(obj, outputFile)
}
override fun <T : Any> deserializeObject(serializedObjectFile: File, objectClass: KClass<T>,
vararg genericParameterTypes: KClass<*>): T? {
return serializer.deserializeObject(serializedObjectFile, objectClass.java, *genericParameterTypes.map { it.java }.toTypedArray())
}
override fun <T : Any> deserializeListOr(serializedObjectFile: File, genericListParameterType: KClass<T>, defaultValue: List<T>): List<T> {
return serializer.deserializeListOr(serializedObjectFile, genericListParameterType.java, defaultValue)
}
}

View File

@ -1,5 +1,6 @@
package net.dankito.banking.util.extraction
import net.dankito.utils.multiplatform.toBigDecimal
import net.dankito.text.extraction.info.invoice.InvoiceDataExtractor

View File

@ -1,8 +1,8 @@
package net.dankito.banking.util.extraction
import net.dankito.utils.multiplatform.File
import net.dankito.text.extraction.TextExtractorRegistry
import net.dankito.text.extraction.model.ErrorType
import java.io.File
open class JavaTextExtractorRegistry(

View File

@ -1,6 +1,5 @@
package net.dankito.banking.util
import net.dankito.banking.bankfinder.InMemoryBankFinder
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.dankito.banking.ui">
<uses-permission android:name="android.permission.INTERNET" />
</manifest>

View File

@ -1,94 +0,0 @@
package net.dankito.banking.ui.util
import net.dankito.banking.ui.model.tan.FlickerCode
import net.dankito.banking.fints.tan.Bit
import net.dankito.banking.fints.tan.FlickerCanvas
import org.slf4j.LoggerFactory
import java.util.concurrent.TimeUnit
open class FlickerCodeAnimator { // TODO: move to fints44
companion object {
const val MinFrequency = 2
const val MaxFrequency = 40
const val DefaultFrequency = 20
private val log = LoggerFactory.getLogger(FlickerCodeAnimator::class.java)
}
protected var currentFrequency: Int = DefaultFrequency
protected var currentStepIndex = 0
@Volatile
protected var isPaused = false
protected var calculateAnimationThread: Thread? = null
@JvmOverloads
open fun animateFlickerCode(flickerCode: FlickerCode, frequency: Int = DefaultFrequency, showStep: (Array<Bit>) -> Unit) {
currentFrequency = frequency
currentStepIndex = 0
val steps = FlickerCanvas(flickerCode.parsedDataSet).steps
stop() // stop may still running previous animation
calculateAnimationThread = Thread({ calculateAnimation(steps, showStep) }, "CalculateFlickerCodeAnimation")
calculateAnimationThread?.start()
}
protected open fun calculateAnimation(steps: List<Array<Bit>>, showStep: (Array<Bit>) -> Unit) {
while (Thread.currentThread().isInterrupted == false) {
if (isPaused == false) {
val nextStep = steps[currentStepIndex]
showStep(nextStep)
currentStepIndex++
if (currentStepIndex >= steps.size) {
currentStepIndex = 0 // all steps shown, start again from beginning
}
}
try {
TimeUnit.MILLISECONDS.sleep(1000L / currentFrequency)
} catch (ignored: Exception) {
Thread.currentThread().interrupt()
}
}
}
open fun pause() {
this.isPaused = true
}
open fun resume() {
this.isPaused = false
}
open fun stop() {
try {
if (calculateAnimationThread?.isInterrupted == false) {
calculateAnimationThread?.interrupt()
calculateAnimationThread?.join(500)
calculateAnimationThread = null
}
} catch (e: Exception) {
log.warn("Could not stop calculateAnimationThread", e)
}
}
open fun setFrequency(frequency: Int) {
if (frequency in MinFrequency..MaxFrequency) {
currentFrequency = frequency
}
}
}

View File

@ -1,15 +0,0 @@
package net.dankito.banking.util
import java.io.File
interface ISerializer {
fun serializeObject(obj: Any, outputFile: File)
fun <T> deserializeObject(serializedObjectFile: File, objectClass: Class<T>, vararg genericParameterTypes: Class<*>): T?
fun <T> deserializeListOr(serializedObjectFile: File, genericListParameterType: Class<T>,
defaultValue: List<T> = listOf()) : List<T>
}

View File

@ -1,24 +0,0 @@
package net.dankito.banking.util
import net.dankito.utils.serialization.JacksonJsonSerializer
import java.io.File
open class JacksonJsonSerializer(
protected val serializer: net.dankito.utils.serialization.ISerializer = JacksonJsonSerializer()
) : ISerializer {
override fun serializeObject(obj: Any, outputFile: File) {
return serializer.serializeObject(obj, outputFile)
}
override fun <T> deserializeObject(serializedObjectFile: File, objectClass: Class<T>,
vararg genericParameterTypes: Class<*>): T? {
return serializer.deserializeObject(serializedObjectFile, objectClass, *genericParameterTypes)
}
override fun <T> deserializeListOr(serializedObjectFile: File, genericListParameterType: Class<T>, defaultValue: List<T>): List<T> {
return serializer.deserializeListOr(serializedObjectFile, genericListParameterType, defaultValue)
}
}

View File

@ -1,20 +0,0 @@
package net.dankito.banking.util
import java.io.File
open class NoOpSerializer : ISerializer {
override fun serializeObject(obj: Any, outputFile: File) {
}
override fun <T> deserializeObject(serializedObjectFile: File, objectClass: Class<T>, vararg genericParameterTypes: Class<*>): T? {
return null
}
override fun <T> deserializeListOr(serializedObjectFile: File, genericListParameterType: Class<T>, defaultValue: List<T>): List<T> {
return defaultValue
}
}

View File

@ -34,24 +34,22 @@ kotlin {
sourceSets {
commonMain {
dependencies {
implementation kotlin("stdlib-common")
implementation project(":BankingUiCommon")
implementation project(":fints4k")
api project(":BankingUiCommon")
api project(":fints4k")
}
}
jvmMain {
dependencies {
api kotlin("stdlib-jdk7")
}
}
iosMain {
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-common:$kotlinVersion"
}
}