gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-taler-android] 01/03: [pos] compare version from backend and show


From: gnunet
Subject: [taler-taler-android] 01/03: [pos] compare version from backend and show error if incompatible
Date: Tue, 21 Jul 2020 20:07:06 +0200

This is an automated email from the git hooks/post-receive script.

torsten-grote pushed a commit to branch master
in repository taler-android.

commit 5d3d85fa7190a70eea8fa67866c343005b9922b0
Author: Torsten Grote <t@grobox.de>
AuthorDate: Tue Jul 21 10:44:32 2020 -0300

    [pos] compare version from backend and show error if incompatible
---
 .../net/taler/merchantpos/config/ConfigManager.kt  | 13 ++--
 merchant-terminal/src/main/res/values/strings.xml  |  1 -
 .../src/main/java/net/taler/common/AndroidUtils.kt |  9 +++
 .../src/main/java/net/taler/common/Version.kt      | 70 ++++++++++++++++++++++
 .../src/main/res/values/strings.xml                | 21 +++++++
 .../src/test/java/net/taler/common/VersionTest.kt  | 65 ++++++++++++++++++++
 6 files changed, 172 insertions(+), 7 deletions(-)

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 eee7905..a7aff18 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
@@ -34,14 +34,14 @@ import com.fasterxml.jackson.module.kotlin.readValue
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
+import net.taler.common.Version
+import net.taler.common.getIncompatibleStringOrNull
 import net.taler.merchantlib.ConfigResponse
 import net.taler.merchantlib.MerchantApi
 import net.taler.merchantpos.LogErrorListener
 import net.taler.merchantpos.R
 import org.json.JSONObject
 
-private const val VERSION = "0:0:0"
-
 private const val SETTINGS_NAME = "taler-merchant-terminal"
 
 private const val SETTINGS_CONFIG_URL = "configUrl"
@@ -52,6 +52,8 @@ internal const val CONFIG_URL_DEMO = 
"https://docs.taler.net/_static/sample-pos-
 internal const val CONFIG_USERNAME_DEMO = ""
 internal const val CONFIG_PASSWORD_DEMO = ""
 
