Skip to content

Commit

Permalink
Convert the model module to Kotlin (#1465)
Browse files Browse the repository at this point in the history
* ChoiceType

* ClassTypeElement

* InstantiationContext

* TupleType, TupleTypeelement, SearchType, Relationship

* NamespaceInfo

* ModelContext

* ModelIdentifier

* ModelInfoProvider, NamespaceAware, ModelInfoReader, ModelInfoReaderFactory, ModelInfoReaderProvider

* small clean up

* NamespaceManager, SystemModelInfoProvider

* clean up

* NamedType, InvalidRedeclarationException

* Break out DataType interface

* DataType

* BaseDataType

* Little bit of cleanup for choice types

* Fixing Locale for string format

* ClassType

* ProfileType

* ListType

* IntervalType

* TypeParameter

* TupleType, ClassType

* Bug fixes for classes and tuples

* GenericClassSignatureParser

* More cleanup of GenericClassSignatureParser

* Remove unused assertion
  • Loading branch information
JPercival authored Dec 11, 2024
1 parent d2b4196 commit 31160ea
Show file tree
Hide file tree
Showing 93 changed files with 2,084 additions and 3,176 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl

plugins {
kotlin("multiplatform")
id("com.diffplug.spotless")
Expand Down Expand Up @@ -65,6 +67,7 @@ kotlin {

// Add Kotlin/WASM compilation target.
// The output is in the JS packages directory.
@OptIn(ExperimentalWasmDsl::class)
wasmJs {
browser { }
binaries.executable()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,8 @@ public ModelInfo load(ModelIdentifier modelIdentifier) {
// VersionedIdentifier.version: Version of the model
for (NpmPackage p : packages) {
try {
var identifier = new ModelIdentifier()
.withId(modelIdentifier.getId())
.withVersion(modelIdentifier.getVersion())
.withSystem(modelIdentifier.getSystem());
var identifier = new ModelIdentifier(
modelIdentifier.getId(), modelIdentifier.getSystem(), modelIdentifier.getVersion());

if (identifier.getSystem() == null) {
identifier.setSystem(p.canonical());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.cqframework.fhir.npm;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

Expand Down Expand Up @@ -117,13 +118,11 @@ void modelInfoProviderLocal() {
.parseResource(NpmPackageManagerTests.class.getResourceAsStream("testig.xml"));
ImplementationGuide ig = (ImplementationGuide) convertor.convertResource(igResource);
NpmPackageManager pm = new NpmPackageManager(ig);
assertTrue(pm.getNpmList().size() >= 1);
assertFalse(pm.getNpmList().isEmpty());

LibraryLoader reader = new LibraryLoader("5.0");
NpmModelInfoProvider mp = new NpmModelInfoProvider(pm.getNpmList(), reader, this);
ModelInfo mi = mp.load(new ModelIdentifier()
.withSystem("http://hl7.org/fhir/us/qicore")
.withId("QICore"));
ModelInfo mi = mp.load(new ModelIdentifier("QICore", "http://hl7.org/fhir/us/qicore", null));
assertNotNull(mi);
assertEquals("QICore", mi.getName());
}
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,7 @@ class CqlCompiler(
if (offendingSymbol is CommonToken) {
builder.recordParsingException(
CqlSyntaxException(
@Suppress("ImplicitDefaultLocale")
String.format("Syntax error at %s", offendingSymbol.text),
String.format(Locale.US, "Syntax error at %s", offendingSymbol.text),
trackback,
e
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package org.cqframework.cql.cql2elm

import com.fasterxml.jackson.databind.ObjectMapper
import java.io.*
import java.util.*

object CqlTranslatorOptionsMapper {
private val om: ObjectMapper = ObjectMapper()
Expand All @@ -15,8 +16,10 @@ object CqlTranslatorOptionsMapper {
fr = FileReader(fileName)
return fromReader(fr)
} catch (@Suppress("SwallowedException") e: IOException) {
@Suppress("TooGenericExceptionThrown", "ImplicitDefaultLocale")
throw RuntimeException(String.format("Errors occurred reading options: %s", e.message))
@Suppress("TooGenericExceptionThrown")
throw RuntimeException(
String.format(Locale.US, "Errors occurred reading options: %s", e.message)
)
}
}

Expand All @@ -25,8 +28,10 @@ object CqlTranslatorOptionsMapper {
try {
return om.readValue(reader, CqlTranslatorOptions::class.java)
} catch (@Suppress("SwallowedException") e: IOException) {
@Suppress("TooGenericExceptionThrown", "ImplicitDefaultLocale")
throw RuntimeException(String.format("Errors occurred reading options: %s", e.message))
@Suppress("TooGenericExceptionThrown")
throw RuntimeException(
String.format(Locale.US, "Errors occurred reading options: %s", e.message)
)
}
}

Expand All @@ -37,8 +42,10 @@ object CqlTranslatorOptionsMapper {
fw = FileWriter(fileName)
toWriter(fw, options)
} catch (@Suppress("SwallowedException") e: IOException) {
@Suppress("TooGenericExceptionThrown", "ImplicitDefaultLocale")
throw RuntimeException(String.format("Errors occurred writing options: %s", e.message))
@Suppress("TooGenericExceptionThrown")
throw RuntimeException(
String.format(Locale.US, "Errors occurred writing options: %s", e.message)
)
}
}

Expand All @@ -48,8 +55,10 @@ object CqlTranslatorOptionsMapper {
try {
om.writeValue(writer, options)
} catch (@Suppress("SwallowedException") e: IOException) {
@Suppress("TooGenericExceptionThrown", "ImplicitDefaultLocale")
throw RuntimeException(String.format("Errors occurred writing options: %s", e.message))
@Suppress("TooGenericExceptionThrown")
throw RuntimeException(
String.format(Locale.US, "Errors occurred writing options: %s", e.message)
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package org.cqframework.cql.cql2elm

import java.util.*
import org.hl7.cql.model.DataType

object DataTypes {
@JvmStatic
fun verifyType(actualType: DataType?, expectedType: DataType?) {
require(subTypeOf(actualType, expectedType)) {
// ERROR:
@Suppress("ImplicitDefaultLocale")
String.format(
Locale.US,
"Expected an expression of type '%s', but found an expression of type '%s'.",
if (expectedType != null) expectedType.toLabel() else "<unknown>",
if (actualType != null) actualType.toLabel() else "<unknown>"
Expand All @@ -25,8 +26,8 @@ object DataTypes {
compatibleWith(sourceType, targetType)
) {
// ERROR:
@Suppress("ImplicitDefaultLocale")
String.format(
Locale.US,
"Expression of type '%s' cannot be cast as a value of type '%s'.",
if (sourceType != null) sourceType.toLabel() else "<unknown>",
if (targetType != null) targetType.toLabel() else "<unknown>"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package org.cqframework.cql.cql2elm

import java.io.InputStream
import java.nio.file.Path
import java.util.*
import kotlin.collections.ArrayList
import org.hl7.cql.model.NamespaceAware
import org.hl7.cql.model.NamespaceManager
import org.hl7.elm.r1.VersionedIdentifier
Expand All @@ -15,30 +17,27 @@ internal class DefaultLibrarySourceLoader : LibrarySourceLoader, NamespaceAware,
private val providers: MutableList<LibrarySourceProvider> = ArrayList()
var initialized: Boolean = false

override fun registerProvider(provider: LibrarySourceProvider?) {
require(provider != null) { "provider is null." }
if (provider is NamespaceAware) {
(provider as NamespaceAware).setNamespaceManager(namespaceManager)
override fun registerProvider(provider: LibrarySourceProvider) {
if (namespaceManager != null && provider is NamespaceAware) {
provider.setNamespaceManager(namespaceManager!!)
}
if (provider is PathAware) {
(provider as PathAware).setPath(path)
if (path != null && provider is PathAware) {
provider.setPath(path!!)
}
providers.add(provider)
}

private var path: Path? = null

override fun setPath(path: Path?) {
if (path == null || !path.toFile().isDirectory) {
throw IllegalArgumentException(
@Suppress("ImplicitDefaultLocale")
String.format("path '%s' is not a valid directory", path)
)
override fun setPath(path: Path) {
require(path.toFile().isDirectory) {
String.format(Locale.US, "path '%s' is not a valid directory", path)
}

this.path = path
for (provider: LibrarySourceProvider? in getProviders()) {
for (provider in getProviders()) {
if (provider is PathAware) {
(provider as PathAware).setPath(path)
provider.setPath(path)
}
}
}
Expand All @@ -60,16 +59,14 @@ internal class DefaultLibrarySourceLoader : LibrarySourceLoader, NamespaceAware,
return providers
}

override fun getLibrarySource(libraryIdentifier: VersionedIdentifier?): InputStream {
require(libraryIdentifier != null) { "libraryIdentifier is null." }
require(!libraryIdentifier.id.isNullOrEmpty()) { "libraryIdentifier Id is null." }
override fun getLibrarySource(libraryIdentifier: VersionedIdentifier): InputStream {
var source: InputStream? = null
for (provider: LibrarySourceProvider in getProviders()) {
val localSource: InputStream? = provider.getLibrarySource(libraryIdentifier)
if (localSource != null) {
require(source == null) {
@Suppress("ImplicitDefaultLocale")
String.format(
Locale.US,
"Multiple sources found for library %s, version %s.",
libraryIdentifier.id,
libraryIdentifier.version
Expand All @@ -80,8 +77,8 @@ internal class DefaultLibrarySourceLoader : LibrarySourceLoader, NamespaceAware,
}
if (source == null) {
throw IllegalArgumentException(
@Suppress("ImplicitDefaultLocale")
String.format(
Locale.US,
"Could not load source for library %s, version %s.",
libraryIdentifier.id,
libraryIdentifier.version
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package org.cqframework.cql.cql2elm

import java.io.*
import java.nio.file.Path
import java.util.*
import org.cqframework.cql.cql2elm.model.Version
import org.hl7.elm.r1.VersionedIdentifier

Expand All @@ -13,19 +14,16 @@ import org.hl7.elm.r1.VersionedIdentifier
// form
// <major>[.<minor>[.<patch>]]
// Usage outside these boundaries will result in errors or incorrect behavior.
@Suppress("ImplicitDefaultLocale")
class DefaultLibrarySourceProvider(path: Path?) : LibrarySourceProvider, PathAware {
class DefaultLibrarySourceProvider(path: Path) : LibrarySourceProvider, PathAware {
private var path: Path? = null

init {
setPath(path)
this.setPath(path)
}

override fun setPath(path: Path?) {
if (path == null || !path.toFile().isDirectory) {
throw IllegalArgumentException(
String.format("path '%s' is not a valid directory", path)
)
override fun setPath(path: Path) {
require(path.toFile().isDirectory) {
String.format(Locale.US, "path '%s' is not a valid directory", path)
}
this.path = path
}
Expand All @@ -38,6 +36,7 @@ class DefaultLibrarySourceProvider(path: Path?) : LibrarySourceProvider, PathAwa
val libraryPath: Path =
currentPath.resolve(
String.format(
Locale.US,
"%s%s.cql",
libraryName,
if (libraryIdentifier.version != null) ("-" + libraryIdentifier.version)
Expand Down Expand Up @@ -107,7 +106,11 @@ class DefaultLibrarySourceProvider(path: Path?) : LibrarySourceProvider, PathAwa
}
} catch (e: FileNotFoundException) {
throw IllegalArgumentException(
String.format("Could not load source for library %s.", libraryIdentifier.id),
String.format(
Locale.US,
"Could not load source for library %s.",
libraryIdentifier.id
),
e
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,18 @@ import org.hl7.elm_modelinfo.r1.serializing.ModelInfoReaderFactory
// form
// <major>[.<minor>[.<patch>]]
// Usage outside these boundaries will result in errors or incorrect behavior.
@Suppress("ImplicitDefaultLocale")
class DefaultModelInfoProvider : ModelInfoProvider, PathAware {
constructor()

constructor(path: Path?) {
setPath(path)
constructor(path: Path) {
this.setPath(path)
}

private var path: Path? = null

override fun setPath(path: Path?) {
require(!(path == null || !path.toFile().isDirectory)) {
String.format("path '%s' is not a valid directory", path)
override fun setPath(path: Path) {
require(path.toFile().isDirectory) {
String.format(Locale.US, "path '%s' is not a valid directory", path)
}
this.path = path
}
Expand All @@ -50,6 +49,7 @@ class DefaultModelInfoProvider : ModelInfoProvider, PathAware {
val modelPath =
currentPath.resolve(
String.format(
Locale.US,
"%s-modelinfo%s.xml",
modelName.lowercase(Locale.getDefault()),
if (modelVersion != null) "-$modelVersion" else ""
Expand Down Expand Up @@ -111,10 +111,11 @@ class DefaultModelInfoProvider : ModelInfoProvider, PathAware {
}
try {
val inputStream: InputStream = FileInputStream(modelFile)
return ModelInfoReaderFactory.getReader("application/xml").read(inputStream)
return ModelInfoReaderFactory.getReader("application/xml")?.read(inputStream)
} catch (e: IOException) {
throw IllegalArgumentException(
String.format(
Locale.US,
"Could not load definition for model info %s.",
modelIdentifier.id
),
Expand Down
Loading

0 comments on commit 31160ea

Please sign in to comment.