From c0bbfacaebf8670d2de42c6fa8429756cfef9b93 Mon Sep 17 00:00:00 2001 From: Rohit Kandimalla Date: Tue, 31 Oct 2023 11:19:19 -0400 Subject: [PATCH 1/3] MAT-6307 pulled new liquid templates from latest release v0.3.0 --- src/main/resources/templates/Library.liquid | 128 ++- src/main/resources/templates/Measure.liquid | 931 ++++++++++++-------- 2 files changed, 665 insertions(+), 394 deletions(-) diff --git a/src/main/resources/templates/Library.liquid b/src/main/resources/templates/Library.liquid index 0b34a7d9..ba3c123e 100644 --- a/src/main/resources/templates/Library.liquid +++ b/src/main/resources/templates/Library.liquid @@ -1,70 +1,89 @@
- {% if Library.id.exists() %} + + {% if Library.title.exists() %} - - + + {% endif %} - {% if Library.url.exists() %} + + + {% if Library.id.exists() %} - - + + {% endif %} + + {% if Library.version.exists() %} {% endif %} + + {% if Library.url.exists() %} + + + + + {% endif %} + {% for identifier in Library.identifier %} - + {% endfor %} + {% if Library.name.exists() %} {% endif %} - {% if Library.title.exists() %} - - - - - {% endif %} + {% if Library.subtitle.exists() %} - + {% endif %} + {% if Library.status.exists() %} {% endif %} - {% if Library.experimental.exists() %} + + {% if Library.experimental.exists() and Library.experimental.value = 'true' %} {% endif %} + {% if Library.type.exists() %} @@ -83,17 +102,18 @@ {% endif %} {% if coding.display.exists() %}

- display: {{coding.display.escape('html')}} + display: {{coding.display}}

{% endif %} {% endfor %} {% endif %} - {% if Library.type.coding.exists().not and Library.type.text.exists() %} + {% if Library.type.coding.exists().not() and Library.type.text.exists() %} {{Library.type.text}} {% endif %} {% endif %} + {% if Library.subject.exists() %} @@ -113,12 +133,12 @@ {% endif %} {% if coding.display.exists() %}

- display: {{coding.display.escape('html')}} + display: {{coding.display}}

{% endif %} {% endfor %} {% endif %} - {% if Library.subject.coding.exists().not and Library.subject.text.exists() %} + {% if Library.subject.coding.exists().not() and Library.subject.text.exists() %} {{Library.subject.text}} {% endif %} @@ -137,106 +157,133 @@ {% endif %} {% if Library.subject.display.exists() %}

- code: {{Library.subject.display.escape('html')}} + code: {{Library.subject.display}}

{% endif %} {% endif %} {% endif %} + {% if Library.date.exists() %} {% endif %} + {% if Library.publisher.exists() %} - + {% endif %} + {% if Library.description.exists() %} - + {% endif %} + {% if Library.extension.where(url = 'http://hl7.org/fhir/uv/cpg/StructureDefinition/cpg-knowledgeCapability').exists() %} {% endif %} + {% if Library.extension.where(url = 'http://hl7.org/fhir/uv/cpg/StructureDefinition/cpg-knowledgeRepresentationLevel').exists() %} {% endif %} + {% if Library.useContext.exists() %} {% endif %} + {% if Library.jurisdiction.exists() %} {% endif %} + + {% if Library.topic.exists() %} + + + + + {% endif %} + {% if Library.purpose.exists() %} - + {% endif %} + {% if Library.usage.exists() %} - + {% endif %} + {% if Library.copyright.exists() %} - + {% endif %} + {% if Library.approvalDate.exists() %} {% endif %} + {% if Library.lastReviewDate.exists() %} {% endif %} + {% if Library.effectivePeriod.exists() %} {% endif %} + {% if Library.relatedArtifact.exists() %} @@ -245,7 +292,7 @@

Documentation

{% endif %} @@ -300,6 +347,7 @@ {% endif %} + {% if Library.parameter.exists() %} @@ -313,6 +361,7 @@ {% endif %} + {% if Library.dataRequirement.exists() %} @@ -356,7 +405,7 @@ {% endif %} {% if coding.display.exists() %}

- display: {{coding.display.escape('html')}} + display: {{coding.display}}

