Gg 202210 shareables (#936)
* Don't validate contained resources against Shareable* Profiles, + validate ShareableMeasure * release notes * fix compile problem Co-authored-by: Grahame Grieve <grahameg@gmail.ccom>
This commit is contained in:
parent
eabf51938b
commit
d71a5833c1
|
@ -1,6 +1,7 @@
|
||||||
## Validator Changes
|
## Validator Changes
|
||||||
|
|
||||||
* Warning in Validator CLI when character encoding is not UTF-8
|
* Warning in Validator CLI when character encoding is not UTF-8
|
||||||
|
* Don't validate contained resources against Shareable* profiles, and also check ShareableMeasure
|
||||||
|
|
||||||
## Other code changes
|
## Other code changes
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.hl7.fhir.convertors.misc;
|
package org.hl7.fhir.convertors.misc;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -28,10 +29,10 @@ public class VSACImporter extends OIDBasedValueSetImporter {
|
||||||
|
|
||||||
public static void main(String[] args) throws FHIRException, IOException, ParseException, URISyntaxException {
|
public static void main(String[] args) throws FHIRException, IOException, ParseException, URISyntaxException {
|
||||||
VSACImporter self = new VSACImporter();
|
VSACImporter self = new VSACImporter();
|
||||||
self.process(args[0], args[1], args[2]);
|
self.process(args[0], args[1], args[2], "true".equals(args[3]));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void process(String source, String dest, String apiKey) throws FHIRException, IOException, URISyntaxException {
|
private void process(String source, String dest, String apiKey, boolean onlyNew) throws FHIRException, IOException, URISyntaxException {
|
||||||
CSVReader csv = new CSVReader(new FileInputStream(source));
|
CSVReader csv = new CSVReader(new FileInputStream(source));
|
||||||
csv.readHeaders();
|
csv.readHeaders();
|
||||||
Map<String, String> errs = new HashMap<>();
|
Map<String, String> errs = new HashMap<>();
|
||||||
|
@ -39,23 +40,25 @@ public class VSACImporter extends OIDBasedValueSetImporter {
|
||||||
FHIRToolingClient fhirToolingClient = new FHIRToolingClient("https://cts.nlm.nih.gov/fhir", "fhir/vsac");
|
FHIRToolingClient fhirToolingClient = new FHIRToolingClient("https://cts.nlm.nih.gov/fhir", "fhir/vsac");
|
||||||
fhirToolingClient.setUsername("apikey");
|
fhirToolingClient.setUsername("apikey");
|
||||||
fhirToolingClient.setPassword(apiKey);
|
fhirToolingClient.setPassword(apiKey);
|
||||||
fhirToolingClient.setTimeout(30000);
|
fhirToolingClient.setTimeout(120000);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
while (csv.line()) {
|
while (csv.line()) {
|
||||||
String oid = csv.cell("OID");
|
String oid = csv.cell("OID");
|
||||||
try {
|
try {
|
||||||
ValueSet vs = fhirToolingClient.read(ValueSet.class, oid);
|
if (!onlyNew || !(new File(Utilities.path(dest, "ValueSet-" + oid + ".json")).exists())) {
|
||||||
try {
|
ValueSet vs = fhirToolingClient.read(ValueSet.class, oid);
|
||||||
ValueSet vse = fhirToolingClient.expandValueset(vs.getUrl(), null);
|
try {
|
||||||
vs.setExpansion(vse.getExpansion());
|
ValueSet vse = fhirToolingClient.expandValueset(vs.getUrl(), null);
|
||||||
j++;
|
vs.setExpansion(vse.getExpansion());
|
||||||
} catch (Exception e) {
|
j++;
|
||||||
errs.put(oid, "Expansion: " +e.getMessage());
|
} catch (Exception e) {
|
||||||
System.out.println(e.getMessage());
|
errs.put(oid, "Expansion: " +e.getMessage());
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
new JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path(dest, "ValueSet-" + oid + ".json")), vs);
|
||||||
}
|
}
|
||||||
new JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path(dest, "ValueSet-" + oid + ".json")), vs);
|
|
||||||
i++;
|
i++;
|
||||||
if (i % 100 == 0) {
|
if (i % 100 == 0) {
|
||||||
System.out.println(":"+i+" ("+j+")");
|
System.out.println(":"+i+" ("+j+")");
|
||||||
|
|
|
@ -635,6 +635,10 @@ public class I18nConstants {
|
||||||
public static final String CODESYSTEM_SHAREABLE_MISSING_HL7 = "CODESYSTEM_SHAREABLE_MISSING_HL7";
|
public static final String CODESYSTEM_SHAREABLE_MISSING_HL7 = "CODESYSTEM_SHAREABLE_MISSING_HL7";
|
||||||
public static final String CODESYSTEM_SHAREABLE_EXTRA_MISSING_HL7 = "CODESYSTEM_SHAREABLE_EXTRA_MISSING_HL7";
|
public static final String CODESYSTEM_SHAREABLE_EXTRA_MISSING_HL7 = "CODESYSTEM_SHAREABLE_EXTRA_MISSING_HL7";
|
||||||
public static final String CODESYSTEM_SHAREABLE_EXTRA_MISSING = "CODESYSTEM_SHAREABLE_EXTRA_MISSING";
|
public static final String CODESYSTEM_SHAREABLE_EXTRA_MISSING = "CODESYSTEM_SHAREABLE_EXTRA_MISSING";
|
||||||
|
public static final String MEASURE_SHAREABLE_MISSING = "MEASURE_SHAREABLE_MISSING";
|
||||||
|
public static final String MEASURE_SHAREABLE_MISSING_HL7 = "MEASURE_SHAREABLE_MISSING_HL7";
|
||||||
|
public static final String MEASURE_SHAREABLE_EXTRA_MISSING_HL7 = "MEASURE_SHAREABLE_EXTRA_MISSING_HL7";
|
||||||
|
public static final String MEASURE_SHAREABLE_EXTRA_MISSING = "MEASURE_SHAREABLE_EXTRA_MISSING";
|
||||||
public static final String VALUESET_UNC_SYSTEM_WARNING = "VALUESET_UNC_SYSTEM_WARNING";
|
public static final String VALUESET_UNC_SYSTEM_WARNING = "VALUESET_UNC_SYSTEM_WARNING";
|
||||||
public static final String VALUESET_UNC_SYSTEM_WARNING_VER = "VALUESET_UNC_SYSTEM_WARNING_VER";
|
public static final String VALUESET_UNC_SYSTEM_WARNING_VER = "VALUESET_UNC_SYSTEM_WARNING_VER";
|
||||||
public static final String VALUESET_IMPORT_UNION_INTERSECTION = "VALUESET_IMPORT_UNION_INTERSECTION";
|
public static final String VALUESET_IMPORT_UNION_INTERSECTION = "VALUESET_IMPORT_UNION_INTERSECTION";
|
||||||
|
|
|
@ -726,7 +726,11 @@ VALUESET_SHAREABLE_MISSING = The ShareableValueSet profile says that the {0} ele
|
||||||
VALUESET_SHAREABLE_EXTRA_MISSING = The ShareableValueSet profile recommends that the {0} element is populated, but it is not present. Published value sets SHOULD conform to the ShareableValueSet profile
|
VALUESET_SHAREABLE_EXTRA_MISSING = The ShareableValueSet profile recommends that the {0} element is populated, but it is not present. Published value sets SHOULD conform to the ShareableValueSet profile
|
||||||
VALUESET_SHAREABLE_MISSING_HL7 = The ShareableValueSet profile says that the {0} element is mandatory, but it is not found. HL7 Published value sets SHALL conform to the ShareableValueSet profile
|
VALUESET_SHAREABLE_MISSING_HL7 = The ShareableValueSet profile says that the {0} element is mandatory, but it is not found. HL7 Published value sets SHALL conform to the ShareableValueSet profile
|
||||||
VALUESET_SHAREABLE_EXTRA_MISSING_HL7 = The ShareableValueSet profile recommends that the {0} element is populated, but it is not found. HL7 Published value sets SHALL conform to the ShareableValueSet profile
|
VALUESET_SHAREABLE_EXTRA_MISSING_HL7 = The ShareableValueSet profile recommends that the {0} element is populated, but it is not found. HL7 Published value sets SHALL conform to the ShareableValueSet profile
|
||||||
CODESYSTEM_SHAREABLE_MISSING = The ShareableCodeSystem profile says that the {0} element is mandatory, but it is not present. Published value sets SHOULD conform to the ShareableCodeSystem profile
|
CODESYSTEM_SHAREABLE_MISSING = The ShareableCodeSystem profile says that the {0} element is mandatory, but it is not present. Published code systems SHOULD conform to the ShareableCodeSystem profile
|
||||||
CODESYSTEM_SHAREABLE_EXTRA_MISSING = The ShareableCodeSystem profile recommends that the {0} element is populated, but it is not present. Published value sets SHOULD conform to the ShareableCodeSystem profile
|
CODESYSTEM_SHAREABLE_EXTRA_MISSING = The ShareableCodeSystem profile recommends that the {0} element is populated, but it is not present. Published code systems SHOULD conform to the ShareableCodeSystem profile
|
||||||
CODESYSTEM_SHAREABLE_MISSING_HL7 = The ShareableCodeSystem profile says that the {0} element is mandatory, but it is not found. HL7 Published value sets SHALL conform to the ShareableCodeSystem profile
|
CODESYSTEM_SHAREABLE_MISSING_HL7 = The ShareableCodeSystem profile says that the {0} element is mandatory, but it is not found. HL7 Published code systems SHALL conform to the ShareableCodeSystem profile
|
||||||
CODESYSTEM_SHAREABLE_EXTRA_MISSING_HL7 = The ShareableCodeSystem profile recommends that the {0} element is populated, but it is not found. HL7 Published value sets SHALL conform to the ShareableCodeSystem profile
|
CODESYSTEM_SHAREABLE_EXTRA_MISSING_HL7 = The ShareableCodeSystem profile recommends that the {0} element is populated, but it is not found. HL7 Published code systems SHALL conform to the ShareableCodeSystem profile
|
||||||
|
MEASURE_SHAREABLE_MISSING = The ShareableMeasure profile says that the {0} element is mandatory, but it is not present. Published measures SHOULD conform to the ShareableMeasure profile
|
||||||
|
MEASURE_SHAREABLE_EXTRA_MISSING = The ShareableMeasure profile recommends that the {0} element is populated, but it is not present. Published measures SHOULD conform to the ShareableMeasure profile
|
||||||
|
MEASURE_SHAREABLE_MISSING_HL7 = The ShareableMeasure profile says that the {0} element is mandatory, but it is not found. HL7 Published measures SHALL conform to the ShareableMeasure profile
|
||||||
|
MEASURE_SHAREABLE_EXTRA_MISSING_HL7 = The ShareableMeasure profile recommends that the {0} element is populated, but it is not found. HL7 Published measures SHALL conform to the ShareableMeasure profile
|
||||||
|
|
|
@ -4638,9 +4638,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
} else if (element.getType().equals("QuestionnaireResponse")) {
|
} else if (element.getType().equals("QuestionnaireResponse")) {
|
||||||
new QuestionnaireValidator(context, myEnableWhenEvaluator, fpe, timeTracker, questionnaireMode, xverManager, jurisdiction).validateQuestionannaireResponse(hostContext, errors, element, stack);
|
new QuestionnaireValidator(context, myEnableWhenEvaluator, fpe, timeTracker, questionnaireMode, xverManager, jurisdiction).validateQuestionannaireResponse(hostContext, errors, element, stack);
|
||||||
} else if (element.getType().equals("Measure")) {
|
} else if (element.getType().equals("Measure")) {
|
||||||
new MeasureValidator(context, timeTracker, xverManager, jurisdiction).validateMeasure(hostContext, errors, element, stack);
|
new MeasureValidator(context, timeTracker, xverManager, jurisdiction, this).validateMeasure(hostContext, errors, element, stack);
|
||||||
} else if (element.getType().equals("MeasureReport")) {
|
} else if (element.getType().equals("MeasureReport")) {
|
||||||
new MeasureValidator(context, timeTracker, xverManager, jurisdiction).validateMeasureReport(hostContext, errors, element, stack);
|
new MeasureValidator(context, timeTracker, xverManager, jurisdiction, this).validateMeasureReport(hostContext, errors, element, stack);
|
||||||
} else if (element.getType().equals("CapabilityStatement")) {
|
} else if (element.getType().equals("CapabilityStatement")) {
|
||||||
validateCapabilityStatement(errors, element, stack);
|
validateCapabilityStatement(errors, element, stack);
|
||||||
} else if (element.getType().equals("CodeSystem")) {
|
} else if (element.getType().equals("CodeSystem")) {
|
||||||
|
|
|
@ -84,7 +84,9 @@ public class CodeSystemValidator extends BaseValidator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkShareableCodeSystem(errors, cs, stack);
|
if (!stack.isContained()) {
|
||||||
|
checkShareableCodeSystem(errors, cs, stack);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,17 +37,20 @@ import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
|
||||||
import org.hl7.fhir.utilities.xml.XMLUtil;
|
import org.hl7.fhir.utilities.xml.XMLUtil;
|
||||||
import org.hl7.fhir.validation.BaseValidator;
|
import org.hl7.fhir.validation.BaseValidator;
|
||||||
import org.hl7.fhir.validation.TimeTracker;
|
import org.hl7.fhir.validation.TimeTracker;
|
||||||
|
import org.hl7.fhir.validation.instance.InstanceValidator;
|
||||||
import org.hl7.fhir.validation.instance.utils.NodeStack;
|
import org.hl7.fhir.validation.instance.utils.NodeStack;
|
||||||
import org.hl7.fhir.validation.instance.utils.ValidatorHostContext;
|
import org.hl7.fhir.validation.instance.utils.ValidatorHostContext;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
|
|
||||||
public class MeasureValidator extends BaseValidator {
|
public class MeasureValidator extends BaseValidator {
|
||||||
|
|
||||||
public MeasureValidator(IWorkerContext context, TimeTracker timeTracker, XVerExtensionManager xverManager, Coding jurisdiction) {
|
private InstanceValidator parent;
|
||||||
|
public MeasureValidator(IWorkerContext context, TimeTracker timeTracker, XVerExtensionManager xverManager, Coding jurisdiction, InstanceValidator parent) {
|
||||||
super(context, xverManager);
|
super(context, xverManager);
|
||||||
source = Source.InstanceValidator;
|
source = Source.InstanceValidator;
|
||||||
this.timeTracker = timeTracker;
|
this.timeTracker = timeTracker;
|
||||||
this.jurisdiction = jurisdiction;
|
this.jurisdiction = jurisdiction;
|
||||||
|
this.parent = parent;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,8 +108,41 @@ public class MeasureValidator extends BaseValidator {
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!stack.isContained()) {
|
||||||
|
checkShareableMeasure(errors, element, stack);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void checkShareableMeasure(List<ValidationMessage> errors, Element cs, NodeStack stack) {
|
||||||
|
if (parent.isForPublication()) {
|
||||||
|
if (isHL7(cs)) {
|
||||||
|
rule(errors, IssueType.REQUIRED, cs.line(), cs.col(), stack.getLiteralPath(), cs.hasChild("url"), I18nConstants.MEASURE_SHAREABLE_MISSING_HL7, "url");
|
||||||
|
rule(errors, IssueType.REQUIRED, cs.line(), cs.col(), stack.getLiteralPath(), cs.hasChild("version"), I18nConstants.MEASURE_SHAREABLE_MISSING_HL7, "version");
|
||||||
|
rule(errors, IssueType.REQUIRED, cs.line(), cs.col(), stack.getLiteralPath(), cs.hasChild("title"), I18nConstants.MEASURE_SHAREABLE_MISSING_HL7, "title");
|
||||||
|
warning(errors, IssueType.REQUIRED, cs.line(), cs.col(), stack.getLiteralPath(), cs.hasChild("name"), I18nConstants.MEASURE_SHAREABLE_EXTRA_MISSING_HL7, "name");
|
||||||
|
rule(errors, IssueType.REQUIRED, cs.line(), cs.col(), stack.getLiteralPath(), cs.hasChild("status"), I18nConstants.MEASURE_SHAREABLE_MISSING_HL7, "status");
|
||||||
|
rule(errors, IssueType.REQUIRED, cs.line(), cs.col(), stack.getLiteralPath(), cs.hasChild("experimental"), I18nConstants.MEASURE_SHAREABLE_MISSING_HL7, "experimental");
|
||||||
|
rule(errors, IssueType.REQUIRED, cs.line(), cs.col(), stack.getLiteralPath(), cs.hasChild("description"), I18nConstants.MEASURE_SHAREABLE_MISSING_HL7, "description");
|
||||||
|
rule(errors, IssueType.REQUIRED, cs.line(), cs.col(), stack.getLiteralPath(), cs.hasChild("content"), I18nConstants.MEASURE_SHAREABLE_MISSING_HL7, "content");
|
||||||
|
if (!"supplement".equals(cs.getChildValue("content"))) {
|
||||||
|
rule(errors, IssueType.REQUIRED, cs.line(), cs.col(), stack.getLiteralPath(), cs.hasChild("caseSensitive"), I18nConstants.MEASURE_SHAREABLE_MISSING_HL7, "caseSensitive");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
warning(errors, IssueType.REQUIRED, cs.line(), cs.col(), stack.getLiteralPath(), cs.hasChild("url"), I18nConstants.MEASURE_SHAREABLE_MISSING, "url");
|
||||||
|
warning(errors, IssueType.REQUIRED, cs.line(), cs.col(), stack.getLiteralPath(), cs.hasChild("version"), I18nConstants.MEASURE_SHAREABLE_MISSING, "version");
|
||||||
|
warning(errors, IssueType.REQUIRED, cs.line(), cs.col(), stack.getLiteralPath(), cs.hasChild("title"), I18nConstants.MEASURE_SHAREABLE_MISSING, "title");
|
||||||
|
warning(errors, IssueType.REQUIRED, cs.line(), cs.col(), stack.getLiteralPath(), cs.hasChild("name"), I18nConstants.MEASURE_SHAREABLE_EXTRA_MISSING, "name");
|
||||||
|
warning(errors, IssueType.REQUIRED, cs.line(), cs.col(), stack.getLiteralPath(), cs.hasChild("status"), I18nConstants.MEASURE_SHAREABLE_MISSING, "status");
|
||||||
|
warning(errors, IssueType.REQUIRED, cs.line(), cs.col(), stack.getLiteralPath(), cs.hasChild("experimental"), I18nConstants.MEASURE_SHAREABLE_MISSING, "experimental");
|
||||||
|
warning(errors, IssueType.REQUIRED, cs.line(), cs.col(), stack.getLiteralPath(), cs.hasChild("description"), I18nConstants.MEASURE_SHAREABLE_MISSING, "description");
|
||||||
|
warning(errors, IssueType.REQUIRED, cs.line(), cs.col(), stack.getLiteralPath(), cs.hasChild("content"), I18nConstants.MEASURE_SHAREABLE_MISSING, "content");
|
||||||
|
if (!"supplement".equals(cs.getChildValue("content"))) {
|
||||||
|
warning(errors, IssueType.REQUIRED, cs.line(), cs.col(), stack.getLiteralPath(), cs.hasChild("caseSensitive"), I18nConstants.MEASURE_SHAREABLE_MISSING, "caseSensitive");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
private void validateMeasureCriteria(ValidatorHostContext hostContext, List<ValidationMessage> errors, MeasureContext mctxt, Element crit, NodeStack nsc) {
|
private void validateMeasureCriteria(ValidatorHostContext hostContext, List<ValidationMessage> errors, MeasureContext mctxt, Element crit, NodeStack nsc) {
|
||||||
String mimeType = crit.getChildValue("language");
|
String mimeType = crit.getChildValue("language");
|
||||||
if (!Utilities.noString(mimeType)) { // that would be an error elsewhere
|
if (!Utilities.noString(mimeType)) { // that would be an error elsewhere
|
||||||
|
|
|
@ -115,8 +115,9 @@ public class StructureDefinitionValidator extends BaseValidator {
|
||||||
for (Element snapshot : snapshots) {
|
for (Element snapshot : snapshots) {
|
||||||
validateElementList(errors, snapshot, stack.push(snapshot, -1, null, null), true, true, sd);
|
validateElementList(errors, snapshot, stack.push(snapshot, -1, null, null), true, true, sd);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateElementList(List<ValidationMessage> errors, Element elementList, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd) {
|
private void validateElementList(List<ValidationMessage> errors, Element elementList, NodeStack stack, boolean snapshot, boolean hasSnapshot, StructureDefinition sd) {
|
||||||
List<Element> elements = elementList.getChildrenByName("element");
|
List<Element> elements = elementList.getChildrenByName("element");
|
||||||
int cc = 0;
|
int cc = 0;
|
||||||
|
|
|
@ -61,7 +61,9 @@ public class ValueSetValidator extends BaseValidator {
|
||||||
cc++;
|
cc++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkShareableValueSet(errors, vs, stack);
|
if (!stack.isContained()) {
|
||||||
|
checkShareableValueSet(errors, vs, stack);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkShareableValueSet(List<ValidationMessage> errors, Element vs, NodeStack stack) {
|
private void checkShareableValueSet(List<ValidationMessage> errors, Element vs, NodeStack stack) {
|
||||||
|
|
Loading…
Reference in New Issue