Search in sources :

Example 66 with NodeStack

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()));
        }
    }
}
Also used : Element(org.hl7.fhir.r5.elementmodel.Element) ArrayList(java.util.ArrayList) NodeStack(org.hl7.fhir.validation.instance.utils.NodeStack) MeasureGroupPopulationComponent(org.hl7.fhir.r5.model.Measure.MeasureGroupPopulationComponent) CodeableConcept(org.hl7.fhir.r5.model.CodeableConcept)

Example 67 with NodeStack

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()));
        }
    }
}
Also used : MeasureGroupStratifierComponent(org.hl7.fhir.r5.model.Measure.MeasureGroupStratifierComponent) Element(org.hl7.fhir.r5.elementmodel.Element) ArrayList(java.util.ArrayList) NodeStack(org.hl7.fhir.validation.instance.utils.NodeStack) CodeableConcept(org.hl7.fhir.r5.model.CodeableConcept)

Example 68 with NodeStack

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
    }
}
Also used : Coding(org.hl7.fhir.r5.model.Coding) Element(org.hl7.fhir.r5.elementmodel.Element) NodeStack(org.hl7.fhir.validation.instance.utils.NodeStack) BigDecimal(java.math.BigDecimal) IOException(java.io.IOException) FHIRException(org.hl7.fhir.exceptions.FHIRException)

Example 69 with NodeStack

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
        }
    }
}
Also used : Element(org.hl7.fhir.r5.elementmodel.Element) ArrayList(java.util.ArrayList) SearchParameter(org.hl7.fhir.r5.model.SearchParameter)

Example 70 with NodeStack

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);
}
Also used : Coding(org.hl7.fhir.r5.model.Coding)

Aggregations

Element (org.hl7.fhir.r5.elementmodel.Element)50 ArrayList (java.util.ArrayList)35 NodeStack (org.hl7.fhir.validation.instance.utils.NodeStack)32 FHIRException (org.hl7.fhir.exceptions.FHIRException)22 IndexedElement (org.hl7.fhir.validation.instance.utils.IndexedElement)22 IOException (java.io.IOException)14 SpecialElement (org.hl7.fhir.r5.elementmodel.Element.SpecialElement)14 NamedElement (org.hl7.fhir.r5.elementmodel.ParserBase.NamedElement)13 DefinitionException (org.hl7.fhir.exceptions.DefinitionException)12 ContactPoint (org.hl7.fhir.r5.model.ContactPoint)12 StructureDefinition (org.hl7.fhir.r5.model.StructureDefinition)12 ValueSet (org.hl7.fhir.r5.model.ValueSet)12 FHIRLexerException (org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException)11 NotImplementedException (org.apache.commons.lang3.NotImplementedException)10 PathEngineException (org.hl7.fhir.exceptions.PathEngineException)10 TerminologyServiceException (org.hl7.fhir.exceptions.TerminologyServiceException)10 ValidationResult (org.hl7.fhir.r5.context.IWorkerContext.ValidationResult)10 List (java.util.List)8 CodeSystem (org.hl7.fhir.r5.model.CodeSystem)8 Coding (org.hl7.fhir.r5.model.Coding)8