{% endif %} {% endfor %} @@ -368,13 +417,14 @@ {% endif %} + {% for c in Library.content %} {% if c.contentType = 'text/cql' %} diff --git a/src/main/resources/templates/Measure.liquid b/src/main/resources/templates/Measure.liquid index f3c4dd40..bbc121ed 100644 --- a/src/main/resources/templates/Measure.liquid +++ b/src/main/resources/templates/Measure.liquid @@ -6,6 +6,14 @@ {% endif %} + + {% if Measure.subtitle.exists() %} + + + + + {% endif %} + {% if Measure.id.exists() %} @@ -116,6 +124,20 @@ {% endif %} + {% if Measure.author.exists() %} + + + + + {% endif %} + + {% if Measure.endorser.exists() %} + + + + + {% endif %} + {% if Measure.description.exists() %} @@ -123,6 +145,79 @@ {% endif %} + {% if Measure.extension.where(url = 'http://hl7.org/fhir/uv/cpg/StructureDefinition/cpg-knowledgeCapability').exists() %} + + + + + {% endif %} + + {% if Measure.extension.where(url = 'http://hl7.org/fhir/uv/cpg/StructureDefinition/cpg-knowledgeRepresentationLevel').exists() %} + + + + + {% endif %} + + {% if Measure.useContext.exists() %} + + + + + {% endif %} + + {% if Measure.jurisdiction.exists() %} + + + + + {% endif %} + + {% if Measure.topic.exists() %} + + + + + {% endif %} + + {% if Measure.purpose.exists() %} + + + + + {% endif %} + + {% if Measure.copyright.exists() %} + + + + + {% endif %} + + {% if Measure.disclaimer.exists() %} + + + + + {% endif %} + {% if Measure.subject.exists() %} @@ -135,7 +230,7 @@

{% endfor %} {% endif %} - {% if Measure.subject.coding.exists().not and Measure.subject.text.exists() %} + {% if Measure.subject.coding.exists().not() and Measure.subject.text.exists() %} {{Measure.subject.text}} {% endif %} @@ -162,17 +257,12 @@ {% endif %} - {% if Measure.copyright.exists() %} + {% if Measure.extension.where(url = 'http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-populationBasis').exists() %} - - - - {% endif %} - - {% if Measure.disclaimer.exists() %} - - - + + {% endif %} @@ -187,13 +277,33 @@

{% endfor %} {% endif %} - {% if Measure.scoring.coding.exists().not and Measure.scoring.text.exists() %} + {% if Measure.scoring.coding.exists().not() and Measure.scoring.text.exists() %} {{Measure.scoring.text}} {% endif %} {% endif %} + {% if Measure.extension.where(url = 'http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-scoringUnit').exists() %} + + + + + {% endif %} + {% if Measure.type.exists() %} @@ -205,17 +315,24 @@

{% endfor %} {% endif %} - {% if Measure.type.coding.exists().not and Measure.type.text.exists() %} + {% if Measure.type.coding.exists().not() and Measure.type.text.exists() %} {{Measure.type.text}} {% endif %} {% endif %} + {% if Measure.riskAdjustment.exists() %} + + + + + {% endif %} + {% if Measure.supplementalData.usage.coding.where(code = 'risk-adjustment-factor').exists() %} {% for supplementalData in Measure.supplementalData.where(usage.coding.where(code = 'risk-adjustment-factor').exists()) %} - + + + + + {% endif %} + + {% if Measure.rationale.exists() %} + + + + + {% endif %} + + {% if Measure.clinicalRecommendationStatement.exists() %} + + + + + {% endif %} + {% if Measure.improvementNotation.exists() %} @@ -248,7 +386,7 @@

{% endfor %} {% endif %} - {% if Measure.improvementNotation.coding.exists().not and Measure.improvementNotation.text.exists() %} + {% if Measure.improvementNotation.coding.exists().not() and Measure.improvementNotation.text.exists() %} {{Measure.improvementNotation.text}} {% endif %} @@ -262,13 +400,6 @@ {% endif %} - {% if Measure.subtitle.exists() %} - - - - - {% endif %} - {% if Measure.group.exists() %} {% if Measure.group[0].population.description.exists() %} @@ -291,6 +422,19 @@ {% endif %} {% endfor %} + {% if group.stratifier.exists() %} + Stratifier Criteria: + {% for stratifier in group.stratifier %} + + + {% if stratifier.description.exists() %} + + {% else %} + + {% endif %} + + {% endfor %} + {% endif %}
Id: {{Library.id}}Title: {{Library.title}}
Url: {{Library.url}}Id: {{Library.id}}
Version: {{Library.version}}
Url: {{Library.url}}
Identifier: + + {% if identifier.type.coding.exists() %} + {% if identifier.type.coding.display.exists() %} + {{identifier.type.coding.display}}{% if identifier.assigner.display.exists() %} ({{identifier.assigner.display}}){% endif %} Identifier: + {% else %} + {{identifier.type.coding.code}}{% if identifier.assigner.display.exists() %} ({{identifier.assigner.display}}){% endif %} identifier: + {% endif %} + {% else %} + {{identifier.use}} + {% endif %} + + - {% if identifier.type.exists() %} -

- type: {{identifier.type.value}} -

