Search in sources :

Example 36 with ValidationResult

use of org.hl7.fhir.r4b.context.IWorkerContext.ValidationResult in project org.hl7.fhir.core by hapifhir.

the class ValueSetCheckerSimple method validateCode.

public ValidationResult validateCode(CodeableConcept code) throws FHIRException {
    // first, we validate the codings themselves
    List<String> errors = new ArrayList<String>();
    List<String> warnings = new ArrayList<String>();
    if (options.getValueSetMode() != ValueSetMode.CHECK_MEMERSHIP_ONLY) {
        for (Coding c : code.getCoding()) {
            if (!c.hasSystem()) {
                warnings.add(context.formatMessage(I18nConstants.CODING_HAS_NO_SYSTEM__CANNOT_VALIDATE));
            }
            CodeSystem cs = resolveCodeSystem(c.getSystem());
            ValidationResult res = null;
            if (cs == null || cs.getContent() != CodeSystemContentMode.COMPLETE) {
                res = context.validateCode(options.noClient(), c, null);
            } else {
                res = validateCode(c, cs);
            }
            if (!res.isOk()) {
                errors.add(res.getMessage());
            } else if (res.getMessage() != null) {
                warnings.add(res.getMessage());
            }
        }
    }
    if (valueset != null && options.getValueSetMode() != ValueSetMode.NO_MEMBERSHIP_CHECK) {
        Boolean result = false;
        for (Coding c : code.getCoding()) {
            Boolean ok = codeInValueSet(c.getSystem(), c.getCode(), warnings);
            if (ok == null && result == false) {
                result = null;
            } else if (ok) {
                result = true;
            }
        }
        if (result == null) {
            warnings.add(0, context.formatMessage(I18nConstants.UNABLE_TO_CHECK_IF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_, valueset.getUrl()));
        } else if (!result) {
            errors.add(0, context.formatMessage(I18nConstants.NONE_OF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_, valueset.getUrl()));
        }
    }
    if (errors.size() > 0) {
        return new ValidationResult(IssueSeverity.ERROR, errors.toString());
    } else if (warnings.size() > 0) {
        return new ValidationResult(IssueSeverity.WARNING, warnings.toString());
    } else {
        return new ValidationResult(IssueSeverity.INFORMATION, null);
    }
}
Also used : Coding(org.hl7.fhir.r4b.model.Coding) ArrayList(java.util.ArrayList) ValidationResult(org.hl7.fhir.r4b.context.IWorkerContext.ValidationResult) CodeSystem(org.hl7.fhir.r4b.model.CodeSystem)

Example 37 with ValidationResult

use of org.hl7.fhir.r4b.context.IWorkerContext.ValidationResult in project org.hl7.fhir.core by hapifhir.

the class ValueSetCheckerSimple method findCodeInExpansion.

private ValidationResult findCodeInExpansion(Coding code, List<ValueSetExpansionContainsComponent> contains) {
    for (ValueSetExpansionContainsComponent containsComponent : contains) {
        if (containsComponent.getSystem().equals(code.getSystem()) && containsComponent.getCode().equals(code.getCode())) {
            ConceptDefinitionComponent ccd = new ConceptDefinitionComponent();
            ccd.setCode(containsComponent.getCode());
            ccd.setDisplay(containsComponent.getDisplay());
            ValidationResult res = new ValidationResult(code.getSystem(), ccd);
            return res;
        }
        if (containsComponent.hasContains()) {
            ValidationResult res = findCodeInExpansion(code, containsComponent.getContains());
            if (res != null) {
                return res;
            }
        }
    }
    return null;
}
Also used : ValueSetExpansionContainsComponent(org.hl7.fhir.r4b.model.ValueSet.ValueSetExpansionContainsComponent) ConceptDefinitionComponent(org.hl7.fhir.r4b.model.CodeSystem.ConceptDefinitionComponent) ValidationResult(org.hl7.fhir.r4b.context.IWorkerContext.ValidationResult)

