From 398cdb93c6d83dfe7bd365f7f50c725339cdb562 Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Tue, 26 Nov 2024 11:39:04 +0530 Subject: [PATCH 1/8] [Automated] Update the native jar versions --- ballerina/Ballerina.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ballerina/Ballerina.toml b/ballerina/Ballerina.toml index 787c91f..92b702b 100644 --- a/ballerina/Ballerina.toml +++ b/ballerina/Ballerina.toml @@ -19,4 +19,4 @@ path = "../native/build/libs/data.xmldata-native-1.1.0-SNAPSHOT.jar" groupId = "io.ballerina.stdlib" artifactId = "constraint-native" version = "1.6.0" -path = "./lib/constraint-native-1.6.0-20241121-170800-002e6d6.jar" +path = "./lib/constraint-native-1.6.0-20241122-133100-98689e2.jar" From 83f4749cfb4c5ad3790ebc32803477731d108321 Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Tue, 26 Nov 2024 16:55:59 +0530 Subject: [PATCH 2/8] [Automated] Update the native jar versions --- ballerina/Dependencies.toml | 127 ------------------------------------ 1 file changed, 127 deletions(-) delete mode 100644 ballerina/Dependencies.toml diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml deleted file mode 100644 index 9cef1b0..0000000 --- a/ballerina/Dependencies.toml +++ /dev/null @@ -1,127 +0,0 @@ -# AUTO-GENERATED FILE. DO NOT MODIFY. - -# This file is auto-generated by Ballerina for managing dependency versions. -# It should not be modified by hand. - -[ballerina] -dependencies-toml-version = "2" -distribution-version = "2201.11.0-20241121-075100-c4c87cbc" - -[[package]] -org = "ballerina" -name = "constraint" -version = "1.6.0" -scope = "testOnly" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] -modules = [ - {org = "ballerina", packageName = "constraint", moduleName = "constraint"} -] - -[[package]] -org = "ballerina" -name = "data.xmldata" -version = "1.1.0" -dependencies = [ - {org = "ballerina", name = "constraint"}, - {org = "ballerina", name = "io"}, - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "test"}, - {org = "ballerina", name = "time"} -] -modules = [ - {org = "ballerina", packageName = "data.xmldata", moduleName = "data.xmldata"} -] - -[[package]] -org = "ballerina" -name = "io" -version = "1.7.0" -scope = "testOnly" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.value"} -] -modules = [ - {org = "ballerina", packageName = "io", moduleName = "io"} -] - -[[package]] -org = "ballerina" -name = "jballerina.java" -version = "0.0.0" -modules = [ - {org = "ballerina", packageName = "jballerina.java", moduleName = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "lang.__internal" -version = "0.0.0" -scope = "testOnly" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.object"} -] - -[[package]] -org = "ballerina" -name = "lang.array" -version = "0.0.0" -scope = "testOnly" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.__internal"} -] - -[[package]] -org = "ballerina" -name = "lang.error" -version = "0.0.0" -scope = "testOnly" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "lang.object" -version = "0.0.0" -scope = "testOnly" - -[[package]] -org = "ballerina" -name = "lang.value" -version = "0.0.0" -scope = "testOnly" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] - -[[package]] -org = "ballerina" -name = "test" -version = "0.0.0" -scope = "testOnly" -dependencies = [ - {org = "ballerina", name = "jballerina.java"}, - {org = "ballerina", name = "lang.array"}, - {org = "ballerina", name = "lang.error"} -] -modules = [ - {org = "ballerina", packageName = "test", moduleName = "test"} -] - -[[package]] -org = "ballerina" -name = "time" -version = "2.6.0" -scope = "testOnly" -dependencies = [ - {org = "ballerina", name = "jballerina.java"} -] -modules = [ - {org = "ballerina", packageName = "time", moduleName = "time"} -] - From 1a0e36178cfdc7f95842f85a2ff259da140f8a79 Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Wed, 27 Nov 2024 09:34:31 +0530 Subject: [PATCH 3/8] Add implementation for finite and enum types --- ballerina/Dependencies.toml | 127 ++++++++++++++++++ ballerina/tests/test_finite_types.bal | 117 ++++++++++++++++ .../lib/data/xmldata/FromString.java | 20 +++ .../lib/data/xmldata/utils/DataUtils.java | 2 +- .../lib/data/xmldata/xml/XmlParser.java | 2 +- 5 files changed, 266 insertions(+), 2 deletions(-) create mode 100644 ballerina/Dependencies.toml create mode 100644 ballerina/tests/test_finite_types.bal diff --git a/ballerina/Dependencies.toml b/ballerina/Dependencies.toml new file mode 100644 index 0000000..9cef1b0 --- /dev/null +++ b/ballerina/Dependencies.toml @@ -0,0 +1,127 @@ +# AUTO-GENERATED FILE. DO NOT MODIFY. + +# This file is auto-generated by Ballerina for managing dependency versions. +# It should not be modified by hand. + +[ballerina] +dependencies-toml-version = "2" +distribution-version = "2201.11.0-20241121-075100-c4c87cbc" + +[[package]] +org = "ballerina" +name = "constraint" +version = "1.6.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] +modules = [ + {org = "ballerina", packageName = "constraint", moduleName = "constraint"} +] + +[[package]] +org = "ballerina" +name = "data.xmldata" +version = "1.1.0" +dependencies = [ + {org = "ballerina", name = "constraint"}, + {org = "ballerina", name = "io"}, + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "test"}, + {org = "ballerina", name = "time"} +] +modules = [ + {org = "ballerina", packageName = "data.xmldata", moduleName = "data.xmldata"} +] + +[[package]] +org = "ballerina" +name = "io" +version = "1.7.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.value"} +] +modules = [ + {org = "ballerina", packageName = "io", moduleName = "io"} +] + +[[package]] +org = "ballerina" +name = "jballerina.java" +version = "0.0.0" +modules = [ + {org = "ballerina", packageName = "jballerina.java", moduleName = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.__internal" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.object"} +] + +[[package]] +org = "ballerina" +name = "lang.array" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.__internal"} +] + +[[package]] +org = "ballerina" +name = "lang.error" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "lang.object" +version = "0.0.0" +scope = "testOnly" + +[[package]] +org = "ballerina" +name = "lang.value" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] + +[[package]] +org = "ballerina" +name = "test" +version = "0.0.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"}, + {org = "ballerina", name = "lang.array"}, + {org = "ballerina", name = "lang.error"} +] +modules = [ + {org = "ballerina", packageName = "test", moduleName = "test"} +] + +[[package]] +org = "ballerina" +name = "time" +version = "2.6.0" +scope = "testOnly" +dependencies = [ + {org = "ballerina", name = "jballerina.java"} +] +modules = [ + {org = "ballerina", packageName = "time", moduleName = "time"} +] + diff --git a/ballerina/tests/test_finite_types.bal b/ballerina/tests/test_finite_types.bal new file mode 100644 index 0000000..3907637 --- /dev/null +++ b/ballerina/tests/test_finite_types.bal @@ -0,0 +1,117 @@ +import ballerina/test; + +enum EnumA { + A = "A", + B, + C = "C2" +} + +type FiniteType true|"A"|1|2; + +@test:Config +function testFiniteTypes() returns error? { + record { + EnumA a; + "A"|"B"|"C" b; + record { + "A"|"B"|"C" c; + EnumA d; + } nested; + } r = check parseAsType(xml `ABBB`); + test:assertEquals(r, {a: "A", b: "B", nested: {c: "B", d: "B"}}); +} + +@test:Config +function testFiniteTypes2() returns error? { + record { + EnumA a; + FiniteType b; + record { + FiniteType c; + FiniteType e; + EnumA d; + } nested; + } r = check parseAsType(xml `C212Atrue`); + test:assertEquals(r, {a: "C2", b: 1, nested: {c: 2, d: "A", e: true}}); +} + +@test:Config +function testFiniteTypes3() returns error? { + record { + EnumA[] a; + ("A"|"B"|"C")[] b; + record { + ("A"|"B"|"C")[] c; + EnumA[] d; + } nested; + } r = check parseAsType(xml `AABBBBBB`); + test:assertEquals(r, {a: ["A", "A"], b: ["B", "B"], nested: {c: ["B", "B"], d: ["B", "B"]}}); +} + +@test:Config +function testFiniteTypes4() returns error? { + record { + EnumA[] a; + FiniteType[] b; + record { + FiniteType[] c; + FiniteType[] e; + EnumA[] d; + } nested; + } r = check parseAsType(xml `C2C21122AAtruetrue`); + test:assertEquals(r, {a: ["C2", "C2"], b: [1, 1], nested: {c: [2, 2], d: ["A", "A"], e: [true, true]}}); +} + +@test:Config +function testFiniteTypesWithXmlString() returns error? { + record { + EnumA a; + "A"|"B"|"C" b; + record { + "A"|"B"|"C" c; + EnumA d; + } nested; + } r = check parseString(string `ABBB`); + test:assertEquals(r, {a: "A", b: "B", nested: {c: "B", d: "B"}}); +} + +@test:Config +function testFiniteTypesWithXmlString2() returns error? { + record { + EnumA a; + FiniteType b; + record { + FiniteType c; + FiniteType e; + EnumA d; + } nested; + } r = check parseString(string `C212Atrue`); + test:assertEquals(r, {a: "C2", b: 1, nested: {c: 2, d: "A", e: true}}); +} + +@test:Config +function testFiniteTypesWithXmlString3() returns error? { + record { + EnumA[] a; + ("A"|"B"|"C")[] b; + record { + ("A"|"B"|"C")[] c; + EnumA[] d; + } nested; + } r = check parseString(string `AABBBBBB`); + test:assertEquals(r, {a: ["A", "A"], b: ["B", "B"], nested: {c: ["B", "B"], d: ["B", "B"]}}); +} + +@test:Config +function testFiniteTypesWithXmlString4() returns error? { + record { + EnumA[] a; + FiniteType[] b; + record { + FiniteType[] c; + FiniteType[] e; + EnumA[] d; + } nested; + } r = check parseString(string `C2C21122AAtruetrue`); + test:assertEquals(r, {a: ["C2", "C2"], b: [1, 1], nested: {c: [2, 2], d: ["A", "A"], e: [true, true]}}); +} diff --git a/native/src/main/java/io/ballerina/lib/data/xmldata/FromString.java b/native/src/main/java/io/ballerina/lib/data/xmldata/FromString.java index 57d3a2f..c9280d0 100644 --- a/native/src/main/java/io/ballerina/lib/data/xmldata/FromString.java +++ b/native/src/main/java/io/ballerina/lib/data/xmldata/FromString.java @@ -22,11 +22,13 @@ import io.ballerina.lib.data.xmldata.utils.DiagnosticLog; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; +import io.ballerina.runtime.api.types.FiniteType; import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.ReferenceType; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.UnionType; +import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BDecimal; import io.ballerina.runtime.api.values.BError; @@ -96,6 +98,8 @@ public static Object fromStringWithType(BString string, Type expType) { return stringToUnion(string, JSON_TYPE_WITH_BASIC_TYPES); case TypeTags.TYPE_REFERENCED_TYPE_TAG: return fromStringWithType(string, ((ReferenceType) expType).getReferredType()); + case TypeTags.FINITE_TYPE_TAG: + return stringToFiniteType(value, (FiniteType) expType); default: return returnError(value, expType.toString()); } @@ -104,6 +108,22 @@ public static Object fromStringWithType(BString string, Type expType) { } } + private static Object stringToFiniteType(String value, FiniteType finiteType) { + return finiteType.getValueSpace().stream() + .filter(finiteValue -> !(convertToSingletonValue(value, finiteValue) instanceof BError)) + .findFirst() + .orElseGet(() -> returnError(value, finiteType.toString())); + } + + private static Object convertToSingletonValue(String str, Object singletonValue) { + String singletonStr = String.valueOf(singletonValue); + if (str.equals(singletonStr)) { + return fromStringWithType(StringUtils.fromString(str), TypeUtils.getType(singletonValue)); + } else { + return returnError(str, singletonStr); + } + } + private static Long stringToInt(String value) throws NumberFormatException { return Long.parseLong(value); } diff --git a/native/src/main/java/io/ballerina/lib/data/xmldata/utils/DataUtils.java b/native/src/main/java/io/ballerina/lib/data/xmldata/utils/DataUtils.java index 5615006..efca262 100644 --- a/native/src/main/java/io/ballerina/lib/data/xmldata/utils/DataUtils.java +++ b/native/src/main/java/io/ballerina/lib/data/xmldata/utils/DataUtils.java @@ -375,7 +375,7 @@ public static boolean isSupportedType(Type type) { switch (type.getTag()) { case TypeTags.NULL_TAG, TypeTags.INT_TAG, TypeTags.BYTE_TAG, TypeTags.FLOAT_TAG, TypeTags.DECIMAL_TAG, TypeTags.BOOLEAN_TAG, TypeTags.STRING_TAG, TypeTags.RECORD_TYPE_TAG, TypeTags.MAP_TAG, - TypeTags.JSON_TAG, TypeTags.ANYDATA_TAG -> { + TypeTags.JSON_TAG, TypeTags.ANYDATA_TAG, TypeTags.FINITE_TYPE_TAG -> { return true; } case TypeTags.ARRAY_TAG -> { diff --git a/native/src/main/java/io/ballerina/lib/data/xmldata/xml/XmlParser.java b/native/src/main/java/io/ballerina/lib/data/xmldata/xml/XmlParser.java index 19e186c..43e9ec8 100644 --- a/native/src/main/java/io/ballerina/lib/data/xmldata/xml/XmlParser.java +++ b/native/src/main/java/io/ballerina/lib/data/xmldata/xml/XmlParser.java @@ -448,7 +448,7 @@ private Object convertStringToRestExpType(BString value, Type expType) { return convertStringToRestExpType(value, ((ArrayType) expType).getElementType()); } case TypeTags.INT_TAG, TypeTags.FLOAT_TAG, TypeTags.DECIMAL_TAG, TypeTags.STRING_TAG, - TypeTags.BOOLEAN_TAG, TypeTags.UNION_TAG -> { + TypeTags.BOOLEAN_TAG, TypeTags.UNION_TAG, TypeTags.FINITE_TYPE_TAG -> { return convertStringToExpType(value, expType); } case TypeTags.ANYDATA_TAG, TypeTags.JSON_TAG -> { From b976d336d7dabd80dcbbe7bf8bff86371d577f83 Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Wed, 27 Nov 2024 10:09:08 +0530 Subject: [PATCH 4/8] Add a test for singleton type with name annotation --- ballerina/tests/test_finite_types.bal | 85 +++++++++++++++++---------- 1 file changed, 53 insertions(+), 32 deletions(-) diff --git a/ballerina/tests/test_finite_types.bal b/ballerina/tests/test_finite_types.bal index 3907637..fd37aed 100644 --- a/ballerina/tests/test_finite_types.bal +++ b/ballerina/tests/test_finite_types.bal @@ -10,108 +10,129 @@ type FiniteType true|"A"|1|2; @test:Config function testFiniteTypes() returns error? { - record { + record {| EnumA a; "A"|"B"|"C" b; - record { + record {| "A"|"B"|"C" c; EnumA d; - } nested; - } r = check parseAsType(xml `ABBB`); + |} nested; + |} r = check parseAsType(xml `ABBB`); test:assertEquals(r, {a: "A", b: "B", nested: {c: "B", d: "B"}}); } @test:Config function testFiniteTypes2() returns error? { - record { + record {| EnumA a; FiniteType b; - record { + record {| FiniteType c; FiniteType e; EnumA d; - } nested; - } r = check parseAsType(xml `C212Atrue`); + |} nested; + |} r = check parseAsType(xml `C212Atrue`); test:assertEquals(r, {a: "C2", b: 1, nested: {c: 2, d: "A", e: true}}); } @test:Config function testFiniteTypes3() returns error? { - record { + record {| EnumA[] a; ("A"|"B"|"C")[] b; - record { + record {| ("A"|"B"|"C")[] c; EnumA[] d; - } nested; - } r = check parseAsType(xml `AABBBBBB`); + |} nested; + |} r = check parseAsType(xml `AABBBBBB`); test:assertEquals(r, {a: ["A", "A"], b: ["B", "B"], nested: {c: ["B", "B"], d: ["B", "B"]}}); } @test:Config function testFiniteTypes4() returns error? { - record { + record {| EnumA[] a; FiniteType[] b; - record { + record {| FiniteType[] c; FiniteType[] e; EnumA[] d; - } nested; - } r = check parseAsType(xml `C2C21122AAtruetrue`); + |} nested; + |} r = check parseAsType(xml `C2C21122AAtruetrue`); test:assertEquals(r, {a: ["C2", "C2"], b: [1, 1], nested: {c: [2, 2], d: ["A", "A"], e: [true, true]}}); } @test:Config function testFiniteTypesWithXmlString() returns error? { - record { + record {| EnumA a; "A"|"B"|"C" b; - record { + record {| "A"|"B"|"C" c; EnumA d; - } nested; - } r = check parseString(string `ABBB`); + |} nested; + |} r = check parseString(string `ABBB`); test:assertEquals(r, {a: "A", b: "B", nested: {c: "B", d: "B"}}); } @test:Config function testFiniteTypesWithXmlString2() returns error? { - record { + record {| EnumA a; FiniteType b; - record { + record {| FiniteType c; FiniteType e; EnumA d; - } nested; - } r = check parseString(string `C212Atrue`); + |} nested; + |} r = check parseString(string `C212Atrue`); test:assertEquals(r, {a: "C2", b: 1, nested: {c: 2, d: "A", e: true}}); } @test:Config function testFiniteTypesWithXmlString3() returns error? { - record { + record {| EnumA[] a; ("A"|"B"|"C")[] b; - record { + record {| ("A"|"B"|"C")[] c; EnumA[] d; - } nested; - } r = check parseString(string `AABBBBBB`); + |} nested; + |} r = check parseString(string `AABBBBBB`); test:assertEquals(r, {a: ["A", "A"], b: ["B", "B"], nested: {c: ["B", "B"], d: ["B", "B"]}}); } @test:Config function testFiniteTypesWithXmlString4() returns error? { - record { + record {| EnumA[] a; FiniteType[] b; - record { + record {| FiniteType[] c; FiniteType[] e; EnumA[] d; - } nested; - } r = check parseString(string `C2C21122AAtruetrue`); + |} nested; + |} r = check parseString(string `C2C21122AAtruetrue`); test:assertEquals(r, {a: ["C2", "C2"], b: [1, 1], nested: {c: [2, 2], d: ["A", "A"], e: [true, true]}}); } +type NestedRec record {| + @Name { + value: "c2" + } + FiniteType c; + FiniteType e; + @Name { + value: "d2" + } + EnumA d; +|}; + +@test:Config +function testFiniteTypes5() returns error? { + record {| + EnumA a; + FiniteType b; + NestedRec nested; + |} r = check parseAsType(xml `C212Atrue`); + test:assertEquals(r, {a: "C2", b: 1, nested: {c: 2, d: "A", e: true}}); +} From e2f78daea5f6c3d42905214aeba5bda1607bab3b Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Wed, 27 Nov 2024 10:19:43 +0530 Subject: [PATCH 5/8] Revert ballerina toml version changes --- ballerina/Ballerina.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ballerina/Ballerina.toml b/ballerina/Ballerina.toml index 92b702b..787c91f 100644 --- a/ballerina/Ballerina.toml +++ b/ballerina/Ballerina.toml @@ -19,4 +19,4 @@ path = "../native/build/libs/data.xmldata-native-1.1.0-SNAPSHOT.jar" groupId = "io.ballerina.stdlib" artifactId = "constraint-native" version = "1.6.0" -path = "./lib/constraint-native-1.6.0-20241122-133100-98689e2.jar" +path = "./lib/constraint-native-1.6.0-20241121-170800-002e6d6.jar" From 6f4a8b8051ab1b64cbeb6fd4d10eb1748cf410f7 Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Wed, 27 Nov 2024 10:22:17 +0530 Subject: [PATCH 6/8] Add license headers for finite tests --- ballerina/tests/test_finite_types.bal | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ballerina/tests/test_finite_types.bal b/ballerina/tests/test_finite_types.bal index fd37aed..58ef756 100644 --- a/ballerina/tests/test_finite_types.bal +++ b/ballerina/tests/test_finite_types.bal @@ -1,3 +1,19 @@ +// Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + import ballerina/test; enum EnumA { From 07a5c491dace6e8322e6082895cc017106eaf2b4 Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Thu, 28 Nov 2024 11:03:56 +0530 Subject: [PATCH 7/8] [Automated] Update the native jar versions --- ballerina/Ballerina.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ballerina/Ballerina.toml b/ballerina/Ballerina.toml index 787c91f..92b702b 100644 --- a/ballerina/Ballerina.toml +++ b/ballerina/Ballerina.toml @@ -19,4 +19,4 @@ path = "../native/build/libs/data.xmldata-native-1.1.0-SNAPSHOT.jar" groupId = "io.ballerina.stdlib" artifactId = "constraint-native" version = "1.6.0" -path = "./lib/constraint-native-1.6.0-20241121-170800-002e6d6.jar" +path = "./lib/constraint-native-1.6.0-20241122-133100-98689e2.jar" From 7f16a0c8681391d9f96dbb81a41383339b77c3f4 Mon Sep 17 00:00:00 2001 From: Sasindu Alahakoon Date: Thu, 28 Nov 2024 11:35:21 +0530 Subject: [PATCH 8/8] Add finite type implementation for numeric types --- ballerina/tests/test_finite_types.bal | 74 +++++++++++++++++-- .../lib/data/xmldata/FromString.java | 23 +++++- 2 files changed, 87 insertions(+), 10 deletions(-) diff --git a/ballerina/tests/test_finite_types.bal b/ballerina/tests/test_finite_types.bal index 58ef756..62bf7e4 100644 --- a/ballerina/tests/test_finite_types.bal +++ b/ballerina/tests/test_finite_types.bal @@ -38,7 +38,7 @@ function testFiniteTypes() returns error? { } @test:Config -function testFiniteTypes2() returns error? { +function testFiniteTypesWithNestedRecords() returns error? { record {| EnumA a; FiniteType b; @@ -52,7 +52,7 @@ function testFiniteTypes2() returns error? { } @test:Config -function testFiniteTypes3() returns error? { +function testFiniteTypeArrays() returns error? { record {| EnumA[] a; ("A"|"B"|"C")[] b; @@ -65,7 +65,7 @@ function testFiniteTypes3() returns error? { } @test:Config -function testFiniteTypes4() returns error? { +function testFiniteTypeArrays2() returns error? { record {| EnumA[] a; FiniteType[] b; @@ -92,7 +92,7 @@ function testFiniteTypesWithXmlString() returns error? { } @test:Config -function testFiniteTypesWithXmlString2() returns error? { +function testFiniteTypesWithNestedRecordsWithXmlString() returns error? { record {| EnumA a; FiniteType b; @@ -106,7 +106,7 @@ function testFiniteTypesWithXmlString2() returns error? { } @test:Config -function testFiniteTypesWithXmlString3() returns error? { +function testFiniteTypeArraysWithXmlString() returns error? { record {| EnumA[] a; ("A"|"B"|"C")[] b; @@ -119,7 +119,7 @@ function testFiniteTypesWithXmlString3() returns error? { } @test:Config -function testFiniteTypesWithXmlString4() returns error? { +function testFiniteTypeArraysWithXmlString2() returns error? { record {| EnumA[] a; FiniteType[] b; @@ -144,7 +144,7 @@ type NestedRec record {| |}; @test:Config -function testFiniteTypes5() returns error? { +function testFiniteTypesWithNameAnnotations() returns error? { record {| EnumA a; FiniteType b; @@ -152,3 +152,63 @@ function testFiniteTypes5() returns error? { |} r = check parseAsType(xml `C212Atrue`); test:assertEquals(r, {a: "C2", b: 1, nested: {c: 2, d: "A", e: true}}); } + +type FiniteValue 100f; + +@test:Config +function testRecordFieldWithSingleFiniteType() returns error? { + record {| + EnumA a; + "A" b; + record {| + FiniteValue c; + EnumA d; + |} nested; + |} r = check parseAsType(xml `AA100.0B`); + test:assertEquals(r, {a: "A", b: "A", nested: {c: 100f, d: "B"}}); +} + +@test:Config +function testRecordFieldWithSingleFiniteType2() returns error? { + record {| + 100f a; + 200.1d b; + 100d c; + 200.1f d; + 100f e; + 200.1d f; + 100d g; + 200.1f h; + |} r = check parseAsType(xml `100200.1100200.1100.0200.1100.0200.1`); + test:assertEquals(r, {a: 100f, b: 200.1d, c: 100d, d: 200.1f, e: 100f, f: 200.1d, g: 100d, h: 200.1f}); +} + +@test:Config +function testRecordFieldWithSingleFiniteType3() returns error? { + record {| + 100f a; + |}|Error r = parseAsType(xml `100.01`); + test:assertTrue(r is Error); + test:assertEquals((r).message(), "'string' value '100.01' cannot be converted to '100.0f'"); + + record {| + 100d a; + |}|Error r2 = parseAsType(xml `100.01`); + test:assertTrue(r2 is Error); + test:assertEquals((r2).message(), "'string' value '100.01' cannot be converted to '100d'"); +} + +@test:Config +function testRecordFieldWithSingleFiniteType4() returns error? { + record {| + 200.1d|100f a; + 200.1d|100d b; + 100d|100f|200.1f c; + 200.1f|200.1d|100f d; + 200.1d|200.1f|100f e; + 100d|100d|200.1d f; + 100d|200.1d|200.1d g; + 200.1f|200.1d|200.1d h; + |} r = check parseAsType(xml `100200.1100200.1100.0200.1100.0200.1`); + test:assertEquals(r, {a: 100f, b: 200.1d, c: 100d, d: 200.1f, e: 100f, f: 200.1d, g: 100d, h: 200.1f}); +} diff --git a/native/src/main/java/io/ballerina/lib/data/xmldata/FromString.java b/native/src/main/java/io/ballerina/lib/data/xmldata/FromString.java index c9280d0..914e96c 100644 --- a/native/src/main/java/io/ballerina/lib/data/xmldata/FromString.java +++ b/native/src/main/java/io/ballerina/lib/data/xmldata/FromString.java @@ -35,6 +35,7 @@ import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BTypedesc; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -117,11 +118,27 @@ private static Object stringToFiniteType(String value, FiniteType finiteType) { private static Object convertToSingletonValue(String str, Object singletonValue) { String singletonStr = String.valueOf(singletonValue); - if (str.equals(singletonStr)) { - return fromStringWithType(StringUtils.fromString(str), TypeUtils.getType(singletonValue)); - } else { + Type type = TypeUtils.getType(singletonValue); + + if (singletonValue instanceof BDecimal decimalValue) { + BigDecimal bigDecimal = decimalValue.decimalValue(); + if (bigDecimal.compareTo(new BigDecimal(str)) == 0) { + return fromStringWithType(StringUtils.fromString(str), type); + } + return returnError(str, singletonStr); + } + + if (singletonValue instanceof Double doubleValue) { + if (doubleValue.compareTo(Double.valueOf(str)) == 0) { + return fromStringWithType(StringUtils.fromString(str), type); + } return returnError(str, singletonStr); } + + if (str.equals(singletonStr)) { + return fromStringWithType(StringUtils.fromString(str), type); + } + return returnError(str, singletonStr); } private static Long stringToInt(String value) throws NumberFormatException {