Search in sources :

Example 41 with ConceptDefinitionComponent

use of org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent 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) {
                    if (warnings != null) {
                        res.setMessage("Not in value set " + valueset.getUrl() + " (" + warnings + ")").setSeverity(IssueSeverity.ERROR);
                    } else {
                        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.r5.model.CodeSystem.ConceptDefinitionComponent) ArrayList(java.util.ArrayList) IssueSeverity(org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity) ValidationResult(org.hl7.fhir.r5.context.IWorkerContext.ValidationResult) CodeSystem(org.hl7.fhir.r5.model.CodeSystem) FHIRException(org.hl7.fhir.exceptions.FHIRException)

Example 42 with ConceptDefinitionComponent

use of org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent in project org.hl7.fhir.core by hapifhir.

the class ValueSetCheckerSimple method validateCode.

private ValidationResult validateCode(Coding code, CodeSystem cs) {
    ConceptDefinitionComponent cc = cs.hasUserData("tx.cs.special") ? ((SpecialCodeSystem) cs.getUserData("tx.cs.special")).findConcept(code) : findCodeInConcept(cs.getConcept(), code.getCode());
    if (cc == null) {
        if (cs.getContent() == CodeSystemContentMode.FRAGMENT) {
            return new ValidationResult(IssueSeverity.WARNING, context.formatMessage(I18nConstants.UNKNOWN_CODE__IN_FRAGMENT, gen(code), cs.getUrl()));
        } else {
            return new ValidationResult(IssueSeverity.ERROR, context.formatMessage(I18nConstants.UNKNOWN_CODE__IN_, gen(code), cs.getUrl()));
        }
    }
    if (code.getDisplay() == null) {
        return new ValidationResult(code.getSystem(), cc);
    }
    CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();
    if (cc.hasDisplay()) {
        b.append(cc.getDisplay());
        if (code.getDisplay().equalsIgnoreCase(cc.getDisplay())) {
            return new ValidationResult(code.getSystem(), cc);
        }
    }
    for (ConceptDefinitionDesignationComponent ds : cc.getDesignation()) {
        b.append(ds.getValue());
        if (code.getDisplay().equalsIgnoreCase(ds.getValue())) {
            return new ValidationResult(code.getSystem(), cc);
        }
    }
    // also check to see if the value set has another display
    ConceptReferenceComponent vs = findValueSetRef(code.getSystem(), code.getCode());
    if (vs != null && (vs.hasDisplay() || vs.hasDesignation())) {
        if (vs.hasDisplay()) {
            b.append(vs.getDisplay());
            if (code.getDisplay().equalsIgnoreCase(vs.getDisplay())) {
                return new ValidationResult(code.getSystem(), cc);
            }
        }
        for (ConceptReferenceDesignationComponent ds : vs.getDesignation()) {
            b.append(ds.getValue());
            if (code.getDisplay().equalsIgnoreCase(ds.getValue())) {
                return new ValidationResult(code.getSystem(), cc);
            }
        }
    }
    return new ValidationResult(IssueSeverity.WARNING, context.formatMessage(I18nConstants.DISPLAY_NAME_FOR__SHOULD_BE_ONE_OF__INSTEAD_OF_, code.getSystem(), code.getCode(), b.toString(), code.getDisplay()), code.getSystem(), cc);
}
Also used : ConceptDefinitionComponent(org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent) ConceptDefinitionDesignationComponent(org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionDesignationComponent) CommaSeparatedStringBuilder(org.hl7.fhir.utilities.CommaSeparatedStringBuilder) ConceptReferenceDesignationComponent(org.hl7.fhir.r5.model.ValueSet.ConceptReferenceDesignationComponent) ValidationResult(org.hl7.fhir.r5.context.IWorkerContext.ValidationResult) ConceptReferenceComponent(org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent)

Example 43 with ConceptDefinitionComponent

use of org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent 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());
            }
        }
    }
    Coding foundCoding = null;
    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;
                foundCoding = c;
            }
        }
        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 {
        ConceptDefinitionComponent cd = new ConceptDefinitionComponent(foundCoding.getCode());
        cd.setDisplay(foundCoding.getDisplay());
        return new ValidationResult(foundCoding.getSystem(), cd);
    }
}
Also used : ConceptDefinitionComponent(org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent) Coding(org.hl7.fhir.r5.model.Coding) ArrayList(java.util.ArrayList) ValidationResult(org.hl7.fhir.r5.context.IWorkerContext.ValidationResult) CodeSystem(org.hl7.fhir.r5.model.CodeSystem)

