use of org.hl7.fhir.validation.instance.utils.NodeStack in project org.hl7.fhir.core by hapifhir.
the class MeasureValidator method validateMeasureReportGroupPopulations.
private void validateMeasureReportGroupPopulations(ValidatorHostContext hostContext, MeasureContext m, MeasureGroupComponent mg, List<ValidationMessage> errors, Element mrg, NodeStack stack, boolean inProgress) {
// there must be a population for each population defined in the measure, and no 4others.
List<MeasureGroupPopulationComponent> pops = new ArrayList<MeasureGroupPopulationComponent>();
List<Element> plist = mrg.getChildrenByName("population");
int i = 0;
for (Element mrgp : plist) {
NodeStack ns = stack.push(mrgp, i, mrgp.getProperty().getDefinition(), mrgp.getProperty().getDefinition());
CodeableConcept cc = ObjectConverter.readAsCodeableConcept(mrgp.getNamedChild("code"));
if (rule(errors, IssueType.BUSINESSRULE, mrgp.line(), mrgp.col(), ns.getLiteralPath(), cc != null, I18nConstants.MEASURE_MR_GRP_POP_NO_CODE)) {
MeasureGroupPopulationComponent mgp = getGroupPopForCode(cc, mg);
if (rule(errors, IssueType.BUSINESSRULE, mrg.line(), mrg.col(), ns.getLiteralPath(), mgp != null, I18nConstants.MEASURE_MR_GRP_POP_UNK_CODE)) {
if (rule(errors, IssueType.BUSINESSRULE, mrg.line(), mrg.col(), ns.getLiteralPath(), !pops.contains(mgp), I18nConstants.MEASURE_MR_GRP_POP_DUPL_CODE)) {
pops.add(mgp);
validateMeasureReportGroupPopulation(hostContext, m, mgp, errors, mrgp, ns, inProgress);
}
}
}
i++;
}
for (MeasureGroupPopulationComponent mgp : mg.getPopulation()) {
if (!pops.contains(mgp) && !mgp.getCode().hasCoding("http://terminology.hl7.org/CodeSystem/measure-population", "measure-observation")) {
rule(errors, IssueType.BUSINESSRULE, mrg.line(), mrg.col(), stack.getLiteralPath(), pops.contains(mg), I18nConstants.MEASURE_MR_GRP_MISSING_BY_CODE, DataRenderer.display(context, mgp.getCode()));
}
}
}
use of org.hl7.fhir.validation.instance.utils.NodeStack in project org.hl7.fhir.core by hapifhir.
the class MeasureValidator method validateMeasureReportGroupStratifiers.
private void validateMeasureReportGroupStratifiers(ValidatorHostContext hostContext, MeasureContext m, MeasureGroupComponent mg, List<ValidationMessage> errors, Element mrg, NodeStack stack, boolean inProgress) {
// there must be a population for each population defined in the measure, and no 4others.
List<MeasureGroupStratifierComponent> strats = new ArrayList<>();
List<Element> slist = mrg.getChildrenByName("stratifier");
int i = 0;
for (Element mrgs : slist) {
NodeStack ns = stack.push(mrgs, i, mrgs.getProperty().getDefinition(), mrgs.getProperty().getDefinition());
CodeableConcept cc = ObjectConverter.readAsCodeableConcept(mrgs.getNamedChild("code"));
if (rule(errors, IssueType.BUSINESSRULE, mrgs.line(), mrgs.col(), ns.getLiteralPath(), cc != null, I18nConstants.MEASURE_MR_GRP_POP_NO_CODE)) {
MeasureGroupStratifierComponent mgs = getGroupStratifierForCode(cc, mg);
if (rule(errors, IssueType.BUSINESSRULE, mrg.line(), mrg.col(), ns.getLiteralPath(), mgs != null, I18nConstants.MEASURE_MR_GRP_POP_UNK_CODE)) {
if (rule(errors, IssueType.BUSINESSRULE, mrg.line(), mrg.col(), ns.getLiteralPath(), !strats.contains(mgs), I18nConstants.MEASURE_MR_GRP_POP_DUPL_CODE)) {
strats.add(mgs);
validateMeasureReportGroupStratifier(hostContext, m, mgs, errors, mrgs, ns, inProgress);
}
}
}
i++;
}
for (MeasureGroupStratifierComponent mgs : mg.getStratifier()) {
if (!strats.contains(mgs)) {
rule(errors, IssueType.BUSINESSRULE, mrg.line(), mrg.col(), stack.getLiteralPath(), strats.contains(mg), I18nConstants.MEASURE_MR_GRP_MISSING_BY_CODE, DataRenderer.display(context, mgs.getCode()));
}
}
}
use of org.hl7.fhir.validation.instance.utils.NodeStack in project org.hl7.fhir.core by hapifhir.
the class MeasureValidator method validateScore.
private void validateScore(ValidatorHostContext hostContext, MeasureContext m, List<ValidationMessage> errors, Element mrg, NodeStack stack, boolean inProgress) {
Element ms = mrg.getNamedChild("measureScore");
// first, we check MeasureReport.type
if ("data-collection".equals(m.reportType())) {
banned(errors, stack, ms, I18nConstants.MEASURE_MR_SCORE_PROHIBITED_RT);
} else if ("cohort".equals(m.scoring())) {
// cohort - there is no measure score
banned(errors, stack, ms, I18nConstants.MEASURE_MR_SCORE_PROHIBITED_MS);
} else if (Utilities.existsInList(m.scoring(), "proportion", "ratio", "continuous-variable")) {
if (rule(errors, IssueType.REQUIRED, mrg.line(), mrg.col(), stack.getLiteralPath(), ms != null, I18nConstants.MEASURE_MR_SCORE_REQUIRED, m.scoring())) {
NodeStack ns = stack.push(ms, -1, ms.getProperty().getDefinition(), ms.getProperty().getDefinition());
Element v = ms.getNamedChild("value");
// TODO: this is a DEQM special and should be handled differently
if (v == null) {
if (ms.hasExtension("http://hl7.org/fhir/us/davinci-deqm/StructureDefinition/extension-alternateScoreType")) {
v = ms.getExtension("http://hl7.org/fhir/us/davinci-deqm/StructureDefinition/extension-alternateScoreType").getNamedChild("value");
}
}
if ("proportion".equals(m.scoring())) {
// proportion - score is a unitless number from 0 ... 1
banned(errors, ns, ms, "unit", I18nConstants.MEASURE_MR_SCORE_UNIT_PROHIBITED, "proportion");
banned(errors, ns, ms, "system", I18nConstants.MEASURE_MR_SCORE_UNIT_PROHIBITED, "proportion");
banned(errors, ns, ms, "code", I18nConstants.MEASURE_MR_SCORE_UNIT_PROHIBITED, "proportion");
if (rule(errors, IssueType.REQUIRED, ms.line(), ms.col(), ns.getLiteralPath(), v != null, I18nConstants.MEASURE_MR_SCORE_VALUE_REQUIRED, "proportion")) {
try {
BigDecimal dec = new BigDecimal(v.primitiveValue());
NodeStack nsv = ns.push(v, -1, v.getProperty().getDefinition(), v.getProperty().getDefinition());
rule(errors, IssueType.REQUIRED, v.line(), v.col(), nsv.getLiteralPath(), dec.compareTo(new BigDecimal(0)) >= 0 && dec.compareTo(new BigDecimal(1)) <= 0, I18nConstants.MEASURE_MR_SCORE_VALUE_INVALID_01);
} catch (Exception e) {
// nothing - will have caused an error elsewhere
}
}
} else if ("ratio".equals(m.scoring())) {
// ratio - score is a number with no value constraints, and maybe with a unit (perhaps constrained by extension)
if (rule(errors, IssueType.REQUIRED, ms.line(), ms.col(), ns.getLiteralPath(), v != null, I18nConstants.MEASURE_MR_SCORE_VALUE_REQUIRED, "ratio")) {
Element unit = ms.getNamedChild("code");
Coding c = m.measure().hasExtension("http://hl7.org/fhir/StructureDefinition/questionnaire-unit") ? (Coding) m.measure().getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/questionnaire-unit").getValue() : null;
if (unit != null) {
if (c != null) {
NodeStack nsc = ns.push(unit, -1, unit.getProperty().getDefinition(), unit.getProperty().getDefinition());
rule(errors, IssueType.CODEINVALID, unit.line(), unit.col(), nsc.getLiteralPath(), c.getCode().equals(unit.primitiveValue()), I18nConstants.MEASURE_MR_SCORE_FIXED, c.getCode());
Element system = ms.getNamedChild("system");
if (system == null) {
NodeStack nss = system == null ? ns : ns.push(system, -1, system.getProperty().getDefinition(), system.getProperty().getDefinition());
rule(errors, IssueType.CODEINVALID, system.line(), system.col(), nss.getLiteralPath(), c.getSystem().equals(system.primitiveValue()), I18nConstants.MEASURE_MR_SCORE_FIXED, c.getSystem());
} else {
rule(errors, IssueType.CODEINVALID, ms.line(), ms.col(), ns.getLiteralPath(), c.getSystem().equals(system.primitiveValue()), I18nConstants.MEASURE_MR_SCORE_FIXED, c.getSystem());
}
}
} else if (c != null) {
rule(errors, IssueType.NOTFOUND, ms.line(), ms.col(), ns.getLiteralPath(), false, I18nConstants.MEASURE_MR_SCORE_FIXED, DataRenderer.display(context, c));
} else {
warning(errors, IssueType.NOTFOUND, ms.line(), ms.col(), ns.getLiteralPath(), false, I18nConstants.MEASURE_MR_SCORE_UNIT_REQUIRED, "ratio");
}
}
} else if ("continuous-variable".equals(m.scoring())) {
// continuous-variable - score is a quantity with a unit per the extension
if (rule(errors, IssueType.REQUIRED, ms.line(), ms.col(), ns.getLiteralPath(), v != null, I18nConstants.MEASURE_MR_SCORE_VALUE_REQUIRED, "continuous-variable")) {
Element unit = ms.getNamedChild("code");
Coding c = m.measure().hasExtension("http://hl7.org/fhir/StructureDefinition/questionnaire-unit") ? (Coding) m.measure().getExtensionByUrl("http://hl7.org/fhir/StructureDefinition/questionnaire-unit").getValue() : null;
if (unit != null) {
if (c != null) {
NodeStack nsc = ns.push(unit, -1, unit.getProperty().getDefinition(), unit.getProperty().getDefinition());
rule(errors, IssueType.CODEINVALID, unit.line(), unit.col(), nsc.getLiteralPath(), c.getCode().equals(unit.primitiveValue()), I18nConstants.MEASURE_MR_SCORE_FIXED, c.getCode());
Element system = ms.getNamedChild("system");
if (system == null) {
NodeStack nss = system == null ? ns : ns.push(system, -1, system.getProperty().getDefinition(), system.getProperty().getDefinition());
rule(errors, IssueType.CODEINVALID, system.line(), system.col(), nss.getLiteralPath(), c.getSystem().equals(system.primitiveValue()), I18nConstants.MEASURE_MR_SCORE_FIXED, c.getSystem());
} else {
rule(errors, IssueType.CODEINVALID, ms.line(), ms.col(), ns.getLiteralPath(), c.getSystem().equals(system.primitiveValue()), I18nConstants.MEASURE_MR_SCORE_FIXED, c.getSystem());
}
}
} else if (c != null) {
rule(errors, IssueType.NOTFOUND, ms.line(), ms.col(), ns.getLiteralPath(), false, I18nConstants.MEASURE_MR_SCORE_FIXED, DataRenderer.display(context, c));
}
}
}
}
// else do nothing - there's a hint elsewhere
}
}
use of org.hl7.fhir.validation.instance.utils.NodeStack in project org.hl7.fhir.core by hapifhir.
the class SearchParameterValidator method validateSearchParameter.
public void validateSearchParameter(List<ValidationMessage> errors, Element cs, NodeStack stack) {
String url = cs.getNamedChildValue("url");
String master = cs.getNamedChildValue("derivedFrom");
if (!Utilities.noString(master)) {
SearchParameter sp = context.fetchResource(SearchParameter.class, master);
if (warning(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), sp != null, I18nConstants.SEARCHPARAMETER_NOTFOUND, master)) {
// base must be in the master list of base
List<Element> bl = cs.getChildren("base");
for (Element b : bl) {
rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), sp.hasBase(b.primitiveValue()) || sp.hasBase("Resource"), I18nConstants.SEARCHPARAMETER_BASE_WRONG, master, b.primitiveValue());
}
rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), !cs.hasChild("type") || sp.getType().toCode().equals(cs.getNamedChildValue("type")), I18nConstants.SEARCHPARAMETER_TYPE_WRONG, master, sp.getType().toCode(), cs.getNamedChildValue("type"));
if (sp.hasExpression() && cs.hasChild("expression") && !sp.getExpression().equals(cs.getNamedChildValue("expression"))) {
List<String> bases = new ArrayList<>();
for (Element b : cs.getChildren("base")) {
bases.add(b.primitiveValue());
}
String expThis = canonicalise(cs.getNamedChildValue("expression"), bases);
String expOther = canonicalise(sp.getExpression(), bases);
warning(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), expThis.equals(expOther), I18nConstants.SEARCHPARAMETER_EXP_WRONG, master, sp.getExpression(), cs.getNamedChildValue("expression"));
}
// todo: check compositions
}
}
}
use of org.hl7.fhir.validation.instance.utils.NodeStack in project org.hl7.fhir.core by hapifhir.
the class ValueSetValidator method prepareValidateValueSetIncludeConcept.
private VSCodingValidationRequest prepareValidateValueSetIncludeConcept(List<ValidationMessage> errors, Element concept, NodeStack stack, String system, String version) {
String code = concept.getChildValue("code");
Coding c = new Coding(system, code, null);
if (version != null) {
c.setVersion(version);
}
return new VSCodingValidationRequest(stack, c);
}
Aggregations