mirror of
https://github.com/hapifhir/org.hl7.fhir.core.git
synced 2025-02-13 16:24:44 +00:00
Merge pull request #940 from hapifhir/gg-202210-coding-validation
Gg 202210 coding validation
This commit is contained in:
commit
53c65d857b
@ -93,4 +93,9 @@ public boolean hasCoding(String system, String code) {
|
|||||||
public void addCoding(String system, String code, String display) {
|
public void addCoding(String system, String code, String display) {
|
||||||
getCoding().add(new Coding(system, code, display));
|
getCoding().add(new Coding(system, code, display));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return hasCoding() ? getCoding().toString() : "["+getText()+"]";
|
||||||
|
}
|
||||||
|
|
@ -365,8 +365,9 @@ public class XmlParser extends ParserBase {
|
|||||||
} else
|
} else
|
||||||
ok = ok || (attr.getLocalName().equals("schemaLocation")); // xsi:schemalocation allowed for non FHIR content
|
ok = ok || (attr.getLocalName().equals("schemaLocation")); // xsi:schemalocation allowed for non FHIR content
|
||||||
ok = ok || (hasTypeAttr(element) && attr.getLocalName().equals("type") && FormatUtilities.NS_XSI.equals(attr.getNamespaceURI())); // xsi:type allowed if element says so
|
ok = ok || (hasTypeAttr(element) && attr.getLocalName().equals("type") && FormatUtilities.NS_XSI.equals(attr.getNamespaceURI())); // xsi:type allowed if element says so
|
||||||
if (!ok)
|
if (!ok) {
|
||||||
logError(line(node, false), col(node, false), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.UNDEFINED_ATTRIBUTE__ON__FOR_TYPE__PROPERTIES__, attr.getNodeName(), node.getNodeName(), element.fhirType(), properties), IssueSeverity.ERROR);
|
logError(line(node, false), col(node, false), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.UNDEFINED_ATTRIBUTE__ON__FOR_TYPE__PROPERTIES__, attr.getNodeName(), node.getNodeName(), element.fhirType(), properties), IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -404,6 +404,11 @@ public boolean hasCoding(String system, String code) {
|
|||||||
public void addCoding(String system, String code, String display) {
|
public void addCoding(String system, String code, String display) {
|
||||||
getCoding().add(new Coding(system, code, display));
|
getCoding().add(new Coding(system, code, display));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return hasCoding() ? getCoding().toString() : "["+getText()+"]";
|
||||||
|
}
|
||||||
|
|
||||||
// end addition
|
// end addition
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package org.hl7.fhir.r5.terminologies;
|
package org.hl7.fhir.r5.terminologies;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -34,10 +35,24 @@ import java.util.List;
|
|||||||
|
|
||||||
|
|
||||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ETooCostly;
|
import org.hl7.fhir.r5.terminologies.ValueSetExpander.ETooCostly;
|
||||||
|
import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass;
|
||||||
import org.hl7.fhir.r5.utils.EOperationOutcome;
|
import org.hl7.fhir.r5.utils.EOperationOutcome;
|
||||||
|
|
||||||
public interface ValueSetChecker {
|
public interface ValueSetChecker {
|
||||||
|
|
||||||
Boolean codeInValueSet(String system, String code, List<String> warnings) throws ETooCostly, EOperationOutcome, Exception;
|
public static class ValidationProcessInfo {
|
||||||
|
private TerminologyServiceErrorClass err;
|
||||||
|
private List<String> warnings = new ArrayList<>();
|
||||||
|
public TerminologyServiceErrorClass getErr() {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
public void setErr(TerminologyServiceErrorClass err) {
|
||||||
|
this.err = err;
|
||||||
|
}
|
||||||
|
public List<String> getWarnings() {
|
||||||
|
return warnings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Boolean codeInValueSet(String system, String code, ValidationProcessInfo info) throws ETooCostly, EOperationOutcome, Exception;
|
||||||
|
|
||||||
}
|
}
|
@ -61,6 +61,7 @@ import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceDesignationComponent;
|
|||||||
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent;
|
||||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||||
|
import org.hl7.fhir.r5.terminologies.ValueSetChecker.ValidationProcessInfo;
|
||||||
import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass;
|
import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass;
|
||||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||||
import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier;
|
import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier;
|
||||||
@ -129,11 +130,11 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe
|
|||||||
public ValidationResult validateCode(CodeableConcept code) throws FHIRException {
|
public ValidationResult validateCode(CodeableConcept code) throws FHIRException {
|
||||||
// first, we validate the codings themselves
|
// first, we validate the codings themselves
|
||||||
List<String> errors = new ArrayList<String>();
|
List<String> errors = new ArrayList<String>();
|
||||||
List<String> warnings = new ArrayList<String>();
|
ValidationProcessInfo info = new ValidationProcessInfo();
|
||||||
if (options.getValueSetMode() != ValueSetMode.CHECK_MEMERSHIP_ONLY) {
|
if (options.getValueSetMode() != ValueSetMode.CHECK_MEMERSHIP_ONLY) {
|
||||||
for (Coding c : code.getCoding()) {
|
for (Coding c : code.getCoding()) {
|
||||||
if (!c.hasSystem()) {
|
if (!c.hasSystem()) {
|
||||||
warnings.add(context.formatMessage(I18nConstants.CODING_HAS_NO_SYSTEM__CANNOT_VALIDATE));
|
info.getWarnings().add(context.formatMessage(I18nConstants.CODING_HAS_NO_SYSTEM__CANNOT_VALIDATE));
|
||||||
}
|
}
|
||||||
CodeSystem cs = resolveCodeSystem(c.getSystem());
|
CodeSystem cs = resolveCodeSystem(c.getSystem());
|
||||||
ValidationResult res = null;
|
ValidationResult res = null;
|
||||||
@ -145,7 +146,7 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe
|
|||||||
if (!res.isOk()) {
|
if (!res.isOk()) {
|
||||||
errors.add(res.getMessage());
|
errors.add(res.getMessage());
|
||||||
} else if (res.getMessage() != null) {
|
} else if (res.getMessage() != null) {
|
||||||
warnings.add(res.getMessage());
|
info.getWarnings().add(res.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,7 +154,7 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe
|
|||||||
if (valueset != null && options.getValueSetMode() != ValueSetMode.NO_MEMBERSHIP_CHECK) {
|
if (valueset != null && options.getValueSetMode() != ValueSetMode.NO_MEMBERSHIP_CHECK) {
|
||||||
Boolean result = false;
|
Boolean result = false;
|
||||||
for (Coding c : code.getCoding()) {
|
for (Coding c : code.getCoding()) {
|
||||||
Boolean ok = codeInValueSet(c.getSystem(), c.getCode(), warnings);
|
Boolean ok = codeInValueSet(c.getSystem(), c.getCode(), info);
|
||||||
if (ok == null && result == false) {
|
if (ok == null && result == false) {
|
||||||
result = null;
|
result = null;
|
||||||
} else if (ok) {
|
} else if (ok) {
|
||||||
@ -162,15 +163,15 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
warnings.add(0, context.formatMessage(I18nConstants.UNABLE_TO_CHECK_IF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_, valueset.getUrl()));
|
info.getWarnings().add(0, context.formatMessage(I18nConstants.UNABLE_TO_CHECK_IF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_, valueset.getUrl()));
|
||||||
} else if (!result) {
|
} else if (!result) {
|
||||||
errors.add(0, context.formatMessage(I18nConstants.NONE_OF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_, valueset.getUrl()));
|
errors.add(0, context.formatMessage(I18nConstants.NONE_OF_THE_PROVIDED_CODES_ARE_IN_THE_VALUE_SET_, valueset.getUrl()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (errors.size() > 0) {
|
if (errors.size() > 0) {
|
||||||
return new ValidationResult(IssueSeverity.ERROR, errors.toString());
|
return new ValidationResult(IssueSeverity.ERROR, errors.toString());
|
||||||
} else if (warnings.size() > 0) {
|
} else if (info.getWarnings().size() > 0) {
|
||||||
return new ValidationResult(IssueSeverity.WARNING, warnings.toString());
|
return new ValidationResult(IssueSeverity.WARNING, info.getWarnings().toString());
|
||||||
} else {
|
} else {
|
||||||
ConceptDefinitionComponent cd = new ConceptDefinitionComponent(foundCoding.getCode());
|
ConceptDefinitionComponent cd = new ConceptDefinitionComponent(foundCoding.getCode());
|
||||||
cd.setDisplay(foundCoding.getDisplay());
|
cd.setDisplay(foundCoding.getDisplay());
|
||||||
@ -251,19 +252,24 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe
|
|||||||
inInclude = checkInclude(code);
|
inInclude = checkInclude(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> warnings = new ArrayList<>();
|
ValidationProcessInfo info = new ValidationProcessInfo();
|
||||||
|
|
||||||
// then, if we have a value set, we check it's in the value set
|
// 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 (valueset != null && options.getValueSetMode() != ValueSetMode.NO_MEMBERSHIP_CHECK) {
|
||||||
if ((res==null || res.isOk())) {
|
if ((res==null || res.isOk())) {
|
||||||
Boolean ok = codeInValueSet(system, code.getCode(), warnings);
|
Boolean ok = codeInValueSet(system, code.getCode(), info);
|
||||||
if (ok == null || !ok) {
|
if (ok == null || !ok) {
|
||||||
if (res == null) {
|
if (res == null) {
|
||||||
res = new ValidationResult((IssueSeverity) null, null);
|
res = new ValidationResult((IssueSeverity) null, null);
|
||||||
}
|
}
|
||||||
if (!inExpansion && !inInclude) {
|
if (info.getErr() != null) {
|
||||||
if (warnings != null) {
|
res.setErrorClass(info.getErr());
|
||||||
res.setMessage("Not in value set "+valueset.getUrl()+" ("+warnings+")").setSeverity(IssueSeverity.ERROR);
|
}
|
||||||
|
if (ok == null) {
|
||||||
|
res.setMessage("Unable to check whether code is in value set "+valueset.getUrl()+": "+info.getWarnings()).setSeverity(IssueSeverity.WARNING);
|
||||||
|
} else if (!inExpansion && !inInclude) {
|
||||||
|
if (!info.getWarnings().isEmpty()) {
|
||||||
|
res.setMessage("Not in value set "+valueset.getUrl()+": "+info.getWarnings()).setSeverity(IssueSeverity.ERROR);
|
||||||
} else {
|
} else {
|
||||||
res.setMessage("Not in value set "+valueset.getUrl()).setSeverity(IssueSeverity.ERROR);
|
res.setMessage("Not in value set "+valueset.getUrl()).setSeverity(IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
@ -640,7 +646,7 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean codeInValueSet(String system, String code, List<String> warnings) throws FHIRException {
|
public Boolean codeInValueSet(String system, String code, ValidationProcessInfo info) throws FHIRException {
|
||||||
if (valueset == null) {
|
if (valueset == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -651,7 +657,7 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe
|
|||||||
} else if (valueset.hasCompose()) {
|
} else if (valueset.hasCompose()) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (ConceptSetComponent vsi : valueset.getCompose().getInclude()) {
|
for (ConceptSetComponent vsi : valueset.getCompose().getInclude()) {
|
||||||
Boolean ok = inComponent(vsi, i, system, code, valueset.getCompose().getInclude().size() == 1, warnings);
|
Boolean ok = inComponent(vsi, i, system, code, valueset.getCompose().getInclude().size() == 1, info);
|
||||||
i++;
|
i++;
|
||||||
if (ok == null && result == false) {
|
if (ok == null && result == false) {
|
||||||
result = null;
|
result = null;
|
||||||
@ -662,7 +668,7 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe
|
|||||||
}
|
}
|
||||||
i = valueset.getCompose().getInclude().size();
|
i = valueset.getCompose().getInclude().size();
|
||||||
for (ConceptSetComponent vsi : valueset.getCompose().getExclude()) {
|
for (ConceptSetComponent vsi : valueset.getCompose().getExclude()) {
|
||||||
Boolean nok = inComponent(vsi, i, system, code, valueset.getCompose().getInclude().size() == 1, warnings);
|
Boolean nok = inComponent(vsi, i, system, code, valueset.getCompose().getInclude().size() == 1, info);
|
||||||
i++;
|
i++;
|
||||||
if (nok == null && result == false) {
|
if (nok == null && result == false) {
|
||||||
result = null;
|
result = null;
|
||||||
@ -675,7 +681,7 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Boolean inComponent(ConceptSetComponent vsi, int vsiIndex, String system, String code, boolean only, List<String> warnings) throws FHIRException {
|
private Boolean inComponent(ConceptSetComponent vsi, int vsiIndex, String system, String code, boolean only, ValidationProcessInfo info) throws FHIRException {
|
||||||
boolean ok = true;
|
boolean ok = true;
|
||||||
|
|
||||||
if (vsi.hasValueSet()) {
|
if (vsi.hasValueSet()) {
|
||||||
@ -721,8 +727,9 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe
|
|||||||
vs.getCompose().addInclude(vsi);
|
vs.getCompose().addInclude(vsi);
|
||||||
ValidationResult res = context.validateCode(options.noClient(), new Coding(system, code, null), vs);
|
ValidationResult res = context.validateCode(options.noClient(), new Coding(system, code, null), vs);
|
||||||
if (res.getErrorClass() == TerminologyServiceErrorClass.UNKNOWN || res.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED || res.getErrorClass() == TerminologyServiceErrorClass.VALUESET_UNSUPPORTED) {
|
if (res.getErrorClass() == TerminologyServiceErrorClass.UNKNOWN || res.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED || res.getErrorClass() == TerminologyServiceErrorClass.VALUESET_UNSUPPORTED) {
|
||||||
if (warnings != null && res.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED) {
|
if (info != null && res.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED) {
|
||||||
warnings.add(context.formatMessage(I18nConstants.TERMINOLOGY_TX_SYSTEM_NOTKNOWN, system));
|
info.getWarnings().add(context.formatMessage(I18nConstants.TERMINOLOGY_TX_SYSTEM_NOTKNOWN, system));
|
||||||
|
info.setErr(TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -4503,7 +4503,18 @@ public class FHIRPathEngine {
|
|||||||
return makeBoolean(false);
|
return makeBoolean(false);
|
||||||
}
|
}
|
||||||
} else if (ns.equals("FHIR")) {
|
} else if (ns.equals("FHIR")) {
|
||||||
return makeBoolean(n.equals(focus.get(0).fhirType()));
|
if (n.equals(focus.get(0).fhirType())) {
|
||||||
|
return makeBoolean(true);
|
||||||
|
} else {
|
||||||
|
StructureDefinition sd = worker.fetchTypeDefinition(focus.get(0).fhirType());
|
||||||
|
while (sd != null) {
|
||||||
|
if (n.equals(sd.getType())) {
|
||||||
|
return makeBoolean(true);
|
||||||
|
}
|
||||||
|
sd = worker.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||||
|
}
|
||||||
|
return makeBoolean(false);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return makeBoolean(false);
|
return makeBoolean(false);
|
||||||
}
|
}
|
||||||
|
@ -103,6 +103,9 @@ public class GraphQLSchemaGenerator {
|
|||||||
if (sd.getKind() == StructureDefinitionKind.COMPLEXTYPE && sd.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
if (sd.getKind() == StructureDefinitionKind.COMPLEXTYPE && sd.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
|
||||||
tl.put(sd.getName(), sd);
|
tl.put(sd.getName(), sd);
|
||||||
}
|
}
|
||||||
|
if (sd.getKind() == StructureDefinitionKind.RESOURCE && sd.getDerivation() != TypeDerivationRule.CONSTRAINT && sd.getAbstract()) {
|
||||||
|
tl.put(sd.getName(), sd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
writer.write("# FHIR GraphQL Schema. Version " + version + "\r\n\r\n");
|
writer.write("# FHIR GraphQL Schema. Version " + version + "\r\n\r\n");
|
||||||
writer.write("# FHIR Defined Primitive types\r\n");
|
writer.write("# FHIR Defined Primitive types\r\n");
|
||||||
@ -290,16 +293,17 @@ public class GraphQLSchemaGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateType(Map<String, String> existingTypeNames, Writer writer, StructureDefinition sd, EnumSet<FHIROperationType> operations) throws IOException {
|
private void generateType(Map<String, String> existingTypeNames, Writer writer, StructureDefinition sd, EnumSet<FHIROperationType> operations) throws IOException {
|
||||||
if (sd.getAbstract()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (operations.contains(FHIROperationType.READ) || operations.contains(FHIROperationType.SEARCH)) {
|
if (operations.contains(FHIROperationType.READ) || operations.contains(FHIROperationType.SEARCH)) {
|
||||||
List<StringBuilder> list = new ArrayList<>();
|
List<StringBuilder> list = new ArrayList<>();
|
||||||
StringBuilder b = new StringBuilder();
|
StringBuilder b = new StringBuilder();
|
||||||
list.add(b);
|
list.add(b);
|
||||||
b.append("type ");
|
b.append("type ");
|
||||||
b.append(sd.getName());
|
b.append(sd.getName());
|
||||||
|
StructureDefinition sdp = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
|
||||||
|
if (sdp != null) {
|
||||||
|
b.append(" implements ");
|
||||||
|
b.append(sdp.getType());
|
||||||
|
}
|
||||||
b.append(" {\r\n");
|
b.append(" {\r\n");
|
||||||
ElementDefinition ed = sd.getSnapshot().getElementFirstRep();
|
ElementDefinition ed = sd.getSnapshot().getElementFirstRep();
|
||||||
generateProperties(existingTypeNames, list, b, sd.getName(), sd, ed, "type", "");
|
generateProperties(existingTypeNames, list, b, sd.getName(), sd, ed, "type", "");
|
||||||
@ -370,7 +374,13 @@ public class GraphQLSchemaGenerator {
|
|||||||
if (suffix)
|
if (suffix)
|
||||||
b.append(Utilities.capitalize(typeDetails.getWorkingCode()));
|
b.append(Utilities.capitalize(typeDetails.getWorkingCode()));
|
||||||
b.append(": ");
|
b.append(": ");
|
||||||
b.append(n);
|
if (!child.getMax().equals("1")) {
|
||||||
|
b.append("[");
|
||||||
|
b.append(n);
|
||||||
|
b.append("]");
|
||||||
|
} else {
|
||||||
|
b.append(n);
|
||||||
|
}
|
||||||
if (!child.getPath().endsWith(".id")) {
|
if (!child.getPath().endsWith(".id")) {
|
||||||
b.append(" _");
|
b.append(" _");
|
||||||
b.append(tail(child.getPath(), suffix));
|
b.append(tail(child.getPath(), suffix));
|
||||||
|
@ -205,6 +205,7 @@ public class ToolingExtensions {
|
|||||||
public static final String EXT_REND_MD = "http://hl7.org/fhir/StructureDefinition/rendering-markdown";
|
public static final String EXT_REND_MD = "http://hl7.org/fhir/StructureDefinition/rendering-markdown";
|
||||||
public static final String EXT_CAP_STMT_EXPECT = "http://hl7.org/fhir/StructureDefinition/capabilitystatement-expectation";
|
public static final String EXT_CAP_STMT_EXPECT = "http://hl7.org/fhir/StructureDefinition/capabilitystatement-expectation";
|
||||||
public static final String EXT_ED_HEIRARCHY = "http://hl7.org/fhir/StructureDefinition/elementdefinition-heirarchy";
|
public static final String EXT_ED_HEIRARCHY = "http://hl7.org/fhir/StructureDefinition/elementdefinition-heirarchy";
|
||||||
|
public static final String EXT_SD_DEPENDENCY = "http://hl7.org/fhir/StructureDefinition/structuredefinition-dependencies";
|
||||||
|
|
||||||
// in the tooling IG
|
// in the tooling IG
|
||||||
public static final String EXT_BINDING_ADDITIONAL = "http://hl7.org/fhir/tools/StructureDefinition/additional-binding";
|
public static final String EXT_BINDING_ADDITIONAL = "http://hl7.org/fhir/tools/StructureDefinition/additional-binding";
|
||||||
|
@ -611,6 +611,7 @@ public class I18nConstants {
|
|||||||
public static final String VALIDATION_VAL_PROFILE_SIGNPOST = "VALIDATION_VAL_PROFILE_SIGNPOST";
|
public static final String VALIDATION_VAL_PROFILE_SIGNPOST = "VALIDATION_VAL_PROFILE_SIGNPOST";
|
||||||
public static final String VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL = "VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL";
|
public static final String VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL = "VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL";
|
||||||
public static final String VALIDATION_VAL_PROFILE_SIGNPOST_META = "VALIDATION_VAL_PROFILE_SIGNPOST_META";
|
public static final String VALIDATION_VAL_PROFILE_SIGNPOST_META = "VALIDATION_VAL_PROFILE_SIGNPOST_META";
|
||||||
|
public static final String VALIDATION_VAL_PROFILE_SIGNPOST_DEP = "VALIDATION_VAL_PROFILE_SIGNPOST_DEP";
|
||||||
public static final String VALIDATION_VAL_PROFILE_SIGNPOST_BUNDLE_PARAM = "VALIDATION_VAL_PROFILE_SIGNPOST_BUNDLE_PARAM";
|
public static final String VALIDATION_VAL_PROFILE_SIGNPOST_BUNDLE_PARAM = "VALIDATION_VAL_PROFILE_SIGNPOST_BUNDLE_PARAM";
|
||||||
public static final String VALIDATION_VAL_PROFILE_SLICEORDER = "Validation_VAL_Profile_SliceOrder";
|
public static final String VALIDATION_VAL_PROFILE_SLICEORDER = "Validation_VAL_Profile_SliceOrder";
|
||||||
public static final String VALIDATION_VAL_PROFILE_OTHER_VERSION = "VALIDATION_VAL_PROFILE_OTHER_VERSION";
|
public static final String VALIDATION_VAL_PROFILE_OTHER_VERSION = "VALIDATION_VAL_PROFILE_OTHER_VERSION";
|
||||||
@ -622,6 +623,7 @@ public class I18nConstants {
|
|||||||
public static final String VALIDATION_VAL_PROFILE_WRONGTYPE = "Validation_VAL_Profile_WrongType";
|
public static final String VALIDATION_VAL_PROFILE_WRONGTYPE = "Validation_VAL_Profile_WrongType";
|
||||||
public static final String VALIDATION_VAL_PROFILE_WRONGTYPE2 = "Validation_VAL_Profile_WrongType2";
|
public static final String VALIDATION_VAL_PROFILE_WRONGTYPE2 = "Validation_VAL_Profile_WrongType2";
|
||||||
public static final String VALIDATION_VAL_UNKNOWN_PROFILE = "Validation_VAL_Unknown_Profile";
|
public static final String VALIDATION_VAL_UNKNOWN_PROFILE = "Validation_VAL_Unknown_Profile";
|
||||||
|
public static final String VALIDATION_VAL_PROFILE_DEPENDS_NOT_RESOLVED = "VALIDATION_VAL_PROFILE_DEPENDS_NOT_RESOLVED";
|
||||||
|
|
||||||
public static final String VALUESET_INCLUDE_INVALID_CONCEPT_CODE = "VALUESET_INCLUDE_INVALID_CONCEPT_CODE";
|
public static final String VALUESET_INCLUDE_INVALID_CONCEPT_CODE = "VALUESET_INCLUDE_INVALID_CONCEPT_CODE";
|
||||||
public static final String VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER = "VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER";
|
public static final String VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER = "VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER";
|
||||||
|
@ -236,6 +236,7 @@ Validation_VAL_Profile_Unknown = Profile reference ''{0}'' has not been checked
|
|||||||
VALIDATION_VAL_PROFILE_UNKNOWN_NOT_POLICY = Profile reference ''{0}'' has not been checked because it is unknown, and the validator is set to not fetch unknown profiles
|
VALIDATION_VAL_PROFILE_UNKNOWN_NOT_POLICY = Profile reference ''{0}'' has not been checked because it is unknown, and the validator is set to not fetch unknown profiles
|
||||||
VALIDATION_VAL_PROFILE_UNKNOWN_ERROR = Profile reference ''{0}'' has not been checked because it is unknown, and fetching it resulted in the error {1}
|
VALIDATION_VAL_PROFILE_UNKNOWN_ERROR = Profile reference ''{0}'' has not been checked because it is unknown, and fetching it resulted in the error {1}
|
||||||
Validation_VAL_Unknown_Profile = Unknown profile {0}
|
Validation_VAL_Unknown_Profile = Unknown profile {0}
|
||||||
|
VALIDATION_VAL_PROFILE_DEPENDS_NOT_RESOLVED = Profile {1} identifies {2} as a dependency (using the extension http://hl7.org/fhir/StructureDefinition/structuredefinition-dependencies), but this profile could not be found
|
||||||
XHTML_XHTML_Attribute_Illegal = Illegal attribute name in the XHTML (''{0}'' on ''{1}'')
|
XHTML_XHTML_Attribute_Illegal = Illegal attribute name in the XHTML (''{0}'' on ''{1}'')
|
||||||
XHTML_XHTML_Element_Illegal = Illegal element name in the XHTML (''{0}'')
|
XHTML_XHTML_Element_Illegal = Illegal element name in the XHTML (''{0}'')
|
||||||
XHTML_XHTML_NS_InValid = Wrong namespace on the XHTML (''{0}'', should be ''{1}'')
|
XHTML_XHTML_NS_InValid = Wrong namespace on the XHTML (''{0}'', should be ''{1}'')
|
||||||
@ -536,6 +537,7 @@ VALIDATION_VAL_GLOBAL_PROFILE_UNKNOWN = Global Profile reference ''{0}'' from IG
|
|||||||
VALIDATION_VAL_PROFILE_SIGNPOST_BASE = Validate resource against profile
|
VALIDATION_VAL_PROFILE_SIGNPOST_BASE = Validate resource against profile
|
||||||
VALIDATION_VAL_PROFILE_SIGNPOST = Validate resource against profile {0}
|
VALIDATION_VAL_PROFILE_SIGNPOST = Validate resource against profile {0}
|
||||||
VALIDATION_VAL_PROFILE_SIGNPOST_META = Validate resource against profile {0} (per meta)
|
VALIDATION_VAL_PROFILE_SIGNPOST_META = Validate resource against profile {0} (per meta)
|
||||||
|
VALIDATION_VAL_PROFILE_SIGNPOST_DEP = Validate resource against profile {0} (per http://hl7.org/fhir/StructureDefinition/structuredefinition-dependencies in {1})
|
||||||
VALIDATION_VAL_PROFILE_SIGNPOST_BUNDLE_PARAM = Validate resource against profile {0} - provided as bundle param
|
VALIDATION_VAL_PROFILE_SIGNPOST_BUNDLE_PARAM = Validate resource against profile {0} - provided as bundle param
|
||||||
VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL = Validate resource against profile {0} - a global profile in {1}
|
VALIDATION_VAL_PROFILE_SIGNPOST_GLOBAL = Validate resource against profile {0} - a global profile in {1}
|
||||||
ERROR_GENERATING_SNAPSHOT = Error generating Snapshot: {0} (this usually arises from a problem in the differential)
|
ERROR_GENERATING_SNAPSHOT = Error generating Snapshot: {0} (this usually arises from a problem in the differential)
|
||||||
|
@ -818,15 +818,31 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||||||
setParents(element);
|
setParents(element);
|
||||||
|
|
||||||
long t = System.nanoTime();
|
long t = System.nanoTime();
|
||||||
|
NodeStack stack = new NodeStack(context, path, element, validationLanguage);
|
||||||
if (profiles == null || profiles.isEmpty()) {
|
if (profiles == null || profiles.isEmpty()) {
|
||||||
validateResource(new ValidatorHostContext(appContext, element), errors, element, element, null, resourceIdRule, new NodeStack(context, path, element, validationLanguage).resetIds(), null);
|
validateResource(new ValidatorHostContext(appContext, element), errors, element, element, null, resourceIdRule, stack.resetIds(), null);
|
||||||
} else {
|
} else {
|
||||||
|
int i = 0;
|
||||||
|
while (i < profiles.size()) {
|
||||||
|
StructureDefinition sd = profiles.get(i);
|
||||||
|
if (sd.hasExtension(ToolingExtensions.EXT_SD_DEPENDENCY)) {
|
||||||
|
for (Extension ext : sd.getExtensionsByUrl(ToolingExtensions.EXT_SD_DEPENDENCY)) {
|
||||||
|
StructureDefinition dep = context.fetchResource( StructureDefinition.class, ext.getValue().primitiveValue());
|
||||||
|
if (dep == null) {
|
||||||
|
warning(errors, IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_DEPENDS_NOT_RESOLVED, ext.getValue().primitiveValue(), sd.getUrl());
|
||||||
|
} else if (!profiles.contains(dep)) {
|
||||||
|
profiles.add(dep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
for (StructureDefinition defn : profiles) {
|
for (StructureDefinition defn : profiles) {
|
||||||
validateResource(new ValidatorHostContext(appContext, element), errors, element, element, defn, resourceIdRule, new NodeStack(context, path, element, validationLanguage).resetIds(), null);
|
validateResource(new ValidatorHostContext(appContext, element), errors, element, element, defn, resourceIdRule, stack.resetIds(), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hintAboutNonMustSupport) {
|
if (hintAboutNonMustSupport) {
|
||||||
checkElementUsage(errors, element, new NodeStack(context, path, element, validationLanguage));
|
checkElementUsage(errors, element, stack);
|
||||||
}
|
}
|
||||||
errors.removeAll(messagesToRemove);
|
errors.removeAll(messagesToRemove);
|
||||||
timeTracker.overall(t);
|
timeTracker.overall(t);
|
||||||
@ -1217,7 +1233,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||||||
checkBindings(errors, path, element, stack, valueset, nextCoding);
|
checkBindings(errors, path, element, stack, valueset, nextCoding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
timeTracker.tx(t, "vc "+DataRenderer.display(context, cc));
|
timeTracker.tx(t, "vc "+cc.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -1692,6 +1708,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||||||
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_14, describeReference(binding.getValueSet(), valueset), getErrorMessage(vr.getMessage()), theSystem+"#"+theCode);
|
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_14, describeReference(binding.getValueSet(), valueset), getErrorMessage(vr.getMessage()), theSystem+"#"+theCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (vr != null && vr.getMessage() != null) {
|
||||||
|
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, vr.getMessage());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (STACK_TRACE) e.printStackTrace();
|
if (STACK_TRACE) e.printStackTrace();
|
||||||
@ -3713,7 +3731,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getErrorMessage(String message) {
|
private String getErrorMessage(String message) {
|
||||||
return message != null ? " (error message = " + message + ")" : "";
|
return message != null ? " (error message = " + message + ")" : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSuppressLoincSnomedMessages() {
|
public boolean isSuppressLoincSnomedMessages() {
|
||||||
@ -4517,28 +4535,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||||||
} else if (!fetcher.fetchesCanonicalResource(this, profile.primitiveValue())) {
|
} else if (!fetcher.fetchesCanonicalResource(this, profile.primitiveValue())) {
|
||||||
warning(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath() + ".meta.profile[" + i + "]", false, I18nConstants.VALIDATION_VAL_PROFILE_UNKNOWN_NOT_POLICY, profile.primitiveValue());
|
warning(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath() + ".meta.profile[" + i + "]", false, I18nConstants.VALIDATION_VAL_PROFILE_UNKNOWN_NOT_POLICY, profile.primitiveValue());
|
||||||
} else {
|
} else {
|
||||||
sd = null;
|
sd = lookupProfileReference(errors, element, stack, i, profile, sd);
|
||||||
String url = profile.primitiveValue();
|
|
||||||
CanonicalResourceLookupResult cr = crLookups.get(url);
|
|
||||||
if (cr != null) {
|
|
||||||
if (cr.error != null) {
|
|
||||||
warning(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath() + ".meta.profile[" + i + "]", false, I18nConstants.VALIDATION_VAL_PROFILE_UNKNOWN_ERROR, url, cr.error);
|
|
||||||
} else {
|
|
||||||
sd = (StructureDefinition) cr.resource;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
sd = (StructureDefinition) fetcher.fetchCanonicalResource(this, url);
|
|
||||||
crLookups.put(url, new CanonicalResourceLookupResult(sd));
|
|
||||||
} catch (Exception e) {
|
|
||||||
if (STACK_TRACE) { e.printStackTrace(); }
|
|
||||||
crLookups.put(url, new CanonicalResourceLookupResult(e.getMessage()));
|
|
||||||
warning(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath() + ".meta.profile[" + i + "]", false, I18nConstants.VALIDATION_VAL_PROFILE_UNKNOWN_ERROR, profile.primitiveValue(), e.getMessage());
|
|
||||||
}
|
|
||||||
if (sd != null) {
|
|
||||||
context.cacheResource(sd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sd != null) {
|
if (sd != null) {
|
||||||
@ -4553,6 +4550,27 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||||||
if (pctOwned) {
|
if (pctOwned) {
|
||||||
pct.done();
|
pct.done();
|
||||||
}
|
}
|
||||||
|
if (sd.hasExtension(ToolingExtensions.EXT_SD_DEPENDENCY)) {
|
||||||
|
for (Extension ext : sd.getExtensionsByUrl(ToolingExtensions.EXT_SD_DEPENDENCY)) {
|
||||||
|
StructureDefinition sdi = context.fetchResource(StructureDefinition.class, ext.getValue().primitiveValue());
|
||||||
|
if (sdi == null) {
|
||||||
|
warning(errors, IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath() + ".meta.profile[" + i + "]", false, I18nConstants.VALIDATION_VAL_PROFILE_DEPENDS_NOT_RESOLVED, ext.getValue().primitiveValue(), sd.getUrl());
|
||||||
|
} else {
|
||||||
|
if (crumbTrails) {
|
||||||
|
element.addMessage(signpost(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST_DEP, sdi.getUrl(), sd.getUrl()));
|
||||||
|
}
|
||||||
|
stack.resetIds();
|
||||||
|
if (pctOwned) {
|
||||||
|
pct = new PercentageTracker(resource.countDescendents(), resource.fhirType(), sdi.getUrl(), logProgress);
|
||||||
|
}
|
||||||
|
startInner(hostContext, errors, resource, element, sdi, stack, false, pct);
|
||||||
|
if (pctOwned) {
|
||||||
|
pct.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4583,6 +4601,32 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||||||
// System.out.println("start: "+(System.currentTimeMillis()-st)+" ("+resource.fhirType()+")");
|
// System.out.println("start: "+(System.currentTimeMillis()-st)+" ("+resource.fhirType()+")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private StructureDefinition lookupProfileReference(List<ValidationMessage> errors, Element element, NodeStack stack,
|
||||||
|
int i, Element profile, StructureDefinition sd) {
|
||||||
|
String url = profile.primitiveValue();
|
||||||
|
CanonicalResourceLookupResult cr = crLookups.get(url);
|
||||||
|
if (cr != null) {
|
||||||
|
if (cr.error != null) {
|
||||||
|
warning(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath() + ".meta.profile[" + i + "]", false, I18nConstants.VALIDATION_VAL_PROFILE_UNKNOWN_ERROR, url, cr.error);
|
||||||
|
} else {
|
||||||
|
sd = (StructureDefinition) cr.resource;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
sd = (StructureDefinition) fetcher.fetchCanonicalResource(this, url);
|
||||||
|
crLookups.put(url, new CanonicalResourceLookupResult(sd));
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (STACK_TRACE) { e.printStackTrace(); }
|
||||||
|
crLookups.put(url, new CanonicalResourceLookupResult(e.getMessage()));
|
||||||
|
warning(errors, IssueType.STRUCTURE, element.line(), element.col(), stack.getLiteralPath() + ".meta.profile[" + i + "]", false, I18nConstants.VALIDATION_VAL_PROFILE_UNKNOWN_ERROR, profile.primitiveValue(), e.getMessage());
|
||||||
|
}
|
||||||
|
if (sd != null) {
|
||||||
|
context.cacheResource(sd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sd;
|
||||||
|
}
|
||||||
|
|
||||||
// private void plog(String msg) {
|
// private void plog(String msg) {
|
||||||
// long n = System.currentTimeMillis();
|
// long n = System.currentTimeMillis();
|
||||||
// String elapsed = Utilities.padLeft(Long.toString(n-start), ' ', 5);
|
// String elapsed = Utilities.padLeft(Long.toString(n-start), ' ', 5);
|
||||||
@ -5720,7 +5764,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||||||
boolean ok;
|
boolean ok;
|
||||||
try {
|
try {
|
||||||
long t = System.nanoTime();
|
long t = System.nanoTime();
|
||||||
ok = fpe.evaluateToBoolean(hostContext, resource, hostContext.getRootResource(), element, n);
|
ok = fpe.evaluateToBoolean(hostContext, resource, hostContext.getRootResource(), element, n);
|
||||||
timeTracker.fpe(t);
|
timeTracker.fpe(t);
|
||||||
msg = fpe.forLog();
|
msg = fpe.forLog();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
|
@ -45,6 +45,13 @@ public class FHIRPathExpressionFixer {
|
|||||||
return ("name.exists() implies name.matches('[A-Z]([A-Za-z0-9_]){0,254}')");
|
return ("name.exists() implies name.matches('[A-Z]([A-Za-z0-9_]){0,254}')");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// R5 ballot
|
||||||
|
if (expr.equals("url.matches('([^|#])*')")) {
|
||||||
|
return ("$this.matches('([^|#])*')");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// clarification in FHIRPath spec
|
// clarification in FHIRPath spec
|
||||||
if ("eld-19".equals(key)) {
|
if ("eld-19".equals(key)) {
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
package org.hl7.fhir.r5.test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hl7.fhir.r5.elementmodel.ParserBase.ValidationPolicy;
|
||||||
|
import org.hl7.fhir.r5.model.CodeSystem;
|
||||||
|
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||||
|
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
|
||||||
|
public class GeneralTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testXMLParse() throws IOException {
|
||||||
|
System.out.println(System.getProperty("java.vm.name"));
|
||||||
|
InputStream stream = TestingUtilities.loadTestResourceStream("validator",
|
||||||
|
"xml_v10.xml");
|
||||||
|
org.hl7.fhir.r5.elementmodel.XmlParser xp = new org.hl7.fhir.r5.elementmodel.XmlParser(TestingUtilities.getSharedWorkerContext());
|
||||||
|
xp.setAllowXsiLocation(true);
|
||||||
|
List<ValidationMessage> errorList = new ArrayList<>();
|
||||||
|
xp.setupValidation(ValidationPolicy.EVERYTHING, errorList);
|
||||||
|
try {
|
||||||
|
Object resource = xp.parse(stream);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
for (ValidationMessage message : errorList) {
|
||||||
|
System.out.println(message.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -419,7 +419,7 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
|
|||||||
|
|
||||||
private void checkOutcomes(List<ValidationMessage> errors, JsonObject focus, String profile, String name) throws IOException {
|
private void checkOutcomes(List<ValidationMessage> errors, JsonObject focus, String profile, String name) throws IOException {
|
||||||
JsonObject java = focus.getAsJsonObject("java");
|
JsonObject java = focus.getAsJsonObject("java");
|
||||||
OperationOutcome goal = (OperationOutcome) new JsonParser().parse(java.getAsJsonObject("outcome"));
|
OperationOutcome goal = java.has("outcome") ? (OperationOutcome) new JsonParser().parse(java.getAsJsonObject("outcome")) : new OperationOutcome();
|
||||||
OperationOutcome actual = OperationOutcomeUtilities.createOutcomeSimple(errors);
|
OperationOutcome actual = OperationOutcomeUtilities.createOutcomeSimple(errors);
|
||||||
actual.setText(null);
|
actual.setText(null);
|
||||||
String json = new JsonParser().setOutputStyle(OutputStyle.PRETTY).composeString(actual);
|
String json = new JsonParser().setOutputStyle(OutputStyle.PRETTY).composeString(actual);
|
||||||
@ -521,8 +521,10 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
|
|||||||
if (java.has("outcome")) {
|
if (java.has("outcome")) {
|
||||||
java.remove("outcome");
|
java.remove("outcome");
|
||||||
}
|
}
|
||||||
JsonObject oj = JsonTrackingParser.parse(json, null);
|
if (actual.hasIssue()) {
|
||||||
java.add("outcome", oj);
|
JsonObject oj = JsonTrackingParser.parse(json, null);
|
||||||
|
java.add("outcome", oj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user