Example 38 with ValidationResult

use of org.hl7.fhir.r4b.context.IWorkerContext.ValidationResult in project org.hl7.fhir.core by hapifhir.

the class ValueSetCheckerSimple method validateCode.

public ValidationResult validateCode(Coding code) throws FHIRException {
    String warningMessage = null;
    // first, we validate the concept itself
    ValidationResult res = null;
    boolean inExpansion = false;
    boolean inInclude = false;
    String system = code.hasSystem() ? code.getSystem() : getValueSetSystemOrNull();
    if (options.getValueSetMode() != ValueSetMode.CHECK_MEMERSHIP_ONLY) {
        if (system == null && !code.hasDisplay()) {
            // dealing with just a plain code (enum)
            system = systemForCodeInValueSet(code.getCode());
        }
        if (!code.hasSystem()) {
            if (options.isGuessSystem() && system == null && Utilities.isAbsoluteUrl(code.getCode())) {
                // this arises when using URIs bound to value sets
                system = "urn:ietf:rfc:3986";
            }
            code.setSystem(system);
        }
        inExpansion = checkExpansion(code);
        inInclude = checkInclude(code);
        CodeSystem cs = resolveCodeSystem(system);
        if (cs == null) {
            warningMessage = "Unable to resolve system " + system;
            if (!inExpansion) {
                if (valueset != null && valueset.hasExpansion()) {
                    return new ValidationResult(IssueSeverity.ERROR, context.formatMessage(I18nConstants.CODESYSTEM_CS_UNK_EXPANSION, valueset.getUrl(), code.getCode().toString(), code.getSystem()));
                } else {
                    throw new FHIRException(warningMessage);
                }
            }
        }
        if (cs != null && cs.hasSupplements()) {
            return new ValidationResult(IssueSeverity.ERROR, context.formatMessage(I18nConstants.CODESYSTEM_CS_NO_SUPPLEMENT, cs.getUrl()));
        }
        if (cs != null && cs.getContent() != CodeSystemContentMode.COMPLETE) {
            warningMessage = "Resolved system " + system + ", but the definition is not complete";
            if (!inExpansion && cs.getContent() != CodeSystemContentMode.FRAGMENT) {
                // we're going to give it a go if it's a fragment
                throw new FHIRException(warningMessage);
            }
        }
        if (cs != null) /*&& (cs.getContent() == CodeSystemContentMode.COMPLETE || cs.getContent() == CodeSystemContentMode.FRAGMENT)*/
        {
            if (!(cs.getContent() == CodeSystemContentMode.COMPLETE || cs.getContent() == CodeSystemContentMode.FRAGMENT)) {
                // we can't validate that here.
                throw new FHIRException("Unable to evaluate based on empty code system");
            }
            res = validateCode(code, cs);
        } else if (cs == null && valueset.hasExpansion() && inExpansion) {
            // we just take the value set as face value then
            res = new ValidationResult(system, new ConceptDefinitionComponent().setCode(code.getCode()).setDisplay(code.getDisplay()));
        } else {
            // disabled waiting for discussion
            throw new FHIRException("No try the server");
        }
    } else {
        inExpansion = checkExpansion(code);
        inInclude = checkInclude(code);
    }
    List<String> warnings = new ArrayList<>();
    // then, if we have a value set, we check it's in the value set
    if (valueset != null && options.getValueSetMode() != ValueSetMode.NO_MEMBERSHIP_CHECK) {
        if ((res == null || res.isOk())) {
            Boolean ok = codeInValueSet(system, code.getCode(), warnings);
            if (ok == null || !ok) {
                if (res == null) {
                    res = new ValidationResult((IssueSeverity) null, null);
                }
                if (!inExpansion && !inInclude) {
                    res.setMessage("Not in value set " + valueset.getUrl()).setSeverity(IssueSeverity.ERROR);
                } else if (warningMessage != null) {
                    res = new ValidationResult(IssueSeverity.WARNING, context.formatMessage(I18nConstants.CODE_FOUND_IN_EXPANSION_HOWEVER_, warningMessage));
                } else if (inExpansion) {
                    res.setMessage("Code found in expansion, however: " + res.getMessage());
                } else if (inInclude) {
                    res.setMessage("Code found in include, however: " + res.getMessage());
                }
            }
        }
    }
    return res;
}
Also used : ConceptDefinitionComponent(org.hl7.fhir.r4b.model.CodeSystem.ConceptDefinitionComponent) ArrayList(java.util.ArrayList) IssueSeverity(org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity) ValidationResult(org.hl7.fhir.r4b.context.IWorkerContext.ValidationResult) CodeSystem(org.hl7.fhir.r4b.model.CodeSystem) FHIRException(org.hl7.fhir.exceptions.FHIRException)