Example 44 with ConceptDefinitionComponent

use of org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent in project org.hl7.fhir.core by hapifhir.

the class ValueSetExpanderSimple method doInternalIncludeCodes.

public void doInternalIncludeCodes(ConceptSetComponent inc, ValueSetExpansionComponent exp, Parameters expParams, List<ValueSet> imports, CodeSystem cs, boolean noInactive) throws NoTerminologyServiceException, TerminologyServiceException, FHIRException {
    if (cs == null) {
        if (context.isNoTerminologyServer())
            throw failTSE("Unable to find code system " + inc.getSystem().toString());
        else
            throw failTSE("Unable to find code system " + inc.getSystem().toString());
    }
    cs.checkNoModifiers("Code System", "expanding");
    if (cs.getContent() != CodeSystemContentMode.COMPLETE && cs.getContent() != CodeSystemContentMode.FRAGMENT)
        throw failTSE("Code system " + inc.getSystem().toString() + " is incomplete");
    if (cs.hasVersion())
        if (!existsInParams(exp.getParameter(), "version", new UriType(cs.getUrl() + "|" + cs.getVersion())))
            exp.getParameter().add(new ValueSetExpansionParameterComponent().setName("version").setValue(new UriType(cs.getUrl() + "|" + cs.getVersion())));
    if (inc.getConcept().size() == 0 && inc.getFilter().size() == 0) {
        // special case - add all the code system
        for (ConceptDefinitionComponent def : cs.getConcept()) {
            addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new AllConceptsFilter(), noInactive);
        }
        if (cs.getContent() == CodeSystemContentMode.FRAGMENT) {
            addFragmentWarning(exp, cs);
        }
        if (cs.getContent() == CodeSystemContentMode.EXAMPLE) {
            addExampleWarning(exp, cs);
        }
    }
    if (!inc.getConcept().isEmpty()) {
        canBeHeirarchy = false;
        for (ConceptReferenceComponent c : inc.getConcept()) {
            c.checkNoModifiers("Code in Code System", "expanding");
            ConceptDefinitionComponent def = CodeSystemUtilities.findCode(cs.getConcept(), c.getCode());
            // default is true if we're a fragment and
            Boolean inactive = false;
            if (def == null) {
                if (cs.getContent() == CodeSystemContentMode.FRAGMENT) {
                    addFragmentWarning(exp, cs);
                } else if (cs.getContent() == CodeSystemContentMode.EXAMPLE) {
                    addExampleWarning(exp, cs);
                } else {
                    if (checkCodesWhenExpanding) {
                        throw failTSE("Unable to find code '" + c.getCode() + "' in code system " + cs.getUrl());
                    }
                }
            } else {
                inactive = CodeSystemUtilities.isInactive(cs, def);
            }
            addCode(inc.getSystem(), c.getCode(), !Utilities.noString(c.getDisplay()) ? c.getDisplay() : def == null ? null : def.getDisplay(), null, convertDesignations(c.getDesignation()), expParams, false, inactive, imports, noInactive);
        }
    }
    if (inc.getFilter().size() > 1) {
        // which will bt the case if we get around to supporting this
        canBeHeirarchy = false;
        // need to and them, and this isn't done yet. But this shouldn't arise in non loinc and snomed value sets
        throw failTSE("Multiple filters not handled yet");
    }
    if (inc.getFilter().size() == 1) {
        if (cs.getContent() == CodeSystemContentMode.FRAGMENT) {
            addFragmentWarning(exp, cs);
        }
        ConceptSetFilterComponent fc = inc.getFilter().get(0);
        if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.ISA) {
            // special: all codes in the target code system under the value
            ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue());
            if (def == null)
                throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
            addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new AllConceptsFilter(), noInactive);
        } else if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.ISNOTA) {
            // special: all codes in the target code system that are not under the value
            ConceptDefinitionComponent defEx = getConceptForCode(cs.getConcept(), fc.getValue());
            if (defEx == null)
                throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
            for (ConceptDefinitionComponent def : cs.getConcept()) {
                addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, defEx, new AllConceptsFilter(), noInactive);
            }
        } else if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.DESCENDENTOF) {
            // special: all codes in the target code system under the value
            ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue());
            if (def == null)
                throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'");
            for (ConceptDefinitionComponent c : def.getConcept()) addCodeAndDescendents(cs, inc.getSystem(), c, null, expParams, imports, null, new AllConceptsFilter(), noInactive);
            if (def.hasUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK)) {
                List<ConceptDefinitionComponent> children = (List<ConceptDefinitionComponent>) def.getUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK);
                for (ConceptDefinitionComponent c : children) addCodeAndDescendents(cs, inc.getSystem(), c, null, expParams, imports, null, new AllConceptsFilter(), noInactive);
            }
        } else if ("display".equals(fc.getProperty()) && fc.getOp() == FilterOperator.EQUAL) {
            // gg; note: wtf is this: if the filter is display=v, look up the code 'v', and see if it's diplsay is 'v'?
            canBeHeirarchy = false;
            ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue());
            if (def != null) {
                if (isNotBlank(def.getDisplay()) && isNotBlank(fc.getValue())) {
                    if (def.getDisplay().contains(fc.getValue())) {
                        addCode(inc.getSystem(), def.getCode(), def.getDisplay(), null, def.getDesignation(), expParams, CodeSystemUtilities.isNotSelectable(cs, def), CodeSystemUtilities.isInactive(cs, def), imports, noInactive);
                    }
                }
            }
        } else if (isDefinedProperty(cs, fc.getProperty())) {
            for (ConceptDefinitionComponent def : cs.getConcept()) {
                addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new PropertyFilter(fc, getPropertyDefinition(cs, fc.getProperty())), noInactive);
            }
        } else {
            throw fail("Search by property[" + fc.getProperty() + "] and op[" + fc.getOp() + "] is not supported yet");
        }
    }
}
Also used : ConceptSetFilterComponent(org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent) ConceptDefinitionComponent(org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent) ValueSetExpansionParameterComponent(org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent) ArrayList(java.util.ArrayList) List(java.util.List) ConceptReferenceComponent(org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent) UriType(org.hl7.fhir.r5.model.UriType)

