Skip to content

Commit

Permalink
Merge branch 'master' into master-release
Browse files Browse the repository at this point in the history
  • Loading branch information
ndegwamartin committed Sep 18, 2023
2 parents edb2842 + 8c1c9e7 commit 6a1ccc3
Show file tree
Hide file tree
Showing 43 changed files with 2,369 additions and 1,726 deletions.
2 changes: 1 addition & 1 deletion buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ repositories {
}

dependencies {
implementation("com.diffplug.spotless:spotless-plugin-gradle:6.6.0")
implementation("com.diffplug.spotless:spotless-plugin-gradle:6.21.0")

implementation("com.android.tools.build:gradle:8.1.1")

Expand Down
17 changes: 3 additions & 14 deletions buildSrc/src/main/kotlin/SpotlessConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.configure

fun Project.configureSpotless() {
val ktlintVersion = "0.41.0"
val ktlintVersion = "0.50.0"
val ktlintOptions = mapOf("indent_size" to "2", "continuation_indent_size" to "2")
apply(plugin = Plugins.BuildPlugins.spotless)
configure<com.diffplug.gradle.spotless.SpotlessExtension> {
Expand All @@ -32,10 +32,10 @@ fun Project.configureSpotless() {
ktfmt().googleStyle()
licenseHeaderFile(
"${project.rootProject.projectDir}/license-header.txt",
"package|import|class|object|sealed|open|interface|abstract "
"package|import|class|object|sealed|open|interface|abstract ",
// It is necessary to tell spotless the top level of a file in order to apply config to it
// See: https://github.com/diffplug/spotless/issues/135
)
)
toggleOffOn()
}
kotlinGradle {
Expand All @@ -49,16 +49,5 @@ fun Project.configureSpotless() {
prettier(mapOf("prettier" to "2.0.5", "@prettier/plugin-xml" to "0.13.0"))
.config(mapOf("parser" to "xml", "tabWidth" to 4))
}
// Creates one off SpotlessApply task for generated files
com.diffplug.gradle.spotless.KotlinExtension(this).apply {
target("**/*_Generated.kt")
ktlint(ktlintVersion).userData(ktlintOptions)
ktfmt().googleStyle()
licenseHeaderFile(
"${project.rootProject.projectDir}/license-header.txt",
"package|import|class|object|sealed|open|interface|abstract "
)
createIndependentApplyTask("spotlessGenerated")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import org.hl7.fhir.r4.model.ValueSet
* @param questionnaireResponse the [QuestionnaireResponse] related to the [Questionnaire]
* @param xFhirQueryResolver the [XFhirQueryResolver] to resolve resources based on the X-FHIR-Query
* @param externalValueSetResolver the [ExternalAnswerValueSetResolver] to resolve value sets
* externally/outside of the [Questionnaire]
* externally/outside of the [Questionnaire]
* @param questionnaireItemParentMap the [Map] of items parent
* @param questionnaireLaunchContextMap the [Map] of launchContext names to their resource values
*/
Expand All @@ -68,7 +68,7 @@ internal class EnabledAnswerOptionsEvaluator(
questionnaire,
questionnaireResponse,
questionnaireItemParentMap,
questionnaireLaunchContextMap
questionnaireLaunchContextMap,
)

private val answerValueSetMap =
Expand All @@ -94,13 +94,19 @@ internal class EnabledAnswerOptionsEvaluator(
questionnaireResponseItem: QuestionnaireResponseItemComponent,
): Pair<
List<Questionnaire.QuestionnaireItemAnswerOptionComponent>,
List<QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent>
List<QuestionnaireResponse.QuestionnaireResponseItemAnswerComponent>,
> {
val resolvedAnswerOptions =
answerOptions(
questionnaireItem,
questionnaireResponseItem,
questionnaireResponse,
questionnaireItemParentMap,
)

val resolvedAnswerOptions = answerOptions(questionnaireItem)

if (questionnaireItem.answerOptionsToggleExpressions.isEmpty())
if (questionnaireItem.answerOptionsToggleExpressions.isEmpty()) {
return Pair(resolvedAnswerOptions, emptyList())
}

val enabledQuestionnaireAnswerOptions =
evaluateAnswerOptionsToggleExpressions(
Expand All @@ -121,29 +127,37 @@ internal class EnabledAnswerOptionsEvaluator(
/**
* In a `choice` or `open-choice` type question, the answer options are defined in one of the
* three elements in the questionnaire:
*
* - `Questionnaire.item.answerOption`: a list of permitted answers to the question
* - `Questionnaire.item.answerValueSet`: a reference to a value set containing a list of
* permitted answers to the question
* permitted answers to the question
* - `Extension answer-expression`: an expression based extension which defines the x-fhir-query
* or fhirpath to evaluate permitted answer options
* or fhirpath to evaluate permitted answer options
*
* Returns the answer options defined in one of the sources above. If the answer options are
* defined in `Questionnaire.item.answerValueSet`, the answer value set will be expanded.
*/
private suspend fun answerOptions(
questionnaireItem: QuestionnaireItemComponent,
questionnaireResponseItem: QuestionnaireResponseItemComponent,
questionnaireResponse: QuestionnaireResponse,
questionnaireItemParentMap: Map<QuestionnaireItemComponent, QuestionnaireItemComponent>,
): List<Questionnaire.QuestionnaireItemAnswerOptionComponent> =
when {
questionnaireItem.answerOption.isNotEmpty() -> questionnaireItem.answerOption
!questionnaireItem.answerValueSet.isNullOrEmpty() ->
resolveAnswerValueSet(questionnaireItem.answerValueSet)
questionnaireItem.answerExpression != null -> resolveAnswerExpression(questionnaireItem)
questionnaireItem.answerExpression != null ->
resolveAnswerExpression(
questionnaireItem,
questionnaireResponseItem,
questionnaireResponse,
questionnaireItemParentMap,
)
else -> emptyList()
}

private suspend fun resolveAnswerValueSet(
uri: String
uri: String,
): List<Questionnaire.QuestionnaireItemAnswerOptionComponent> {
// If cache hit, return it
if (answerValueSetMap.contains(uri)) {
Expand All @@ -164,7 +178,7 @@ internal class EnabledAnswerOptionsEvaluator(
.filterNot { it.abstract || it.inactive }
.map { component ->
Questionnaire.QuestionnaireItemAnswerOptionComponent(
Coding(component.system, component.code, component.display)
Coding(component.system, component.code, component.display),
)
}
}
Expand All @@ -185,6 +199,9 @@ internal class EnabledAnswerOptionsEvaluator(
// https://build.fhir.org/ig/HL7/sdc/expressions.html#x-fhir-query-enhancements
private suspend fun resolveAnswerExpression(
item: QuestionnaireItemComponent,
responseItem: QuestionnaireResponseItemComponent,
questionnaireResponse: QuestionnaireResponse,
questionnaireItemParentMap: Map<QuestionnaireItemComponent, QuestionnaireItemComponent>,
): List<Questionnaire.QuestionnaireItemAnswerOptionComponent> {
// Check cache first for database queries
val answerExpression = item.answerExpression ?: return emptyList()
Expand All @@ -208,16 +225,16 @@ internal class EnabledAnswerOptionsEvaluator(
options
}
?: error(
"XFhirQueryResolver cannot be null. Please provide the XFhirQueryResolver via DataCaptureConfig."
"XFhirQueryResolver cannot be null. Please provide the XFhirQueryResolver via DataCaptureConfig.",
)
}
answerExpression.isFhirPath -> {
val data = fhirPathEngine.evaluate(questionnaireResponse, answerExpression.expression)
val data = expressionEvaluator.evaluateExpression(item, responseItem, answerExpression)
item.extractAnswerOptions(data)
}
else ->
throw UnsupportedOperationException(
"${answerExpression.language} not supported for answer-expression yet"
"${answerExpression.language} not supported for answer-expression yet",
)
}
}
Expand All @@ -232,18 +249,19 @@ internal class EnabledAnswerOptionsEvaluator(
.map {
val (expression, toggleOptions) = it
val evaluationResult =
if (expression.isFhirPath)
if (expression.isFhirPath) {
fhirPathEngine.convertToBoolean(
expressionEvaluator.evaluateExpression(
item,
questionnaireResponseItem,
expression,
)
),
)
else
} else {
throw UnsupportedOperationException(
"${expression.language} not supported yet for answer-options-toggle-expression"
"${expression.language} not supported yet for answer-options-toggle-expression",
)
}
evaluationResult to toggleOptions
}
.partition { it.first }
Expand Down
Loading

0 comments on commit 6a1ccc3

Please sign in to comment.