Example 39 with ValidationResult

use of org.hl7.fhir.r4b.context.IWorkerContext.ValidationResult in project org.hl7.fhir.core by hapifhir.

the class ValueSetRenderer method genInclude.

private boolean genInclude(XhtmlNode ul, ConceptSetComponent inc, String type, List<String> langs, boolean doDesignations, List<UsedConceptMap> maps, Map<String, String> designations, int index) throws FHIRException, IOException {
    boolean hasExtensions = false;
    XhtmlNode li;
    li = ul.li();
    CodeSystem e = getContext().getWorker().fetchCodeSystem(inc.getSystem());
    Map<String, ConceptDefinitionComponent> definitions = new HashMap<>();
    if (inc.hasSystem()) {
        if (inc.getConcept().size() == 0 && inc.getFilter().size() == 0) {
            li.addText(type + " all codes defined in ");
            addCsRef(inc, li, e);
        } else {
            if (inc.getConcept().size() > 0) {
                li.addText(type + " these codes as defined in ");
                addCsRef(inc, li, e);
                if (inc.hasVersion()) {
                    li.addText(" version ");
                    li.code(inc.getVersion());
                }
                // for performance reasons, we do all the fetching in one batch
                definitions = getConceptsForCodes(e, inc);
                XhtmlNode t = li.table("none");
                boolean hasComments = false;
                boolean hasDefinition = false;
                for (ConceptReferenceComponent c : inc.getConcept()) {
                    hasComments = hasComments || ExtensionHelper.hasExtension(c, ToolingExtensions.EXT_VS_COMMENT);
                    ConceptDefinitionComponent cc = definitions.get(c.getCode());
                    hasDefinition = hasDefinition || ((cc != null && cc.hasDefinition()) || ExtensionHelper.hasExtension(c, ToolingExtensions.EXT_DEFINITION));
                }
                if (hasComments || hasDefinition)
                    hasExtensions = true;
                addMapHeaders(addTableHeaderRowStandard(t, false, true, hasDefinition, hasComments, false, false, null, langs, designations, doDesignations), maps);
                for (ConceptReferenceComponent c : inc.getConcept()) {
                    XhtmlNode tr = t.tr();
                    XhtmlNode td = tr.td();
                    ConceptDefinitionComponent cc = definitions.get(c.getCode());
                    addCodeToTable(false, inc.getSystem(), c.getCode(), c.hasDisplay() ? c.getDisplay() : cc != null ? cc.getDisplay() : "", td);
                    td = tr.td();
                    if (!Utilities.noString(c.getDisplay()))
                        td.addText(c.getDisplay());
                    else if (cc != null && !Utilities.noString(cc.getDisplay()))
                        td.addText(cc.getDisplay());
                    if (hasDefinition) {
                        td = tr.td();
                        if (ExtensionHelper.hasExtension(c, ToolingExtensions.EXT_DEFINITION)) {
                            smartAddText(td, ToolingExtensions.readStringExtension(c, ToolingExtensions.EXT_DEFINITION));
                        } else if (cc != null && !Utilities.noString(cc.getDefinition())) {
                            smartAddText(td, cc.getDefinition());
                        }
                    }
                    if (hasComments) {
                        td = tr.td();
                        if (ExtensionHelper.hasExtension(c, ToolingExtensions.EXT_VS_COMMENT)) {
                            smartAddText(td, "Note: " + ToolingExtensions.readStringExtension(c, ToolingExtensions.EXT_VS_COMMENT));
                        }
                    }
                    if (doDesignations) {
                        addDesignationsToRow(c, designations, tr);
                        addLangaugesToRow(c, langs, tr);
                    }
                }
            }
            if (inc.getFilter().size() > 0) {
                li.addText(type + " codes from ");
                addCsRef(inc, li, e);
                li.tx(" where ");
                for (int i = 0; i < inc.getFilter().size(); i++) {
                    ConceptSetFilterComponent f = inc.getFilter().get(i);
                    if (i > 0) {
                        if (i == inc.getFilter().size() - 1) {
                            li.tx(" and ");
                        } else {
                            li.tx(", ");
                        }
                    }
                    if (f.getOp() == FilterOperator.EXISTS) {
                        if (f.getValue().equals("true")) {
                            li.tx(f.getProperty() + " exists");
                        } else {
                            li.tx(f.getProperty() + " doesn't exist");
                        }
                    } else {
                        li.tx(f.getProperty() + " " + describe(f.getOp()) + " ");
                        if (e != null && codeExistsInValueSet(e, f.getValue())) {
                            String href = getContext().fixReference(getCsRef(e));
                            if (href.contains("#"))
                                href = href + "-" + Utilities.nmtokenize(f.getValue());
                            else
                                href = href + "#" + e.getId() + "-" + Utilities.nmtokenize(f.getValue());
                            li.ah(href).addText(f.getValue());
                        } else if ("concept".equals(f.getProperty()) && inc.hasSystem()) {
                            li.addText(f.getValue());
                            ValidationResult vr = getContext().getWorker().validateCode(getContext().getTerminologyServiceOptions(), inc.getSystem(), inc.getVersion(), f.getValue(), null);
                            if (vr.isOk()) {
                                li.tx(" (" + vr.getDisplay() + ")");
                            }
                        } else
                            li.addText(f.getValue());
                        String disp = ToolingExtensions.getDisplayHint(f);
                        if (disp != null)
                            li.tx(" (" + disp + ")");
                    }
                }
            }
        }
        if (inc.hasValueSet()) {
            li.tx(", where the codes are contained in ");
            boolean first = true;
            for (UriType vs : inc.getValueSet()) {
                if (first)
                    first = false;
                else
                    li.tx(", ");
                AddVsRef(vs.asStringValue(), li);
            }
        }
        if (inc.hasExtension(ToolingExtensions.EXT_EXPAND_RULES) || inc.hasExtension(ToolingExtensions.EXT_EXPAND_GROUP)) {
            hasExtensions = true;
            renderExpansionRules(li, inc, index, definitions);
        }
    } else {
        li.tx("Import all the codes that are contained in ");
        if (inc.getValueSet().size() < 4) {
            boolean first = true;
            for (UriType vs : inc.getValueSet()) {
                if (first)
                    first = false;
                else
                    li.tx(", ");
                AddVsRef(vs.asStringValue(), li);
            }
        } else {
            XhtmlNode xul = li.ul();
            for (UriType vs : inc.getValueSet()) {
                AddVsRef(vs.asStringValue(), xul.li());
            }
        }
    }
    return hasExtensions;
}
Also used : ConceptSetFilterComponent(org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent) ConceptDefinitionComponent(org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent) HashMap(java.util.HashMap) ValidationResult(org.hl7.fhir.r5.context.IWorkerContext.ValidationResult) CodeSystem(org.hl7.fhir.r5.model.CodeSystem) ConceptReferenceComponent(org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent) XhtmlNode(org.hl7.fhir.utilities.xhtml.XhtmlNode) UriType(org.hl7.fhir.r5.model.UriType)