Example 45 with ConceptDefinitionComponent

use of org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent in project org.hl7.fhir.core by hapifhir.

the class CodeSystemUtilities method addOtherChild.

// see http://hl7.org/fhir/R4/codesystem.html#hierachy
public static void addOtherChild(CodeSystem cs, ConceptDefinitionComponent owner, String code) {
    defineChildProperty(cs);
    owner.addProperty().setCode("child").setValue(new CodeType(code));
}
Also used : CodeType(org.hl7.fhir.r5.model.CodeType)

Aggregations

ConceptDefinitionComponent (org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent)54 ArrayList (java.util.ArrayList)26 XhtmlNode (org.hl7.fhir.utilities.xhtml.XhtmlNode)26 ConceptDefinitionComponent (org.hl7.fhir.r4b.model.CodeSystem.ConceptDefinitionComponent)22 CodeSystem (org.hl7.fhir.r5.model.CodeSystem)21 ConceptDefinitionComponent (org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent)17 ConceptDefinitionComponent (org.hl7.fhir.r4.model.CodeSystem.ConceptDefinitionComponent)16 ValueSet (org.hl7.fhir.dstu2.model.ValueSet)15 FHIRException (org.hl7.fhir.exceptions.FHIRException)14 CommaSeparatedStringBuilder (org.hl7.fhir.utilities.CommaSeparatedStringBuilder)12 ConceptPropertyComponent (org.hl7.fhir.r4b.model.CodeSystem.ConceptPropertyComponent)10 ConceptPropertyComponent (org.hl7.fhir.r5.model.CodeSystem.ConceptPropertyComponent)10 IOException (java.io.IOException)9 HashMap (java.util.HashMap)9 NotImplementedException (org.apache.commons.lang3.NotImplementedException)9 TerminologyServiceException (org.hl7.fhir.exceptions.TerminologyServiceException)9 FileNotFoundException (java.io.FileNotFoundException)8 ConceptDefinitionComponent (org.hl7.fhir.dstu2016may.model.CodeSystem.ConceptDefinitionComponent)8 ValidationResult (org.hl7.fhir.r5.context.IWorkerContext.ValidationResult)8 ConceptDefinitionDesignationComponent (org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionDesignationComponent)8