+private val VERSION = Version(1, 0, 0)
+
 private val TAG = ConfigManager::class.java.simpleName
 
 interface ConfigurationReceiver {
@@ -131,10 +133,9 @@ class ConfigManager(
         merchantConfig: MerchantConfig,
         configResponse: ConfigResponse
     ) = scope.launch(Dispatchers.Default) {
-        // TODO do real matching
-        if (VERSION != configResponse.version) {
-            val str = context.getString(R.string.config_error_version)
-            mConfigUpdateResult.postValue(ConfigUpdateResult.Error(str))
+        val versionIncompatible = VERSION.getIncompatibleStringOrNull(context, 
configResponse.version)
+        if (versionIncompatible != null) {
+            
mConfigUpdateResult.postValue(ConfigUpdateResult.Error(versionIncompatible))
             return@launch
         }
         for (receiver in configurationReceivers) {
diff --git a/merchant-terminal/src/main/res/values/strings.xml 
b/merchant-terminal/src/main/res/values/strings.xml
index 931f31c..b3dcd8d 100644
--- a/merchant-terminal/src/main/res/values/strings.xml
+++ b/merchant-terminal/src/main/res/values/strings.xml
@@ -22,7 +22,6 @@
     <string name="config_password">Password</string>
     <string name="config_ok">Fetch configuration</string>
     <string name="config_auth_error">Error: Invalid username or 
password</string>
-    <string name="config_error_version">Error: Incompatible backend 
version</string>
     <string name="config_error_network">Error: Could not connect to 
configuration server</string>
     <string name="config_error_category">Error: No valid product category 
found</string>
     <string name="config_error_malformed">Error: The configuration JSON is 
malformed</string>
diff --git a/taler-kotlin-common/src/main/java/net/taler/common/AndroidUtils.kt 
b/taler-kotlin-common/src/main/java/net/taler/common/AndroidUtils.kt
index ba6ee1c..b46f306 100644
--- a/taler-kotlin-common/src/main/java/net/taler/common/AndroidUtils.kt
+++ b/taler-kotlin-common/src/main/java/net/taler/common/AndroidUtils.kt
@@ -112,3 +112,12 @@ fun Long.toShortDate(context: Context): CharSequence {
     val flags = FORMAT_SHOW_DATE or FORMAT_SHOW_YEAR or FORMAT_ABBREV_ALL
     return formatDateTime(context, this, flags)
 }
+
+fun Version.getIncompatibleStringOrNull(context: Context, otherVersion: 
String): String? {
+    val other = Version.parse(otherVersion) ?: return 
context.getString(R.string.version_invalid)
+    val match = compare(other) ?: return 
context.getString(R.string.version_invalid)
+    if (match.compatible) return null
+    if (match.currentCmp < 0) return 
context.getString(R.string.version_too_old)
+    if (match.currentCmp > 0) return 
context.getString(R.string.version_too_new)
+    throw AssertionError("$this == $other")
+}
diff --git a/taler-kotlin-common/src/main/java/net/taler/common/Version.kt 
b/taler-kotlin-common/src/main/java/net/taler/common/Version.kt
new file mode 100644
index 0000000..8774115
--- /dev/null
+++ b/taler-kotlin-common/src/main/java/net/taler/common/Version.kt
@@ -0,0 +1,70 @@
+/*
+ * This file is part of GNU Taler
+ * (C) 2020 Taler Systems S.A.
+ *
+ * GNU Taler is free software; you can redistribute it and/or modify it under 
the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+ * A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+package net.taler.common
+
+import kotlin.math.sign
+
+/**
+ * Semantic versioning, but libtool-style.
+ * See 
https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
+ */
+data class Version(
+    val current: Int,
+    val revision: Int,
+    val age: Int
+) {
+    companion object {
+        fun parse(v: String): Version? {
+            val elements = v.split(":")
+            if (elements.size != 3) return null
+            val (currentStr, revisionStr, ageStr) = elements
+            val current = currentStr.toIntOrNull()
+            val revision = revisionStr.toIntOrNull()
+            val age = ageStr.toIntOrNull()
+            if (current == null || revision == null || age == null) return null
+            return Version(current, revision, age)
+        }
+    }
+
+    /**
+     * Compare two libtool-style versions.
+     *
+     * Returns a [VersionMatchResult] or null if the given version was null.
+     */
+    fun compare(other: Version?): VersionMatchResult? {
+        if (other == null) return null
+        val compatible = current - age <= other.current &&
+                current >= other.current - other.age
+        val currentCmp = sign((current - other.current).toDouble()).toInt()
+        return VersionMatchResult(compatible, currentCmp)
+    }
+
+    /**
+     * Result of comparing two libtool versions.
+     */
+    data class VersionMatchResult(
+        /**
+         * Is the first version compatible with the second?
+         */
+        val compatible: Boolean,
+        /**
+         * Is the first version older (-1), newer (+1) or identical (0)?
+         */
+        val currentCmp: Int
+    )
+
+}
diff --git a/taler-kotlin-common/src/main/res/values/strings.xml 
b/taler-kotlin-common/src/main/res/values/strings.xml
new file mode 100644
index 0000000..a5b1df1
--- /dev/null
+++ b/taler-kotlin-common/src/main/res/values/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ This file is part of GNU Taler
+  ~ (C) 2020 Taler Systems S.A.
+  ~
+  ~ GNU Taler is free software; you can redistribute it and/or modify it under 
the
+  ~ terms of the GNU General Public License as published by the Free Software
+  ~ Foundation; either version 3, or (at your option) any later version.
+  ~
+  ~ GNU Taler is distributed in the hope that it will be useful, but WITHOUT 
ANY
+  ~ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+  ~ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU General Public License along 
with
+  ~ GNU Taler; see the file COPYING.  If not, see 
<http://www.gnu.org/licenses/>
+  -->
+
+<resources>
+    <string name="version_invalid">Invalid version. Please try again 
later!</string>
+    <string name="version_too_old">App too old. Please upgrade!</string>
+    <string name="version_too_new">Service outdated. Please wait until it gets 
upgraded.</string>
+</resources>
diff --git a/taler-kotlin-common/src/test/java/net/taler/common/VersionTest.kt 
b/taler-kotlin-common/src/test/java/net/taler/common/VersionTest.kt
new file mode 100644
index 0000000..70f30eb
--- /dev/null
+++ b/taler-kotlin-common/src/test/java/net/taler/common/VersionTest.kt
@@ -0,0 +1,65 @@
+/*
+ * This file is part of GNU Taler
+ * (C) 2020 Taler Systems S.A.
+ *
+ * GNU Taler is free software; you can redistribute it and/or modify it under 
the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
FOR
+ * A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+package net.taler.common
+
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNull
+import org.junit.Test
+
+class VersionTest {
+
+    @Test
+    fun testParse() {
+        assertNull(Version.parse(""))
+        assertNull(Version.parse("foo"))
+        assertNull(Version.parse("foo:bar:foo"))
+        assertNull(Version.parse("0:0:0:"))
+        assertNull(Version.parse("0:0:"))
+        assertEquals(Version(0, 0, 0), Version.parse("0:0:0"))
+        assertEquals(Version(1, 2, 3), Version.parse("1:2:3"))
+        assertEquals(Version(1337, 42, 23), Version.parse("1337:42:23"))
+    }
+
+    @Test
+    fun testComparision() {
+        assertEquals(
+            Version.VersionMatchResult(true, 0),
+            Version.parse("0:0:0")!!.compare(Version.parse("0:0:0"))
+        )
+        assertEquals(
+            Version.VersionMatchResult(true, -1),
+            Version.parse("0:0:0")!!.compare(Version.parse("1:0:1"))
+        )
+        assertEquals(
+            Version.VersionMatchResult(true, -1),
+            Version.parse("0:0:0")!!.compare(Version.parse("1:5:1"))
+        )
+        assertEquals(
+            Version.VersionMatchResult(false, -1),
+            Version.parse("0:0:0")!!.compare(Version.parse("1:5:0"))
+        )
+        assertEquals(
+            Version.VersionMatchResult(false, 1),
+            Version.parse("1:0:0")!!.compare(Version.parse("0:5:0"))
+        )
+        assertEquals(
+            Version.VersionMatchResult(true, 0),
+            Version.parse("1:0:1")!!.compare(Version.parse("1:5:1"))
+        )
+    }
+
+}

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]