Example 40 with ValidationResult

use of org.hl7.fhir.r4b.context.IWorkerContext.ValidationResult in project org.hl7.fhir.core by hapifhir.

the class StructureMapUtilities method buildCoding.

private Coding buildCoding(String uri, String code) throws FHIRException {
    // if we can get this as a valueSet, we will
    String system = null;
    String display = null;
    String version = null;
    ValueSet vs = Utilities.noString(uri) ? null : worker.fetchResourceWithException(ValueSet.class, uri);
    if (vs != null) {
        ValueSetExpansionOutcome vse = worker.expandVS(vs, true, false);
        if (vse.getError() != null)
            throw new FHIRException(vse.getError());
        CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
        for (ValueSetExpansionContainsComponent t : vse.getValueset().getExpansion().getContains()) {
            if (t.hasCode())
                b.append(t.getCode());
            if (code.equals(t.getCode()) && t.hasSystem()) {
                system = t.getSystem();
                version = t.getVersion();
                display = t.getDisplay();
                break;
            }
            if (code.equalsIgnoreCase(t.getDisplay()) && t.hasSystem()) {
                system = t.getSystem();
                version = t.getVersion();
                display = t.getDisplay();
                break;
            }
        }
        if (system == null)
            throw new FHIRException("The code '" + code + "' is not in the value set '" + uri + "' (valid codes: " + b.toString() + "; also checked displays)");
    } else {
        system = uri;
    }
    ValidationResult vr = worker.validateCode(terminologyServiceOptions.setVersionFlexible(true), system, version, code, null);
    if (vr != null && vr.getDisplay() != null)
        display = vr.getDisplay();
    return new Coding().setSystem(system).setCode(code).setDisplay(display);
}
Also used : ValueSetExpansionContainsComponent(org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent) ValueSetExpansionOutcome(org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome) CommaSeparatedStringBuilder(org.hl7.fhir.utilities.CommaSeparatedStringBuilder) ValidationResult(org.hl7.fhir.r5.context.IWorkerContext.ValidationResult) FHIRException(org.hl7.fhir.exceptions.FHIRException)

