use of org.hl7.fhir.r4b.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;
}
use of org.hl7.fhir.r4b.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);
}
use of org.hl7.fhir.r4b.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);
}
}
use of org.hl7.fhir.r4b.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");
}
}
}
use of org.hl7.fhir.r4b.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));
}
Aggregations