- {% endif %} {% if identifier.value.exists() %}

- value: {{identifier.value}} + {{identifier.value}}

{% endif %}
Name: {{Library.name}}
Title: {{Library.title.escape('html')}}
Subtitle: {{Library.subtitle.escape('html')}}{{Library.subtitle}}
Status: {{Library.status.value}}
Experimental: {{Library.experimental.value}}
Type:
Subject:
Date: {{Library.date}}
Publisher: {{Library.publisher.escape('html')}}{{Library.publisher}}
Description: {{Library.description.escape('html')}}{{Library.description}}
Knowledge Capability: - {% for extension in Library.extension.where(url = 'http://hl7.org/fhir/uv/cpg/StructureDefinition/cpg-knowledgeCapability') %}{{extension.value}} {% endfor %} + {% for extension in Library.extension.where(url = 'http://hl7.org/fhir/uv/cpg/StructureDefinition/cpg-knowledgeCapability') %} + {{extension.value}} + {% endfor %}
Knowledge Representation Level: - {% for extension in Library.extension.where(url = 'http://hl7.org/fhir/uv/cpg/StructureDefinition/cpg-knowledgeRepresentationLevel') %}{{extension.value}}{% endfor %} + {% for extension in Library.extension.where(url = 'http://hl7.org/fhir/uv/cpg/StructureDefinition/cpg-knowledgeRepresentationLevel') %} + {{extension.value}} + {% endfor %}
Use Context: - + + + + {% for useContext in Library.useContext %} - - + {% endfor %}
codevaluedisplay
codevalue
{{useContext.code.code}}{{useContext.value.coding.first().code}}{{useContext.value.coding.first().display.escape('html')}}{{useContext.value.text}}
Jurisdiction: {{Library.jurisdiction.first().coding.first().code}}
Topic: {{Library.topic.first().coding.first().code}}
Purpose: {{Library.purpose.escape('html')}}{{Library.purpose}}
Usage: {{Library.usage.escape('html')}}{{Library.usage}}
Copyright: {{Library.copyright.escape('html')}}{{Library.copyright}}
Approval Date: {{Library.approvalDate}}
Last Review Date: {{Library.lastReviewDate}}
Effective Period: {{Library.effectivePeriod.start}}..{{Library.effectivePeriod.end}}
Related Artifacts:
Parameters:
Data Requirements:
- +
Content: {{c.contentType}}
{{c.data.decode('base64').escape('html')}}
{{c.data.decode('base64')}}
{{Measure.title}}
Subtitle: {{Measure.subtitle}}
Id:
Author: {{Measure.author}}
Endorser: {{Measure.endorser}}
Description:
Knowledge Capability: + {% for extension in Measure.extension.where(url = 'http://hl7.org/fhir/uv/cpg/StructureDefinition/cpg-knowledgeCapability') %}{{extension.value}} {% endfor %} +
Knowledge Representation Level: + {% for extension in Measure.extension.where(url = 'http://hl7.org/fhir/uv/cpg/StructureDefinition/cpg-knowledgeRepresentationLevel') %}{{extension.value}}{% endfor %} +
Use Context: + + + + + + {% for useContext in Measure.useContext %} + + + + + {% endfor %} +
codevalue
{{useContext.code.code}}{{useContext.value.text}}
+
Jurisdiction: {{Measure.jurisdiction.first().coding.first().code}}
Topic: {{Measure.topic.first().coding.first().code}}
Purpose: {{Measure.purpose}}
Copyright: {{Measure.copyright}}
Disclaimer: {{Measure.disclaimer}}
Subject:
Copyright: {{Measure.copyright}}
Disclaimer: {{Measure.disclaimer}}Basis: + {{Measure.extension.where(url = 'http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-populationBasis').first().value}} +
Scoring unit: + {% for scoringUnit in Measure.extension.where(url = 'http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-scoringUnit') %} + {% if scoringUnit.coding.exists() %} + {% for coding in scoringUnit.coding %} +

+ {{iif(coding.display.exists(), coding.display, coding.code)}} {{iif(coding.system != 'http://unitsofmeasure.org', '(' + coding.system + ')', '')}} +

+ {% endfor %} + {% endif %} + {% if scoringUnit.coding.exists().not() and scoringUnit.text.exists() %} + {{scoringUnit.text}} + {% endif %} + {% endfor %} +
Type:
Risk Adjustment: {{Measure.riskAdjustment}}
Risk Adjustment Factor: Risk Adjustment Factor:

{% if supplementalData.code.exists() %} @@ -237,6 +354,27 @@ {% endfor %} {% endif %} + {% if Measure.rateAggregation.exists() %} +

