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);
}
}
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;
}
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;
}
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;
}
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);
}
Aggregations