From 35bc91761ad1f8336f331c6b04cff8bf4d9ae064 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Mon, 24 Aug 2020 14:28:34 -0300 Subject: Upgrade to Kotlin 1.4 --- build.gradle | 4 ++-- cashier/build.gradle | 7 ++++--- merchant-lib/build.gradle | 2 -- .../main/java/net/taler/merchantlib/MerchantApi.kt | 11 ++++------- .../src/main/java/net/taler/merchantlib/Orders.kt | 23 ++++++++++++---------- .../main/java/net/taler/merchantlib/Response.kt | 5 +++-- .../java/net/taler/merchantlib/MockHttpClient.kt | 5 +++-- .../net/taler/merchantpos/config/ConfigManager.kt | 2 +- multiplatform | 2 +- taler-kotlin-android/build.gradle | 4 ++-- .../java/net/taler/common/ContractTermsTest.kt | 3 +-- wallet/build.gradle | 4 ++-- .../net/taler/wallet/backend/WalletBackendApi.kt | 19 +++++++++--------- .../net/taler/wallet/backend/WalletResponse.kt | 17 ++++++++-------- .../taler/wallet/payment/PromptPaymentFragment.kt | 4 ++-- .../net/taler/wallet/backend/WalletResponseTest.kt | 11 +++++------ 16 files changed, 60 insertions(+), 63 deletions(-) diff --git a/build.gradle b/build.gradle index 442d232..7c9e378 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ buildscript { - ext.kotlin_version = '1.3.72' - ext.ktor_version = "1.3.2" + ext.kotlin_version = '1.4.0' + ext.ktor_version = "1.4.0" ext.nav_version = "2.3.0" ext.lifecycle_version = "2.2.0" // check https://android-rebuilds.beuc.net/ for availability of free build tools diff --git a/cashier/build.gradle b/cashier/build.gradle index 341562d..916758b 100644 --- a/cashier/build.gradle +++ b/cashier/build.gradle @@ -59,13 +59,14 @@ android { dependencies { implementation project(":taler-kotlin-android") - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' - implementation 'androidx.security:security-crypto:1.0.0-rc02' - implementation 'com.google.android.material:material:1.1.0' + implementation 'androidx.constraintlayout:constraintlayout:2.0.0' + implementation 'androidx.security:security-crypto:1.0.0-rc03' + implementation 'com.google.android.material:material:1.2.0' implementation "androidx.navigation:navigation-fragment-ktx:$nav_version" implementation "androidx.navigation:navigation-ui-ktx:$nav_version" + // https://github.com/square/okhttp/releases implementation "com.squareup.okhttp3:okhttp:3.12.12" testImplementation 'junit:junit:4.13' diff --git a/merchant-lib/build.gradle b/merchant-lib/build.gradle index 5082253..9b349ea 100644 --- a/merchant-lib/build.gradle +++ b/merchant-lib/build.gradle @@ -47,8 +47,6 @@ android { dependencies { api project(":taler-kotlin-android") - implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - api "io.ktor:ktor-client:$ktor_version" api "io.ktor:ktor-client-okhttp:$ktor_version" api "io.ktor:ktor-client-serialization-jvm:$ktor_version" diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/MerchantApi.kt b/merchant-lib/src/main/java/net/taler/merchantlib/MerchantApi.kt index a4ca397..ea5b996 100644 --- a/merchant-lib/src/main/java/net/taler/merchantlib/MerchantApi.kt +++ b/merchant-lib/src/main/java/net/taler/merchantlib/MerchantApi.kt @@ -31,7 +31,6 @@ import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonConfiguration import net.taler.merchantlib.Response.Companion.response class MerchantApi( @@ -116,10 +115,8 @@ fun getDefaultHttpClient(): HttpClient = HttpClient(OkHttp) { } fun getSerializer() = KotlinxSerializer( - Json( - JsonConfiguration( - encodeDefaults = false, - ignoreUnknownKeys = true - ) - ) + Json { + encodeDefaults = false + ignoreUnknownKeys = true + } ) diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/Orders.kt b/merchant-lib/src/main/java/net/taler/merchantlib/Orders.kt index 0a405ad..9c23ef1 100644 --- a/merchant-lib/src/main/java/net/taler/merchantlib/Orders.kt +++ b/merchant-lib/src/main/java/net/taler/merchantlib/Orders.kt @@ -16,14 +16,16 @@ package net.taler.merchantlib -import kotlinx.serialization.Decoder -import kotlinx.serialization.Encoder import kotlinx.serialization.KSerializer import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.Serializer -import kotlinx.serialization.json.JsonInput +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import kotlinx.serialization.json.JsonDecoder import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.boolean +import kotlinx.serialization.json.jsonPrimitive import net.taler.common.ContractTerms import net.taler.lib.common.Duration @@ -45,19 +47,20 @@ data class PostOrderResponse( sealed class CheckPaymentResponse { abstract val paid: Boolean + @Suppress("EXPERIMENTAL_API_USAGE") @Serializer(forClass = CheckPaymentResponse::class) companion object : KSerializer { override fun deserialize(decoder: Decoder): CheckPaymentResponse { - val input = decoder as JsonInput - val tree = input.decodeJson() as JsonObject - val orderStatus = tree.getPrimitive("order_status").content -// return if (orderStatus == "paid") decoder.json.fromJson(Paid.serializer(), tree) -// else decoder.json.fromJson(Unpaid.serializer(), tree) + val input = decoder as JsonDecoder + val tree = input.decodeJsonElement() as JsonObject + val orderStatus = tree.getValue("order_status").jsonPrimitive.content +// return if (orderStatus == "paid") decoder.json.decodeFromJsonElement(Paid.serializer(), tree) +// else decoder.json.decodeFromJsonElement(Unpaid.serializer(), tree) // manual parsing due to https://github.com/Kotlin/kotlinx.serialization/issues/576 return if (orderStatus == "paid") Paid( - refunded = tree.getPrimitive("refunded").boolean + refunded = tree.getValue("refunded").jsonPrimitive.boolean ) else Unpaid( - talerPayUri = tree.getPrimitive("taler_pay_uri").content + talerPayUri = tree.getValue("taler_pay_uri").jsonPrimitive.content ) } diff --git a/merchant-lib/src/main/java/net/taler/merchantlib/Response.kt b/merchant-lib/src/main/java/net/taler/merchantlib/Response.kt index fb48b46..1b63900 100644 --- a/merchant-lib/src/main/java/net/taler/merchantlib/Response.kt +++ b/merchant-lib/src/main/java/net/taler/merchantlib/Response.kt @@ -70,11 +70,12 @@ class Response private constructor( } private suspend fun getExceptionString(e: ResponseException): String { + val response = e.response ?: return e.toString() return try { - val error: Error = e.response.receive() + val error: Error = response.receive() "Error ${error.code}: ${error.hint}" } catch (ex: Exception) { - "Status code: ${e.response.status.value}" + "Status code: ${response.status.value}" } } diff --git a/merchant-lib/src/test/java/net/taler/merchantlib/MockHttpClient.kt b/merchant-lib/src/test/java/net/taler/merchantlib/MockHttpClient.kt index 993be15..c8e6f22 100644 --- a/merchant-lib/src/test/java/net/taler/merchantlib/MockHttpClient.kt +++ b/merchant-lib/src/test/java/net/taler/merchantlib/MockHttpClient.kt @@ -32,6 +32,7 @@ import io.ktor.http.content.TextContent import io.ktor.http.fullPath import io.ktor.http.headersOf import io.ktor.http.hostWithPort +import kotlinx.serialization.json.Json.Default.parseToJsonElement import org.junit.Assert.assertEquals object MockHttpClient { @@ -75,8 +76,8 @@ object MockHttpClient { private val Url.fullUrl: String get() = "${protocol.name}://$hostWithPortIfRequired$fullPath" private fun assertJsonEquals(json1: String, json2: String) { - val parsed1 = kotlinx.serialization.json.Json.parseJson(json1) - val parsed2 = kotlinx.serialization.json.Json.parseJson(json2) + val parsed1 = parseToJsonElement(json1) + val parsed2 = parseToJsonElement(json2) assertEquals(parsed1, parsed2) } diff --git a/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigManager.kt b/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigManager.kt index 23abe7d..d7c446f 100644 --- a/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigManager.kt +++ b/merchant-terminal/src/main/java/net/taler/merchantpos/config/ConfigManager.kt @@ -115,7 +115,7 @@ class ConfigManager( Log.e(TAG, "Error retrieving merchant config", e) val msg = if (e is ClientRequestException) { context.getString( - if (e.response.status == Unauthorized) R.string.config_auth_error + if (e.response?.status == Unauthorized) R.string.config_auth_error else R.string.config_error_network ) } else { diff --git a/multiplatform b/multiplatform index dade047..6f698f4 160000 --- a/multiplatform +++ b/multiplatform @@ -1 +1 @@ -Subproject commit dade0470c7e378c72ac2f2fd2a623416dadbff10 +Subproject commit 6f698f4d0ef580a898d3b03e9e8954af4f194037 diff --git a/taler-kotlin-android/build.gradle b/taler-kotlin-android/build.gradle index ca4df8a..5cb0b0e 100644 --- a/taler-kotlin-android/build.gradle +++ b/taler-kotlin-android/build.gradle @@ -52,7 +52,6 @@ android { dependencies { api project(":multiplatform:common") - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.core:core-ktx:1.3.1' @@ -67,8 +66,9 @@ dependencies { implementation 'com.google.zxing:core:3.4.0' // needs minSdkVersion 24+ // JSON parsing and serialization - api "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.20.0" + api "org.jetbrains.kotlinx:kotlinx-serialization-core:1.0.0-RC" implementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.10.2" + implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" lintPublish 'com.github.thirdegg:lint-rules:0.0.4-alpha' diff --git a/taler-kotlin-android/src/test/java/net/taler/common/ContractTermsTest.kt b/taler-kotlin-android/src/test/java/net/taler/common/ContractTermsTest.kt index 62e8922..0e410ca 100644 --- a/taler-kotlin-android/src/test/java/net/taler/common/ContractTermsTest.kt +++ b/taler-kotlin-android/src/test/java/net/taler/common/ContractTermsTest.kt @@ -23,7 +23,6 @@ import com.fasterxml.jackson.module.kotlin.readValue import net.taler.lib.common.Amount import net.taler.lib.common.AmountMixin import net.taler.lib.common.Timestamp -import net.taler.lib.common.Timestamp.Companion.NEVER import net.taler.lib.common.TimestampMixin import org.junit.Assert.assertEquals import org.junit.Test @@ -75,7 +74,7 @@ class ContractTermsTest { """.trimIndent() val contractTerms: ContractTerms = mapper.readValue(json) assertEquals("Essay: 1. The Free Software Definition", contractTerms.summary) - assertEquals(Timestamp(NEVER), contractTerms.refundDeadline) + assertEquals(Timestamp.never(), contractTerms.refundDeadline) } } diff --git a/wallet/build.gradle b/wallet/build.gradle index 87019f8..8806a5a 100644 --- a/wallet/build.gradle +++ b/wallet/build.gradle @@ -20,7 +20,7 @@ plugins { id "com.android.application" id "kotlin-android" id "kotlin-android-extensions" - id 'kotlinx-serialization' + id "kotlinx-serialization" id "de.undercouch.download" } @@ -104,7 +104,7 @@ dependencies { implementation 'androidx.preference:preference:1.1.1' implementation 'com.google.android.material:material:1.2.0' - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'androidx.constraintlayout:constraintlayout:2.0.0' // Lists and Selection implementation "androidx.recyclerview:recyclerview:1.1.0" diff --git a/wallet/src/main/java/net/taler/wallet/backend/WalletBackendApi.kt b/wallet/src/main/java/net/taler/wallet/backend/WalletBackendApi.kt index 5ca2255..693fe7e 100644 --- a/wallet/src/main/java/net/taler/wallet/backend/WalletBackendApi.kt +++ b/wallet/src/main/java/net/taler/wallet/backend/WalletBackendApi.kt @@ -32,7 +32,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import kotlinx.serialization.KSerializer import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonConfiguration import net.taler.wallet.backend.WalletBackendService.Companion.MSG_COMMAND import net.taler.wallet.backend.WalletBackendService.Companion.MSG_NOTIFY import net.taler.wallet.backend.WalletBackendService.Companion.MSG_REPLY @@ -49,9 +48,9 @@ class WalletBackendApi( private val app: Application, private val notificationHandler: ((payload: JSONObject) -> Unit) ) { - private val json = Json( - JsonConfiguration.Stable.copy(ignoreUnknownKeys = true) - ) + private val json = Json { + ignoreUnknownKeys = true + } private var walletBackendMessenger: Messenger? = null private val queuedMessages = LinkedList() private val handlers = ConcurrentHashMap Unit>() @@ -153,14 +152,14 @@ class WalletBackendApi( serializer: KSerializer? = null, args: (JSONObject.() -> JSONObject)? = null ): WalletResponse = withContext(Dispatchers.Default) { - suspendCoroutine> { cont -> + suspendCoroutine { cont -> sendRequest(operation, args?.invoke(JSONObject())) { isError, message -> val response = if (isError) { - val error = json.parse(WalletErrorInfo.serializer(), message.toString()) - WalletResponse.Error(error) + val error = json.decodeFromString(WalletErrorInfo.serializer(), message.toString()) + WalletResponse.Error(error) } else { @Suppress("UNCHECKED_CAST") // if serializer is null, T must be Unit - val t: T = serializer?.let { json.parse(serializer, message.toString()) } ?: Unit as T + val t: T = serializer?.let { json.decodeFromString(serializer, message.toString()) } ?: Unit as T WalletResponse.Success(t) } cont.resume(response) @@ -173,11 +172,11 @@ class WalletBackendApi( mapper: ObjectMapper, noinline args: (JSONObject.() -> JSONObject)? = null ): WalletResponse = withContext(Dispatchers.Default) { - suspendCoroutine> { cont -> + suspendCoroutine { cont -> sendRequest(operation, args?.invoke(JSONObject())) { isError, message -> val response = if (isError) { val error: WalletErrorInfo = mapper.readValue(message.toString()) - WalletResponse.Error(error) + WalletResponse.Error(error) } else { val t: T = mapper.readValue(message.toString()) WalletResponse.Success(t) diff --git a/wallet/src/main/java/net/taler/wallet/backend/WalletResponse.kt b/wallet/src/main/java/net/taler/wallet/backend/WalletResponse.kt index ab3d42e..57ce82e 100644 --- a/wallet/src/main/java/net/taler/wallet/backend/WalletResponse.kt +++ b/wallet/src/main/java/net/taler/wallet/backend/WalletResponse.kt @@ -21,18 +21,17 @@ import com.fasterxml.jackson.databind.DeserializationContext import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.annotation.JsonDeserialize import com.fasterxml.jackson.databind.deser.std.StdDeserializer -import kotlinx.serialization.Decoder -import kotlinx.serialization.Encoder import kotlinx.serialization.KSerializer -import kotlinx.serialization.PrimitiveDescriptor -import kotlinx.serialization.PrimitiveKind.STRING import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlinx.serialization.json.JsonInput +import kotlinx.serialization.descriptors.PrimitiveKind.STRING +import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import kotlinx.serialization.json.JsonDecoder import kotlinx.serialization.json.JsonObject import org.json.JSONObject - @Serializable sealed class WalletResponse { @Serializable @@ -96,11 +95,11 @@ data class WalletErrorInfo( class JSONObjectDeserializer : KSerializer { - override val descriptor = PrimitiveDescriptor("JSONObjectDeserializer", STRING) + override val descriptor = PrimitiveSerialDescriptor("JSONObjectDeserializer", STRING) override fun deserialize(decoder: Decoder): JSONObject { - val input = decoder as JsonInput - val tree = input.decodeJson() as JsonObject + val input = decoder as JsonDecoder + val tree = input.decodeJsonElement() as JsonObject return JSONObject(tree.toString()) } diff --git a/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt b/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt index 3d00900..99a6ec8 100644 --- a/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt +++ b/wallet/src/main/java/net/taler/wallet/payment/PromptPaymentFragment.kt @@ -58,7 +58,7 @@ class PromptPaymentFragment : Fragment(), ProductImageClickListener { } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - paymentManager.payStatus.observe(viewLifecycleOwner, this::onPaymentStatusChanged) + paymentManager.payStatus.observe(viewLifecycleOwner, ::onPaymentStatusChanged) paymentManager.detailsShown.observe(viewLifecycleOwner, Observer { shown -> beginDelayedTransition(view as ViewGroup) val res = if (shown) R.string.payment_hide_details else R.string.payment_show_details @@ -91,7 +91,7 @@ class PromptPaymentFragment : Fragment(), ProductImageClickListener { } } - private fun onPaymentStatusChanged(payStatus: PayStatus) { + private fun onPaymentStatusChanged(payStatus: PayStatus?) { when (payStatus) { is PayStatus.Prepared -> { showLoading(false) diff --git a/wallet/src/test/java/net/taler/wallet/backend/WalletResponseTest.kt b/wallet/src/test/java/net/taler/wallet/backend/WalletResponseTest.kt index d8f28c5..a81626c 100644 --- a/wallet/src/test/java/net/taler/wallet/backend/WalletResponseTest.kt +++ b/wallet/src/test/java/net/taler/wallet/backend/WalletResponseTest.kt @@ -21,7 +21,6 @@ import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.KotlinModule import com.fasterxml.jackson.module.kotlin.readValue import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonConfiguration import net.taler.lib.common.Amount import net.taler.lib.common.AmountMixin import net.taler.lib.common.Timestamp @@ -32,9 +31,9 @@ import org.junit.Test class WalletResponseTest { - private val json = Json( - JsonConfiguration.Stable.copy(ignoreUnknownKeys = true) - ) + private val json = Json { + ignoreUnknownKeys = true + } private val mapper = ObjectMapper() .registerModule(KotlinModule()) @@ -45,7 +44,7 @@ class WalletResponseTest { @Test fun testBalanceResponse() { val serializer = WalletResponse.Success.serializer(BalanceResponse.serializer()) - val response = json.parse( + val response = json.decodeFromString( serializer, """ { "type": "response", @@ -82,7 +81,7 @@ class WalletResponseTest { "message":"unexpected exception: Error: BUG: invariant violation (purchase status)" } """.trimIndent() - val info = json.parse(WalletErrorInfo.serializer(), infoJson) + val info = json.decodeFromString(WalletErrorInfo.serializer(), infoJson) val infoJackson: WalletErrorInfo = mapper.readValue(infoJson) println(info.userFacingMsg) assertEquals(info.userFacingMsg, infoJackson.userFacingMsg) -- cgit v1.2.3