Aggregations

FHIRException (org.hl7.fhir.exceptions.FHIRException)32 IOException (java.io.IOException)22 ValidationResult (org.hl7.fhir.r5.context.IWorkerContext.ValidationResult)20 TerminologyServiceException (org.hl7.fhir.exceptions.TerminologyServiceException)17 DefinitionException (org.hl7.fhir.exceptions.DefinitionException)15 FileNotFoundException (java.io.FileNotFoundException)14 ValidationResult (ca.uhn.fhir.validation.ValidationResult)12 CodeSystem (org.hl7.fhir.r5.model.CodeSystem)12 ConceptDefinitionComponent (org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent)11 ValueSet (org.hl7.fhir.r5.model.ValueSet)11 CommaSeparatedStringBuilder (org.hl7.fhir.utilities.CommaSeparatedStringBuilder)11 NoTerminologyServiceException (org.hl7.fhir.exceptions.NoTerminologyServiceException)10 ValidationResult (org.hl7.fhir.r4b.context.IWorkerContext.ValidationResult)10 ArrayList (java.util.ArrayList)9 Coding (org.hl7.fhir.r5.model.Coding)9 NotImplementedException (org.apache.commons.lang3.NotImplementedException)7 PathEngineException (org.hl7.fhir.exceptions.PathEngineException)7 ValidationResult (org.hl7.fhir.r4.context.IWorkerContext.ValidationResult)7 ConceptDefinitionComponent (org.hl7.fhir.r4b.model.CodeSystem.ConceptDefinitionComponent)7 FHIRLexerException (org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException)7