Rate Aggregation: {{Measure.rateAggregation}}
Rationale: {{Measure.rationale}}
Clinical recommendation statement: {{Measure.clinicalRecommendationStatement}}
Improvement Notation:
Subtitle: {{Measure.subtitle}}
{{stratifier.code.coding[0].display}}:{{stratifier.description}}None
{% endfor %} @@ -366,7 +510,7 @@ {% endif %} {% if Measure.relatedArtifact.where(type = 'depends-on').exists() and - Measure.extension.where(url = 'http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-effectiveDataRequirements').exists().not %} + Measure.extension.where(url = 'http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-effectiveDataRequirements').exists().not() %}

Dependencies

\ No newline at end of file From 87efd5647af2d31dff74492f47bd9277ff15915c Mon Sep 17 00:00:00 2001 From: Rohit Kandimalla Date: Tue, 31 Oct 2023 15:33:51 -0400 Subject: [PATCH 2/3] Cleaning up code --- .../cms/madie/madiefhirservice/services/ExportService.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/gov/cms/madie/madiefhirservice/services/ExportService.java b/src/main/java/gov/cms/madie/madiefhirservice/services/ExportService.java index 47397c9f..79922e42 100644 --- a/src/main/java/gov/cms/madie/madiefhirservice/services/ExportService.java +++ b/src/main/java/gov/cms/madie/madiefhirservice/services/ExportService.java @@ -1,6 +1,5 @@ package gov.cms.madie.madiefhirservice.services; -import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; import java.security.Principal; @@ -44,7 +43,6 @@ public byte[] createExport(Measure madieMeasure, Principal principal, String acc throw new InternalServerException( "Unexpected error while generating exports for measureID: " + madieMeasure.getId()); } - byte[] result = utility.getZipBundle(bundle, exportFileName); - return result; + return utility.getZipBundle(bundle, exportFileName); } } From ad229b5a35c07c8afb8345a2f097ee297965dd0f Mon Sep 17 00:00:00 2001 From: Rohit Kandimalla Date: Wed, 1 Nov 2023 15:03:44 -0400 Subject: [PATCH 3/3] MAT-6307 escaping html chars from library resource during HR generation --- .../services/HumanReadableService.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/main/java/gov/cms/madie/madiefhirservice/services/HumanReadableService.java b/src/main/java/gov/cms/madie/madiefhirservice/services/HumanReadableService.java index 6416a0b6..cb39e93f 100644 --- a/src/main/java/gov/cms/madie/madiefhirservice/services/HumanReadableService.java +++ b/src/main/java/gov/cms/madie/madiefhirservice/services/HumanReadableService.java @@ -3,6 +3,7 @@ import static org.springframework.web.util.HtmlUtils.htmlEscape; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -270,6 +271,8 @@ public String generateLibraryHumanReadable(Library library) { var versionConvertor_40_50 = new VersionConvertor_40_50(new BaseAdvisor_40_50()); org.hl7.fhir.r5.model.Library r5Library = (org.hl7.fhir.r5.model.Library) versionConvertor_40_50.convertResource(library); + // escape html + escapeLibrary(r5Library); String template = getData("/templates/Library.liquid"); try { LiquidEngine.LiquidDocument doc = liquidEngine.parse(template, "libray-hr"); @@ -281,6 +284,40 @@ public String generateLibraryHumanReadable(Library library) { } } + private void escapeLibrary(org.hl7.fhir.r5.model.Library r5Library) { + r5Library.setTitle(escapeStr(r5Library.getTitle())); + r5Library.setSubtitle(escapeStr(r5Library.getSubtitle())); + r5Library.setPublisher(escapeStr(r5Library.getPublisher())); + r5Library.setDescription(escapeStr(r5Library.getDescription())); + r5Library.setPurpose(escapeStr(r5Library.getPurpose())); + r5Library.setUsage(escapeStr(r5Library.getUsage())); + r5Library.setCopyright(escapeStr(r5Library.getCopyright())); + + r5Library + .getRelatedArtifact() + .forEach( + relatedArtifact -> relatedArtifact.setDisplay(escapeStr(relatedArtifact.getDisplay()))); + r5Library + .getDataRequirement() + .forEach( + dataRequirement -> + dataRequirement + .getCodeFilter() + .forEach( + cf -> + cf.getCode() + .forEach( + coding -> coding.setDisplay(escapeStr(coding.getDisplay()))))); + + r5Library.setContent( + r5Library.getContent().stream() + .filter(content -> content.getContentType().equalsIgnoreCase("text/cql")) + .map( + content -> + content.setData(escapeStr(Arrays.toString(content.getData())).getBytes())) + .collect(Collectors.toList())); + } + private Extension createEffectiveDataRequirementExtension() { var extension = new Extension(); extension.setUrl(CqfMeasures.EFFECTIVE_DATA_REQUIREMENT_URL);