Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert elm, elm-xmlutil, model-xmlutil to Kotlin Multiplatform (Kotlin feature branch) #1494

Merged
merged 1 commit into from
Jan 31, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Convert the elm, elm-xmlutil, model-xmlutil modules to Kotlin Multipl…
…atform. Polyfill BigDecimal with kt-math-js in JS.
  • Loading branch information
antvaset committed Jan 31, 2025
commit 5260d8419a36c29684ac44310f7018498efec8d6
Original file line number Diff line number Diff line change
@@ -84,6 +84,8 @@ kotlin {
jvmTest {
dependencies {
implementation(kotlin("test-junit5"))
implementation("org.junit.jupiter:junit-jupiter")
implementation("org.slf4j:slf4j-simple:2.0.13")
}
}

Original file line number Diff line number Diff line change
@@ -218,21 +218,15 @@ class CqlTranslator(
return VersionedIdentifier().withId(name).withSystem(system)
}

@Throws(IOException::class)
fun convertToXml(library: Library): String {
val writer = StringWriter()
ElmLibraryWriterFactory.getWriter(LibraryContentType.XML.mimeType())
.write(library, writer)
return writer.buffer.toString()
return ElmLibraryWriterFactory.getWriter(LibraryContentType.XML.mimeType())
.writeAsString(library)
}

@JvmStatic
@Throws(IOException::class)
fun convertToJson(library: Library): String {
val writer = StringWriter()
ElmLibraryWriterFactory.getWriter(LibraryContentType.JSON.mimeType())
.write(library, writer)
return writer.buffer.toString()
return ElmLibraryWriterFactory.getWriter(LibraryContentType.JSON.mimeType())
.writeAsString(library)
}
}
}
Original file line number Diff line number Diff line change
@@ -6,6 +6,8 @@ import java.io.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
import kotlin.collections.HashSet
import kotlinx.io.asSource
import kotlinx.io.buffered
import org.cqframework.cql.cql2elm.model.CompiledLibrary
import org.cqframework.cql.cql2elm.tracking.Trackable.resultType
import org.cqframework.cql.cql2elm.ucum.UcumService
@@ -188,7 +190,7 @@ constructor(
try {
library =
ElmLibraryReaderFactory.getReader(type.mimeType())
.read(InputStreamReader(librarySource))
.read(librarySource.asSource().buffered())
} catch (@Suppress("SwallowedException") e: IOException) {
// intentionally ignored
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.cqframework.cql.elm;

import static kotlinx.io.CoreKt.buffered;
import static kotlinx.io.JvmCoreKt.asSource;
import static org.junit.jupiter.api.Assertions.*;

import java.io.*;
@@ -178,7 +180,7 @@ private void testElmDeserialization(String path, String xmlFileName, String json
Library xmlLibrary = null;
try {
xmlLibrary = new org.cqframework.cql.elm.serializing.xmlutil.ElmXmlLibraryReader()
.read(new FileReader(path + "/" + xmlFileName));
.read(buffered(asSource(new FileInputStream(path + "/" + xmlFileName))));
} catch (Exception e) {
throw new IllegalArgumentException(
String.format("Errors occurred reading ELM from xml %s: %s", xmlFileName, e.getMessage()));
@@ -187,7 +189,7 @@ private void testElmDeserialization(String path, String xmlFileName, String json
Library jsonLibrary;
try {
jsonLibrary = new org.cqframework.cql.elm.serializing.xmlutil.ElmJsonLibraryReader()
.read(new FileReader(path + "/" + jsonFileName));
.read(buffered(asSource(new FileInputStream(path + "/" + jsonFileName))));
} catch (Exception e) {
throw new IllegalArgumentException(
String.format("Errors occurred reading ELM from json %s: %s", jsonFileName, e.getMessage()));
@@ -340,27 +342,26 @@ void emptyStringsTest() throws IOException {

String xml = toXml(translator.toELM());

Library xmlLibrary =
new org.cqframework.cql.elm.serializing.xmlutil.ElmXmlLibraryReader().read(new StringReader(xml));
Library xmlLibrary = new org.cqframework.cql.elm.serializing.xmlutil.ElmXmlLibraryReader().read(xml);
validateEmptyStringsTest(xmlLibrary);

String json = toJson(translator.toELM());
Library jsonLibrary =
new org.cqframework.cql.elm.serializing.xmlutil.ElmJsonLibraryReader().read(new StringReader(json));
Library jsonLibrary = new org.cqframework.cql.elm.serializing.xmlutil.ElmJsonLibraryReader().read(json);
validateEmptyStringsTest(jsonLibrary);
}

private static Library deserializeJsonLibrary(String filePath) throws IOException {
final InputStream resourceAsStream = ElmDeserializeTests.class.getResourceAsStream(filePath);
assertNotNull(resourceAsStream);
return new org.cqframework.cql.elm.serializing.xmlutil.ElmJsonLibraryReader()
.read(new InputStreamReader(resourceAsStream));
.read(buffered(asSource(resourceAsStream)));
}

private static Library deserializeXmlLibrary(String filePath) throws IOException {
final InputStream resourceAsStream = ElmDeserializeTests.class.getResourceAsStream(filePath);
assertNotNull(resourceAsStream);
return new org.cqframework.cql.elm.serializing.xmlutil.ElmXmlLibraryReader().read(resourceAsStream);
return new org.cqframework.cql.elm.serializing.xmlutil.ElmXmlLibraryReader()
.read(buffered(asSource(resourceAsStream)));
}

private static void verifySigLevels(Library library, LibraryBuilder.SignatureLevel expectedSignatureLevel) {
45 changes: 30 additions & 15 deletions Src/java/elm-xmlutil/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,22 +1,37 @@
plugins {
id("cql.library-conventions")
id("cql.kotlin-multiplatform-conventions")
kotlin("plugin.serialization")
}

dependencies {
api(project(":model"))
api(project(":elm"))
kotlin {
sourceSets {
commonMain {
dependencies {
api(project(":model"))
api(project(":elm"))

implementation("org.jetbrains.kotlinx:kotlinx-io-core:0.6.0")
implementation("io.github.pdvrieze.xmlutil:core:0.90.3")
implementation("io.github.pdvrieze.xmlutil:serialization:0.90.3")
implementation("io.github.pdvrieze.xmlutil:serialization-jvm:0.90.3")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
implementation("org.jetbrains.kotlinx:kotlinx-io-core:0.6.0")
implementation("io.github.pdvrieze.xmlutil:core:0.90.3")
implementation("io.github.pdvrieze.xmlutil:serialization:0.90.3")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
}
}

testImplementation(project(":cql-to-elm"))
testImplementation(project(":model-xmlutil"))
testImplementation(project(":ucum"))
testImplementation(project(":quick"))
testImplementation("org.xmlunit:xmlunit-assertj:2.10.0")
testImplementation("org.skyscreamer:jsonassert:1.5.1")
jvmMain {
dependencies {
implementation("io.github.pdvrieze.xmlutil:serialization-jvm:0.90.3")
}
}

jvmTest {
dependencies {
implementation(project(":cql-to-elm"))
implementation(project(":model-xmlutil"))
implementation(project(":ucum"))
implementation(project(":quick"))
implementation("org.xmlunit:xmlunit-assertj:2.10.0")
implementation("org.skyscreamer:jsonassert:1.5.1")
}
}
}
}
Original file line number Diff line number Diff line change
@@ -3,10 +3,10 @@ package org.cqframework.cql.elm.serializing.xmlutil
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.plus
import kotlinx.serialization.modules.serializersModuleOf
import org.cqframework.cql.elm.serializing.BigDecimalJsonSerializer
import org.cqframework.cql.elm.serializing.NarrativeJsonSerializer
import org.hl7.elm_modelinfo.r1.serializing.BigDecimalJsonSerializer

val json = Json {
internal val json = Json {
serializersModule =
serializersModuleOf(BigDecimalJsonSerializer) +
serializersModuleOf(NarrativeJsonSerializer) +
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.cqframework.cql.elm.serializing.xmlutil

import kotlinx.io.Source
import kotlinx.io.readString
import org.cqframework.cql.elm.serializing.ElmLibraryReader
import org.hl7.elm.r1.Library

class ElmJsonLibraryReader : ElmLibraryReader {
override fun read(string: String): Library {
return json.decodeFromString(LibraryWrapper.serializer(), string).library
}
override fun read(source: Source): Library {
return read(source.readString())
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package org.cqframework.cql.elm.serializing.xmlutil

import java.io.Writer
import kotlinx.io.Sink
import kotlinx.io.writeString
import org.cqframework.cql.elm.serializing.ElmLibraryWriter
import org.hl7.elm.r1.Library

class ElmJsonLibraryWriter : ElmLibraryWriter {
override fun write(library: Library, writer: Writer) {
writer.write(writeAsString(library))
override fun write(library: Library, sink: Sink) {
sink.writeString(writeAsString(library))
}

override fun writeAsString(library: Library): String {
Original file line number Diff line number Diff line change
@@ -5,10 +5,6 @@ import org.cqframework.cql.elm.serializing.ElmLibraryReaderProvider

class ElmLibraryReaderProvider : ElmLibraryReaderProvider {
override fun create(contentType: String): ElmLibraryReader {
var contentType: String? = contentType
if (contentType == null) {
contentType = "application/elm+json"
}
return when (contentType) {
"application/elm+xml" -> ElmXmlLibraryReader()
"application/elm+json" -> ElmJsonLibraryReader()
Original file line number Diff line number Diff line change
@@ -5,10 +5,6 @@ import org.cqframework.cql.elm.serializing.ElmLibraryWriterProvider

class ElmLibraryWriterProvider : ElmLibraryWriterProvider {
override fun create(contentType: String): ElmLibraryWriter {
var contentType: String? = contentType
if (contentType == null) {
contentType = "application/elm+json"
}
return when (contentType) {
"application/elm+xml" -> ElmXmlLibraryWriter()
"application/elm+json" -> ElmJsonLibraryWriter()
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ import nl.adaptivity.xmlutil.XMLConstants
import nl.adaptivity.xmlutil.serialization.DefaultXmlSerializationPolicy
import nl.adaptivity.xmlutil.serialization.XML
import nl.adaptivity.xmlutil.serialization.structure.SafeParentInfo
import org.hl7.elm_modelinfo.r1.serializing.BigDecimalXmlSerializer
import org.cqframework.cql.elm.serializing.BigDecimalXmlSerializer

val builder =
DefaultXmlSerializationPolicy.Builder().apply {
@@ -49,7 +49,7 @@ val mixedContentSerializersModule = SerializersModule {
}
}

val xml =
internal val xml =
XML(
serializersModuleOf(BigDecimalXmlSerializer) +
mixedContentSerializersModule +
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
@file:Suppress("detekt:all")

package org.cqframework.cql.elm.serializing.xmlutil

import kotlinx.io.Source
import kotlinx.io.readString
import org.cqframework.cql.elm.serializing.ElmLibraryReader
import org.hl7.elm.r1.Library

class ElmXmlLibraryReader : ElmLibraryReader {
override fun read(string: String): Library {
return xml.decodeFromString(Library.serializer(), string)
}
override fun read(source: Source): Library {
return read(source.readString())
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package org.cqframework.cql.elm.serializing.xmlutil

import java.io.Writer
import kotlinx.io.Sink
import kotlinx.io.writeString
import org.cqframework.cql.elm.serializing.ElmLibraryWriter
import org.hl7.elm.r1.Library

class ElmXmlLibraryWriter : ElmLibraryWriter {
override fun write(library: Library, writer: Writer) {
writer.write(writeAsString(library))
override fun write(library: Library, sink: Sink) {
sink.writeString(writeAsString(library))
}

override fun writeAsString(library: Library): String {

return xml.encodeToString(Library.serializer(), library)
}
}
Original file line number Diff line number Diff line change
@@ -2,17 +2,15 @@

import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import org.hl7.elm.r1.Library;
import org.junit.jupiter.api.Test;

class ElmJsonLibraryReaderTest {

@Test
void read() throws IOException {
void read() {
var reader = new ElmJsonLibraryReader();
Library library = reader.read(new ByteArrayInputStream("{\"library\" : { \"type\" : \"Library\"}}".getBytes()));
Library library = reader.read("{\"library\" : { \"type\" : \"Library\"}}");
assertNotNull(library);
}
}
Original file line number Diff line number Diff line change
@@ -2,18 +2,16 @@

import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import org.hl7.elm.r1.Library;
import org.junit.jupiter.api.Test;

class ElmXmlLibraryReaderTest {

@Test
void read() throws IOException {
void read() {
var reader = new ElmXmlLibraryReader();
Library library =
reader.read(new ByteArrayInputStream("<library xmlns=\"urn:hl7-org:elm:r1\"></library>".getBytes()));
reader.read("<library xmlns=\"urn:hl7-org:elm:r1\"></library>");
assertNotNull(library);
}
}
Original file line number Diff line number Diff line change
@@ -3,8 +3,6 @@
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

@@ -32,9 +30,7 @@ void roundTrip(String cqlFile) throws IOException {
assertEquals(0, translator.getErrors().size());

var xml = translator.toXml();
var library = reader.read(new StringReader(xml));
var stringWriter = new StringWriter();
writer.write(library, stringWriter);
assertEquals(xml, stringWriter.toString());
var library = reader.read(xml);
assertEquals(xml, writer.writeAsString(library));
}
}
Loading
Loading