Merge pull request #1423 from hapifhir/2023-09-gg-shlinks-validation
Add SHLinks validation
This commit is contained in:
commit
345b2ac83e
|
@ -172,12 +172,20 @@
|
||||||
<version>4.12</version>
|
<version>4.12</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.nimbusds</groupId>
|
||||||
|
<artifactId>nimbus-jose-jwt</artifactId>
|
||||||
|
<version>9.30.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.sourceforge.plantuml</groupId>
|
<groupId>net.sourceforge.plantuml</groupId>
|
||||||
<artifactId>plantuml-mit</artifactId>
|
<artifactId>plantuml-mit</artifactId>
|
||||||
<version>1.2023.9</version>
|
<version>1.2023.9</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.hl7.fhir.r5.elementmodel;
|
package org.hl7.fhir.r5.elementmodel;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
@ -44,10 +45,14 @@ public class FmlParser extends ParserBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<NamedElement> parse(InputStream stream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
public List<NamedElement> parse(InputStream inStream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
||||||
|
byte[] content = TextFile.streamToBytes(inStream);
|
||||||
|
ByteArrayInputStream stream = new ByteArrayInputStream(content);
|
||||||
String text = TextFile.streamToString(stream);
|
String text = TextFile.streamToString(stream);
|
||||||
List<NamedElement> result = new ArrayList<>();
|
List<NamedElement> result = new ArrayList<>();
|
||||||
result.add(new NamedElement(null, parse(text)));
|
NamedElement ctxt = new NamedElement("focus", "fml", content);
|
||||||
|
ctxt.setElement(parse(ctxt.getErrors(), text));
|
||||||
|
result.add(ctxt);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +62,7 @@ public class FmlParser extends ParserBase {
|
||||||
throw new Error("Not done yet");
|
throw new Error("Not done yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Element parse(String text) throws FHIRException {
|
public Element parse(List<ValidationMessage> errors, String text) throws FHIRException {
|
||||||
FHIRLexer lexer = new FHIRLexer(text, "source", true, true);
|
FHIRLexer lexer = new FHIRLexer(text, "source", true, true);
|
||||||
if (lexer.done())
|
if (lexer.done())
|
||||||
throw lexer.error("Map Input cannot be empty");
|
throw lexer.error("Map Input cannot be empty");
|
||||||
|
@ -112,13 +117,13 @@ public class FmlParser extends ParserBase {
|
||||||
if (policy == ValidationPolicy.NONE) {
|
if (policy == ValidationPolicy.NONE) {
|
||||||
throw e;
|
throw e;
|
||||||
} else {
|
} else {
|
||||||
logError("2023-02-24", e.getLocation().getLine(), e.getLocation().getColumn(), "??", IssueType.INVALID, e.getMessage(), IssueSeverity.FATAL);
|
logError(errors, "2023-02-24", e.getLocation().getLine(), e.getLocation().getColumn(), "??", IssueType.INVALID, e.getMessage(), IssueSeverity.FATAL);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (policy == ValidationPolicy.NONE) {
|
if (policy == ValidationPolicy.NONE) {
|
||||||
throw e;
|
throw e;
|
||||||
} else {
|
} else {
|
||||||
logError("2023-02-24", -1, -1, "?", IssueType.INVALID, e.getMessage(), IssueSeverity.FATAL);
|
logError(errors, "2023-02-24", -1, -1, "?", IssueType.INVALID, e.getMessage(), IssueSeverity.FATAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.setIgnorePropertyOrder(true);
|
result.setIgnorePropertyOrder(true);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package org.hl7.fhir.r5.elementmodel;
|
package org.hl7.fhir.r5.elementmodel;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2011+, HL7, Inc.
|
Copyright (c) 2011+, HL7, Inc.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
@ -50,6 +52,7 @@ import org.hl7.fhir.r5.conformance.profile.ProfileUtilities;
|
||||||
import org.hl7.fhir.r5.context.ContextUtilities;
|
import org.hl7.fhir.r5.context.ContextUtilities;
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
import org.hl7.fhir.r5.elementmodel.Element.SpecialElement;
|
import org.hl7.fhir.r5.elementmodel.Element.SpecialElement;
|
||||||
|
import org.hl7.fhir.r5.elementmodel.ParserBase.NamedElement;
|
||||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||||
import org.hl7.fhir.r5.formats.JsonCreator;
|
import org.hl7.fhir.r5.formats.JsonCreator;
|
||||||
import org.hl7.fhir.r5.formats.JsonCreatorCanonical;
|
import org.hl7.fhir.r5.formats.JsonCreatorCanonical;
|
||||||
|
@ -95,63 +98,66 @@ public class JsonParser extends ParserBase {
|
||||||
|
|
||||||
this.profileUtilities = new ProfileUtilities(this.context, null, null, new FHIRPathEngine(context));
|
this.profileUtilities = new ProfileUtilities(this.context, null, null, new FHIRPathEngine(context));
|
||||||
}
|
}
|
||||||
|
//
|
||||||
public Element parse(String source, String type) throws Exception {
|
// public Element parse(String source, String type) throws Exception {
|
||||||
JsonObject obj = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(source, true, true);
|
// JsonObject obj = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(source, true, true);
|
||||||
String path = "/"+type;
|
// String path = "/"+type;
|
||||||
StructureDefinition sd = getDefinition(-1, -1, type);
|
// StructureDefinition sd = getDefinition(-1, -1, type);
|
||||||
if (sd == null)
|
// if (sd == null)
|
||||||
return null;
|
// return null;
|
||||||
|
//
|
||||||
Element result = new Element(type, new Property(context, sd.getSnapshot().getElement().get(0), sd, this.profileUtilities));
|
// Element result = new Element(type, new Property(context, sd.getSnapshot().getElement().get(0), sd, this.profileUtilities));
|
||||||
result.setPath(type);
|
// result.setPath(type);
|
||||||
checkObject(obj, result, path);
|
// checkObject(obj, result, path);
|
||||||
result.setType(type);
|
// result.setType(type);
|
||||||
parseChildren(path, obj, result, true);
|
// parseChildren(path, obj, result, true);
|
||||||
result.numberChildren();
|
// result.numberChildren();
|
||||||
return result;
|
// return result;
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<NamedElement> parse(InputStream stream) throws IOException, FHIRException {
|
public List<NamedElement> parse(InputStream inStream) throws IOException, FHIRException {
|
||||||
|
byte[] content = TextFile.streamToBytes(inStream);
|
||||||
|
NamedElement ctxt = new NamedElement("focus", "json", content);
|
||||||
|
|
||||||
|
ByteArrayInputStream stream = new ByteArrayInputStream(content);
|
||||||
|
|
||||||
// if we're parsing at this point, then we're going to use the custom parser
|
// if we're parsing at this point, then we're going to use the custom parser
|
||||||
List<NamedElement> res = new ArrayList<>();
|
|
||||||
String source = TextFile.streamToString(stream);
|
String source = TextFile.streamToString(stream);
|
||||||
JsonObject obj = null;
|
JsonObject obj = null;
|
||||||
if (policy == ValidationPolicy.EVERYTHING) {
|
if (policy == ValidationPolicy.EVERYTHING) {
|
||||||
try {
|
try {
|
||||||
obj = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(source, true, true);
|
obj = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(source, true, true);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, -1, -1,context.formatMessage(I18nConstants.DOCUMENT), IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_, e.getMessage()), IssueSeverity.FATAL);
|
logError(ctxt.getErrors(), ValidationMessage.NO_RULE_DATE, -1, -1,context.formatMessage(I18nConstants.DOCUMENT), IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_, e.getMessage()), IssueSeverity.FATAL);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
obj = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(source, true, true);
|
obj = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(source, true, true);
|
||||||
}
|
}
|
||||||
Element e = parse(obj);
|
ctxt.setElement(parse(ctxt.getErrors(), obj));
|
||||||
if (e != null) {
|
|
||||||
res.add(new NamedElement(null, e));
|
List<NamedElement> res = new ArrayList<>();
|
||||||
}
|
res.add(ctxt);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Element parse(JsonObject object) throws FHIRException {
|
public Element parse(List<ValidationMessage> errors, JsonObject object) throws FHIRException {
|
||||||
StructureDefinition sd = getLogical();
|
StructureDefinition sd = getLogical();
|
||||||
String name;
|
String name;
|
||||||
String path;
|
String path;
|
||||||
if (sd == null) {
|
if (sd == null) {
|
||||||
JsonElement rt = object.get("resourceType");
|
JsonElement rt = object.get("resourceType");
|
||||||
if (rt == null) {
|
if (rt == null) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(object), col(object), "$", IssueType.INVALID, context.formatMessage(I18nConstants.UNABLE_TO_FIND_RESOURCETYPE_PROPERTY), IssueSeverity.FATAL);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(object), col(object), "$", IssueType.INVALID, context.formatMessage(I18nConstants.UNABLE_TO_FIND_RESOURCETYPE_PROPERTY), IssueSeverity.FATAL);
|
||||||
return null;
|
return null;
|
||||||
} else if (!rt.isJsonString()) {
|
} else if (!rt.isJsonString()) {
|
||||||
logError("2022-11-26", line(object), col(object), "$", IssueType.INVALID, context.formatMessage(I18nConstants.RESOURCETYPE_PROPERTY_WRONG_TYPE, rt.type().toName()), IssueSeverity.FATAL);
|
logError(errors, "2022-11-26", line(object), col(object), "$", IssueType.INVALID, context.formatMessage(I18nConstants.RESOURCETYPE_PROPERTY_WRONG_TYPE, rt.type().toName()), IssueSeverity.FATAL);
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
name = rt.asString();
|
name = rt.asString();
|
||||||
|
|
||||||
sd = getDefinition(line(object), col(object), name);
|
sd = getDefinition(errors, line(object), col(object), name);
|
||||||
if (sd == null) {
|
if (sd == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -162,25 +168,25 @@ public class JsonParser extends ParserBase {
|
||||||
path = sd.getTypeTail();
|
path = sd.getTypeTail();
|
||||||
}
|
}
|
||||||
baseElement = new Element(name, new Property(context, sd.getSnapshot().getElement().get(0), sd, this.profileUtilities));
|
baseElement = new Element(name, new Property(context, sd.getSnapshot().getElement().get(0), sd, this.profileUtilities));
|
||||||
checkObject(object, baseElement, path);
|
checkObject(errors, object, baseElement, path);
|
||||||
baseElement.markLocation(line(object), col(object));
|
baseElement.markLocation(line(object), col(object));
|
||||||
baseElement.setType(name);
|
baseElement.setType(name);
|
||||||
baseElement.setPath(baseElement.fhirTypeRoot());
|
baseElement.setPath(baseElement.fhirTypeRoot());
|
||||||
parseChildren(path, object, baseElement, true);
|
parseChildren(errors, path, object, baseElement, true);
|
||||||
baseElement.numberChildren();
|
baseElement.numberChildren();
|
||||||
return baseElement;
|
return baseElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkObject(JsonObject object, Element b, String path) {
|
private void checkObject(List<ValidationMessage> errors, JsonObject object, Element b, String path) {
|
||||||
checkComments(object, b, path);
|
checkComments(errors, object, b, path);
|
||||||
if (policy == ValidationPolicy.EVERYTHING) {
|
if (policy == ValidationPolicy.EVERYTHING) {
|
||||||
if (object.getProperties().size() == 0) {
|
if (object.getProperties().size() == 0) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(object), col(object), path, IssueType.INVALID, context.formatMessage(I18nConstants.OBJECT_MUST_HAVE_SOME_CONTENT), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(object), col(object), path, IssueType.INVALID, context.formatMessage(I18nConstants.OBJECT_MUST_HAVE_SOME_CONTENT), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkComments(JsonElement element, Element b, String path) throws FHIRFormatError {
|
private void checkComments(List<ValidationMessage> errors, JsonElement element, Element b, String path) throws FHIRFormatError {
|
||||||
if (element != null && element.hasComments()) {
|
if (element != null && element.hasComments()) {
|
||||||
if (allowComments) {
|
if (allowComments) {
|
||||||
for (JsonComment c : element.getComments()) {
|
for (JsonComment c : element.getComments()) {
|
||||||
|
@ -188,13 +194,13 @@ public class JsonParser extends ParserBase {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (JsonComment c : element.getComments()) {
|
for (JsonComment c : element.getComments()) {
|
||||||
logError("2022-11-26", c.getStart().getLine(), c.getStart().getCol(), path, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_COMMENTS_NOT_ALLOWED), IssueSeverity.ERROR);
|
logError(errors, "2022-11-26", c.getStart().getLine(), c.getStart().getCol(), path, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_COMMENTS_NOT_ALLOWED), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseChildren(String path, JsonObject object, Element element, boolean hasResourceType) throws FHIRException {
|
private void parseChildren(List<ValidationMessage> errors, String path, JsonObject object, Element element, boolean hasResourceType) throws FHIRException {
|
||||||
reapComments(object, element);
|
reapComments(object, element);
|
||||||
List<Property> properties = element.getProperty().getChildProperties(element.getName(), null);
|
List<Property> properties = element.getProperty().getChildProperties(element.getName(), null);
|
||||||
Set<String> processed = new HashSet<String>();
|
Set<String> processed = new HashSet<String>();
|
||||||
|
@ -205,13 +211,13 @@ public class JsonParser extends ParserBase {
|
||||||
Set<String> unique = new HashSet<>();
|
Set<String> unique = new HashSet<>();
|
||||||
for (JsonProperty p : object.getProperties()) {
|
for (JsonProperty p : object.getProperties()) {
|
||||||
if (p.isUnquotedName()) {
|
if (p.isUnquotedName()) {
|
||||||
logError("2022-11-26", line(p.getValue()), col(p.getValue()), path, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_PROPERTY_NO_QUOTES, p.getName()), IssueSeverity.ERROR);
|
logError(errors, "2022-11-26", line(p.getValue()), col(p.getValue()), path, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_PROPERTY_NO_QUOTES, p.getName()), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
if (p.isNoComma()) {
|
if (p.isNoComma()) {
|
||||||
logError("2022-11-26", line(p.getValue()), col(p.getValue()), path, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_COMMA_MISSING), IssueSeverity.ERROR);
|
logError(errors, "2022-11-26", line(p.getValue()), col(p.getValue()), path, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_COMMA_MISSING), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
if (unique.contains(p.getName())) {
|
if (unique.contains(p.getName())) {
|
||||||
logError("2022-11-26", line(p.getValue()), col(p.getValue()), path, IssueType.INVALID, context.formatMessage(I18nConstants.DUPLICATE_JSON_PROPERTY, p.getName()), IssueSeverity.ERROR);
|
logError(errors, "2022-11-26", line(p.getValue()), col(p.getValue()), path, IssueType.INVALID, context.formatMessage(I18nConstants.DUPLICATE_JSON_PROPERTY, p.getName()), IssueSeverity.ERROR);
|
||||||
} else {
|
} else {
|
||||||
unique.add(p.getName());
|
unique.add(p.getName());
|
||||||
recognisedChildren.put(p.getName(), p);
|
recognisedChildren.put(p.getName(), p);
|
||||||
|
@ -221,7 +227,7 @@ public class JsonParser extends ParserBase {
|
||||||
// note that we do not trouble ourselves to maintain the wire format order here - we don't even know what it was anyway
|
// note that we do not trouble ourselves to maintain the wire format order here - we don't even know what it was anyway
|
||||||
// first pass: process the properties
|
// first pass: process the properties
|
||||||
for (Property property : properties) {
|
for (Property property : properties) {
|
||||||
parseChildItem(path, recognisedChildren, element, processed, property);
|
parseChildItem(errors, path, recognisedChildren, element, processed, property);
|
||||||
}
|
}
|
||||||
|
|
||||||
// second pass: check for things not processed
|
// second pass: check for things not processed
|
||||||
|
@ -231,32 +237,32 @@ public class JsonParser extends ParserBase {
|
||||||
StructureDefinition sd = element.getProperty().isLogical() ? new ContextUtilities(context).fetchByJsonName(e.getKey()) : null;
|
StructureDefinition sd = element.getProperty().isLogical() ? new ContextUtilities(context).fetchByJsonName(e.getKey()) : null;
|
||||||
if (sd != null) {
|
if (sd != null) {
|
||||||
Property property = new Property(context, sd.getSnapshot().getElementFirstRep(), sd, element.getProperty().getUtils());
|
Property property = new Property(context, sd.getSnapshot().getElementFirstRep(), sd, element.getProperty().getUtils());
|
||||||
parseChildItem(path, recognisedChildren, element, null, property);
|
parseChildItem(errors, path, recognisedChildren, element, null, property);
|
||||||
} else if ("fhir_comments".equals(e.getKey()) && (VersionUtilities.isR2BVer(context.getVersion()) || VersionUtilities.isR2Ver(context.getVersion()))) {
|
} else if ("fhir_comments".equals(e.getKey()) && (VersionUtilities.isR2BVer(context.getVersion()) || VersionUtilities.isR2Ver(context.getVersion()))) {
|
||||||
if (!e.getValue().getValue().isJsonArray()) {
|
if (!e.getValue().getValue().isJsonArray()) {
|
||||||
logError("2022-12-17", line(e.getValue().getValue()), col(e.getValue().getValue()), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.ILLEGAL_COMMENT_TYPE, e.getValue().getValue().type().toName()), IssueSeverity.ERROR);
|
logError(errors, "2022-12-17", line(e.getValue().getValue()), col(e.getValue().getValue()), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.ILLEGAL_COMMENT_TYPE, e.getValue().getValue().type().toName()), IssueSeverity.ERROR);
|
||||||
} else {
|
} else {
|
||||||
for (JsonElement c : e.getValue().getValue().asJsonArray()) {
|
for (JsonElement c : e.getValue().getValue().asJsonArray()) {
|
||||||
if (!c.isJsonString()) {
|
if (!c.isJsonString()) {
|
||||||
logError("2022-12-17", line(e.getValue().getValue()), col(e.getValue().getValue()), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.ILLEGAL_COMMENT_TYPE, c.type().toName()), IssueSeverity.ERROR);
|
logError(errors, "2022-12-17", line(e.getValue().getValue()), col(e.getValue().getValue()), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.ILLEGAL_COMMENT_TYPE, c.type().toName()), IssueSeverity.ERROR);
|
||||||
} else {
|
} else {
|
||||||
element.getComments().add(c.asString());
|
element.getComments().add(c.asString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(e.getValue().getValue()), col(e.getValue().getValue()), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.UNRECOGNISED_PROPERTY_, e.getKey()), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(e.getValue().getValue()), col(e.getValue().getValue()), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.UNRECOGNISED_PROPERTY_, e.getKey()), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (object.isExtraComma()) {
|
if (object.isExtraComma()) {
|
||||||
logError("2022-11-26", object.getEnd().getLine(), object.getEnd().getCol(), path, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_COMMA_EXTRA, "Object"), IssueSeverity.ERROR);
|
logError(errors, "2022-11-26", object.getEnd().getLine(), object.getEnd().getCol(), path, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_COMMA_EXTRA, "Object"), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void parseChildItem(String path, Map<String, JsonProperty> children, Element context, Set<String> processed, Property property) {
|
public void parseChildItem(List<ValidationMessage> errors, String path, Map<String, JsonProperty> children, Element context, Set<String> processed, Property property) {
|
||||||
if (property.isChoice() || property.getDefinition().getPath().endsWith("data[x]")) {
|
if (property.isChoice() || property.getDefinition().getPath().endsWith("data[x]")) {
|
||||||
if (property.isJsonPrimitiveChoice()) {
|
if (property.isJsonPrimitiveChoice()) {
|
||||||
if (children.containsKey(property.getJsonName())) {
|
if (children.containsKey(property.getJsonName())) {
|
||||||
|
@ -264,30 +270,30 @@ public class JsonParser extends ParserBase {
|
||||||
if (processed != null) processed.add(property.getJsonName());
|
if (processed != null) processed.add(property.getJsonName());
|
||||||
String type = getTypeFromJsonType(je);
|
String type = getTypeFromJsonType(je);
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(je), col(je), path, IssueType.STRUCTURE, this.context.formatMessage(I18nConstants.UNRECOGNISED_PROPERTY_TYPE, describeType(je), property.getName(), property.typeSummary()), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(je), col(je), path, IssueType.STRUCTURE, this.context.formatMessage(I18nConstants.UNRECOGNISED_PROPERTY_TYPE, describeType(je), property.getName(), property.typeSummary()), IssueSeverity.ERROR);
|
||||||
} else if (property.hasType(type)) {
|
} else if (property.hasType(type)) {
|
||||||
Property np = new Property(property.getContext(), property.getDefinition(), property.getStructure(), property.getUtils(), type);
|
Property np = new Property(property.getContext(), property.getDefinition(), property.getStructure(), property.getUtils(), type);
|
||||||
parseChildPrimitive(children, context, processed, np, path, property.getName(), false);
|
parseChildPrimitive(errors, children, context, processed, np, path, property.getName(), false);
|
||||||
} else {
|
} else {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(je), col(je), path, IssueType.STRUCTURE, this.context.formatMessage(I18nConstants.UNRECOGNISED_PROPERTY_TYPE_WRONG, describeType(je), property.getName(), type, property.typeSummary()), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(je), col(je), path, IssueType.STRUCTURE, this.context.formatMessage(I18nConstants.UNRECOGNISED_PROPERTY_TYPE_WRONG, describeType(je), property.getName(), type, property.typeSummary()), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (TypeRefComponent type : property.getDefinition().getType()) {
|
for (TypeRefComponent type : property.getDefinition().getType()) {
|
||||||
String eName = property.getJsonName().substring(0, property.getName().length()-3) + Utilities.capitalize(type.getWorkingCode());
|
String eName = property.getJsonName().substring(0, property.getName().length()-3) + Utilities.capitalize(type.getWorkingCode());
|
||||||
if (!isPrimitive(type.getWorkingCode()) && children.containsKey(eName)) {
|
if (!isPrimitive(type.getWorkingCode()) && children.containsKey(eName)) {
|
||||||
parseChildComplex(path, children, context, processed, property, eName, false);
|
parseChildComplex(errors, path, children, context, processed, property, eName, false);
|
||||||
break;
|
break;
|
||||||
} else if (isPrimitive(type.getWorkingCode()) && (children.containsKey(eName) || children.containsKey("_"+eName))) {
|
} else if (isPrimitive(type.getWorkingCode()) && (children.containsKey(eName) || children.containsKey("_"+eName))) {
|
||||||
parseChildPrimitive(children, context, processed, property, path, eName, false);
|
parseChildPrimitive(errors, children, context, processed, property, path, eName, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (property.isPrimitive(property.getType(null))) {
|
} else if (property.isPrimitive(property.getType(null))) {
|
||||||
parseChildPrimitive(children, context, processed, property, path, property.getJsonName(), property.hasJsonName());
|
parseChildPrimitive(errors, children, context, processed, property, path, property.getJsonName(), property.hasJsonName());
|
||||||
} else if (children.containsKey(property.getJsonName())) {
|
} else if (children.containsKey(property.getJsonName())) {
|
||||||
parseChildComplex(path, children, context, processed, property, property.getJsonName(), property.hasJsonName());
|
parseChildComplex(errors, path, children, context, processed, property, property.getJsonName(), property.hasJsonName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,7 +317,7 @@ public class JsonParser extends ParserBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseChildComplex(String path, Map<String, JsonProperty> children, Element element, Set<String> processed, Property property, String name, boolean isJsonName) throws FHIRException {
|
private void parseChildComplex(List<ValidationMessage> errors, String path, Map<String, JsonProperty> children, Element element, Set<String> processed, Property property, String name, boolean isJsonName) throws FHIRException {
|
||||||
if (processed != null) {
|
if (processed != null) {
|
||||||
processed.add(name);
|
processed.add(name);
|
||||||
}
|
}
|
||||||
|
@ -322,49 +328,49 @@ public class JsonParser extends ParserBase {
|
||||||
if (property.isList() && !property.isJsonKeyArray() && (e instanceof JsonArray)) {
|
if (property.isList() && !property.isJsonKeyArray() && (e instanceof JsonArray)) {
|
||||||
JsonArray arr = (JsonArray) e;
|
JsonArray arr = (JsonArray) e;
|
||||||
if (arr.isExtraComma()) {
|
if (arr.isExtraComma()) {
|
||||||
logError("2022-11-26", arr.getEnd().getLine(), arr.getEnd().getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_COMMA_EXTRA, "Array"), IssueSeverity.ERROR);
|
logError(errors, "2022-11-26", arr.getEnd().getLine(), arr.getEnd().getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_COMMA_EXTRA, "Array"), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
if (arr.size() == 0) {
|
if (arr.size() == 0) {
|
||||||
if (property.canBeEmpty()) {
|
if (property.canBeEmpty()) {
|
||||||
// nothing
|
// nothing
|
||||||
} else {
|
} else {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ARRAY_CANNOT_BE_EMPTY), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ARRAY_CANNOT_BE_EMPTY), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int c = 0;
|
int c = 0;
|
||||||
for (JsonElement am : arr) {
|
for (JsonElement am : arr) {
|
||||||
parseChildComplexInstance(npath+"["+c+"]", fpath+"["+c+"]", element, property, name, am, c == 0 ? arr : null, path);
|
parseChildComplexInstance(errors, npath+"["+c+"]", fpath+"["+c+"]", element, property, name, am, c == 0 ? arr : null, path);
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
} else if (property.isJsonKeyArray()) {
|
} else if (property.isJsonKeyArray()) {
|
||||||
String code = property.getJsonKeyProperty();
|
String code = property.getJsonKeyProperty();
|
||||||
List<Property> properties = property.getChildProperties(element.getName(), null);
|
List<Property> properties = property.getChildProperties(element.getName(), null);
|
||||||
if (properties.size() != 2) {
|
if (properties.size() != 2) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.OBJECT_CANNOT_BE_KEYED_ARRAY_CHILD_COUNT, propNames(properties)), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.OBJECT_CANNOT_BE_KEYED_ARRAY_CHILD_COUNT, propNames(properties)), IssueSeverity.ERROR);
|
||||||
} else {
|
} else {
|
||||||
Property propK = properties.get(0);
|
Property propK = properties.get(0);
|
||||||
Property propV = properties.get(1);
|
Property propV = properties.get(1);
|
||||||
if (!propK.getName().equals(code)) {
|
if (!propK.getName().equals(code)) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.OBJECT_CANNOT_BE_KEYED_ARRAY_PROP_NAME, propNames(properties)), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.OBJECT_CANNOT_BE_KEYED_ARRAY_PROP_NAME, propNames(properties)), IssueSeverity.ERROR);
|
||||||
} else if (!propK.isPrimitive()) {
|
} else if (!propK.isPrimitive()) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.OBJECT_CANNOT_BE_KEYED_ARRAY_PROP_TYPE, propNames(properties), propK.typeSummary()), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.OBJECT_CANNOT_BE_KEYED_ARRAY_PROP_TYPE, propNames(properties), propK.typeSummary()), IssueSeverity.ERROR);
|
||||||
} else if (propV.isList()) {
|
} else if (propV.isList()) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.OBJECT_CANNOT_BE_KEYED_ARRAY_NO_LIST, propV.getName()), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.OBJECT_CANNOT_BE_KEYED_ARRAY_NO_LIST, propV.getName()), IssueSeverity.ERROR);
|
||||||
} else if (propV.isChoice() && propV.getName().endsWith("[x]")) {
|
} else if (propV.isChoice() && propV.getName().endsWith("[x]")) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.OBJECT_CANNOT_BE_KEYED_ARRAY_NO_CHOICE, propV.getName()), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.OBJECT_CANNOT_BE_KEYED_ARRAY_NO_CHOICE, propV.getName()), IssueSeverity.ERROR);
|
||||||
} else if (!(e instanceof JsonObject)) {
|
} else if (!(e instanceof JsonObject)) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_AN_OBJECT_NOT_, describe(e)), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_AN_OBJECT_NOT_, describe(e)), IssueSeverity.ERROR);
|
||||||
} else {
|
} else {
|
||||||
JsonObject o = (JsonObject) e;
|
JsonObject o = (JsonObject) e;
|
||||||
if (o.isExtraComma()) {
|
if (o.isExtraComma()) {
|
||||||
logError("2022-11-26", o.getEnd().getLine(), o.getEnd().getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_COMMA_EXTRA, "Object"), IssueSeverity.ERROR);
|
logError(errors, "2022-11-26", o.getEnd().getLine(), o.getEnd().getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_COMMA_EXTRA, "Object"), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
Set<String> names = new HashSet<>();
|
Set<String> names = new HashSet<>();
|
||||||
for (JsonProperty pv : o.getProperties()) {
|
for (JsonProperty pv : o.getProperties()) {
|
||||||
if (names.contains(pv.getName())) {
|
if (names.contains(pv.getName())) {
|
||||||
logError("2022-11-26", line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.DUPLICATE_JSON_PROPERTY_KEY, pv.getName()), IssueSeverity.ERROR);
|
logError(errors, "2022-11-26", line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.DUPLICATE_JSON_PROPERTY_KEY, pv.getName()), IssueSeverity.ERROR);
|
||||||
} else {
|
} else {
|
||||||
names.add(pv.getName());
|
names.add(pv.getName());
|
||||||
}
|
}
|
||||||
|
@ -378,7 +384,7 @@ public class JsonParser extends ParserBase {
|
||||||
// handle the key
|
// handle the key
|
||||||
String fpathKey = fpathArr+"."+propK.getName();
|
String fpathKey = fpathArr+"."+propK.getName();
|
||||||
Element nKey = new Element(code, propK).markLocation(line(pv.getValue()), col(pv.getValue()));
|
Element nKey = new Element(code, propK).markLocation(line(pv.getValue()), col(pv.getValue()));
|
||||||
checkComments(pv.getValue(), n, fpathArr);
|
checkComments(errors, pv.getValue(), n, fpathArr);
|
||||||
nKey.setPath(fpathKey);
|
nKey.setPath(fpathKey);
|
||||||
n.getChildren().add(nKey);
|
n.getChildren().add(nKey);
|
||||||
nKey.setValue(pv.getName());
|
nKey.setValue(pv.getName());
|
||||||
|
@ -390,12 +396,12 @@ public class JsonParser extends ParserBase {
|
||||||
ok = false;
|
ok = false;
|
||||||
String type = getTypeFromJsonType(pv.getValue());
|
String type = getTypeFromJsonType(pv.getValue());
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(pv.getValue()), col(pv.getValue()), path, IssueType.STRUCTURE, this.context.formatMessage(I18nConstants.UNRECOGNISED_PROPERTY_TYPE, describeType(pv.getValue()), propV.getName(), propV.typeSummary()), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(pv.getValue()), col(pv.getValue()), path, IssueType.STRUCTURE, this.context.formatMessage(I18nConstants.UNRECOGNISED_PROPERTY_TYPE, describeType(pv.getValue()), propV.getName(), propV.typeSummary()), IssueSeverity.ERROR);
|
||||||
} else if (propV.hasType(type)) {
|
} else if (propV.hasType(type)) {
|
||||||
pvl = new Property(propV.getContext(), propV.getDefinition(), propV.getStructure(), propV.getUtils(), type);
|
pvl = new Property(propV.getContext(), propV.getDefinition(), propV.getStructure(), propV.getUtils(), type);
|
||||||
ok = true;
|
ok = true;
|
||||||
} else {
|
} else {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(pv.getValue()), col(pv.getValue()), path, IssueType.STRUCTURE, this.context.formatMessage(I18nConstants.UNRECOGNISED_PROPERTY_TYPE_WRONG, describeType(pv.getValue()), propV.getName(), type, propV.typeSummary()), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(pv.getValue()), col(pv.getValue()), path, IssueType.STRUCTURE, this.context.formatMessage(I18nConstants.UNRECOGNISED_PROPERTY_TYPE_WRONG, describeType(pv.getValue()), propV.getName(), type, propV.typeSummary()), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ok) {
|
if (ok) {
|
||||||
|
@ -403,11 +409,11 @@ public class JsonParser extends ParserBase {
|
||||||
String npathV = npathArr+"."+pvl.getName();
|
String npathV = npathArr+"."+pvl.getName();
|
||||||
String fpathV = fpathArr+"."+pvl.getName();
|
String fpathV = fpathArr+"."+pvl.getName();
|
||||||
if (propV.isPrimitive(pvl.getType(null))) {
|
if (propV.isPrimitive(pvl.getType(null))) {
|
||||||
parseChildPrimitiveInstance(n, pvl, pvl.getName(), false, npathV, fpathV, pv.getValue(), null);
|
parseChildPrimitiveInstance(errors, n, pvl, pvl.getName(), false, npathV, fpathV, pv.getValue(), null);
|
||||||
} else if (pv.getValue() instanceof JsonObject || pv.getValue() instanceof JsonNull) {
|
} else if (pv.getValue() instanceof JsonObject || pv.getValue() instanceof JsonNull) {
|
||||||
parseChildComplexInstance(npathV, fpathV, n, pvl, pvl.getName(), pv.getValue(), null, null);
|
parseChildComplexInstance(errors, npathV, fpathV, n, pvl, pvl.getName(), pv.getValue(), null, null);
|
||||||
} else {
|
} else {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_AN_OBJECT_NOT_, describe(pv.getValue())), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_AN_OBJECT_NOT_, describe(pv.getValue())), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
@ -416,9 +422,9 @@ public class JsonParser extends ParserBase {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (property.isList()) {
|
if (property.isList()) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_AN_ARRAY_NOT_, describe(e), name, path), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_AN_ARRAY_NOT_, describe(e), name, path), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
parseChildComplexInstance(npath, fpath, element, property, name, e, null, null);
|
parseChildComplexInstance(errors, npath, fpath, element, property, name, e, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,7 +436,7 @@ public class JsonParser extends ParserBase {
|
||||||
return b.toString();
|
return b.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseChildComplexInstance(String npath, String fpath, Element element, Property property, String name, JsonElement e, JsonElement commentContext, String commentPath) throws FHIRException {
|
private void parseChildComplexInstance(List<ValidationMessage> errors, String npath, String fpath, Element element, Property property, String name, JsonElement e, JsonElement commentContext, String commentPath) throws FHIRException {
|
||||||
if (property.hasTypeSpecifier()) {
|
if (property.hasTypeSpecifier()) {
|
||||||
FHIRPathEngine fpe = new FHIRPathEngine(context);
|
FHIRPathEngine fpe = new FHIRPathEngine(context);
|
||||||
String type = null;
|
String type = null;
|
||||||
|
@ -445,19 +451,19 @@ public class JsonParser extends ParserBase {
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, type);
|
StructureDefinition sd = context.fetchResource(StructureDefinition.class, type);
|
||||||
if (sd == null) {
|
if (sd == null) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.TYPE_SPECIFIER_ILLEGAL_TYPE, type, cond), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.TYPE_SPECIFIER_ILLEGAL_TYPE, type, cond), IssueSeverity.ERROR);
|
||||||
} else {
|
} else {
|
||||||
if (sd.getAbstract()) {
|
if (sd.getAbstract()) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.TYPE_SPECIFIER_ABSTRACT_TYPE, type, cond), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.TYPE_SPECIFIER_ABSTRACT_TYPE, type, cond), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
property = property.cloneToType(sd);
|
property = property.cloneToType(sd);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
StructureDefinition sd = context.fetchTypeDefinition(property.getType());
|
StructureDefinition sd = context.fetchTypeDefinition(property.getType());
|
||||||
if (sd == null) {
|
if (sd == null) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.TYPE_SPECIFIER_NM_ILLEGAL_TYPE, property.getType()), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.TYPE_SPECIFIER_NM_ILLEGAL_TYPE, property.getType()), IssueSeverity.ERROR);
|
||||||
} else if (sd.getAbstract()) {
|
} else if (sd.getAbstract()) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.TYPE_SPECIFIER_NM_ABSTRACT_TYPE, property.getType()), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.TYPE_SPECIFIER_NM_ABSTRACT_TYPE, property.getType()), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -465,26 +471,26 @@ public class JsonParser extends ParserBase {
|
||||||
JsonObject child = (JsonObject) e;
|
JsonObject child = (JsonObject) e;
|
||||||
Element n = new Element(name, property).markLocation(line(child), col(child));
|
Element n = new Element(name, property).markLocation(line(child), col(child));
|
||||||
n.setPath(fpath);
|
n.setPath(fpath);
|
||||||
checkComments(commentContext, n, commentPath);
|
checkComments(errors, commentContext, n, commentPath);
|
||||||
checkObject(child, n, npath);
|
checkObject(errors, child, n, npath);
|
||||||
element.getChildren().add(n);
|
element.getChildren().add(n);
|
||||||
if (property.isResource()) {
|
if (property.isResource()) {
|
||||||
parseResource(npath, child, n, property);
|
parseResource(errors, npath, child, n, property);
|
||||||
} else {
|
} else {
|
||||||
parseChildren(npath, child, n, false);
|
parseChildren(errors, npath, child, n, false);
|
||||||
}
|
}
|
||||||
} else if (property.isNullable() && e instanceof JsonNull) {
|
} else if (property.isNullable() && e instanceof JsonNull) {
|
||||||
// we create an element marked as a null element so we know something was present
|
// we create an element marked as a null element so we know something was present
|
||||||
JsonNull child = (JsonNull) e;
|
JsonNull child = (JsonNull) e;
|
||||||
Element n = new Element(name, property).markLocation(line(child), col(child));
|
Element n = new Element(name, property).markLocation(line(child), col(child));
|
||||||
checkComments(commentContext, n, commentPath);
|
checkComments(errors, commentContext, n, commentPath);
|
||||||
checkComments(child, n, fpath);
|
checkComments(errors, child, n, fpath);
|
||||||
n.setPath(fpath);
|
n.setPath(fpath);
|
||||||
element.getChildren().add(n);
|
element.getChildren().add(n);
|
||||||
n.setNull(true);
|
n.setNull(true);
|
||||||
// nothing to do, it's ok, but we treat it like it doesn't exist
|
// nothing to do, it's ok, but we treat it like it doesn't exist
|
||||||
} else {
|
} else {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE__NOT_, (property.isList() ? "an Array" : "an Object"), describe(e), name, npath), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(e), col(e), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE__NOT_, (property.isList() ? "an Array" : "an Object"), describe(e), name, npath), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,7 +514,7 @@ public class JsonParser extends ParserBase {
|
||||||
return e.type().toName();
|
return e.type().toName();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseChildPrimitive(Map<String, JsonProperty> children, Element element, Set<String> processed, Property property, String path, String name, boolean isJsonName) throws FHIRException {
|
private void parseChildPrimitive(List<ValidationMessage> errors, Map<String, JsonProperty> children, Element element, Set<String> processed, Property property, String path, String name, boolean isJsonName) throws FHIRException {
|
||||||
String npath = path+"."+property.getName();
|
String npath = path+"."+property.getName();
|
||||||
String fpath = element.getPath()+"."+property.getName();
|
String fpath = element.getPath()+"."+property.getName();
|
||||||
processed.add(name);
|
processed.add(name);
|
||||||
|
@ -516,40 +522,40 @@ public class JsonParser extends ParserBase {
|
||||||
JsonProperty main = children.containsKey(name) ? children.get(name) : null;
|
JsonProperty main = children.containsKey(name) ? children.get(name) : null;
|
||||||
JsonProperty fork = children.containsKey("_"+name) ? children.get("_"+name) : null;
|
JsonProperty fork = children.containsKey("_"+name) ? children.get("_"+name) : null;
|
||||||
if (main != null && main.getValue().isJsonString() && main.isUnquotedValue()) {
|
if (main != null && main.getValue().isJsonString() && main.isUnquotedValue()) {
|
||||||
logError("2022-11-26", line(main.getValue()), col(main.getValue()), path, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_PROPERTY_VALUE_NO_QUOTES, main.getName(), main.getValue().asString()), IssueSeverity.ERROR);
|
logError(errors, "2022-11-26", line(main.getValue()), col(main.getValue()), path, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_PROPERTY_VALUE_NO_QUOTES, main.getName(), main.getValue().asString()), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
if (main != null || fork != null) {
|
if (main != null || fork != null) {
|
||||||
if (property.isList()) {
|
if (property.isList()) {
|
||||||
boolean ok = true;
|
boolean ok = true;
|
||||||
if (!(main == null || main.getValue() instanceof JsonArray)) {
|
if (!(main == null || main.getValue() instanceof JsonArray)) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(main.getValue()), col(main.getValue()), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_AN_ARRAY_NOT_, describe(main.getValue()), name, path), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(main.getValue()), col(main.getValue()), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_AN_ARRAY_NOT_, describe(main.getValue()), name, path), IssueSeverity.ERROR);
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
if (!(fork == null || fork.getValue() instanceof JsonArray)) {
|
if (!(fork == null || fork.getValue() instanceof JsonArray)) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(fork.getValue()), col(fork.getValue()), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_BASE_PROPERTY_MUST_BE_AN_ARRAY_NOT_, describe(main.getValue()), name, path), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(fork.getValue()), col(fork.getValue()), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_BASE_PROPERTY_MUST_BE_AN_ARRAY_NOT_, describe(main.getValue()), name, path), IssueSeverity.ERROR);
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
if (ok) {
|
if (ok) {
|
||||||
JsonArray arr1 = (JsonArray) (main == null ? null : main.getValue());
|
JsonArray arr1 = (JsonArray) (main == null ? null : main.getValue());
|
||||||
JsonArray arr2 = (JsonArray) (fork == null ? null : fork.getValue());
|
JsonArray arr2 = (JsonArray) (fork == null ? null : fork.getValue());
|
||||||
if (arr1 != null && arr1.isExtraComma()) {
|
if (arr1 != null && arr1.isExtraComma()) {
|
||||||
logError("2022-11-26", arr1.getEnd().getLine(), arr1.getEnd().getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_COMMA_EXTRA, "Array"), IssueSeverity.ERROR);
|
logError(errors, "2022-11-26", arr1.getEnd().getLine(), arr1.getEnd().getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_COMMA_EXTRA, "Array"), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
if (arr2 != null && arr2.isExtraComma()) {
|
if (arr2 != null && arr2.isExtraComma()) {
|
||||||
logError("2022-11-26", arr2.getEnd().getLine(), arr2.getEnd().getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_COMMA_EXTRA, "Array"), IssueSeverity.ERROR);
|
logError(errors, "2022-11-26", arr2.getEnd().getLine(), arr2.getEnd().getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_COMMA_EXTRA, "Array"), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < Math.max(arrC(arr1), arrC(arr2)); i++) {
|
for (int i = 0; i < Math.max(arrC(arr1), arrC(arr2)); i++) {
|
||||||
JsonElement m = arrI(arr1, i);
|
JsonElement m = arrI(arr1, i);
|
||||||
JsonElement f = arrI(arr2, i);
|
JsonElement f = arrI(arr2, i);
|
||||||
if (m != null && m.isJsonString() && arr1.isUnquoted(i)) {
|
if (m != null && m.isJsonString() && arr1.isUnquoted(i)) {
|
||||||
logError("2022-11-26", line(m), col(m), path+"."+name+"["+i+"]", IssueType.INVALID, context.formatMessage(I18nConstants.JSON_PROPERTY_VALUE_NO_QUOTES, "item", m.asString()), IssueSeverity.ERROR);
|
logError(errors, "2022-11-26", line(m), col(m), path+"."+name+"["+i+"]", IssueType.INVALID, context.formatMessage(I18nConstants.JSON_PROPERTY_VALUE_NO_QUOTES, "item", m.asString()), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
parseChildPrimitiveInstance(element, property, name, isJsonName, npath, fpath, m, f);
|
parseChildPrimitiveInstance(errors, element, property, name, isJsonName, npath, fpath, m, f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
parseChildPrimitiveInstance(element, property, name, isJsonName, npath, fpath, main == null ? null : main.getValue(), fork == null ? null : fork.getValue());
|
parseChildPrimitiveInstance(errors, element, property, name, isJsonName, npath, fpath, main == null ? null : main.getValue(), fork == null ? null : fork.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -562,19 +568,19 @@ public class JsonParser extends ParserBase {
|
||||||
return arr == null ? 0 : arr.size();
|
return arr == null ? 0 : arr.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseChildPrimitiveInstance(Element element, Property property, String name, boolean isJsonName, String npath, String fpath, JsonElement main, JsonElement fork) throws FHIRException {
|
private void parseChildPrimitiveInstance(List<ValidationMessage> errors, Element element, Property property, String name, boolean isJsonName, String npath, String fpath, JsonElement main, JsonElement fork) throws FHIRException {
|
||||||
if (main != null && !(main.isJsonBoolean() || main.isJsonNumber() || main.isJsonString())) {
|
if (main != null && !(main.isJsonBoolean() || main.isJsonNumber() || main.isJsonString())) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(main), col(main), npath, IssueType.INVALID, context.formatMessage(
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(main), col(main), npath, IssueType.INVALID, context.formatMessage(
|
||||||
I18nConstants.THIS_PROPERTY_MUST_BE_AN_SIMPLE_VALUE_NOT_, describe(main), name, npath), IssueSeverity.ERROR);
|
I18nConstants.THIS_PROPERTY_MUST_BE_AN_SIMPLE_VALUE_NOT_, describe(main), name, npath), IssueSeverity.ERROR);
|
||||||
} else if (fork != null && !(fork instanceof JsonObject)) {
|
} else if (fork != null && !(fork instanceof JsonObject)) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(fork), col(fork), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_AN_OBJECT_NOT_, describe(fork), name, npath), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(fork), col(fork), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_AN_OBJECT_NOT_, describe(fork), name, npath), IssueSeverity.ERROR);
|
||||||
} else {
|
} else {
|
||||||
Element n = new Element(isJsonName ? property.getName() : name, property).markLocation(line(main != null ? main : fork), col(main != null ? main : fork));
|
Element n = new Element(isJsonName ? property.getName() : name, property).markLocation(line(main != null ? main : fork), col(main != null ? main : fork));
|
||||||
if (main != null) {
|
if (main != null) {
|
||||||
checkComments(main, n, npath);
|
checkComments(errors, main, n, npath);
|
||||||
}
|
}
|
||||||
if (fork != null) {
|
if (fork != null) {
|
||||||
checkComments(fork, n, npath);
|
checkComments(errors, fork, n, npath);
|
||||||
}
|
}
|
||||||
n.setPath(fpath);
|
n.setPath(fpath);
|
||||||
element.getChildren().add(n);
|
element.getChildren().add(n);
|
||||||
|
@ -587,55 +593,55 @@ public class JsonParser extends ParserBase {
|
||||||
n.setXhtml(xhtml.setXmlMode(true).parse(n.getValue(), null).getDocumentElement());
|
n.setXhtml(xhtml.setXmlMode(true).parse(n.getValue(), null).getDocumentElement());
|
||||||
if (policy == ValidationPolicy.EVERYTHING) {
|
if (policy == ValidationPolicy.EVERYTHING) {
|
||||||
for (StringPair s : xhtml.getValidationIssues()) {
|
for (StringPair s : xhtml.getValidationIssues()) {
|
||||||
logError("2022-11-17", line(main), col(main), npath, IssueType.INVALID, context.formatMessage(s.getName(), s.getValue()), IssueSeverity.ERROR);
|
logError(errors, "2022-11-17", line(main), col(main), npath, IssueType.INVALID, context.formatMessage(s.getName(), s.getValue()), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(main), col(main), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_XHTML_, e.getMessage()), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(main), col(main), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_XHTML_, e.getMessage()), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (policy == ValidationPolicy.EVERYTHING) {
|
if (policy == ValidationPolicy.EVERYTHING) {
|
||||||
// now we cross-check the primitive format against the stated type
|
// now we cross-check the primitive format against the stated type
|
||||||
if (Utilities.existsInList(n.getType(), "boolean")) {
|
if (Utilities.existsInList(n.getType(), "boolean")) {
|
||||||
if (!p.isJsonBoolean()) {
|
if (!p.isJsonBoolean()) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(main), col(main), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_THE_PRIMITIVE_VALUE_MUST_BE_A_BOOLEAN), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(main), col(main), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_THE_PRIMITIVE_VALUE_MUST_BE_A_BOOLEAN), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
} else if (Utilities.existsInList(n.getType(), "integer", "unsignedInt", "positiveInt", "decimal")) {
|
} else if (Utilities.existsInList(n.getType(), "integer", "unsignedInt", "positiveInt", "decimal")) {
|
||||||
if (!p.isJsonNumber())
|
if (!p.isJsonNumber())
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(main), col(main), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_THE_PRIMITIVE_VALUE_MUST_BE_A_NUMBER), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(main), col(main), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_THE_PRIMITIVE_VALUE_MUST_BE_A_NUMBER), IssueSeverity.ERROR);
|
||||||
} else if (!p.isJsonString()) {
|
} else if (!p.isJsonString()) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(main), col(main), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_THE_PRIMITIVE_VALUE_MUST_BE_A_STRING), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(main), col(main), npath, IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_JSON_THE_PRIMITIVE_VALUE_MUST_BE_A_STRING), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fork != null) {
|
if (fork != null) {
|
||||||
JsonObject child = (JsonObject) fork;
|
JsonObject child = (JsonObject) fork;
|
||||||
checkObject(child, n, npath);
|
checkObject(errors, child, n, npath);
|
||||||
parseChildren(npath, child, n, false);
|
parseChildren(errors, npath, child, n, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void parseResource(String npath, JsonObject res, Element parent, Property elementProperty) throws FHIRException {
|
private void parseResource(List<ValidationMessage> errors, String npath, JsonObject res, Element parent, Property elementProperty) throws FHIRException {
|
||||||
JsonElement rt = res.get("resourceType");
|
JsonElement rt = res.get("resourceType");
|
||||||
if (rt == null) {
|
if (rt == null) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(res), col(res), npath, IssueType.INVALID, context.formatMessage(I18nConstants.UNABLE_TO_FIND_RESOURCETYPE_PROPERTY), IssueSeverity.FATAL);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(res), col(res), npath, IssueType.INVALID, context.formatMessage(I18nConstants.UNABLE_TO_FIND_RESOURCETYPE_PROPERTY), IssueSeverity.FATAL);
|
||||||
} else if (!rt.isJsonString()) {
|
} else if (!rt.isJsonString()) {
|
||||||
logError("2022-11-26", line(res), col(res), npath, IssueType.INVALID, context.formatMessage(I18nConstants.RESOURCETYPE_PROPERTY_WRONG_TYPE, rt.type().toName()), IssueSeverity.FATAL);
|
logError(errors, "2022-11-26", line(res), col(res), npath, IssueType.INVALID, context.formatMessage(I18nConstants.RESOURCETYPE_PROPERTY_WRONG_TYPE, rt.type().toName()), IssueSeverity.FATAL);
|
||||||
} else {
|
} else {
|
||||||
String name = rt.asString();
|
String name = rt.asString();
|
||||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(name, null));
|
StructureDefinition sd = context.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(name, null));
|
||||||
if (sd == null) {
|
if (sd == null) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(res), col(res), npath, IssueType.INVALID, context.formatMessage(I18nConstants.CONTAINED_RESOURCE_DOES_NOT_APPEAR_TO_BE_A_FHIR_RESOURCE_UNKNOWN_NAME_, name), IssueSeverity.FATAL);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(res), col(res), npath, IssueType.INVALID, context.formatMessage(I18nConstants.CONTAINED_RESOURCE_DOES_NOT_APPEAR_TO_BE_A_FHIR_RESOURCE_UNKNOWN_NAME_, name), IssueSeverity.FATAL);
|
||||||
} else {
|
} else {
|
||||||
parent.updateProperty(new Property(context, sd.getSnapshot().getElement().get(0), sd, this.profileUtilities), SpecialElement.fromProperty(parent.getProperty()), elementProperty);
|
parent.updateProperty(new Property(context, sd.getSnapshot().getElement().get(0), sd, this.profileUtilities), SpecialElement.fromProperty(parent.getProperty()), elementProperty);
|
||||||
parent.setType(name);
|
parent.setType(name);
|
||||||
parseChildren(npath, res, parent, true);
|
parseChildren(errors, npath, res, parent, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (res.isExtraComma()) {
|
if (res.isExtraComma()) {
|
||||||
logError("2022-11-26", res.getEnd().getLine(), res.getEnd().getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_COMMA_EXTRA, "Object"), IssueSeverity.ERROR);
|
logError(errors, "2022-11-26", res.getEnd().getLine(), res.getEnd().getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.JSON_COMMA_EXTRA, "Object"), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,9 +48,10 @@ import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
public class Manager {
|
public class Manager {
|
||||||
|
|
||||||
//TODO use EnumMap
|
//TODO use EnumMap
|
||||||
public enum FhirFormat { XML, JSON, TURTLE, TEXT, VBAR, SHC, FML;
|
public enum FhirFormat { XML, JSON, TURTLE, TEXT, VBAR, SHC, SHL, FML;
|
||||||
// SHC = smart health cards, including as text versions of QR codes
|
// SHC = smart health cards, including as text versions of QR codes
|
||||||
|
// SHL = smart health links, also a text version of the QR code
|
||||||
|
|
||||||
public String getExtension() {
|
public String getExtension() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case JSON:
|
case JSON:
|
||||||
|
@ -65,6 +66,8 @@ public class Manager {
|
||||||
return "hl7";
|
return "hl7";
|
||||||
case SHC:
|
case SHC:
|
||||||
return "shc";
|
return "shc";
|
||||||
|
case SHL:
|
||||||
|
return "shl";
|
||||||
case FML:
|
case FML:
|
||||||
return "fml";
|
return "fml";
|
||||||
}
|
}
|
||||||
|
@ -85,6 +88,8 @@ public class Manager {
|
||||||
return VBAR;
|
return VBAR;
|
||||||
case "shc":
|
case "shc":
|
||||||
return SHC;
|
return SHC;
|
||||||
|
case "shl":
|
||||||
|
return SHL;
|
||||||
case "fml":
|
case "fml":
|
||||||
return FML;
|
return FML;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +111,7 @@ public class Manager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Element parseSingle(IWorkerContext context, InputStream source, FhirFormat inputFormat) throws FHIRFormatError, DefinitionException, IOException, FHIRException {
|
public static Element parseSingle(IWorkerContext context, InputStream source, FhirFormat inputFormat) throws FHIRFormatError, DefinitionException, IOException, FHIRException {
|
||||||
return makeParser(context, inputFormat).parseSingle(source);
|
return makeParser(context, inputFormat).parseSingle(source, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,6 +129,7 @@ public class Manager {
|
||||||
case TURTLE : return new TurtleParser(context);
|
case TURTLE : return new TurtleParser(context);
|
||||||
case VBAR : return new VerticalBarParser(context);
|
case VBAR : return new VerticalBarParser(context);
|
||||||
case SHC : return new SHCParser(context);
|
case SHC : return new SHCParser(context);
|
||||||
|
case SHL : return new SHLParser(context);
|
||||||
case FML : return new FmlParser(context);
|
case FML : return new FmlParser(context);
|
||||||
case TEXT : throw new Error("Programming logic error: do not call makeParser for a text resource");
|
case TEXT : throw new Error("Programming logic error: do not call makeParser for a text resource");
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,18 +71,49 @@ public abstract class ParserBase {
|
||||||
|
|
||||||
public class NamedElement {
|
public class NamedElement {
|
||||||
private String name;
|
private String name;
|
||||||
|
private String extension;
|
||||||
private Element element;
|
private Element element;
|
||||||
public NamedElement(String name, Element element) {
|
private byte[] content;
|
||||||
|
private List<ValidationMessage> errors = new ArrayList<>();
|
||||||
|
|
||||||
|
public NamedElement(String name, String extension, Element element, byte[] content) {
|
||||||
super();
|
super();
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.element = element;
|
this.element = element;
|
||||||
|
this.content = content;
|
||||||
|
this.extension = extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NamedElement(String name, String extension, byte[] content) {
|
||||||
|
super();
|
||||||
|
this.name = name;
|
||||||
|
this.content = content;
|
||||||
|
this.extension = extension;
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Element getElement() {
|
public Element getElement() {
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public byte[] getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ValidationMessage> getErrors() {
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setElement(Element element) {
|
||||||
|
this.element = element;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFilename() {
|
||||||
|
return name+"."+extension;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +137,6 @@ public abstract class ParserBase {
|
||||||
|
|
||||||
protected IWorkerContext context;
|
protected IWorkerContext context;
|
||||||
protected ValidationPolicy policy;
|
protected ValidationPolicy policy;
|
||||||
protected List<ValidationMessage> errors;
|
|
||||||
protected ILinkResolver linkResolver;
|
protected ILinkResolver linkResolver;
|
||||||
protected boolean showDecorations;
|
protected boolean showDecorations;
|
||||||
protected IdRenderingPolicy idPolicy = IdRenderingPolicy.All;
|
protected IdRenderingPolicy idPolicy = IdRenderingPolicy.All;
|
||||||
|
@ -118,30 +148,32 @@ public abstract class ParserBase {
|
||||||
policy = ValidationPolicy.NONE;
|
policy = ValidationPolicy.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setupValidation(ValidationPolicy policy, List<ValidationMessage> errors) {
|
public void setupValidation(ValidationPolicy policy) {
|
||||||
this.policy = policy;
|
this.policy = policy;
|
||||||
this.errors = errors;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract List<NamedElement> parse(InputStream stream) throws IOException, FHIRFormatError, DefinitionException, FHIRException;
|
public abstract List<NamedElement> parse(InputStream stream) throws IOException, FHIRFormatError, DefinitionException, FHIRException;
|
||||||
|
|
||||||
public Element parseSingle(InputStream stream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
public Element parseSingle(InputStream stream, List<ValidationMessage> errors) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
||||||
if (errors == null) {
|
|
||||||
errors = new ArrayList<>();
|
|
||||||
}
|
|
||||||
List<NamedElement> res = parse(stream);
|
List<NamedElement> res = parse(stream);
|
||||||
if (res == null) {
|
|
||||||
throw new FHIRException("Parsing FHIR content failed: "+errorSummary());
|
|
||||||
} else if (res.size() == 0) {
|
|
||||||
throw new FHIRException("Parsing FHIR content returned no elements in a context where one element is required because: "+errorSummary());
|
|
||||||
}
|
|
||||||
if (res.size() != 1) {
|
if (res.size() != 1) {
|
||||||
throw new FHIRException("Parsing FHIR content returned multiple elements in a context where only one element is allowed");
|
throw new FHIRException("Parsing FHIR content returned multiple elements in a context where only one element is allowed");
|
||||||
}
|
}
|
||||||
return res.get(0).getElement();
|
var resE = res.get(0);
|
||||||
|
if (resE.getElement() == null) {
|
||||||
|
throw new FHIRException("Parsing FHIR content failed: "+errorSummary(resE.errors));
|
||||||
|
} else if (res.size() == 0) {
|
||||||
|
throw new FHIRException("Parsing FHIR content returned no elements in a context where one element is required because: "+errorSummary(resE.errors));
|
||||||
|
}
|
||||||
|
if (errors != null) {
|
||||||
|
errors.addAll(resE.getErrors());
|
||||||
|
}
|
||||||
|
return resE.getElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String errorSummary() {
|
private String errorSummary(List<ValidationMessage> errors) {
|
||||||
if (errors == null || errors.size() == 0) {
|
if (errors == null || errors.size() == 0) {
|
||||||
return "(no error description)";
|
return "(no error description)";
|
||||||
} else {
|
} else {
|
||||||
|
@ -152,7 +184,7 @@ public abstract class ParserBase {
|
||||||
public abstract void compose(Element e, OutputStream destination, OutputStyle style, String base) throws FHIRException, IOException;
|
public abstract void compose(Element e, OutputStream destination, OutputStyle style, String base) throws FHIRException, IOException;
|
||||||
|
|
||||||
//FIXME: i18n should be done here
|
//FIXME: i18n should be done here
|
||||||
public void logError(String ruleDate, int line, int col, String path, IssueType type, String message, IssueSeverity level) throws FHIRFormatError {
|
public void logError(List<ValidationMessage> errors, String ruleDate, int line, int col, String path, IssueType type, String message, IssueSeverity level) throws FHIRFormatError {
|
||||||
if (errors != null) {
|
if (errors != null) {
|
||||||
if (policy == ValidationPolicy.EVERYTHING) {
|
if (policy == ValidationPolicy.EVERYTHING) {
|
||||||
ValidationMessage msg = new ValidationMessage(Source.InstanceValidator, type, line, col, path, message, level);
|
ValidationMessage msg = new ValidationMessage(Source.InstanceValidator, type, line, col, path, message, level);
|
||||||
|
@ -164,13 +196,13 @@ public abstract class ParserBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected StructureDefinition getDefinition(int line, int col, String ns, String name) throws FHIRFormatError {
|
protected StructureDefinition getDefinition(List<ValidationMessage> errors, int line, int col, String ns, String name) throws FHIRFormatError {
|
||||||
if (ns == null) {
|
if (ns == null) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line, col, name, IssueType.STRUCTURE, context.formatMessage(I18nConstants.THIS__CANNOT_BE_PARSED_AS_A_FHIR_OBJECT_NO_NAMESPACE, name), IssueSeverity.FATAL);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line, col, name, IssueType.STRUCTURE, context.formatMessage(I18nConstants.THIS__CANNOT_BE_PARSED_AS_A_FHIR_OBJECT_NO_NAMESPACE, name), IssueSeverity.FATAL);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line, col, name, IssueType.STRUCTURE, context.formatMessage(I18nConstants.THIS_CANNOT_BE_PARSED_AS_A_FHIR_OBJECT_NO_NAME), IssueSeverity.FATAL);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line, col, name, IssueType.STRUCTURE, context.formatMessage(I18nConstants.THIS_CANNOT_BE_PARSED_AS_A_FHIR_OBJECT_NO_NAME), IssueSeverity.FATAL);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
for (StructureDefinition sd : context.fetchResourcesByType(StructureDefinition.class)) {
|
for (StructureDefinition sd : context.fetchResourcesByType(StructureDefinition.class)) {
|
||||||
|
@ -183,7 +215,7 @@ public abstract class ParserBase {
|
||||||
return sd;
|
return sd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line, col, name, IssueType.STRUCTURE, context.formatMessage(I18nConstants.THIS_DOES_NOT_APPEAR_TO_BE_A_FHIR_RESOURCE_UNKNOWN_NAMESPACENAME_, ns, name), IssueSeverity.FATAL);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line, col, name, IssueType.STRUCTURE, context.formatMessage(I18nConstants.THIS_DOES_NOT_APPEAR_TO_BE_A_FHIR_RESOURCE_UNKNOWN_NAMESPACENAME_, ns, name), IssueSeverity.FATAL);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,9 +223,9 @@ public abstract class ParserBase {
|
||||||
return type == null || !type.contains("/") ? type : type.substring(type.lastIndexOf("/")+1);
|
return type == null || !type.contains("/") ? type : type.substring(type.lastIndexOf("/")+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected StructureDefinition getDefinition(int line, int col, String name) throws FHIRFormatError {
|
protected StructureDefinition getDefinition(List<ValidationMessage> errors, int line, int col, String name) throws FHIRFormatError {
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line, col, name, IssueType.STRUCTURE, context.formatMessage(I18nConstants.THIS_CANNOT_BE_PARSED_AS_A_FHIR_OBJECT_NO_NAME), IssueSeverity.FATAL);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line, col, name, IssueType.STRUCTURE, context.formatMessage(I18nConstants.THIS_CANNOT_BE_PARSED_AS_A_FHIR_OBJECT_NO_NAME), IssueSeverity.FATAL);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// first pass: only look at base definitions
|
// first pass: only look at base definitions
|
||||||
|
@ -209,7 +241,7 @@ public abstract class ParserBase {
|
||||||
return sd;
|
return sd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line, col, name, IssueType.STRUCTURE, context.formatMessage(I18nConstants.THIS_DOES_NOT_APPEAR_TO_BE_A_FHIR_RESOURCE_UNKNOWN_NAME_, name), IssueSeverity.FATAL);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line, col, name, IssueType.STRUCTURE, context.formatMessage(I18nConstants.THIS_DOES_NOT_APPEAR_TO_BE_A_FHIR_RESOURCE_UNKNOWN_NAME_, name), IssueSeverity.FATAL);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.hl7.fhir.r5.elementmodel;
|
package org.hl7.fhir.r5.elementmodel;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -17,6 +18,7 @@ import org.hl7.fhir.exceptions.DefinitionException;
|
||||||
import org.hl7.fhir.exceptions.FHIRException;
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
|
import org.hl7.fhir.r5.elementmodel.ParserBase.NamedElement;
|
||||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||||
import org.hl7.fhir.utilities.TextFile;
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
@ -56,20 +58,25 @@ public class SHCParser extends ParserBase {
|
||||||
jsonParser = new JsonParser(context);
|
jsonParser = new JsonParser(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<NamedElement> parse(InputStream stream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
public List<NamedElement> parse(InputStream inStream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
||||||
|
byte[] content = TextFile.streamToBytes(inStream);
|
||||||
|
ByteArrayInputStream stream = new ByteArrayInputStream(content);
|
||||||
List<NamedElement> res = new ArrayList<>();
|
List<NamedElement> res = new ArrayList<>();
|
||||||
|
NamedElement shc = new NamedElement("shc", "json", content);
|
||||||
|
res.add(shc);
|
||||||
|
|
||||||
String src = TextFile.streamToString(stream).trim();
|
String src = TextFile.streamToString(stream).trim();
|
||||||
List<String> list = new ArrayList<>();
|
List<String> list = new ArrayList<>();
|
||||||
String pfx = null;
|
String pfx = null;
|
||||||
if (src.startsWith("{")) {
|
if (src.startsWith("{")) {
|
||||||
JsonObject json = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(src);
|
JsonObject json = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(src);
|
||||||
if (checkProperty(json, "$", "verifiableCredential", true, "Array")) {
|
if (checkProperty(shc.getErrors(), json, "$", "verifiableCredential", true, "Array")) {
|
||||||
pfx = "verifiableCredential";
|
pfx = "verifiableCredential";
|
||||||
JsonArray arr = json.getJsonArray("verifiableCredential");
|
JsonArray arr = json.getJsonArray("verifiableCredential");
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (JsonElement e : arr) {
|
for (JsonElement e : arr) {
|
||||||
if (!(e instanceof JsonPrimitive)) {
|
if (!(e instanceof JsonPrimitive)) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(e), col(e), "$.verifiableCredential["+i+"]", IssueType.STRUCTURE, "Wrong Property verifiableCredential in JSON Payload. Expected : String but found "+e.type().toName(), IssueSeverity.ERROR);
|
logError(shc.getErrors(), ValidationMessage.NO_RULE_DATE, line(e), col(e), "$.verifiableCredential["+i+"]", IssueType.STRUCTURE, "Wrong Property verifiableCredential in JSON Payload. Expected : String but found "+e.type().toName(), IssueSeverity.ERROR);
|
||||||
} else {
|
} else {
|
||||||
list.add(e.asString());
|
list.add(e.asString());
|
||||||
}
|
}
|
||||||
|
@ -87,66 +94,65 @@ public class SHCParser extends ParserBase {
|
||||||
c++;
|
c++;
|
||||||
JWT jwt = null;
|
JWT jwt = null;
|
||||||
try {
|
try {
|
||||||
jwt = decodeJWT(ssrc);
|
jwt = decodeJWT(shc.getErrors(), ssrc);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, 1, 1, prefix+"JWT", IssueType.INVALID, "Unable to decode JWT token", IssueSeverity.ERROR);
|
logError(shc.getErrors(), ValidationMessage.NO_RULE_DATE, 1, 1, prefix+"JWT", IssueType.INVALID, "Unable to decode JWT token", IssueSeverity.ERROR);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkNamedProperties(jwt.getPayload(), prefix+"payload", "iss", "nbf", "vc");
|
checkNamedProperties(shc.getErrors(), jwt.getPayload(), prefix+"payload", "iss", "nbf", "vc");
|
||||||
checkProperty(jwt.getPayload(), prefix+"payload", "iss", true, "String");
|
checkProperty(shc.getErrors(), jwt.getPayload(), prefix+"payload", "iss", true, "String");
|
||||||
logError(ValidationMessage.NO_RULE_DATE, 1, 1, prefix+"JWT", IssueType.INFORMATIONAL, "The FHIR Validator does not check the JWT signature "+
|
logError(shc.getErrors(), ValidationMessage.NO_RULE_DATE, 1, 1, prefix+"JWT", IssueType.INFORMATIONAL, "The FHIR Validator does not check the JWT signature "+
|
||||||
"(see https://demo-portals.smarthealth.cards/VerifierPortal.html or https://github.com/smart-on-fhir/health-cards-dev-tools) (Issuer = '"+jwt.getPayload().asString("iss")+"')", IssueSeverity.INFORMATION);
|
"(see https://demo-portals.smarthealth.cards/VerifierPortal.html or https://github.com/smart-on-fhir/health-cards-dev-tools) (Issuer = '"+jwt.getPayload().asString("iss")+"')", IssueSeverity.INFORMATION);
|
||||||
checkProperty(jwt.getPayload(), prefix+"payload", "nbf", true, "Number");
|
checkProperty(shc.getErrors(), jwt.getPayload(), prefix+"payload", "nbf", true, "Number");
|
||||||
JsonObject vc = jwt.getPayload().getJsonObject("vc");
|
JsonObject vc = jwt.getPayload().getJsonObject("vc");
|
||||||
if (vc == null) {
|
if (vc == null) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, 1, 1, "JWT", IssueType.STRUCTURE, "Unable to find property 'vc' in the payload", IssueSeverity.ERROR);
|
logError(shc.getErrors(), ValidationMessage.NO_RULE_DATE, 1, 1, "JWT", IssueType.STRUCTURE, "Unable to find property 'vc' in the payload", IssueSeverity.ERROR);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
String path = prefix+"payload.vc";
|
String path = prefix+"payload.vc";
|
||||||
checkNamedProperties(vc, path, "type", "credentialSubject");
|
checkNamedProperties(shc.getErrors(), vc, path, "type", "credentialSubject");
|
||||||
if (!checkProperty(vc, path, "type", true, "Array")) {
|
if (!checkProperty(shc.getErrors(), vc, path, "type", true, "Array")) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
JsonArray type = vc.getJsonArray("type");
|
JsonArray type = vc.getJsonArray("type");
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (JsonElement e : type) {
|
for (JsonElement e : type) {
|
||||||
if (e.type() != JsonElementType.STRING) {
|
if (e.type() != JsonElementType.STRING) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(e), col(e), path+".type["+i+"]", IssueType.STRUCTURE, "Wrong Property Type in JSON Payload. Expected : String but found "+e.type().toName(), IssueSeverity.ERROR);
|
logError(shc.getErrors(), ValidationMessage.NO_RULE_DATE, line(e), col(e), path+".type["+i+"]", IssueType.STRUCTURE, "Wrong Property Type in JSON Payload. Expected : String but found "+e.type().toName(), IssueSeverity.ERROR);
|
||||||
} else {
|
} else {
|
||||||
types.add(e.asString());
|
types.add(e.asString());
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (!types.contains("https://smarthealth.cards#health-card")) {
|
if (!types.contains("https://smarthealth.cards#health-card")) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(vc), col(vc), path, IssueType.STRUCTURE, "Card does not claim to be of type https://smarthealth.cards#health-card, cannot validate", IssueSeverity.ERROR);
|
logError(shc.getErrors(), ValidationMessage.NO_RULE_DATE, line(vc), col(vc), path, IssueType.STRUCTURE, "Card does not claim to be of type https://smarthealth.cards#health-card, cannot validate", IssueSeverity.ERROR);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
if (!checkProperty(vc, path, "credentialSubject", true, "Object")) {
|
if (!checkProperty(shc.getErrors(), vc, path, "credentialSubject", true, "Object")) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
JsonObject cs = vc.getJsonObject("credentialSubject");
|
JsonObject cs = vc.getJsonObject("credentialSubject");
|
||||||
path = path+".credentialSubject";
|
path = path+".credentialSubject";
|
||||||
if (!checkProperty(cs, path, "fhirVersion", true, "String")) {
|
if (!checkProperty(shc.getErrors(), cs, path, "fhirVersion", true, "String")) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
JsonElement fv = cs.get("fhirVersion");
|
JsonElement fv = cs.get("fhirVersion");
|
||||||
if (!VersionUtilities.versionsCompatible(context.getVersion(), fv.asString())) {
|
if (!VersionUtilities.versionsCompatible(context.getVersion(), fv.asString())) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(fv), col(fv), path+".fhirVersion", IssueType.STRUCTURE, "Card claims to be of version "+fv.asString()+", cannot be validated against version "+context.getVersion(), IssueSeverity.ERROR);
|
logError(shc.getErrors(), ValidationMessage.NO_RULE_DATE, line(fv), col(fv), path+".fhirVersion", IssueType.STRUCTURE, "Card claims to be of version "+fv.asString()+", cannot be validated against version "+context.getVersion(), IssueSeverity.ERROR);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
if (!checkProperty(cs, path, "fhirBundle", true, "Object")) {
|
if (!checkProperty(shc.getErrors(), cs, path, "fhirBundle", true, "Object")) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
// ok. all checks passed, we can now validate the bundle
|
// ok. all checks passed, we can now validate the bundle
|
||||||
Element e = jsonParser.parse(cs.getJsonObject("fhirBundle"));
|
NamedElement bnd = new NamedElement(path, "json", org.hl7.fhir.utilities.json.parser.JsonParser.composeBytes(cs.getJsonObject("fhirBundle")));
|
||||||
if (e != null) {
|
res.add(bnd);
|
||||||
res.add(new NamedElement(path, e));
|
bnd.setElement(jsonParser.parse(bnd.getErrors(), cs.getJsonObject("fhirBundle")));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getImpliedProfile() {
|
public String getImpliedProfile() {
|
||||||
|
@ -163,27 +169,27 @@ public class SHCParser extends ParserBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean checkProperty(JsonObject obj, String path, String name, boolean required, String type) {
|
private boolean checkProperty(List<ValidationMessage> errors, JsonObject obj, String path, String name, boolean required, String type) {
|
||||||
JsonElement e = obj.get(name);
|
JsonElement e = obj.get(name);
|
||||||
if (e != null) {
|
if (e != null) {
|
||||||
String t = e.type().toName();
|
String t = e.type().toName();
|
||||||
if (!type.equals(t)) {
|
if (!type.equals(t)) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(e), col(e), path+"."+name, IssueType.STRUCTURE, "Wrong Property Type in JSON Payload. Expected : "+type+" but found "+t, IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(e), col(e), path+"."+name, IssueType.STRUCTURE, "Wrong Property Type in JSON Payload. Expected : "+type+" but found "+t, IssueSeverity.ERROR);
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (required) {
|
} else if (required) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(obj), col(obj), path, IssueType.STRUCTURE, "Missing Property in JSON Payload: "+name, IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(obj), col(obj), path, IssueType.STRUCTURE, "Missing Property in JSON Payload: "+name, IssueSeverity.ERROR);
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkNamedProperties(JsonObject obj, String path, String... names) {
|
private void checkNamedProperties(List<ValidationMessage> errors, JsonObject obj, String path, String... names) {
|
||||||
for (JsonProperty e : obj.getProperties()) {
|
for (JsonProperty e : obj.getProperties()) {
|
||||||
if (!Utilities.existsInList(e.getName(), names)) {
|
if (!Utilities.existsInList(e.getName(), names)) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(e.getValue()), col(e.getValue()), path+"."+e.getName(), IssueType.STRUCTURE, "Unknown Property in JSON Payload", IssueSeverity.WARNING);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(e.getValue()), col(e.getValue()), path+"."+e.getName(), IssueType.STRUCTURE, "Unknown Property in JSON Payload", IssueSeverity.WARNING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -242,12 +248,12 @@ public class SHCParser extends ParserBase {
|
||||||
return b.toString();
|
return b.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JWT decodeJWT(String jwt) throws IOException, DataFormatException {
|
public JWT decodeJWT(List<ValidationMessage> errors, String jwt) throws IOException, DataFormatException {
|
||||||
if (jwt.startsWith("shc:/")) {
|
if (jwt.startsWith("shc:/")) {
|
||||||
jwt = decodeQRCode(jwt);
|
jwt = decodeQRCode(jwt);
|
||||||
}
|
}
|
||||||
if (jwt.length() > MAX_ALLOWED_SHC_LENGTH) {
|
if (jwt.length() > MAX_ALLOWED_SHC_LENGTH) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, -1, -1, "jwt", IssueType.TOOLONG, "JWT Payload limit length is "+MAX_ALLOWED_SHC_LENGTH+" bytes for a single image - this has "+jwt.length()+" bytes", IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, -1, -1, "jwt", IssueType.TOOLONG, "JWT Payload limit length is "+MAX_ALLOWED_SHC_LENGTH+" bytes for a single image - this has "+jwt.length()+" bytes", IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] parts = splitToken(jwt);
|
String[] parts = splitToken(jwt);
|
||||||
|
|
|
@ -0,0 +1,468 @@
|
||||||
|
package org.hl7.fhir.r5.elementmodel;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.ZoneOffset;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.zip.DataFormatException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.zip.Inflater;
|
||||||
|
|
||||||
|
import org.hl7.fhir.exceptions.DefinitionException;
|
||||||
|
import org.hl7.fhir.exceptions.FHIRException;
|
||||||
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
|
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||||
|
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||||
|
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||||
|
import org.hl7.fhir.utilities.SimpleHTTPClient;
|
||||||
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
|
import org.hl7.fhir.utilities.VersionUtilities;
|
||||||
|
import org.hl7.fhir.utilities.SimpleHTTPClient.HTTPResult;
|
||||||
|
import org.hl7.fhir.utilities.json.model.JsonArray;
|
||||||
|
import org.hl7.fhir.utilities.json.model.JsonElement;
|
||||||
|
import org.hl7.fhir.utilities.json.model.JsonElementType;
|
||||||
|
import org.hl7.fhir.utilities.json.model.JsonObject;
|
||||||
|
import org.hl7.fhir.utilities.json.model.JsonPrimitive;
|
||||||
|
import org.hl7.fhir.utilities.json.model.JsonProperty;
|
||||||
|
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||||
|
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||||
|
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
|
||||||
|
|
||||||
|
import com.nimbusds.jose.JWEObject;
|
||||||
|
import com.nimbusds.jose.Payload;
|
||||||
|
import com.nimbusds.jose.crypto.DirectDecrypter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this class is actually a smart health link retreiver.
|
||||||
|
* It's going to parse the link, check it, and then return
|
||||||
|
* 2 items, the link with validation information in an Element, and the
|
||||||
|
* parsed whatever that the link pointed to
|
||||||
|
*
|
||||||
|
* Error locations in the first item are in the decoded JSON file the URL contains, or 0,0 if not in the json file
|
||||||
|
* Error locations in the second item are in the decoded payload
|
||||||
|
*
|
||||||
|
* @author grahame
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SHLParser extends ParserBase {
|
||||||
|
private static boolean testMode;
|
||||||
|
|
||||||
|
private boolean post = true;
|
||||||
|
private String url = null;
|
||||||
|
private byte[] key = null;
|
||||||
|
private String ct;
|
||||||
|
|
||||||
|
public SHLParser(IWorkerContext context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<NamedElement> parse(InputStream inStream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
||||||
|
byte[] content = TextFile.streamToBytes(inStream);
|
||||||
|
|
||||||
|
List<NamedElement> res = new ArrayList<>();
|
||||||
|
NamedElement shl = addNamedElement(res, "shl", "txt", content);
|
||||||
|
String src = TextFile.bytesToString(content);
|
||||||
|
|
||||||
|
if (src.startsWith("shlink:/")) {
|
||||||
|
src = src.substring(8);
|
||||||
|
} else if (src.contains("#shlink:/")) {
|
||||||
|
String pfx = src.substring(0, src.indexOf("#shlink:/"));
|
||||||
|
src = src.substring(src.indexOf("#shlink:/")+9);
|
||||||
|
if (!Utilities.isAbsoluteUrlLinkable(pfx)) {
|
||||||
|
logError(shl.getErrors(), "202-08-31", 1, 1, "shl", IssueType.STRUCTURE, "if a prefix is present, it must be a URL, not "+pfx, IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logError(shl.getErrors(), "202-08-31", 1, 1, "shl", IssueType.STRUCTURE, "This content does not appear to be an Smart Health Link", IssueSeverity.ERROR);
|
||||||
|
src = null;
|
||||||
|
}
|
||||||
|
if (src != null) {
|
||||||
|
byte[] cntin = Base64.getUrlDecoder().decode(src);
|
||||||
|
NamedElement json = addNamedElement(res, "json", "json", cntin);
|
||||||
|
JsonObject j = null;
|
||||||
|
try {
|
||||||
|
j = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(cntin);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logError(json.getErrors(), "202-08-31", 1, 1, "shl.json", IssueType.STRUCTURE, "The JSON is not valid: "+e.getMessage(), IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
if (j != null) {
|
||||||
|
byte[] cntout = org.hl7.fhir.utilities.json.parser.JsonParser.composeBytes(j, false);
|
||||||
|
if (!Arrays.equals(cntin, cntout)) {
|
||||||
|
logError(shl.getErrors(), "202-08-31", 1, 1, "shl", IssueType.STRUCTURE, "The JSON does not seem to be minified properly", IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
if (checkJson(json.getErrors(), j)) {
|
||||||
|
HTTPResult cnt = null;
|
||||||
|
if (post) {
|
||||||
|
try {
|
||||||
|
cnt = fetchManifest();
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
logError(json.getErrors(), "202-08-31", 1, 1, "shl.json", IssueType.STRUCTURE, "The manifest could not be fetched because the host "+e.getMessage()+" is unknown", IssueSeverity.ERROR);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logError(json.getErrors(), "202-08-31", 1, 1, "shl.json", IssueType.STRUCTURE, "The manifest could not be fetched: "+e.getMessage(), IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
if (cnt != null) {
|
||||||
|
if (cnt.getContentType() == null) {
|
||||||
|
logError(json.getErrors(), "202-08-31", 1, 1, "shl.json.url.fetch()", IssueType.NOTFOUND, "The server did not return a Content-Type header - should be 'application/json'", IssueSeverity.WARNING);
|
||||||
|
} else if (!"application/json".equals(cnt.getContentType())) {
|
||||||
|
logError(json.getErrors(), "202-08-31", 1, 1, "shl.json.url.fetch()", IssueType.STRUCTURE, "The server returned the wrong Content-Type header '"+cnt.getContentType()+"' - must be 'application/json'", IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
checkManifest(res, cnt);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
cnt = fetchFile(url+"?recipient=FHIR%20Validator", "application/jose");
|
||||||
|
} catch (Exception e) {
|
||||||
|
logError(json.getErrors(), "202-08-31", 1, 1, "shl,json.url", IssueType.STRUCTURE, "The document could not be fetched: "+e.getMessage(), IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
if (cnt != null) {
|
||||||
|
if (cnt.getContentType() == null) {
|
||||||
|
logError(json.getErrors(), "202-08-31", 1, 1, "shl.json.url.fetch()", IssueType.NOTFOUND, "The server did not return a Content-Type header - should be 'application/jose'", IssueSeverity.WARNING);
|
||||||
|
} else if (!"application/json".equals(cnt.getContentType())) {
|
||||||
|
logError(json.getErrors(), "202-08-31", 1, 1, "shl.json.url.fetch()", IssueType.STRUCTURE, "The server returned the wrong Content-Type header '"+cnt.getContentType()+"' - must be 'application/jose'", IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
processContent(res, json.getErrors(), "shl.url.fetched()", "document", cnt.getContentAsString(), ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void checkManifest(List<NamedElement> res, HTTPResult cnt) throws IOException {
|
||||||
|
NamedElement manifest = addNamedElement(res, "manifest", "json", cnt.getContent());
|
||||||
|
|
||||||
|
if (!cnt.getContentType().equals("application/json")) {
|
||||||
|
logError(manifest.getErrors(), "202-08-31", 1, 1, "manifest", IssueType.STRUCTURE, "The mime type should be application/json not "+cnt.getContentType(), IssueSeverity.ERROR);
|
||||||
|
} else {
|
||||||
|
JsonObject j = null;
|
||||||
|
try {
|
||||||
|
j = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(cnt.getContent());
|
||||||
|
} catch (Exception e) {
|
||||||
|
logError(manifest.getErrors(), "202-08-31", 1, 1, "manifest", IssueType.STRUCTURE, "The JSON is not valid: "+e.getMessage(), IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
if (j != null) {
|
||||||
|
for (JsonProperty p : j.getProperties()) {
|
||||||
|
if (!p.getName().equals("files")) {
|
||||||
|
logError(manifest.getErrors(), "202-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "manifest."+p.getName(),
|
||||||
|
IssueType.STRUCTURE, "Unexpected property name "+p.getName(), IssueSeverity.WARNING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j.has("files")) {
|
||||||
|
JsonElement f = j.get("files");
|
||||||
|
if (f.isJsonArray()) {
|
||||||
|
int i = 0;
|
||||||
|
for (JsonElement e : f.asJsonArray()) {
|
||||||
|
if (e.isJsonObject()) {
|
||||||
|
processManifestEntry(res, manifest.getErrors(), e.asJsonObject(), "manifest.files["+i+"]", "files["+i+"]");
|
||||||
|
} else {
|
||||||
|
logError(manifest.getErrors(), "202-08-31", e.getStart().getLine(), e.getStart().getCol(), "manifest.files["+i+"]",
|
||||||
|
IssueType.STRUCTURE, "files must be an object, not a "+f.type().name(), IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logError(manifest.getErrors(), "202-08-31", f.getStart().getLine(), f.getStart().getCol(), "manifest.files",
|
||||||
|
IssueType.STRUCTURE, "files must be an array, not a "+f.type().name(), IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logError(manifest.getErrors(), "202-08-31", j.getStart().getLine(), j.getStart().getCol(), "manifest",
|
||||||
|
IssueType.STRUCTURE, "files not found", IssueSeverity.WARNING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processManifestEntry(List<NamedElement> res, List<ValidationMessage> errors, JsonObject j, String path, String name) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
||||||
|
for (JsonProperty p : j.getProperties()) {
|
||||||
|
if (!Utilities.existsInList(p.getName(), "contentType", "location", "embedded")) {
|
||||||
|
logError(errors, "202-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "manifest."+p.getName(),
|
||||||
|
IssueType.STRUCTURE, "Unexpected property "+p.getName(), IssueSeverity.WARNING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JsonElement cte = j.get("contentType");
|
||||||
|
JsonElement loce = j.get("location");
|
||||||
|
JsonElement embe = j.get("embedded");
|
||||||
|
String ct = null;
|
||||||
|
if (cte == null) {
|
||||||
|
logError(errors, "202-08-31", j.getStart().getLine(), j.getStart().getCol(), path, IssueType.STRUCTURE, "contentType not found", IssueSeverity.ERROR);
|
||||||
|
} else if (!cte.isJsonString()) {
|
||||||
|
logError(errors, "202-08-31", j.getStart().getLine(), j.getStart().getCol(), path+".contentType", IssueType.STRUCTURE, "contentType must be a string not a "+cte.type().name(), IssueSeverity.ERROR);
|
||||||
|
} else {
|
||||||
|
ct = cte.asString();
|
||||||
|
if (!Utilities.existsInList(ct, "application/smart-health-card", "application/smart-api-access", "application/fhir+json")) {
|
||||||
|
logError(errors, "202-08-31", j.getStart().getLine(), j.getStart().getCol(), path+".contentType", IssueType.STRUCTURE, "contentType must be one of application/smart-health-card, application/smart-api-access or application/fhir+json", IssueSeverity.ERROR);
|
||||||
|
ct = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (loce != null && !loce.isJsonString()) {
|
||||||
|
logError(errors, "202-08-31", j.getStart().getLine(), j.getStart().getCol(), path+".location", IssueType.STRUCTURE, "location must be a string not a "+loce.type().name(), IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
if (embe != null && !embe.isJsonString()) {
|
||||||
|
logError(errors, "202-08-31", j.getStart().getLine(), j.getStart().getCol(), path+".embedded", IssueType.STRUCTURE, "embedded must be a string not a "+embe.type().name(), IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
if (loce == null && embe == null) {
|
||||||
|
logError(errors, "202-08-31", j.getStart().getLine(), j.getStart().getCol(), path, IssueType.STRUCTURE, "Found neither a location nor an embedded property", IssueSeverity.ERROR);
|
||||||
|
} else if (loce != null && embe != null) {
|
||||||
|
logError(errors, "202-08-31", j.getStart().getLine(), j.getStart().getCol(), path, IssueType.STRUCTURE, "Found both a location nor an embedded property - only one can be present", IssueSeverity.ERROR);
|
||||||
|
} else if (ct != null) {
|
||||||
|
if (embe != null) {
|
||||||
|
processContent(res, errors, path+".embedded", name, embe.asString(), ct);
|
||||||
|
} else if (loce != null) { // it will be, just removes a warning
|
||||||
|
HTTPResult cnt = null;
|
||||||
|
try {
|
||||||
|
cnt = fetchFile(loce.asString(), "application/jose");
|
||||||
|
} catch (Exception e) {
|
||||||
|
logError(errors, "202-08-31", 1, 1, "shl", IssueType.STRUCTURE, "The document could not be fetched: "+e.getMessage(), IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
if (cnt != null) {
|
||||||
|
if (cnt.getContentType() == null) {
|
||||||
|
logError(errors, "202-08-31", 1, 1, "shl.json.url.fetch()", IssueType.NOTFOUND, "The server did not return a Content-Type header - should be 'application/jose'", IssueSeverity.WARNING);
|
||||||
|
} else if (!"application/json".equals(cnt.getContentType())) {
|
||||||
|
logError(errors, "202-08-31", 1, 1, "shl.json.url.fetch()", IssueType.STRUCTURE, "The server returned the wrong Content-Type header '"+cnt.getContentType()+"' - must be 'application/jose'", IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
processContent(res, errors, path+".url.fetch()", name, cnt.getContentAsString(), ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processContent(List<NamedElement> res, List<ValidationMessage> errors, String path, String name, String jose, String ct) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
||||||
|
NamedElement bin = addNamedElement(res, "encrypted", "jose", TextFile.stringToBytes(jose, false));
|
||||||
|
byte[] cnt = null;
|
||||||
|
JWEObject jwe;
|
||||||
|
try {
|
||||||
|
jwe = JWEObject.parse(jose);
|
||||||
|
jwe.decrypt(new DirectDecrypter(key));
|
||||||
|
cnt = jwe.getPayload().toBytes();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logError(bin.getErrors(), "202-08-31", 1, 1, path, IssueType.STRUCTURE, "Decruption failed: "+e.getMessage(), IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
if (cnt != null) {
|
||||||
|
switch (ct) {
|
||||||
|
case "application/smart-health-card":
|
||||||
|
//a JSON file with a .verifiableCredential array containing SMART Health Card JWS strings, as specified by https://spec.smarthealth.cards#via-file-download.
|
||||||
|
SHCParser shc = new SHCParser(context);
|
||||||
|
res.addAll(shc.parse(new ByteArrayInputStream(cnt)));
|
||||||
|
break;
|
||||||
|
case "application/fhir+json":
|
||||||
|
NamedElement doc = addNamedElement(res, name, "json", cnt);
|
||||||
|
// a JSON file containing any FHIR resource (e.g., an individual resource or a Bundle of resources). Generally this format may not be tamper-proof.
|
||||||
|
logError(doc.getErrors(), "202-08-31", 1, 1, name, IssueType.STRUCTURE, "Processing content of type 'application/smart-api-access' is not done yet", IssueSeverity.INFORMATION);
|
||||||
|
break;
|
||||||
|
case "application/smart-api-access":
|
||||||
|
doc = addNamedElement(res, name, "api.json", cnt);
|
||||||
|
// a JSON file with a SMART Access Token Response (see SMART App Launch). Two additional properties are defined:
|
||||||
|
// aud Required string indicating the FHIR Server Base URL where this token can be used (e.g., "https://server.example.org/fhir")
|
||||||
|
// query: Optional array of strings acting as hints to the client, indicating queries it might want to make (e.g., ["Coverage?patient=123&_tag=family-insurance"])
|
||||||
|
logError(doc.getErrors(), "202-08-31", 1, 1, name, IssueType.STRUCTURE, "Processing content of type 'application/smart-api-access' is not done yet", IssueSeverity.INFORMATION);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
doc = addNamedElement(res, name, "bin", cnt);
|
||||||
|
logError(doc.getErrors(), "202-08-31", 1, 1, name, IssueType.STRUCTURE, "The Content-Type '"+ct+"' is not known", IssueSeverity.INFORMATION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private NamedElement addNamedElement(List<NamedElement> res, String name, String type, byte[] content) {
|
||||||
|
NamedElement result = new NamedElement(name, type, content);
|
||||||
|
res.add(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private HTTPResult fetchFile(String url, String ct) throws IOException {
|
||||||
|
SimpleHTTPClient fetcher = new SimpleHTTPClient();
|
||||||
|
fetcher.addHeader("Accept", ct);
|
||||||
|
HTTPResult res = fetcher.get(url);
|
||||||
|
res.checkThrowException();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private HTTPResult fetchManifest() throws IOException {
|
||||||
|
if (testMode) {
|
||||||
|
return new HTTPResult(url, 200, "OK", "application/json", TextFile.streamToBytes(TestingUtilities.loadTestResourceStream("validator", "shlink.manifest.json")));
|
||||||
|
}
|
||||||
|
SimpleHTTPClient fetcher = new SimpleHTTPClient();
|
||||||
|
JsonObject j = new JsonObject();
|
||||||
|
j.add("recipient", "FHIR Validator");
|
||||||
|
HTTPResult res = fetcher.post(url, "application/json", org.hl7.fhir.utilities.json.parser.JsonParser.composeBytes(j), "application/json");
|
||||||
|
res.checkThrowException();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkJson(List<ValidationMessage> errors, JsonObject j) {
|
||||||
|
boolean ok = true;
|
||||||
|
boolean fUrl = false;
|
||||||
|
boolean fKey = false;
|
||||||
|
boolean fCty = false;
|
||||||
|
boolean hp = false;
|
||||||
|
boolean hu = false;
|
||||||
|
for (JsonProperty p : j.getProperties()) {
|
||||||
|
switch (p.getName()) {
|
||||||
|
case "url":
|
||||||
|
fUrl = true;
|
||||||
|
if (!p.getValue().isJsonString()) {
|
||||||
|
logError(errors, "2023-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "shl."+p.getName(),
|
||||||
|
IssueType.STRUCTURE, "url must be a string", IssueSeverity.ERROR);
|
||||||
|
ok = false;
|
||||||
|
} else if (!Utilities.isAbsoluteUrlLinkable(p.getValue().asString())) {
|
||||||
|
logError(errors, "2023-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "shl."+p.getName(),
|
||||||
|
IssueType.STRUCTURE, "url is not valid: "+p.getValue().asString(), IssueSeverity.ERROR);
|
||||||
|
ok = false;
|
||||||
|
} else {
|
||||||
|
url = p.getValue().asString();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "key":
|
||||||
|
fKey = true;
|
||||||
|
if (!p.getValue().isJsonString()) {
|
||||||
|
logError(errors, "2023-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "shl."+p.getName(),
|
||||||
|
IssueType.STRUCTURE, "key must be a string", IssueSeverity.ERROR);
|
||||||
|
ok = false;
|
||||||
|
} else if (p.getValue().asString().length() != 43) {
|
||||||
|
logError(errors, "2023-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "shl."+p.getName(),
|
||||||
|
IssueType.STRUCTURE, "key must contain 43 chars", IssueSeverity.ERROR);
|
||||||
|
ok = false;
|
||||||
|
} else {
|
||||||
|
key = Base64.getUrlDecoder().decode(p.getValue().asString());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "exp":
|
||||||
|
if (!p.getValue().isJsonNumber()) {
|
||||||
|
logError(errors, "2023-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "shl."+p.getName(),
|
||||||
|
IssueType.STRUCTURE, "exp must be a number", IssueSeverity.ERROR);
|
||||||
|
} else if (!Utilities.isDecimal(p.getValue().asJsonNumber().getValue(), false)) {
|
||||||
|
logError(errors, "2023-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "shl."+p.getName(),
|
||||||
|
IssueType.STRUCTURE, "exp must be a valid number", IssueSeverity.ERROR);
|
||||||
|
} else {
|
||||||
|
String v = p.getValue().asJsonNumber().getValue();
|
||||||
|
if (v.contains(".")) {
|
||||||
|
v = v.substring(0, v.indexOf("."));
|
||||||
|
}
|
||||||
|
|
||||||
|
long epochSecs = Long.valueOf(v);
|
||||||
|
LocalDateTime date = LocalDateTime.ofEpochSecond(epochSecs, 0, ZoneOffset.UTC);
|
||||||
|
LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
|
||||||
|
Duration duration = Duration.between(now, date);
|
||||||
|
|
||||||
|
if (date.isBefore(now)) {
|
||||||
|
logError(errors, "2023-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "shl."+p.getName(),
|
||||||
|
IssueType.STRUCTURE, "The content has expired (by "+Utilities.describeDuration(duration)+")", IssueSeverity.WARNING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "flag":
|
||||||
|
if (!p.getValue().isJsonString()) {
|
||||||
|
logError(errors, "2023-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "shl."+p.getName(),
|
||||||
|
IssueType.STRUCTURE, "flag must be a string", IssueSeverity.ERROR);
|
||||||
|
} else {
|
||||||
|
String flag = p.getValue().asString();
|
||||||
|
for (char c : flag.toCharArray()) {
|
||||||
|
switch (c) {
|
||||||
|
case 'L': // ok
|
||||||
|
break;
|
||||||
|
case 'P':
|
||||||
|
hp = true;
|
||||||
|
break;
|
||||||
|
case 'U':
|
||||||
|
hu = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logError(errors, "2023-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "shl."+p.getName(),
|
||||||
|
IssueType.STRUCTURE, "Illegal Character "+c+" in flag", IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hu && hp) {
|
||||||
|
logError(errors, "2023-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "shl."+p.getName(),
|
||||||
|
IssueType.STRUCTURE, "Illegal combination in flag: both P and U are present", IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
if (hp) {
|
||||||
|
logError(errors, "2023-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "shl."+p.getName(),
|
||||||
|
IssueType.BUSINESSRULE, "The validator is unable to retrieve the content referred to by the URL because a password is required", IssueSeverity.INFORMATION);
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
if (hu) {
|
||||||
|
post = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "label":
|
||||||
|
if (!p.getValue().isJsonString()) {
|
||||||
|
logError(errors, "2023-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "shl."+p.getName(),
|
||||||
|
IssueType.STRUCTURE, "label must be a string", IssueSeverity.ERROR);
|
||||||
|
} else if (p.getValue().asString().length() > 80) {
|
||||||
|
logError(errors, "2023-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "shl."+p.getName(),
|
||||||
|
IssueType.STRUCTURE, "label must be no longer than 80 chars", IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "cty" :
|
||||||
|
if (!p.getValue().isJsonString()) {
|
||||||
|
logError(errors, "2023-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "shl."+p.getName(),
|
||||||
|
IssueType.STRUCTURE, "cty must be a string", IssueSeverity.ERROR);
|
||||||
|
} else if (!Utilities.existsInList(p.getValue().asString(), "application/smart-health-card", "application/smart-api-access", "application/fhir+json")) {
|
||||||
|
logError(errors, "2023-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "shl."+p.getName(),
|
||||||
|
IssueType.STRUCTURE, "cty must be one of 'application/smart-health-card/, 'application/smart-api-access', 'application/fhir+json'", IssueSeverity.ERROR);
|
||||||
|
} else {
|
||||||
|
ct = p.getValue().asString();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "v":
|
||||||
|
if (!p.getValue().isJsonString()) {
|
||||||
|
logError(errors, "2023-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "shl."+p.getName(),
|
||||||
|
IssueType.STRUCTURE, "v must be a string", IssueSeverity.ERROR);
|
||||||
|
} else if (p.getValue().asString().length() <= 80) {
|
||||||
|
logError(errors, "2023-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "shl."+p.getName(),
|
||||||
|
IssueType.STRUCTURE, "if present, v must be '1'", IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
logError(errors, "202-08-31", p.getValue().getStart().getLine(), p.getValue().getStart().getCol(), "shl."+p.getName(),
|
||||||
|
IssueType.STRUCTURE, "Illegal property name "+p.getName(), IssueSeverity.ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hu && !fCty) {
|
||||||
|
logError(errors, "202-08-31", 1, 1, "shl", IssueType.STRUCTURE, "Flag 'U' found, but no 'cty' header which is required for the U flag", IssueSeverity.ERROR);
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
if (!fUrl) {
|
||||||
|
logError(errors, "202-08-31", 1, 1, "shl", IssueType.STRUCTURE, "No url found", IssueSeverity.ERROR);
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
if (!fKey) {
|
||||||
|
logError(errors, "202-08-31", 1, 1, "shl", IssueType.STRUCTURE, "No key found", IssueSeverity.ERROR);
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void compose(Element e, OutputStream destination, OutputStyle style, String base) throws FHIRException, IOException {
|
||||||
|
throw new FHIRFormatError("Writing resources is not supported for the SHL format");
|
||||||
|
// because then we'd have to try to sign, and we're just not going to be doing that from the element model
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isTestMode() {
|
||||||
|
return testMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setTestMode(boolean testMode) {
|
||||||
|
SHLParser.testMode = testMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
package org.hl7.fhir.r5.elementmodel;
|
package org.hl7.fhir.r5.elementmodel;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2011+, HL7, Inc.
|
Copyright (c) 2011+, HL7, Inc.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
@ -43,6 +45,7 @@ import org.hl7.fhir.exceptions.FHIRException;
|
||||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
import org.hl7.fhir.r5.elementmodel.Element.SpecialElement;
|
import org.hl7.fhir.r5.elementmodel.Element.SpecialElement;
|
||||||
|
import org.hl7.fhir.r5.elementmodel.ParserBase.NamedElement;
|
||||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||||
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
import org.hl7.fhir.r5.model.ElementDefinition.TypeRefComponent;
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
|
@ -78,53 +81,52 @@ public class TurtleParser extends ParserBase {
|
||||||
super(context);
|
super(context);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public List<NamedElement> parse(InputStream input) throws IOException, FHIRException {
|
public List<NamedElement> parse(InputStream inStream) throws IOException, FHIRException {
|
||||||
List<NamedElement> res = new ArrayList<>();
|
byte[] content = TextFile.streamToBytes(inStream);
|
||||||
|
NamedElement ctxt = new NamedElement("focus", "ttl", content);
|
||||||
|
ByteArrayInputStream stream = new ByteArrayInputStream(content);
|
||||||
|
|
||||||
Turtle src = new Turtle();
|
Turtle src = new Turtle();
|
||||||
if (policy == ValidationPolicy.EVERYTHING) {
|
if (policy == ValidationPolicy.EVERYTHING) {
|
||||||
try {
|
try {
|
||||||
src.parse(TextFile.streamToString(input));
|
src.parse(TextFile.streamToString(stream));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, -1, -1, "(document)", IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_TURTLE_, e.getMessage()), IssueSeverity.FATAL);
|
logError(ctxt.getErrors(), ValidationMessage.NO_RULE_DATE, -1, -1, "(document)", IssueType.INVALID, context.formatMessage(I18nConstants.ERROR_PARSING_TURTLE_, e.getMessage()), IssueSeverity.FATAL);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Element e = parse(src);
|
ctxt.setElement(parse(ctxt.getErrors(), src));
|
||||||
if (e != null) {
|
|
||||||
res.add(new NamedElement(null, e));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
src.parse(TextFile.streamToString(input));
|
src.parse(TextFile.streamToString(stream));
|
||||||
Element e = parse(src);
|
ctxt.setElement(parse(ctxt.getErrors(), src));
|
||||||
if (e != null) {
|
|
||||||
res.add(new NamedElement(null, e));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
List<NamedElement> res = new ArrayList<>();
|
||||||
|
res.add(ctxt);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Element parse(Turtle src) throws FHIRException {
|
private Element parse(List<ValidationMessage> errors, Turtle src) throws FHIRException {
|
||||||
// we actually ignore the stated URL here
|
// we actually ignore the stated URL here
|
||||||
for (TTLComplex cmp : src.getObjects().values()) {
|
for (TTLComplex cmp : src.getObjects().values()) {
|
||||||
for (String p : cmp.getPredicates().keySet()) {
|
for (String p : cmp.getPredicates().keySet()) {
|
||||||
if ((FHIR_URI_BASE + "nodeRole").equals(p) && cmp.getPredicates().get(p).hasValue(FHIR_URI_BASE + "treeRoot")) {
|
if ((FHIR_URI_BASE + "nodeRole").equals(p) && cmp.getPredicates().get(p).hasValue(FHIR_URI_BASE + "treeRoot")) {
|
||||||
return parse(src, cmp);
|
return parse(errors, src, cmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// still here: well, we didn't find a start point
|
// still here: well, we didn't find a start point
|
||||||
String msg = "Error parsing Turtle: unable to find any node maked as the entry point (where " + FHIR_URI_BASE + "nodeRole = " + FHIR_URI_BASE + "treeRoot)";
|
String msg = "Error parsing Turtle: unable to find any node maked as the entry point (where " + FHIR_URI_BASE + "nodeRole = " + FHIR_URI_BASE + "treeRoot)";
|
||||||
if (policy == ValidationPolicy.EVERYTHING) {
|
if (policy == ValidationPolicy.EVERYTHING) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, -1, -1, "(document)", IssueType.INVALID, msg, IssueSeverity.FATAL);
|
logError(errors, ValidationMessage.NO_RULE_DATE, -1, -1, "(document)", IssueType.INVALID, msg, IssueSeverity.FATAL);
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
throw new FHIRFormatError(msg);
|
throw new FHIRFormatError(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Element parse(Turtle src, TTLComplex cmp) throws FHIRException {
|
private Element parse(List<ValidationMessage> errors, Turtle src, TTLComplex cmp) throws FHIRException {
|
||||||
TTLObject type = cmp.getPredicates().get("http://www.w3.org/2000/01/rdf-schema#type");
|
TTLObject type = cmp.getPredicates().get("http://www.w3.org/2000/01/rdf-schema#type");
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, cmp.getLine(), cmp.getCol(), "(document)", IssueType.INVALID, context.formatMessage(I18nConstants.UNKNOWN_RESOURCE_TYPE_MISSING_RDFSTYPE), IssueSeverity.FATAL);
|
logError(errors, ValidationMessage.NO_RULE_DATE, cmp.getLine(), cmp.getCol(), "(document)", IssueType.INVALID, context.formatMessage(I18nConstants.UNKNOWN_RESOURCE_TYPE_MISSING_RDFSTYPE), IssueSeverity.FATAL);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (type instanceof TTLList) {
|
if (type instanceof TTLList) {
|
||||||
|
@ -137,7 +139,7 @@ public class TurtleParser extends ParserBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(type instanceof TTLURL)) {
|
if (!(type instanceof TTLURL)) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, cmp.getLine(), cmp.getCol(), "(document)", IssueType.INVALID, context.formatMessage(I18nConstants.UNEXPECTED_DATATYPE_FOR_RDFSTYPE), IssueSeverity.FATAL);
|
logError(errors, ValidationMessage.NO_RULE_DATE, cmp.getLine(), cmp.getCol(), "(document)", IssueType.INVALID, context.formatMessage(I18nConstants.UNEXPECTED_DATATYPE_FOR_RDFSTYPE), IssueSeverity.FATAL);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String name = ((TTLURL) type).getUri();
|
String name = ((TTLURL) type).getUri();
|
||||||
|
@ -145,19 +147,19 @@ public class TurtleParser extends ParserBase {
|
||||||
name = name.substring(name.lastIndexOf("/")+1);
|
name = name.substring(name.lastIndexOf("/")+1);
|
||||||
String path = "/"+name;
|
String path = "/"+name;
|
||||||
|
|
||||||
StructureDefinition sd = getDefinition(cmp.getLine(), cmp.getCol(), ns, name);
|
StructureDefinition sd = getDefinition(errors, cmp.getLine(), cmp.getCol(), ns, name);
|
||||||
if (sd == null)
|
if (sd == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
Element result = new Element(name, new Property(context, sd.getSnapshot().getElement().get(0), sd));
|
Element result = new Element(name, new Property(context, sd.getSnapshot().getElement().get(0), sd));
|
||||||
result.markLocation(cmp.getLine(), cmp.getCol());
|
result.markLocation(cmp.getLine(), cmp.getCol());
|
||||||
result.setType(name);
|
result.setType(name);
|
||||||
parseChildren(src, path, cmp, result, false);
|
parseChildren(errors, src, path, cmp, result, false);
|
||||||
result.numberChildren();
|
result.numberChildren();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseChildren(Turtle src, String path, TTLComplex object, Element element, boolean primitive) throws FHIRException {
|
private void parseChildren(List<ValidationMessage> errors, Turtle src, String path, TTLComplex object, Element element, boolean primitive) throws FHIRException {
|
||||||
|
|
||||||
List<Property> properties = element.getProperty().getChildProperties(element.getName(), null);
|
List<Property> properties = element.getProperty().getChildProperties(element.getName(), null);
|
||||||
Set<String> processed = new HashSet<String>();
|
Set<String> processed = new HashSet<String>();
|
||||||
|
@ -170,10 +172,10 @@ public class TurtleParser extends ParserBase {
|
||||||
if (property.isChoice()) {
|
if (property.isChoice()) {
|
||||||
for (TypeRefComponent type : property.getDefinition().getType()) {
|
for (TypeRefComponent type : property.getDefinition().getType()) {
|
||||||
String eName = property.getName().substring(0, property.getName().length()-3) + Utilities.capitalize(type.getCode());
|
String eName = property.getName().substring(0, property.getName().length()-3) + Utilities.capitalize(type.getCode());
|
||||||
parseChild(src, object, element, processed, property, path, getFormalName(property, eName));
|
parseChild(errors, src, object, element, processed, property, path, getFormalName(property, eName));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
parseChild(src, object, element, processed, property, path, getFormalName(property));
|
parseChild(errors, src, object, element, processed, property, path, getFormalName(property));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,13 +184,13 @@ public class TurtleParser extends ParserBase {
|
||||||
for (String u : object.getPredicates().keySet()) {
|
for (String u : object.getPredicates().keySet()) {
|
||||||
if (!processed.contains(u)) {
|
if (!processed.contains(u)) {
|
||||||
TTLObject n = object.getPredicates().get(u);
|
TTLObject n = object.getPredicates().get(u);
|
||||||
logError(ValidationMessage.NO_RULE_DATE, n.getLine(), n.getCol(), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.UNRECOGNISED_PREDICATE_, u), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, n.getLine(), n.getCol(), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.UNRECOGNISED_PREDICATE_, u), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseChild(Turtle src, TTLComplex object, Element context, Set<String> processed, Property property, String path, String name) throws FHIRException {
|
private void parseChild(List<ValidationMessage> errors, Turtle src, TTLComplex object, Element context, Set<String> processed, Property property, String path, String name) throws FHIRException {
|
||||||
processed.add(name);
|
processed.add(name);
|
||||||
String npath = path+"/"+property.getName();
|
String npath = path+"/"+property.getName();
|
||||||
TTLObject e = object.getPredicates().get(FHIR_URI_BASE + name);
|
TTLObject e = object.getPredicates().get(FHIR_URI_BASE + name);
|
||||||
|
@ -197,22 +199,22 @@ public class TurtleParser extends ParserBase {
|
||||||
if (property.isList() && (e instanceof TTLList)) {
|
if (property.isList() && (e instanceof TTLList)) {
|
||||||
TTLList arr = (TTLList) e;
|
TTLList arr = (TTLList) e;
|
||||||
for (TTLObject am : arr.getList()) {
|
for (TTLObject am : arr.getList()) {
|
||||||
parseChildInstance(src, npath, object, context, property, name, am);
|
parseChildInstance(errors, src, npath, object, context, property, name, am);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
parseChildInstance(src, npath, object, context, property, name, e);
|
parseChildInstance(errors, src, npath, object, context, property, name, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseChildInstance(Turtle src, String npath, TTLComplex object, Element element, Property property, String name, TTLObject e) throws FHIRException {
|
private void parseChildInstance(List<ValidationMessage> errors, Turtle src, String npath, TTLComplex object, Element element, Property property, String name, TTLObject e) throws FHIRException {
|
||||||
if (property.isResource())
|
if (property.isResource())
|
||||||
parseResource(src, npath, object, element, property, name, e);
|
parseResource(errors, src, npath, object, element, property, name, e);
|
||||||
else if (e instanceof TTLComplex) {
|
else if (e instanceof TTLComplex) {
|
||||||
TTLComplex child = (TTLComplex) e;
|
TTLComplex child = (TTLComplex) e;
|
||||||
Element n = new Element(tail(name), property).markLocation(e.getLine(), e.getCol());
|
Element n = new Element(tail(name), property).markLocation(e.getLine(), e.getCol());
|
||||||
element.getChildren().add(n);
|
element.getChildren().add(n);
|
||||||
if (property.isPrimitive(property.getType(tail(name)))) {
|
if (property.isPrimitive(property.getType(tail(name)))) {
|
||||||
parseChildren(src, npath, child, n, true);
|
parseChildren(errors, src, npath, child, n, true);
|
||||||
TTLObject val = child.getPredicates().get(FHIR_URI_BASE + "value");
|
TTLObject val = child.getPredicates().get(FHIR_URI_BASE + "value");
|
||||||
if (val != null) {
|
if (val != null) {
|
||||||
if (val instanceof TTLLiteral) {
|
if (val instanceof TTLLiteral) {
|
||||||
|
@ -221,13 +223,13 @@ public class TurtleParser extends ParserBase {
|
||||||
// todo: check type
|
// todo: check type
|
||||||
n.setValue(value);
|
n.setValue(value);
|
||||||
} else
|
} else
|
||||||
logError(ValidationMessage.NO_RULE_DATE, object.getLine(), object.getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_A_LITERAL_NOT_, "a "+e.getClass().getName()), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, object.getLine(), object.getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_A_LITERAL_NOT_, "a "+e.getClass().getName()), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
parseChildren(src, npath, child, n, false);
|
parseChildren(errors, src, npath, child, n, false);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
logError(ValidationMessage.NO_RULE_DATE, object.getLine(), object.getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_A_URI_OR_BNODE_NOT_, "a "+e.getClass().getName()), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, object.getLine(), object.getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.THIS_PROPERTY_MUST_BE_A_URI_OR_BNODE_NOT_, "a "+e.getClass().getName()), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -235,7 +237,7 @@ public class TurtleParser extends ParserBase {
|
||||||
return name.substring(name.lastIndexOf(".")+1);
|
return name.substring(name.lastIndexOf(".")+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseResource(Turtle src, String npath, TTLComplex object, Element element, Property property, String name, TTLObject e) throws FHIRException {
|
private void parseResource(List<ValidationMessage> errors, Turtle src, String npath, TTLComplex object, Element element, Property property, String name, TTLObject e) throws FHIRException {
|
||||||
TTLComplex obj;
|
TTLComplex obj;
|
||||||
if (e instanceof TTLComplex)
|
if (e instanceof TTLComplex)
|
||||||
obj = (TTLComplex) e;
|
obj = (TTLComplex) e;
|
||||||
|
@ -243,7 +245,7 @@ public class TurtleParser extends ParserBase {
|
||||||
String url = ((TTLURL) e).getUri();
|
String url = ((TTLURL) e).getUri();
|
||||||
obj = src.getObject(url);
|
obj = src.getObject(url);
|
||||||
if (obj == null) {
|
if (obj == null) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, e.getLine(), e.getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.REFERENCE_TO__CANNOT_BE_RESOLVED, url), IssueSeverity.FATAL);
|
logError(errors, ValidationMessage.NO_RULE_DATE, e.getLine(), e.getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.REFERENCE_TO__CANNOT_BE_RESOLVED, url), IssueSeverity.FATAL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
@ -251,7 +253,7 @@ public class TurtleParser extends ParserBase {
|
||||||
|
|
||||||
TTLObject type = obj.getPredicates().get("http://www.w3.org/2000/01/rdf-schema#type");
|
TTLObject type = obj.getPredicates().get("http://www.w3.org/2000/01/rdf-schema#type");
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, object.getLine(), object.getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.UNKNOWN_RESOURCE_TYPE_MISSING_RDFSTYPE), IssueSeverity.FATAL);
|
logError(errors, ValidationMessage.NO_RULE_DATE, object.getLine(), object.getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.UNKNOWN_RESOURCE_TYPE_MISSING_RDFSTYPE), IssueSeverity.FATAL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (type instanceof TTLList) {
|
if (type instanceof TTLList) {
|
||||||
|
@ -264,14 +266,14 @@ public class TurtleParser extends ParserBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(type instanceof TTLURL)) {
|
if (!(type instanceof TTLURL)) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, object.getLine(), object.getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.UNEXPECTED_DATATYPE_FOR_RDFSTYPE), IssueSeverity.FATAL);
|
logError(errors, ValidationMessage.NO_RULE_DATE, object.getLine(), object.getCol(), npath, IssueType.INVALID, context.formatMessage(I18nConstants.UNEXPECTED_DATATYPE_FOR_RDFSTYPE), IssueSeverity.FATAL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String rt = ((TTLURL) type).getUri();
|
String rt = ((TTLURL) type).getUri();
|
||||||
String ns = rt.substring(0, rt.lastIndexOf("/"));
|
String ns = rt.substring(0, rt.lastIndexOf("/"));
|
||||||
rt = rt.substring(rt.lastIndexOf("/")+1);
|
rt = rt.substring(rt.lastIndexOf("/")+1);
|
||||||
|
|
||||||
StructureDefinition sd = getDefinition(object.getLine(), object.getCol(), ns, rt);
|
StructureDefinition sd = getDefinition(errors, object.getLine(), object.getCol(), ns, rt);
|
||||||
if (sd == null)
|
if (sd == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -279,7 +281,7 @@ public class TurtleParser extends ParserBase {
|
||||||
element.getChildren().add(n);
|
element.getChildren().add(n);
|
||||||
n.updateProperty(new Property(this.context, sd.getSnapshot().getElement().get(0), sd), SpecialElement.fromProperty(n.getProperty()), property);
|
n.updateProperty(new Property(this.context, sd.getSnapshot().getElement().get(0), sd), SpecialElement.fromProperty(n.getProperty()), property);
|
||||||
n.setType(rt);
|
n.setType(rt);
|
||||||
parseChildren(src, npath, obj, n, false);
|
parseChildren(errors, src, npath, obj, n, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getFormalName(Property property) {
|
private String getFormalName(Property property) {
|
||||||
|
|
|
@ -32,6 +32,7 @@ package org.hl7.fhir.r5.elementmodel;
|
||||||
|
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
@ -45,6 +46,7 @@ import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||||
import org.hl7.fhir.r5.context.IWorkerContext;
|
import org.hl7.fhir.r5.context.IWorkerContext;
|
||||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||||
import org.hl7.fhir.r5.model.StructureDefinition;
|
import org.hl7.fhir.r5.model.StructureDefinition;
|
||||||
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides special support for parsing v2 by the v2 logical model
|
* This class provides special support for parsing v2 by the v2 logical model
|
||||||
|
@ -452,16 +454,18 @@ public class VerticalBarParser extends ParserBase {
|
||||||
private Delimiters delimiters = new Delimiters();
|
private Delimiters delimiters = new Delimiters();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<NamedElement> parse(InputStream stream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
public List<NamedElement> parse(InputStream inStream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
||||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/v2/StructureDefinition/Message");
|
StructureDefinition sd = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/v2/StructureDefinition/Message");
|
||||||
Element message = new Element("Message", new Property(context, sd.getSnapshot().getElementFirstRep(), sd));
|
Element message = new Element("Message", new Property(context, sd.getSnapshot().getElementFirstRep(), sd));
|
||||||
|
byte[] content = TextFile.streamToBytes(inStream);
|
||||||
|
ByteArrayInputStream stream = new ByteArrayInputStream(content);
|
||||||
VerticalBarParserReader reader = new VerticalBarParserReader(new BufferedInputStream(stream), charset);
|
VerticalBarParserReader reader = new VerticalBarParserReader(new BufferedInputStream(stream), charset);
|
||||||
|
|
||||||
preDecode(reader);
|
preDecode(reader);
|
||||||
while (!reader.isFinished()) // && (getOptions().getSegmentLimit() == 0 || getOptions().getSegmentLimit() > message.getSegments().size()))
|
while (!reader.isFinished()) // && (getOptions().getSegmentLimit() == 0 || getOptions().getSegmentLimit() > message.getSegments().size()))
|
||||||
readSegment(message, reader);
|
readSegment(message, reader);
|
||||||
List<NamedElement> res = new ArrayList<>();
|
List<NamedElement> res = new ArrayList<>();
|
||||||
res.add(new NamedElement(null, message));
|
res.add(new NamedElement("focus", "hl7", message, content));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package org.hl7.fhir.r5.elementmodel;
|
package org.hl7.fhir.r5.elementmodel;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2011+, HL7, Inc.
|
Copyright (c) 2011+, HL7, Inc.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
@ -64,6 +66,7 @@ import org.hl7.fhir.r5.utils.formats.XmlLocationAnnotator;
|
||||||
import org.hl7.fhir.r5.utils.formats.XmlLocationData;
|
import org.hl7.fhir.r5.utils.formats.XmlLocationData;
|
||||||
import org.hl7.fhir.utilities.ElementDecoration;
|
import org.hl7.fhir.utilities.ElementDecoration;
|
||||||
import org.hl7.fhir.utilities.StringPair;
|
import org.hl7.fhir.utilities.StringPair;
|
||||||
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||||
|
@ -108,8 +111,12 @@ public class XmlParser extends ParserBase {
|
||||||
this.allowXsiLocation = allowXsiLocation;
|
this.allowXsiLocation = allowXsiLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<NamedElement> parse(InputStream stream) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
public List<NamedElement> parse(InputStream inStream) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
||||||
List<NamedElement> res = new ArrayList<>();
|
|
||||||
|
byte[] content = TextFile.streamToBytes(inStream);
|
||||||
|
NamedElement context = new NamedElement("focus", "xml", content);
|
||||||
|
|
||||||
|
ByteArrayInputStream stream = new ByteArrayInputStream(content);
|
||||||
Document doc = null;
|
Document doc = null;
|
||||||
try {
|
try {
|
||||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
|
@ -125,11 +132,11 @@ public class XmlParser extends ParserBase {
|
||||||
if (policy == ValidationPolicy.EVERYTHING) {
|
if (policy == ValidationPolicy.EVERYTHING) {
|
||||||
// The SAX interface appears to not work when reporting the correct version/encoding.
|
// The SAX interface appears to not work when reporting the correct version/encoding.
|
||||||
// if we can, we'll inspect the header/encoding ourselves
|
// if we can, we'll inspect the header/encoding ourselves
|
||||||
if (stream.markSupported()) {
|
|
||||||
stream.mark(1024);
|
stream.mark(1024);
|
||||||
version = checkHeader(stream);
|
version = checkHeader(context.getErrors(), stream);
|
||||||
stream.reset();
|
stream.reset();
|
||||||
}
|
|
||||||
// use a slower parser that keeps location data
|
// use a slower parser that keeps location data
|
||||||
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||||
Transformer nullTransformer = transformerFactory.newTransformer();
|
Transformer nullTransformer = transformerFactory.newTransformer();
|
||||||
|
@ -161,18 +168,17 @@ public class XmlParser extends ParserBase {
|
||||||
if (e.getMessage().contains("lineNumber:") && e.getMessage().contains("columnNumber:")) {
|
if (e.getMessage().contains("lineNumber:") && e.getMessage().contains("columnNumber:")) {
|
||||||
int line = Utilities.parseInt(extractVal(e.getMessage(), "lineNumber"), 0);
|
int line = Utilities.parseInt(extractVal(e.getMessage(), "lineNumber"), 0);
|
||||||
int col = Utilities.parseInt(extractVal(e.getMessage(), "columnNumber"), 0);
|
int col = Utilities.parseInt(extractVal(e.getMessage(), "columnNumber"), 0);
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line, col, "(xml)", IssueType.INVALID, e.getMessage().substring(e.getMessage().lastIndexOf(";")+1).trim(), IssueSeverity.FATAL);
|
logError(context.getErrors(), ValidationMessage.NO_RULE_DATE, line, col, "(xml)", IssueType.INVALID, e.getMessage().substring(e.getMessage().lastIndexOf(";")+1).trim(), IssueSeverity.FATAL);
|
||||||
} else {
|
} else {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, 0, 0, "(xml)", IssueType.INVALID, e.getMessage(), IssueSeverity.FATAL);
|
logError(context.getErrors(), ValidationMessage.NO_RULE_DATE, 0, 0, "(xml)", IssueType.INVALID, e.getMessage(), IssueSeverity.FATAL);
|
||||||
}
|
}
|
||||||
doc = null;
|
doc = null;
|
||||||
}
|
}
|
||||||
if (doc != null) {
|
if (doc != null) {
|
||||||
Element e = parse(doc);
|
context.setElement(parse(context.getErrors(), doc));
|
||||||
if (e != null) {
|
|
||||||
res.add(new NamedElement(null, e));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
List<NamedElement> res = new ArrayList<>();
|
||||||
|
res.add(context);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,12 +188,12 @@ public class XmlParser extends ParserBase {
|
||||||
src = src.substring(0, src.indexOf(";")).trim();
|
src = src.substring(0, src.indexOf(";")).trim();
|
||||||
return src;
|
return src;
|
||||||
}
|
}
|
||||||
private void checkForProcessingInstruction(Document document) throws FHIRFormatError {
|
private void checkForProcessingInstruction(List<ValidationMessage> errors, Document document) throws FHIRFormatError {
|
||||||
if (policy == ValidationPolicy.EVERYTHING && FormatUtilities.FHIR_NS.equals(document.getDocumentElement().getNamespaceURI())) {
|
if (policy == ValidationPolicy.EVERYTHING && FormatUtilities.FHIR_NS.equals(document.getDocumentElement().getNamespaceURI())) {
|
||||||
Node node = document.getFirstChild();
|
Node node = document.getFirstChild();
|
||||||
while (node != null) {
|
while (node != null) {
|
||||||
if (node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE)
|
if (node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE)
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(document, false), col(document, false), "(document)", IssueType.INVALID, context.formatMessage(
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(document, false), col(document, false), "(document)", IssueType.INVALID, context.formatMessage(
|
||||||
I18nConstants.NO_PROCESSING_INSTRUCTIONS_ALLOWED_IN_RESOURCES), IssueSeverity.ERROR);
|
I18nConstants.NO_PROCESSING_INSTRUCTIONS_ALLOWED_IN_RESOURCES), IssueSeverity.ERROR);
|
||||||
node = node.getNextSibling();
|
node = node.getNextSibling();
|
||||||
}
|
}
|
||||||
|
@ -205,27 +211,27 @@ public class XmlParser extends ParserBase {
|
||||||
return loc == null ? 0 : end ? loc.getEndColumn() : loc.getStartColumn();
|
return loc == null ? 0 : end ? loc.getEndColumn() : loc.getStartColumn();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Element parse(Document doc) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
public Element parse(List<ValidationMessage> errors, Document doc) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
||||||
checkForProcessingInstruction(doc);
|
checkForProcessingInstruction(errors, doc);
|
||||||
org.w3c.dom.Element element = doc.getDocumentElement();
|
org.w3c.dom.Element element = doc.getDocumentElement();
|
||||||
return parse(element);
|
return parse(errors, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Element parse(org.w3c.dom.Element element) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
public Element parse(List<ValidationMessage> errors, org.w3c.dom.Element element) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
||||||
String ns = element.getNamespaceURI();
|
String ns = element.getNamespaceURI();
|
||||||
String name = element.getLocalName();
|
String name = element.getLocalName();
|
||||||
String path = "/"+pathPrefix(ns)+name;
|
String path = "/"+pathPrefix(ns)+name;
|
||||||
|
|
||||||
StructureDefinition sd = getDefinition(line(element, false), col(element, false), (ns == null ? "noNamespace" : ns), name);
|
StructureDefinition sd = getDefinition(errors, line(element, false), col(element, false), (ns == null ? "noNamespace" : ns), name);
|
||||||
if (sd == null)
|
if (sd == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
Element result = new Element(element.getLocalName(), new Property(context, sd.getSnapshot().getElement().get(0), sd));
|
Element result = new Element(element.getLocalName(), new Property(context, sd.getSnapshot().getElement().get(0), sd));
|
||||||
result.setPath(element.getLocalName());
|
result.setPath(element.getLocalName());
|
||||||
checkElement(element, path, result.getProperty());
|
checkElement(errors, element, path, result.getProperty());
|
||||||
result.markLocation(line(element, false), col(element, false));
|
result.markLocation(line(element, false), col(element, false));
|
||||||
result.setType(element.getLocalName());
|
result.setType(element.getLocalName());
|
||||||
parseChildren(path, element, result);
|
parseChildren(errors, path, element, result);
|
||||||
result.numberChildren();
|
result.numberChildren();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -264,33 +270,33 @@ public class XmlParser extends ParserBase {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkElement(org.w3c.dom.Element element, String path, Property prop) throws FHIRFormatError {
|
private void checkElement(List<ValidationMessage> errors, org.w3c.dom.Element element, String path, Property prop) throws FHIRFormatError {
|
||||||
if (policy == ValidationPolicy.EVERYTHING) {
|
if (policy == ValidationPolicy.EVERYTHING) {
|
||||||
if (empty(element) && FormatUtilities.FHIR_NS.equals(element.getNamespaceURI())) // this rule only applies to FHIR Content
|
if (empty(element) && FormatUtilities.FHIR_NS.equals(element.getNamespaceURI())) // this rule only applies to FHIR Content
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(element, false), col(element, false), path, IssueType.INVALID, context.formatMessage(I18nConstants.ELEMENT_MUST_HAVE_SOME_CONTENT), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(element, false), col(element, false), path, IssueType.INVALID, context.formatMessage(I18nConstants.ELEMENT_MUST_HAVE_SOME_CONTENT), IssueSeverity.ERROR);
|
||||||
String ns = prop.getXmlNamespace();
|
String ns = prop.getXmlNamespace();
|
||||||
String elementNs = element.getNamespaceURI();
|
String elementNs = element.getNamespaceURI();
|
||||||
if (elementNs == null) {
|
if (elementNs == null) {
|
||||||
elementNs = "noNamespace";
|
elementNs = "noNamespace";
|
||||||
}
|
}
|
||||||
if (!elementNs.equals(ns))
|
if (!elementNs.equals(ns))
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(element, false), col(element, false), path, IssueType.INVALID, context.formatMessage(I18nConstants.WRONG_NAMESPACE__EXPECTED_, ns), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(element, false), col(element, false), path, IssueType.INVALID, context.formatMessage(I18nConstants.WRONG_NAMESPACE__EXPECTED_, ns), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Element parse(org.w3c.dom.Element base, String type) throws Exception {
|
public Element parse(List<ValidationMessage> errors, org.w3c.dom.Element base, String type) throws Exception {
|
||||||
StructureDefinition sd = getDefinition(0, 0, FormatUtilities.FHIR_NS, type);
|
StructureDefinition sd = getDefinition(errors, 0, 0, FormatUtilities.FHIR_NS, type);
|
||||||
Element result = new Element(base.getLocalName(), new Property(context, sd.getSnapshot().getElement().get(0), sd));
|
Element result = new Element(base.getLocalName(), new Property(context, sd.getSnapshot().getElement().get(0), sd));
|
||||||
result.setPath(base.getLocalName());
|
result.setPath(base.getLocalName());
|
||||||
String path = "/"+pathPrefix(base.getNamespaceURI())+base.getLocalName();
|
String path = "/"+pathPrefix(base.getNamespaceURI())+base.getLocalName();
|
||||||
checkElement(base, path, result.getProperty());
|
checkElement(errors, base, path, result.getProperty());
|
||||||
result.setType(base.getLocalName());
|
result.setType(base.getLocalName());
|
||||||
parseChildren(path, base, result);
|
parseChildren(errors, path, base, result);
|
||||||
result.numberChildren();
|
result.numberChildren();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseChildren(String path, org.w3c.dom.Element node, Element element) throws FHIRFormatError, FHIRException, IOException, DefinitionException {
|
private void parseChildren(List<ValidationMessage> errors, String path, org.w3c.dom.Element node, Element element) throws FHIRFormatError, FHIRException, IOException, DefinitionException {
|
||||||
// this parsing routine retains the original order in a the XML file, to support validation
|
// this parsing routine retains the original order in a the XML file, to support validation
|
||||||
reapComments(node, element);
|
reapComments(node, element);
|
||||||
List<Property> properties = element.getProperty().getChildProperties(element.getName(), XMLUtil.getXsiType(node));
|
List<Property> properties = element.getProperty().getChildProperties(element.getName(), XMLUtil.getXsiType(node));
|
||||||
|
@ -333,7 +339,7 @@ public class XmlParser extends ParserBase {
|
||||||
}
|
}
|
||||||
line = line(nt, end);
|
line = line(nt, end);
|
||||||
col = col(nt, end);
|
col = col(nt, end);
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line, col, path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.TEXT_SHOULD_NOT_BE_PRESENT, Utilities.makeSingleLine(n.getTextContent().trim())), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line, col, path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.TEXT_SHOULD_NOT_BE_PRESENT, Utilities.makeSingleLine(n.getTextContent().trim())), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
n = n.getNextSibling();
|
n = n.getNextSibling();
|
||||||
}
|
}
|
||||||
|
@ -344,7 +350,7 @@ public class XmlParser extends ParserBase {
|
||||||
Node attr = node.getAttributes().item(i);
|
Node attr = node.getAttributes().item(i);
|
||||||
String value = attr.getNodeValue();
|
String value = attr.getNodeValue();
|
||||||
if (!validAttrValue(value)) {
|
if (!validAttrValue(value)) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line, col, path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.XML_ATTR_VALUE_INVALID, attr.getNodeName()), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line, col, path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.XML_ATTR_VALUE_INVALID, attr.getNodeName()), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
if (!(attr.getNodeName().equals("xmlns") || attr.getNodeName().startsWith("xmlns:"))) {
|
if (!(attr.getNodeName().equals("xmlns") || attr.getNodeName().startsWith("xmlns:"))) {
|
||||||
Property property = getAttrProp(properties, attr.getLocalName(), attr.getNamespaceURI());
|
Property property = getAttrProp(properties, attr.getLocalName(), attr.getNamespaceURI());
|
||||||
|
@ -369,7 +375,7 @@ public class XmlParser extends ParserBase {
|
||||||
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(ValidationMessage.NO_RULE_DATE, 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(errors, ValidationMessage.NO_RULE_DATE, 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -397,7 +403,7 @@ public class XmlParser extends ParserBase {
|
||||||
xhtml = xp.parseHtmlNode((org.w3c.dom.Element) child);
|
xhtml = xp.parseHtmlNode((org.w3c.dom.Element) child);
|
||||||
if (policy == ValidationPolicy.EVERYTHING) {
|
if (policy == ValidationPolicy.EVERYTHING) {
|
||||||
for (StringPair s : xp.getValidationIssues()) {
|
for (StringPair s : xp.getValidationIssues()) {
|
||||||
logError("2022-11-17", line(child, false), col(child, false), path, IssueType.INVALID, context.formatMessage(s.getName(), s.getValue()), IssueSeverity.ERROR);
|
logError(errors, "2022-11-17", line(child, false), col(child, false), path, IssueType.INVALID, context.formatMessage(s.getName(), s.getValue()), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,7 +418,7 @@ public class XmlParser extends ParserBase {
|
||||||
} else {
|
} else {
|
||||||
n.setPath(element.getPath()+"."+property.getName());
|
n.setPath(element.getPath()+"."+property.getName());
|
||||||
}
|
}
|
||||||
checkElement((org.w3c.dom.Element) child, npath, n.getProperty());
|
checkElement(errors, (org.w3c.dom.Element) child, npath, n.getProperty());
|
||||||
boolean ok = true;
|
boolean ok = true;
|
||||||
if (property.isChoice()) {
|
if (property.isChoice()) {
|
||||||
if (property.getDefinition().hasRepresentation(PropertyRepresentation.TYPEATTR)) {
|
if (property.getDefinition().hasRepresentation(PropertyRepresentation.TYPEATTR)) {
|
||||||
|
@ -422,7 +428,7 @@ public class XmlParser extends ParserBase {
|
||||||
xsiType = ToolingExtensions.readStringExtension(property.getDefinition(), "http://hl7.org/fhir/StructureDefinition/elementdefinition-defaulttype");
|
xsiType = ToolingExtensions.readStringExtension(property.getDefinition(), "http://hl7.org/fhir/StructureDefinition/elementdefinition-defaulttype");
|
||||||
n.setType(xsiType);
|
n.setType(xsiType);
|
||||||
} else {
|
} else {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(child, false), col(child, false), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.NO_TYPE_FOUND_ON_, child.getLocalName()), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(child, false), col(child, false), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.NO_TYPE_FOUND_ON_, child.getLocalName()), IssueSeverity.ERROR);
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -437,18 +443,18 @@ public class XmlParser extends ParserBase {
|
||||||
element.getChildren().add(n);
|
element.getChildren().add(n);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
if (property.isResource())
|
if (property.isResource())
|
||||||
parseResource(npath, (org.w3c.dom.Element) child, n, property);
|
parseResource(errors, npath, (org.w3c.dom.Element) child, n, property);
|
||||||
else
|
else
|
||||||
parseChildren(npath, (org.w3c.dom.Element) child, n);
|
parseChildren(errors, npath, (org.w3c.dom.Element) child, n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(child, false), col(child, false), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.UNDEFINED_ELEMENT_, child.getLocalName(), path), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(child, false), col(child, false), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.UNDEFINED_ELEMENT_, child.getLocalName(), path), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
} else if (child.getNodeType() == Node.CDATA_SECTION_NODE){
|
} else if (child.getNodeType() == Node.CDATA_SECTION_NODE){
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(child, false), col(child, false), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.CDATA_IS_NOT_ALLOWED), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(child, false), col(child, false), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.CDATA_IS_NOT_ALLOWED), IssueSeverity.ERROR);
|
||||||
} else if (!Utilities.existsInList(child.getNodeType(), 3, 8)) {
|
} else if (!Utilities.existsInList(child.getNodeType(), 3, 8)) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, line(child, false), col(child, false), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.NODE_TYPE__IS_NOT_ALLOWED, Integer.toString(child.getNodeType())), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, line(child, false), col(child, false), path, IssueType.STRUCTURE, context.formatMessage(I18nConstants.NODE_TYPE__IS_NOT_ALLOWED, Integer.toString(child.getNodeType())), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
child = child.getNextSibling();
|
child = child.getNextSibling();
|
||||||
}
|
}
|
||||||
|
@ -542,7 +548,7 @@ public class XmlParser extends ParserBase {
|
||||||
throw new FHIRException(context.formatMessage(I18nConstants.UNKNOWN_DATE_FORMAT_, fmt));
|
throw new FHIRException(context.formatMessage(I18nConstants.UNKNOWN_DATE_FORMAT_, fmt));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseResource(String string, org.w3c.dom.Element container, Element parent, Property elementProperty) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
private void parseResource(List<ValidationMessage> errors, String string, org.w3c.dom.Element container, Element parent, Property elementProperty) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
||||||
org.w3c.dom.Element res = XMLUtil.getFirstChild(container);
|
org.w3c.dom.Element res = XMLUtil.getFirstChild(container);
|
||||||
String name = res.getLocalName();
|
String name = res.getLocalName();
|
||||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(name, null));
|
StructureDefinition sd = context.fetchResource(StructureDefinition.class, ProfileUtilities.sdNs(name, null));
|
||||||
|
@ -550,7 +556,7 @@ public class XmlParser extends ParserBase {
|
||||||
throw new FHIRFormatError(context.formatMessage(I18nConstants.CONTAINED_RESOURCE_DOES_NOT_APPEAR_TO_BE_A_FHIR_RESOURCE_UNKNOWN_NAME_, res.getLocalName()));
|
throw new FHIRFormatError(context.formatMessage(I18nConstants.CONTAINED_RESOURCE_DOES_NOT_APPEAR_TO_BE_A_FHIR_RESOURCE_UNKNOWN_NAME_, res.getLocalName()));
|
||||||
parent.updateProperty(new Property(context, sd.getSnapshot().getElement().get(0), sd), SpecialElement.fromProperty(parent.getProperty()), elementProperty);
|
parent.updateProperty(new Property(context, sd.getSnapshot().getElement().get(0), sd), SpecialElement.fromProperty(parent.getProperty()), elementProperty);
|
||||||
parent.setType(name);
|
parent.setType(name);
|
||||||
parseChildren(res.getLocalName(), res, parent);
|
parseChildren(errors, res.getLocalName(), res, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reapComments(org.w3c.dom.Element element, Element context) {
|
private void reapComments(org.w3c.dom.Element element, Element context) {
|
||||||
|
@ -767,7 +773,7 @@ public class XmlParser extends ParserBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String checkHeader(InputStream stream) throws IOException {
|
private String checkHeader(List<ValidationMessage> errors, InputStream stream) throws IOException {
|
||||||
try {
|
try {
|
||||||
// the stream will either start with the UTF-8 BOF or with <xml
|
// the stream will either start with the UTF-8 BOF or with <xml
|
||||||
int i0 = stream.read();
|
int i0 = stream.read();
|
||||||
|
@ -803,7 +809,7 @@ public class XmlParser extends ParserBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (e != null && !"UTF-8".equalsIgnoreCase(e)) {
|
if (e != null && !"UTF-8".equalsIgnoreCase(e)) {
|
||||||
logError(ValidationMessage.NO_RULE_DATE, 0, 0, "XML", IssueType.INVALID, context.formatMessage(I18nConstants.XML_ENCODING_INVALID), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, 0, 0, "XML", IssueType.INVALID, context.formatMessage(I18nConstants.XML_ENCODING_INVALID), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
i = header.indexOf("version=\"");
|
i = header.indexOf("version=\"");
|
||||||
|
@ -818,7 +824,7 @@ public class XmlParser extends ParserBase {
|
||||||
return "?xml-p1?";
|
return "?xml-p1?";
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// suppress this error
|
// suppress this error
|
||||||
logError(ValidationMessage.NO_RULE_DATE, 0, 0, "XML", IssueType.INVALID, e.getMessage(), IssueSeverity.ERROR);
|
logError(errors, ValidationMessage.NO_RULE_DATE, 0, 0, "XML", IssueType.INVALID, e.getMessage(), IssueSeverity.ERROR);
|
||||||
}
|
}
|
||||||
return "?xml-p2?";
|
return "?xml-p2?";
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,7 @@ public class CodeSystemUtilities {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(ConceptDefinitionComponent o1, ConceptDefinitionComponent o2) {
|
public int compare(ConceptDefinitionComponent o1, ConceptDefinitionComponent o2) {
|
||||||
return o1.getCode().compareToIgnoreCase(o2.getCode());
|
return o1.hasCode() ? o1.getCode().compareToIgnoreCase(o2.getCode()) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -252,7 +252,7 @@ public class CodeSystemUtilities {
|
||||||
private static String defineProperty(CodeSystem cs, String code, PropertyType pt) {
|
private static String defineProperty(CodeSystem cs, String code, PropertyType pt) {
|
||||||
String url = "http://hl7.org/fhir/concept-properties#"+code;
|
String url = "http://hl7.org/fhir/concept-properties#"+code;
|
||||||
for (PropertyComponent p : cs.getProperty()) {
|
for (PropertyComponent p : cs.getProperty()) {
|
||||||
if (p.getCode().equals(code)) {
|
if (p.hasCode() && p.getCode().equals(code)) {
|
||||||
if (!p.getUri().equals(url)) {
|
if (!p.getUri().equals(url)) {
|
||||||
throw new Error("URI mismatch for code "+code+" url = "+p.getUri()+" vs "+url);
|
throw new Error("URI mismatch for code "+code+" url = "+p.getUri()+" vs "+url);
|
||||||
}
|
}
|
||||||
|
@ -391,7 +391,7 @@ public class CodeSystemUtilities {
|
||||||
|
|
||||||
public static void defineCodeSystemProperty(CodeSystem cs, String code, String description, PropertyType type) {
|
public static void defineCodeSystemProperty(CodeSystem cs, String code, String description, PropertyType type) {
|
||||||
for (PropertyComponent p : cs.getProperty()) {
|
for (PropertyComponent p : cs.getProperty()) {
|
||||||
if (p.getCode().equals(code))
|
if (p.hasCode() && p.getCode().equals(code))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cs.addProperty().setCode(code).setDescription(description).setType(type).setUri("http://hl7.org/fhir/concept-properties#"+code);
|
cs.addProperty().setCode(code).setDescription(description).setType(type).setUri("http://hl7.org/fhir/concept-properties#"+code);
|
||||||
|
@ -466,7 +466,7 @@ public class CodeSystemUtilities {
|
||||||
|
|
||||||
public static ConceptDefinitionComponent findCode(List<ConceptDefinitionComponent> list, String code) {
|
public static ConceptDefinitionComponent findCode(List<ConceptDefinitionComponent> list, String code) {
|
||||||
for (ConceptDefinitionComponent c : list) {
|
for (ConceptDefinitionComponent c : list) {
|
||||||
if (c.getCode().equals(code))
|
if (c.hasCode() && c.getCode().equals(code))
|
||||||
return c;
|
return c;
|
||||||
ConceptDefinitionComponent s = findCode(c.getConcept(), code);
|
ConceptDefinitionComponent s = findCode(c.getConcept(), code);
|
||||||
if (s != null)
|
if (s != null)
|
||||||
|
@ -477,7 +477,7 @@ public class CodeSystemUtilities {
|
||||||
|
|
||||||
public static ConceptDefinitionComponent findCodeOrAltCode(List<ConceptDefinitionComponent> list, String code, String use) {
|
public static ConceptDefinitionComponent findCodeOrAltCode(List<ConceptDefinitionComponent> list, String code, String use) {
|
||||||
for (ConceptDefinitionComponent c : list) {
|
for (ConceptDefinitionComponent c : list) {
|
||||||
if (c.getCode().equals(code))
|
if (c.hasCode() && c.getCode().equals(code))
|
||||||
return c;
|
return c;
|
||||||
for (ConceptPropertyComponent p : c.getProperty()) {
|
for (ConceptPropertyComponent p : c.getProperty()) {
|
||||||
if ("alternateCode".equals(p.getCode()) && (use == null || hasUse(p, use)) && p.hasValue() && p.getValue().isPrimitive() && code.equals(p.getValue().primitiveValue())) {
|
if ("alternateCode".equals(p.getCode()) && (use == null || hasUse(p, use)) && p.hasValue() && p.getValue().isPrimitive() && code.equals(p.getValue().primitiveValue())) {
|
||||||
|
@ -537,29 +537,30 @@ public class CodeSystemUtilities {
|
||||||
|
|
||||||
public static DataType readProperty(ConceptDefinitionComponent concept, String code) {
|
public static DataType readProperty(ConceptDefinitionComponent concept, String code) {
|
||||||
for (ConceptPropertyComponent p : concept.getProperty())
|
for (ConceptPropertyComponent p : concept.getProperty())
|
||||||
if (p.getCode().equals(code))
|
if (p.hasCode() && p.getCode().equals(code))
|
||||||
return p.getValue();
|
return p.getValue();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConceptPropertyComponent getProperty(ConceptDefinitionComponent concept, String code) {
|
public static ConceptPropertyComponent getProperty(ConceptDefinitionComponent concept, String code) {
|
||||||
for (ConceptPropertyComponent p : concept.getProperty())
|
for (ConceptPropertyComponent p : concept.getProperty())
|
||||||
if (p.getCode().equals(code))
|
if (p.hasCode() && p.getCode().equals(code))
|
||||||
return p;
|
return p;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<ConceptPropertyComponent> getPropertyValues(ConceptDefinitionComponent concept, String code) {
|
public static List<ConceptPropertyComponent> getPropertyValues(ConceptDefinitionComponent concept, String code) {
|
||||||
List<ConceptPropertyComponent> res = new ArrayList<>();
|
List<ConceptPropertyComponent> res = new ArrayList<>();
|
||||||
for (ConceptPropertyComponent p : concept.getProperty()) {
|
if (code != null) {
|
||||||
if (p.getCode().equals(code)) {
|
for (ConceptPropertyComponent p : concept.getProperty()) {
|
||||||
res.add(p);
|
if (code.equals(p.getCode())) {
|
||||||
|
res.add(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// see http://hl7.org/fhir/R4/codesystem.html#hierachy
|
// see http://hl7.org/fhir/R4/codesystem.html#hierachy
|
||||||
// returns additional parents not in the heirarchy
|
// returns additional parents not in the heirarchy
|
||||||
public static List<String> getOtherChildren(CodeSystem cs, ConceptDefinitionComponent c) {
|
public static List<String> getOtherChildren(CodeSystem cs, ConceptDefinitionComponent c) {
|
||||||
|
@ -828,7 +829,7 @@ public class CodeSystemUtilities {
|
||||||
|
|
||||||
private static String defineProperty(CodeSystem cs, PropertyComponent pd, PropertyType pt) {
|
private static String defineProperty(CodeSystem cs, PropertyComponent pd, PropertyType pt) {
|
||||||
for (PropertyComponent p : cs.getProperty()) {
|
for (PropertyComponent p : cs.getProperty()) {
|
||||||
if (p.getCode().equals(pd.getCode())) {
|
if (p.hasCode() && p.getCode().equals(pd.getCode())) {
|
||||||
if (!p.getUri().equals(pd.getUri())) {
|
if (!p.getUri().equals(pd.getUri())) {
|
||||||
throw new Error("URI mismatch for code "+pd.getCode()+" url = "+p.getUri()+" vs "+pd.getUri());
|
throw new Error("URI mismatch for code "+pd.getCode()+" url = "+p.getUri()+" vs "+pd.getUri());
|
||||||
}
|
}
|
||||||
|
@ -846,7 +847,7 @@ public class CodeSystemUtilities {
|
||||||
|
|
||||||
private static PropertyComponent getPropertyDefinition(CodeSystem cs, ConceptPropertyComponent p) {
|
private static PropertyComponent getPropertyDefinition(CodeSystem cs, ConceptPropertyComponent p) {
|
||||||
for (PropertyComponent t : cs.getProperty()) {
|
for (PropertyComponent t : cs.getProperty()) {
|
||||||
if (t.getCode().equals(p.getCode())) {
|
if (t.hasCode() && t.getCode().equals(p.getCode())) {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -881,7 +882,7 @@ public class CodeSystemUtilities {
|
||||||
|
|
||||||
public static boolean hasPropertyDef(CodeSystem cs, String property) {
|
public static boolean hasPropertyDef(CodeSystem cs, String property) {
|
||||||
for (PropertyComponent pd : cs.getProperty()) {
|
for (PropertyComponent pd : cs.getProperty()) {
|
||||||
if (pd.getCode().equals(property)) {
|
if (pd.hasCode() && pd.getCode().equals(property)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -688,10 +688,10 @@ public class ValueSetValidator extends ValueSetProcessBase {
|
||||||
ConceptDefinitionComponent cc = cs.hasUserData("tx.cs.special") ? ((SpecialCodeSystem) cs.getUserData("tx.cs.special")).findConcept(code) : findCodeInConcept(cs.getConcept(), code.getCode(), allAltCodes);
|
ConceptDefinitionComponent cc = cs.hasUserData("tx.cs.special") ? ((SpecialCodeSystem) cs.getUserData("tx.cs.special")).findConcept(code) : findCodeInConcept(cs.getConcept(), code.getCode(), allAltCodes);
|
||||||
if (cc == null) {
|
if (cc == null) {
|
||||||
if (cs.getContent() == CodeSystemContentMode.FRAGMENT) {
|
if (cs.getContent() == CodeSystemContentMode.FRAGMENT) {
|
||||||
String msg = context.formatMessage(I18nConstants.UNKNOWN_CODE__IN_FRAGMENT, code.getCode(), cs.getUrl());
|
String msg = context.formatMessage(I18nConstants.UNKNOWN_CODE__IN_FRAGMENT, code.getCode(), cs.getVersionedUrl());
|
||||||
return new ValidationResult(IssueSeverity.WARNING, msg, makeIssue(IssueSeverity.ERROR, IssueType.CODEINVALID, path+".code", msg));
|
return new ValidationResult(IssueSeverity.WARNING, msg, makeIssue(IssueSeverity.ERROR, IssueType.CODEINVALID, path+".code", msg));
|
||||||
} else {
|
} else {
|
||||||
String msg = context.formatMessage(I18nConstants.UNKNOWN_CODE__IN_, code.getCode(), cs.getUrl());
|
String msg = context.formatMessage(I18nConstants.UNKNOWN_CODE__IN_, code.getCode(), cs.getVersionedUrl());
|
||||||
return new ValidationResult(IssueSeverity.ERROR, msg, makeIssue(IssueSeverity.ERROR, IssueType.CODEINVALID, path+".code", msg));
|
return new ValidationResult(IssueSeverity.ERROR, msg, makeIssue(IssueSeverity.ERROR, IssueType.CODEINVALID, path+".code", msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,14 @@ public class CommaSeparatedStringBuilder {
|
||||||
return b.toString();
|
return b.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String join(String sep, String[] list) {
|
||||||
|
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(sep);
|
||||||
|
for (String s : list) {
|
||||||
|
b.append(s);
|
||||||
|
}
|
||||||
|
return b.toString();
|
||||||
|
}
|
||||||
|
|
||||||
public static String build(List<String> list) {
|
public static String build(List<String> list) {
|
||||||
CommaSeparatedStringBuilder self = new CommaSeparatedStringBuilder();
|
CommaSeparatedStringBuilder self = new CommaSeparatedStringBuilder();
|
||||||
for (String s : list) {
|
for (String s : list) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ public class SimpleHTTPClient {
|
||||||
TOKEN
|
TOKEN
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Header {
|
public static class Header {
|
||||||
private String name;
|
private String name;
|
||||||
private String value;
|
private String value;
|
||||||
public Header(String name, String value) {
|
public Header(String name, String value) {
|
||||||
|
@ -44,7 +44,7 @@ public class SimpleHTTPClient {
|
||||||
private static final int MAX_REDIRECTS = 5;
|
private static final int MAX_REDIRECTS = 5;
|
||||||
private static int counter = 1;
|
private static int counter = 1;
|
||||||
|
|
||||||
public class HTTPResult {
|
public static class HTTPResult {
|
||||||
private int code;
|
private int code;
|
||||||
private String contentType;
|
private String contentType;
|
||||||
private byte[] content;
|
private byte[] content;
|
||||||
|
@ -90,6 +90,10 @@ public class SimpleHTTPClient {
|
||||||
|
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContentAsString() {
|
||||||
|
return new String(content, StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,22 @@ public class PackageList {
|
||||||
json.set("date", date);
|
json.set("date", date);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPartofMainSpec() {
|
public List<String> subPackages() {
|
||||||
|
List<String> list = new ArrayList<>();
|
||||||
|
if (json.has("sub-packages")) {
|
||||||
|
list.addAll(json.getStrings("sub-packages"));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearSubPackages() {
|
||||||
|
json.remove("sub-packages");
|
||||||
|
}
|
||||||
|
public void addSubPackage(String s) {
|
||||||
|
json.forceArray("sub-packages").add(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isPartofMainSpec() {
|
||||||
return Utilities.startsWithInList(path(), "http://hl7.org/fhir/DSTU2", "http://hl7.org/fhir/2015Sep", "http://hl7.org/fhir/2015May");
|
return Utilities.startsWithInList(path(), "http://hl7.org/fhir/DSTU2", "http://hl7.org/fhir/2015Sep", "http://hl7.org/fhir/2015May");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -787,22 +787,22 @@ BUNDLE_BUNDLE_POSSIBLE_MATCH_NO_FU = Entry {0} matches the reference {1} by type
|
||||||
BUNDLE_BUNDLE_POSSIBLE_MATCH_WRONG_FU = Entry {0} matches the reference {1} by type and id but it''s fullUrl {2} does not match the full target URL {3} by Bundle resolution rules
|
BUNDLE_BUNDLE_POSSIBLE_MATCH_WRONG_FU = Entry {0} matches the reference {1} by type and id but it''s fullUrl {2} does not match the full target URL {3} by Bundle resolution rules
|
||||||
SD_ILLEGAL_CHARACTERISTICS = This element has a {0} but the types {1} do not make this kind of constraint relevant
|
SD_ILLEGAL_CHARACTERISTICS = This element has a {0} but the types {1} do not make this kind of constraint relevant
|
||||||
SD_VALUE_COMPLEX_FIXED = For the complex type {0}, consider using a pattern rather than a fixed value to avoid over-constraining the instance
|
SD_VALUE_COMPLEX_FIXED = For the complex type {0}, consider using a pattern rather than a fixed value to avoid over-constraining the instance
|
||||||
VALUESET_SHAREABLE_MISSING = The ShareableValueSet profile says that the {0} element is mandatory, but it is not present. Published value sets SHOULD conform to the ShareableValueSet profile
|
VALUESET_SHAREABLE_MISSING = Published value sets SHOULD conform to the ShareableValueSet profile, which says that the element ValueSet.{0} is mandatory, but it is not present
|
||||||
VALUESET_SHAREABLE_EXTRA_MISSING = The ShareableValueSet profile recommends that the {0} element is populated, but it is not present. Published value sets SHOULD conform to the ShareableValueSet profile
|
VALUESET_SHAREABLE_EXTRA_MISSING = Published value sets SHOULD conform to the ShareableValueSet profile, which says that the element ValueSet.{0} should be present, but it is not
|
||||||
VALUESET_SHAREABLE_MISSING_HL7 = The ShareableValueSet profile says that the {0} element is mandatory, but it is not found. HL7 Published value sets SHALL conform to the ShareableValueSet profile
|
VALUESET_SHAREABLE_MISSING_HL7 = Published value sets SHALL conform to the ShareableValueSet profile, which says that the element ValueSet.{0} is mandatory, but it is not present
|
||||||
VALUESET_SHAREABLE_EXTRA_MISSING_HL7 = The ShareableValueSet profile recommends that the {0} element is populated, but it is not found. HL7 Published value sets SHALL conform to the ShareableValueSet profile
|
VALUESET_SHAREABLE_EXTRA_MISSING_HL7 = Published value sets SHALL conform to the ShareableValueSet profile, which says that the element ValueSet.{0} should be present, but it is not
|
||||||
CODESYSTEM_SHAREABLE_MISSING = The ShareableCodeSystem profile says that the {0} element is mandatory, but it is not present. Published code systems SHOULD conform to the ShareableCodeSystem profile
|
CODESYSTEM_SHAREABLE_MISSING = Published code systems SHOULD conform to the ShareableCodeSystem profile, which says that the element CodeSystem.{0} is mandatory, but it is not present
|
||||||
CODESYSTEM_SHAREABLE_EXTRA_MISSING = The ShareableCodeSystem profile recommends that the {0} element is populated, but it is not present. Published code systems SHOULD conform to the ShareableCodeSystem profile
|
CODESYSTEM_SHAREABLE_EXTRA_MISSING = Published code systems SHOULD conform to the ShareableCodeSystem profile, which says that the element CodeSystem.{0} should be present, but it is not
|
||||||
CODESYSTEM_SHAREABLE_MISSING_HL7 = The ShareableCodeSystem profile says that the {0} element is mandatory, but it is not found. HL7 Published code systems SHALL conform to the ShareableCodeSystem profile
|
CODESYSTEM_SHAREABLE_MISSING_HL7 = Published code systems SHALL conform to the ShareableCodeSystem profile, which says that the element CodeSystem.{0} is mandatory, but it is not present
|
||||||
CODESYSTEM_SHAREABLE_EXTRA_MISSING_HL7 = The ShareableCodeSystem profile recommends that the {0} element is populated, but it is not found. HL7 Published code systems SHALL conform to the ShareableCodeSystem profile
|
CODESYSTEM_SHAREABLE_EXTRA_MISSING_HL7 = Published code systems SHALL conform to the ShareableCodeSystem profile, which says that the element CodeSystem.{0} should be present, but it is not
|
||||||
CONCEPTMAP_SHAREABLE_MISSING = The ShareableConceptMap profile says that the {0} element is mandatory, but it is not present. Published concept maps SHOULD conform to the ShareableConceptMap profile
|
CONCEPTMAP_SHAREABLE_MISSING = Published concept maps SHOULD conform to the ShareableConceptMap profile, which says that the element ConceptMap.{0} is mandatory, but it is not present
|
||||||
CONCEPTMAP_SHAREABLE_EXTRA_MISSING = The ShareableConceptMap profile recommends that the {0} element is populated, but it is not present. Published concept maps SHOULD conform to the ShareableConceptMap profile
|
CONCEPTMAP_SHAREABLE_EXTRA_MISSING = Published concept maps SHOULD conform to the ShareableConceptMap profile, which says that the element ConceptMap.{0} should be present, but it is not
|
||||||
CONCEPTMAP_SHAREABLE_MISSING_HL7 = The ShareableConceptMap profile says that the {0} element is mandatory, but it is not found. HL7 Published concept maps SHALL conform to the ShareableConceptMap profile
|
CONCEPTMAP_SHAREABLE_MISSING_HL7 = Published concept maps SHALL conform to the ShareableConceptMap profile, which says that the element ConceptMap.{0} is mandatory, but it is not present
|
||||||
CONCEPTMAP_SHAREABLE_EXTRA_MISSING_HL7 = The ShareableConceptMap profile recommends that the {0} element is populated, but it is not found. HL7 Published concept maps SHALL conform to the ShareableConceptMap profile
|
CONCEPTMAP_SHAREABLE_EXTRA_MISSING_HL7 = Published concept maps SHALL conform to the ShareableConceptMap profile, which says that the element ConceptMap.{0} should be present, but it is not
|
||||||
MEASURE_SHAREABLE_MISSING = The ShareableMeasure profile says that the {0} element is mandatory, but it is not present. Published measures SHOULD conform to the ShareableMeasure profile
|
MEASURE_SHAREABLE_MISSING = Published measures SHOULD conform to the ShareableMeasure profile, which says that the element Measure.{0} is mandatory, but it is not present
|
||||||
MEASURE_SHAREABLE_EXTRA_MISSING = The ShareableMeasure profile recommends that the {0} element is populated, but it is not present. Published measures SHOULD conform to the ShareableMeasure profile
|
MEASURE_SHAREABLE_EXTRA_MISSING = Published measures SHOULD conform to the ShareableMeasure profile, which says that the element Measure.{0} should be present, but it is not
|
||||||
MEASURE_SHAREABLE_MISSING_HL7 = The ShareableMeasure profile says that the {0} element is mandatory, but it is not found. HL7 Published measures SHALL conform to the ShareableMeasure profile
|
MEASURE_SHAREABLE_MISSING_HL7 = Published measures SHALL conform to the ShareableMeasure profile, which says that the element Measure.{0} is mandatory, but it is not present
|
||||||
MEASURE_SHAREABLE_EXTRA_MISSING_HL7 = The ShareableMeasure profile recommends that the {0} element is populated, but it is not found. HL7 Published measures SHALL conform to the ShareableMeasure profile
|
MEASURE_SHAREABLE_EXTRA_MISSING_HL7 = Published measures SHALL conform to the ShareableMeasure profile, which says that the element Measure.{0} should be present, but it is not
|
||||||
TYPE_SPECIFIC_CHECKS_DT_MARKDOWN_HTML = The markdown contains content that appears to be an embedded HTML tag starting at ''{0}''. This will (or SHOULD) be escaped by the presentation layer. The content should be checked to confirm that this is the desired behaviour
|
TYPE_SPECIFIC_CHECKS_DT_MARKDOWN_HTML = The markdown contains content that appears to be an embedded HTML tag starting at ''{0}''. This will (or SHOULD) be escaped by the presentation layer. The content should be checked to confirm that this is the desired behaviour
|
||||||
TYPE_SPECIFIER_ILLEGAL_TYPE = The Type specifier {1} specified an invalid type {0}
|
TYPE_SPECIFIER_ILLEGAL_TYPE = The Type specifier {1} specified an invalid type {0}
|
||||||
TYPE_SPECIFIER_ABSTRACT_TYPE = The Type specifier {1} specified an abstract type {0}
|
TYPE_SPECIFIER_ABSTRACT_TYPE = The Type specifier {1} specified an abstract type {0}
|
||||||
|
|
|
@ -69,6 +69,9 @@ public class ResourceChecker {
|
||||||
if (src.startsWith("shc:/")) {
|
if (src.startsWith("shc:/")) {
|
||||||
return FhirFormat.SHC;
|
return FhirFormat.SHC;
|
||||||
}
|
}
|
||||||
|
if (src.startsWith("shlink:/") || src.contains("#shlink:/")) {
|
||||||
|
return FhirFormat.SHL;
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
}
|
}
|
||||||
return Manager.FhirFormat.TEXT;
|
return Manager.FhirFormat.TEXT;
|
||||||
|
@ -101,9 +104,13 @@ public class ResourceChecker {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
String s = new String(cnt, StandardCharsets.UTF_8);
|
String s = new String(cnt, StandardCharsets.UTF_8);
|
||||||
if (s.startsWith("shc:/"))
|
if (s.startsWith("shlink:/") || s.contains("#shlink:/")) {
|
||||||
|
return FhirFormat.SHL;
|
||||||
|
}
|
||||||
|
if (s.startsWith("shc:/")) {
|
||||||
s = SHCParser.decodeQRCode(s);
|
s = SHCParser.decodeQRCode(s);
|
||||||
JWT jwt = new SHCParser(context).decodeJWT(s);
|
}
|
||||||
|
JWT jwt = new SHCParser(context).decodeJWT(null, s);
|
||||||
return Manager.FhirFormat.SHC;
|
return Manager.FhirFormat.SHC;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
|
|
|
@ -700,7 +700,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
||||||
if (sourceSD.getKind() == StructureDefinition.StructureDefinitionKind.LOGICAL) {
|
if (sourceSD.getKind() == StructureDefinition.StructureDefinitionKind.LOGICAL) {
|
||||||
parser.setLogical(sourceSD);
|
parser.setLogical(sourceSD);
|
||||||
}
|
}
|
||||||
org.hl7.fhir.r5.elementmodel.Element src = parser.parseSingle(new ByteArrayInputStream(source.getBytes()));
|
org.hl7.fhir.r5.elementmodel.Element src = parser.parseSingle(new ByteArrayInputStream(source.getBytes()), null);
|
||||||
scu.transform(null, src, map, resource);
|
scu.transform(null, src, map, resource);
|
||||||
resource.populatePaths(null);
|
resource.populatePaths(null);
|
||||||
return resource;
|
return resource;
|
||||||
|
|
|
@ -283,6 +283,24 @@ public class ValidatorCli {
|
||||||
res.add("hl7.fhir.uv.ips#1.1.0");
|
res.add("hl7.fhir.uv.ips#1.1.0");
|
||||||
res.add("-profile");
|
res.add("-profile");
|
||||||
res.add("http://hl7.org/fhir/uv/ips/StructureDefinition/Bundle-uv-ips");
|
res.add("http://hl7.org/fhir/uv/ips/StructureDefinition/Bundle-uv-ips");
|
||||||
|
res.add("-extension");
|
||||||
|
res.add("any");
|
||||||
|
res.add("-bundle");
|
||||||
|
res.add("Composition:0");
|
||||||
|
res.add("http://hl7.org/fhir/uv/ips/StructureDefinition/Composition-uv-ips");
|
||||||
|
} else if (a.equals("-ips:au")) {
|
||||||
|
res.add("-version");
|
||||||
|
res.add("4.0");
|
||||||
|
res.add("-check-ips-codes");
|
||||||
|
res.add("-ig");
|
||||||
|
res.add("hl7.fhir.au.ips#current");
|
||||||
|
res.add("-profile");
|
||||||
|
res.add("http://hl7.org.au/fhir/ips/StructureDefinition/Bundle-au-ips");
|
||||||
|
res.add("-extension");
|
||||||
|
res.add("any");
|
||||||
|
res.add("-bundle");
|
||||||
|
res.add("Composition:0");
|
||||||
|
res.add("http://hl7.org.au/fhir/ips/StructureDefinition/Composition-au-ips");
|
||||||
} else if (a.equals("-ips#")) {
|
} else if (a.equals("-ips#")) {
|
||||||
res.add("-version");
|
res.add("-version");
|
||||||
res.add("4.0");
|
res.add("4.0");
|
||||||
|
@ -291,6 +309,11 @@ public class ValidatorCli {
|
||||||
res.add("hl7.fhir.uv.ips#"+a.substring(5));
|
res.add("hl7.fhir.uv.ips#"+a.substring(5));
|
||||||
res.add("-profile");
|
res.add("-profile");
|
||||||
res.add("http://hl7.org/fhir/uv/ips/StructureDefinition/Bundle-uv-ips");
|
res.add("http://hl7.org/fhir/uv/ips/StructureDefinition/Bundle-uv-ips");
|
||||||
|
res.add("-extension");
|
||||||
|
res.add("any");
|
||||||
|
res.add("-bundle");
|
||||||
|
res.add("Composition:0");
|
||||||
|
res.add("http://hl7.org/fhir/uv/ips/StructureDefinition/Composition-uv-ips");
|
||||||
} else if (a.startsWith("-ips$")) {
|
} else if (a.startsWith("-ips$")) {
|
||||||
res.add("-version");
|
res.add("-version");
|
||||||
res.add("4.0");
|
res.add("4.0");
|
||||||
|
@ -299,6 +322,11 @@ public class ValidatorCli {
|
||||||
res.add("hl7.fhir.uv.ips#current$"+a.substring(5));
|
res.add("hl7.fhir.uv.ips#current$"+a.substring(5));
|
||||||
res.add("-profile");
|
res.add("-profile");
|
||||||
res.add("http://hl7.org/fhir/uv/ips/StructureDefinition/Bundle-uv-ips");
|
res.add("http://hl7.org/fhir/uv/ips/StructureDefinition/Bundle-uv-ips");
|
||||||
|
res.add("-extension");
|
||||||
|
res.add("any");
|
||||||
|
res.add("-bundle");
|
||||||
|
res.add("Composition:0");
|
||||||
|
res.add("http://hl7.org/fhir/uv/ips/StructureDefinition/Composition-uv-ips");
|
||||||
} else {
|
} else {
|
||||||
res.add(a);
|
res.add(a);
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,6 +176,7 @@ import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
|
||||||
import org.hl7.fhir.utilities.MarkDownProcessor;
|
import org.hl7.fhir.utilities.MarkDownProcessor;
|
||||||
import org.hl7.fhir.utilities.SIDUtilities;
|
import org.hl7.fhir.utilities.SIDUtilities;
|
||||||
import org.hl7.fhir.utilities.StandardsStatus;
|
import org.hl7.fhir.utilities.StandardsStatus;
|
||||||
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
import org.hl7.fhir.utilities.UnicodeUtilities;
|
import org.hl7.fhir.utilities.UnicodeUtilities;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.Utilities.DecimalStatus;
|
import org.hl7.fhir.utilities.Utilities.DecimalStatus;
|
||||||
|
@ -269,6 +270,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
private static final String HTML_FRAGMENT_REGEX = "[a-zA-Z]\\w*(((\\s+)(\\S)*)*)";
|
private static final String HTML_FRAGMENT_REGEX = "[a-zA-Z]\\w*(((\\s+)(\\S)*)*)";
|
||||||
private static final boolean STACK_TRACE = false;
|
private static final boolean STACK_TRACE = false;
|
||||||
private static final boolean DEBUG_ELEMENT = false;
|
private static final boolean DEBUG_ELEMENT = false;
|
||||||
|
private static final boolean SAVE_INTERMEDIARIES = false; // set this to true to get the intermediary formats while we are waiting for a UI around this z(SHC/SHL)
|
||||||
|
|
||||||
private static final HashSet<String> NO_TX_SYSTEM_EXEMPT = new HashSet<>(Arrays.asList("http://loinc.org", "http://unitsofmeasure.org", "http://hl7.org/fhir/sid/icd-9-cm", "http://snomed.info/sct", "http://www.nlm.nih.gov/research/umls/rxnorm"));
|
private static final HashSet<String> NO_TX_SYSTEM_EXEMPT = new HashSet<>(Arrays.asList("http://loinc.org", "http://unitsofmeasure.org", "http://hl7.org/fhir/sid/icd-9-cm", "http://snomed.info/sct", "http://www.nlm.nih.gov/research/umls/rxnorm"));
|
||||||
private static final HashSet<String> NO_HTTPS_LIST = new HashSet<>(Arrays.asList("https://loinc.org", "https://unitsofmeasure.org", "https://snomed.info/sct", "https://www.nlm.nih.gov/research/umls/rxnorm"));
|
private static final HashSet<String> NO_HTTPS_LIST = new HashSet<>(Arrays.asList("https://loinc.org", "https://unitsofmeasure.org", "https://snomed.info/sct", "https://www.nlm.nih.gov/research/umls/rxnorm"));
|
||||||
|
@ -514,6 +516,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
private Map<String, CanonicalResourceLookupResult> crLookups = new HashMap<>();
|
private Map<String, CanonicalResourceLookupResult> crLookups = new HashMap<>();
|
||||||
private boolean logProgress;
|
private boolean logProgress;
|
||||||
private CodingsObserver codingObserver;
|
private CodingsObserver codingObserver;
|
||||||
|
public List<NamedElement> validatedContent;
|
||||||
|
|
||||||
public InstanceValidator(@Nonnull IWorkerContext theContext, @Nonnull IEvaluationContext hostServices, @Nonnull XVerExtensionManager xverManager) {
|
public InstanceValidator(@Nonnull IWorkerContext theContext, @Nonnull IEvaluationContext hostServices, @Nonnull XVerExtensionManager xverManager) {
|
||||||
super(theContext, xverManager, false);
|
super(theContext, xverManager, false);
|
||||||
|
@ -724,7 +727,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
if (parser instanceof XmlParser) {
|
if (parser instanceof XmlParser) {
|
||||||
((XmlParser) parser).setAllowXsiLocation(allowXsiLocation);
|
((XmlParser) parser).setAllowXsiLocation(allowXsiLocation);
|
||||||
}
|
}
|
||||||
parser.setupValidation(ValidationPolicy.EVERYTHING, errors);
|
parser.setupValidation(ValidationPolicy.EVERYTHING);
|
||||||
if (parser instanceof XmlParser) {
|
if (parser instanceof XmlParser) {
|
||||||
((XmlParser) parser).setAllowXsiLocation(allowXsiLocation);
|
((XmlParser) parser).setAllowXsiLocation(allowXsiLocation);
|
||||||
}
|
}
|
||||||
|
@ -732,14 +735,21 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
((JsonParser) parser).setAllowComments(allowComments);
|
((JsonParser) parser).setAllowComments(allowComments);
|
||||||
}
|
}
|
||||||
long t = System.nanoTime();
|
long t = System.nanoTime();
|
||||||
List<NamedElement> list = null;
|
validatedContent = null;
|
||||||
try {
|
try {
|
||||||
list = parser.parse(stream);
|
validatedContent = parser.parse(stream);
|
||||||
} catch (IOException e1) {
|
} catch (IOException e1) {
|
||||||
throw new FHIRException(e1);
|
throw new FHIRException(e1);
|
||||||
}
|
}
|
||||||
timeTracker.load(t);
|
timeTracker.load(t);
|
||||||
if (list != null && !list.isEmpty()) {
|
if (validatedContent != null && !validatedContent.isEmpty()) {
|
||||||
|
if (SAVE_INTERMEDIARIES) {
|
||||||
|
int index = 0;
|
||||||
|
for (NamedElement ne : validatedContent) {
|
||||||
|
index++;
|
||||||
|
saveValidatedContent(ne, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
String url = parser.getImpliedProfile();
|
String url = parser.getImpliedProfile();
|
||||||
if (url != null) {
|
if (url != null) {
|
||||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, url);
|
StructureDefinition sd = context.fetchResource(StructureDefinition.class, url);
|
||||||
|
@ -749,11 +759,27 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
profiles.add(sd);
|
profiles.add(sd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (NamedElement ne : list) {
|
for (NamedElement ne : validatedContent) {
|
||||||
validate(appContext, errors, ne.getName(), ne.getElement(), profiles);
|
if (ne.getElement() != null) {
|
||||||
|
validate(appContext, ne.getErrors(), validatedContent.size() > 1 ? ne.getName() : null, ne.getElement(), profiles);
|
||||||
|
}
|
||||||
|
errors.addAll(ne.getErrors());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (list == null || list.isEmpty()) ? null : list.get(0).getElement(); // todo: this is broken, but fixing it really complicates things elsewhere, so we do this for now
|
return (validatedContent == null || validatedContent.isEmpty()) ? null : validatedContent.get(0).getElement(); // todo: this is broken, but fixing it really complicates things elsewhere, so we do this for now
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveValidatedContent(NamedElement ne, int index) {
|
||||||
|
String tgt = null;
|
||||||
|
try {
|
||||||
|
tgt = Utilities.path("[tmp]", "validator", "content");
|
||||||
|
Utilities.createDirectory(tgt);
|
||||||
|
tgt = Utilities.path(tgt, "content-"+index+"-"+ne.getFilename());
|
||||||
|
TextFile.bytesToFile(ne.getContent(), tgt);
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Error saving internal content to '"+tgt+"': "+e.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -796,11 +822,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
@Override
|
@Override
|
||||||
public org.hl7.fhir.r5.elementmodel.Element validate(Object appContext, List<ValidationMessage> errors, org.w3c.dom.Element element, List<StructureDefinition> profiles) throws FHIRException {
|
public org.hl7.fhir.r5.elementmodel.Element validate(Object appContext, List<ValidationMessage> errors, org.w3c.dom.Element element, List<StructureDefinition> profiles) throws FHIRException {
|
||||||
XmlParser parser = new XmlParser(context);
|
XmlParser parser = new XmlParser(context);
|
||||||
parser.setupValidation(ValidationPolicy.EVERYTHING, errors);
|
parser.setupValidation(ValidationPolicy.EVERYTHING);
|
||||||
long t = System.nanoTime();
|
long t = System.nanoTime();
|
||||||
Element e;
|
Element e;
|
||||||
try {
|
try {
|
||||||
e = parser.parse(element);
|
e = parser.parse(errors, element);
|
||||||
} catch (IOException e1) {
|
} catch (IOException e1) {
|
||||||
throw new FHIRException(e1);
|
throw new FHIRException(e1);
|
||||||
}
|
}
|
||||||
|
@ -828,11 +854,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
@Override
|
@Override
|
||||||
public org.hl7.fhir.r5.elementmodel.Element validate(Object appContext, List<ValidationMessage> errors, Document document, List<StructureDefinition> profiles) throws FHIRException {
|
public org.hl7.fhir.r5.elementmodel.Element validate(Object appContext, List<ValidationMessage> errors, Document document, List<StructureDefinition> profiles) throws FHIRException {
|
||||||
XmlParser parser = new XmlParser(context);
|
XmlParser parser = new XmlParser(context);
|
||||||
parser.setupValidation(ValidationPolicy.EVERYTHING, errors);
|
parser.setupValidation(ValidationPolicy.EVERYTHING);
|
||||||
long t = System.nanoTime();
|
long t = System.nanoTime();
|
||||||
Element e;
|
Element e;
|
||||||
try {
|
try {
|
||||||
e = parser.parse(document);
|
e = parser.parse(errors, document);
|
||||||
} catch (IOException e1) {
|
} catch (IOException e1) {
|
||||||
throw new FHIRException(e1);
|
throw new FHIRException(e1);
|
||||||
}
|
}
|
||||||
|
@ -859,9 +885,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
@Override
|
@Override
|
||||||
public org.hl7.fhir.r5.elementmodel.Element validate(Object appContext, List<ValidationMessage> errors, JsonObject object, List<StructureDefinition> profiles) throws FHIRException {
|
public org.hl7.fhir.r5.elementmodel.Element validate(Object appContext, List<ValidationMessage> errors, JsonObject object, List<StructureDefinition> profiles) throws FHIRException {
|
||||||
JsonParser parser = new JsonParser(context, new ProfileUtilities(context, null, null, fpe));
|
JsonParser parser = new JsonParser(context, new ProfileUtilities(context, null, null, fpe));
|
||||||
parser.setupValidation(ValidationPolicy.EVERYTHING, errors);
|
parser.setupValidation(ValidationPolicy.EVERYTHING);
|
||||||
long t = System.nanoTime();
|
long t = System.nanoTime();
|
||||||
Element e = parser.parse(object);
|
Element e = parser.parse(errors, object);
|
||||||
timeTracker.load(t);
|
timeTracker.load(t);
|
||||||
if (e != null)
|
if (e != null)
|
||||||
validate(appContext, errors, null, e, profiles);
|
validate(appContext, errors, null, e, profiles);
|
||||||
|
@ -4982,6 +5008,30 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
pct.done();
|
pct.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (defn.hasExtension(ToolingExtensions.EXT_SD_IMPOSE_PROFILE)) {
|
||||||
|
for (Extension ext : defn.getExtensionsByUrl(ToolingExtensions.EXT_SD_IMPOSE_PROFILE)) {
|
||||||
|
StructureDefinition sdi = context.fetchResource(StructureDefinition.class, ext.getValue().primitiveValue());
|
||||||
|
if (sdi == null) {
|
||||||
|
warning(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, element.line(), element.col(), stack.getLiteralPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_DEPENDS_NOT_RESOLVED, ext.getValue().primitiveValue(), defn.getVersionedUrl());
|
||||||
|
} else {
|
||||||
|
if (crumbTrails) {
|
||||||
|
element.addMessage(signpost(errors, NO_RULE_DATE, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), I18nConstants.VALIDATION_VAL_PROFILE_SIGNPOST_DEP, sdi.getUrl(), defn.getVersionedUrl()));
|
||||||
|
}
|
||||||
|
stack.resetIds();
|
||||||
|
if (pctOwned) {
|
||||||
|
pct = new PercentageTracker(resource.countDescendents(), resource.fhirType(), sdi.getUrl(), logProgress);
|
||||||
|
}
|
||||||
|
ok = startInner(hostContext, errors, resource, element, sdi, stack, false, pct, mode.withSource(ProfileSource.ProfileDependency)) && ok;
|
||||||
|
if (pctOwned) {
|
||||||
|
pct.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Element meta = element.getNamedChild(META);
|
Element meta = element.getNamedChild(META);
|
||||||
if (meta != null) {
|
if (meta != null) {
|
||||||
List<Element> profiles = new ArrayList<Element>();
|
List<Element> profiles = new ArrayList<Element>();
|
||||||
|
|
|
@ -348,7 +348,7 @@ public class R4R5MapTester implements IValidatorResourceFetcher {
|
||||||
|
|
||||||
private int testRoundTrip(JsonObject json, StructureDefinition sd, StructureDefinition tsd, ResolvedGroup tgtG, ResolvedGroup srcG, Stats stats, InputStream stream, String code) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
private int testRoundTrip(JsonObject json, StructureDefinition sd, StructureDefinition tsd, ResolvedGroup tgtG, ResolvedGroup srcG, Stats stats, InputStream stream, String code) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
|
||||||
stats.example();
|
stats.example();
|
||||||
Element r4 = new org.hl7.fhir.r5.elementmodel.JsonParser(context).setLogical(tsd).parseSingle(stream);
|
Element r4 = new org.hl7.fhir.r5.elementmodel.JsonParser(context).setLogical(tsd).parseSingle(stream, null);
|
||||||
stats.parsed();
|
stats.parsed();
|
||||||
int elementCountBefore = r4.countDescendents()+1;
|
int elementCountBefore = r4.countDescendents()+1;
|
||||||
String id = r4.getIdBase();
|
String id = r4.getIdBase();
|
||||||
|
|
|
@ -21,9 +21,9 @@ public class GeneralTests {
|
||||||
org.hl7.fhir.r5.elementmodel.XmlParser xp = new org.hl7.fhir.r5.elementmodel.XmlParser(TestingUtilities.getSharedWorkerContext());
|
org.hl7.fhir.r5.elementmodel.XmlParser xp = new org.hl7.fhir.r5.elementmodel.XmlParser(TestingUtilities.getSharedWorkerContext());
|
||||||
xp.setAllowXsiLocation(true);
|
xp.setAllowXsiLocation(true);
|
||||||
List<ValidationMessage> errorList = new ArrayList<>();
|
List<ValidationMessage> errorList = new ArrayList<>();
|
||||||
xp.setupValidation(ValidationPolicy.EVERYTHING, errorList);
|
xp.setupValidation(ValidationPolicy.EVERYTHING);
|
||||||
try {
|
try {
|
||||||
Object resource = xp.parse(stream);
|
xp.parseSingle(stream, errorList);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.hl7.fhir.r5.elementmodel.Element;
|
||||||
import org.hl7.fhir.r5.elementmodel.Manager;
|
import org.hl7.fhir.r5.elementmodel.Manager;
|
||||||
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
|
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
|
||||||
import org.hl7.fhir.r5.elementmodel.ObjectConverter;
|
import org.hl7.fhir.r5.elementmodel.ObjectConverter;
|
||||||
|
import org.hl7.fhir.r5.elementmodel.SHLParser;
|
||||||
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
import org.hl7.fhir.r5.formats.IParser.OutputStyle;
|
||||||
import org.hl7.fhir.r5.formats.JsonParser;
|
import org.hl7.fhir.r5.formats.JsonParser;
|
||||||
import org.hl7.fhir.r5.formats.XmlParser;
|
import org.hl7.fhir.r5.formats.XmlParser;
|
||||||
|
@ -170,6 +171,7 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
|
||||||
TestingUtilities.injectCorePackageLoader();
|
TestingUtilities.injectCorePackageLoader();
|
||||||
|
|
||||||
CacheVerificationLogger logger = new CacheVerificationLogger();
|
CacheVerificationLogger logger = new CacheVerificationLogger();
|
||||||
|
// SHLParser.setTestMode(true);
|
||||||
long setup = System.nanoTime();
|
long setup = System.nanoTime();
|
||||||
|
|
||||||
logOutput("---- " + name + " ---------------------------------------------------------------- ("+System.getProperty("java.vm.name")+")");
|
logOutput("---- " + name + " ---------------------------------------------------------------- ("+System.getProperty("java.vm.name")+")");
|
||||||
|
@ -692,16 +694,16 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe
|
||||||
if (url.equals("Patient/test")) {
|
if (url.equals("Patient/test")) {
|
||||||
res = new ObjectConverter(vCurr.getContext()).convert(new Patient());
|
res = new ObjectConverter(vCurr.getContext()).convert(new Patient());
|
||||||
} else if (TestingUtilities.findTestResource("validator", url.replace("/", "-").toLowerCase() + ".json")) {
|
} else if (TestingUtilities.findTestResource("validator", url.replace("/", "-").toLowerCase() + ".json")) {
|
||||||
res = Manager.makeParser(vCurr.getContext(), FhirFormat.JSON).parseSingle(TestingUtilities.loadTestResourceStream("validator", url.replace("/", "-").toLowerCase() + ".json"));
|
res = Manager.makeParser(vCurr.getContext(), FhirFormat.JSON).parseSingle(TestingUtilities.loadTestResourceStream("validator", url.replace("/", "-").toLowerCase() + ".json"), null);
|
||||||
} else if (TestingUtilities.findTestResource("validator", url.replace("/", "-").toLowerCase() + ".xml")) {
|
} else if (TestingUtilities.findTestResource("validator", url.replace("/", "-").toLowerCase() + ".xml")) {
|
||||||
res = Manager.makeParser(vCurr.getContext(), FhirFormat.XML).parseSingle(TestingUtilities.loadTestResourceStream("validator", url.replace("/", "-").toLowerCase() + ".xml"));
|
res = Manager.makeParser(vCurr.getContext(), FhirFormat.XML).parseSingle(TestingUtilities.loadTestResourceStream("validator", url.replace("/", "-").toLowerCase() + ".xml"), null);
|
||||||
}
|
}
|
||||||
if (res == null && url.contains("/")) {
|
if (res == null && url.contains("/")) {
|
||||||
String tail = url.substring(url.indexOf("/") + 1);
|
String tail = url.substring(url.indexOf("/") + 1);
|
||||||
if (TestingUtilities.findTestResource("validator", tail.replace("/", "-").toLowerCase() + ".json")) {
|
if (TestingUtilities.findTestResource("validator", tail.replace("/", "-").toLowerCase() + ".json")) {
|
||||||
res = Manager.makeParser(vCurr.getContext(), FhirFormat.JSON).parseSingle(TestingUtilities.loadTestResourceStream("validator", tail.replace("/", "-").toLowerCase() + ".json"));
|
res = Manager.makeParser(vCurr.getContext(), FhirFormat.JSON).parseSingle(TestingUtilities.loadTestResourceStream("validator", tail.replace("/", "-").toLowerCase() + ".json"), null);
|
||||||
} else if (TestingUtilities.findTestResource("validator", tail.replace("/", "-").toLowerCase() + ".xml")) {
|
} else if (TestingUtilities.findTestResource("validator", tail.replace("/", "-").toLowerCase() + ".xml")) {
|
||||||
res = Manager.makeParser(vCurr.getContext(), FhirFormat.XML).parseSingle(TestingUtilities.loadTestResourceStream("validator", tail.replace("/", "-").toLowerCase() + ".xml"));
|
res = Manager.makeParser(vCurr.getContext(), FhirFormat.XML).parseSingle(TestingUtilities.loadTestResourceStream("validator", tail.replace("/", "-").toLowerCase() + ".xml"), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -15,7 +15,6 @@ v: {
|
||||||
"code" : "207",
|
"code" : "207",
|
||||||
"system" : "http://hl7.org/fhir/sid/cvx",
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
"version" : "20210406",
|
"version" : "20210406",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -37,7 +36,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Wrong Display Name 'X SARS-COV-2 (COVID-19) vaccine, mRNA, spike protein, LNP, preservative free, 100 mcg/0.5mL dose' for http://hl7.org/fhir/sid/cvx#207 - should be 'SARS-COV-2 (COVID-19) vaccine, mRNA, spike protein, LNP, preservative free, 100 mcg/0.5mL dose' (for the language(s) '--') (from Tx-Server)",
|
"error" : "Wrong Display Name 'X SARS-COV-2 (COVID-19) vaccine, mRNA, spike protein, LNP, preservative free, 100 mcg/0.5mL dose' for http://hl7.org/fhir/sid/cvx#207 - should be 'SARS-COV-2 (COVID-19) vaccine, mRNA, spike protein, LNP, preservative free, 100 mcg/0.5mL dose' (for the language(s) '--') (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -59,7 +57,6 @@ v: {
|
||||||
"code" : "208",
|
"code" : "208",
|
||||||
"system" : "http://hl7.org/fhir/sid/cvx",
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
"version" : "20210406",
|
"version" : "20210406",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -81,7 +78,6 @@ v: {
|
||||||
"code" : "208",
|
"code" : "208",
|
||||||
"system" : "http://hl7.org/fhir/sid/cvx",
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
"version" : "20210406",
|
"version" : "20210406",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -102,6 +98,225 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Unknown Code '209' in the system 'http://hl7.org/fhir/sid/cvx'; The provided code 'http://hl7.org/fhir/sid/cvx#209' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
"error" : "Unknown Code '209' in the system 'http://hl7.org/fhir/sid/cvx'; The provided code 'http://hl7.org/fhir/sid/cvx#209' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"code" : "115"
|
||||||
|
}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"display" : "tetanus toxoid, reduced diphtheria toxoid, and acellular pertussis vaccine, adsorbed",
|
||||||
|
"code" : "115",
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"version" : "20210406",
|
||||||
|
"unknown-systems" : "",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"code" : "10"
|
||||||
|
}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"display" : "poliovirus vaccine, inactivated",
|
||||||
|
"code" : "10",
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"version" : "20210406",
|
||||||
|
"unknown-systems" : "",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"code" : "85"
|
||||||
|
}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"display" : "hepatitis A vaccine, unspecified formulation",
|
||||||
|
"code" : "85",
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"version" : "20210406",
|
||||||
|
"unknown-systems" : "",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"code" : "25"
|
||||||
|
}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"display" : "typhoid vaccine, live, oral",
|
||||||
|
"code" : "25",
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"version" : "20210406",
|
||||||
|
"unknown-systems" : "",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"code" : "37"
|
||||||
|
}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"display" : "yellow fever vaccine",
|
||||||
|
"code" : "37",
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"version" : "20210406",
|
||||||
|
"unknown-systems" : "",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"code" : "185"
|
||||||
|
}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"display" : "Seasonal, quadrivalent, recombinant, injectable influenza vaccine, preservative free",
|
||||||
|
"code" : "185",
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"version" : "20210406",
|
||||||
|
"unknown-systems" : "",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"code" : "150"
|
||||||
|
}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"display" : "Influenza, injectable, quadrivalent, preservative free",
|
||||||
|
"code" : "150",
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"version" : "20210406",
|
||||||
|
"unknown-systems" : "",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"code" : "207"
|
||||||
|
}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"display" : "SARS-COV-2 (COVID-19) vaccine, mRNA, spike protein, LNP, preservative free, 100 mcg/0.5mL dose",
|
||||||
|
"code" : "207",
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"version" : "20210406",
|
||||||
|
"unknown-systems" : "",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"code" : "171"
|
||||||
|
}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"display" : "Influenza, injectable, Madin Darby Canine Kidney, preservative free, quadrivalent",
|
||||||
|
"code" : "171",
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"version" : "20210406",
|
||||||
|
"unknown-systems" : "",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"code" : "88"
|
||||||
|
}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"display" : "influenza virus vaccine, unspecified formulation",
|
||||||
|
"code" : "88",
|
||||||
|
"system" : "http://hl7.org/fhir/sid/cvx",
|
||||||
|
"version" : "20210406",
|
||||||
"unknown-systems" : "",
|
"unknown-systems" : "",
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
|
|
|
@ -15,6 +15,28 @@ v: {
|
||||||
"code" : "20049000",
|
"code" : "20049000",
|
||||||
"system" : "http://standardterms.edqm.eu",
|
"system" : "http://standardterms.edqm.eu",
|
||||||
"version" : "5 March 2019",
|
"version" : "5 March 2019",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"system" : "http://standardterms.edqm.eu",
|
||||||
|
"code" : "20053000",
|
||||||
|
"display" : "Oral use"
|
||||||
|
}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"display" : "Oral use",
|
||||||
|
"code" : "20053000",
|
||||||
|
"system" : "http://standardterms.edqm.eu",
|
||||||
|
"version" : "5 March 2019",
|
||||||
"unknown-systems" : "",
|
"unknown-systems" : "",
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
|
|
|
@ -15,7 +15,6 @@ v: {
|
||||||
"code" : "NO",
|
"code" : "NO",
|
||||||
"system" : "urn:iso:std:iso:3166",
|
"system" : "urn:iso:std:iso:3166",
|
||||||
"version" : "2018",
|
"version" : "2018",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -37,7 +36,6 @@ v: {
|
||||||
"code" : "US",
|
"code" : "US",
|
||||||
"system" : "urn:iso:std:iso:3166",
|
"system" : "urn:iso:std:iso:3166",
|
||||||
"version" : "2018",
|
"version" : "2018",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -59,7 +57,6 @@ v: {
|
||||||
"code" : "US",
|
"code" : "US",
|
||||||
"system" : "urn:iso:std:iso:3166",
|
"system" : "urn:iso:std:iso:3166",
|
||||||
"version" : "2018",
|
"version" : "2018",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -81,6 +78,27 @@ v: {
|
||||||
"code" : "NO",
|
"code" : "NO",
|
||||||
"system" : "urn:iso:std:iso:3166",
|
"system" : "urn:iso:std:iso:3166",
|
||||||
"version" : "2018",
|
"version" : "2018",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"system" : "urn:iso:std:iso:3166",
|
||||||
|
"code" : "NO",
|
||||||
|
"display" : "Alderney"
|
||||||
|
}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"severity" : "error",
|
||||||
|
"error" : "Wrong Display Name 'Alderney' for urn:iso:std:iso:3166#NO - should be 'Norway' (for the language(s) '--') (from Tx-Server)",
|
||||||
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
"unknown-systems" : "",
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,7 +15,6 @@ v: {
|
||||||
"code" : "1000990",
|
"code" : "1000990",
|
||||||
"system" : "http://www.nlm.nih.gov/research/umls/rxnorm",
|
"system" : "http://www.nlm.nih.gov/research/umls/rxnorm",
|
||||||
"version" : "??",
|
"version" : "??",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -38,7 +37,6 @@ v: {
|
||||||
"code" : "1010603",
|
"code" : "1010603",
|
||||||
"system" : "http://www.nlm.nih.gov/research/umls/rxnorm",
|
"system" : "http://www.nlm.nih.gov/research/umls/rxnorm",
|
||||||
"version" : "??",
|
"version" : "??",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -61,7 +59,6 @@ v: {
|
||||||
"code" : "1298088",
|
"code" : "1298088",
|
||||||
"system" : "http://www.nlm.nih.gov/research/umls/rxnorm",
|
"system" : "http://www.nlm.nih.gov/research/umls/rxnorm",
|
||||||
"version" : "??",
|
"version" : "??",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -84,7 +81,6 @@ v: {
|
||||||
"code" : "1010600",
|
"code" : "1010600",
|
||||||
"system" : "http://www.nlm.nih.gov/research/umls/rxnorm",
|
"system" : "http://www.nlm.nih.gov/research/umls/rxnorm",
|
||||||
"version" : "??",
|
"version" : "??",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -106,6 +102,27 @@ v: {
|
||||||
"code" : "1591957",
|
"code" : "1591957",
|
||||||
"system" : "http://www.nlm.nih.gov/research/umls/rxnorm",
|
"system" : "http://www.nlm.nih.gov/research/umls/rxnorm",
|
||||||
"version" : "??",
|
"version" : "??",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"system" : "http://www.nlm.nih.gov/research/umls/rxnorm",
|
||||||
|
"code" : "617311",
|
||||||
|
"display" : "atorvastatin 40mg Oral Tablet"
|
||||||
|
}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"severity" : "error",
|
||||||
|
"error" : "Wrong Display Name 'atorvastatin 40mg Oral Tablet' for http://www.nlm.nih.gov/research/umls/rxnorm#617311 - should be one of 3 choices: 'atorvastatin 40 MG Oral Tablet', 'atorvastatin (as atorvastatin calcium) 40 MG Oral Tablet' or 'atorvastatin calcium 40 MG Oral Tablet' (for the language(s) '--') (from Tx-Server)",
|
||||||
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
"unknown-systems" : "",
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
|
|
|
@ -15,7 +15,6 @@ v: {
|
||||||
"code" : "721912009",
|
"code" : "721912009",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -38,7 +37,6 @@ v: {
|
||||||
"code" : "91935009",
|
"code" : "91935009",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -61,7 +59,6 @@ v: {
|
||||||
"code" : "3718001",
|
"code" : "3718001",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -83,7 +80,6 @@ v: {
|
||||||
"code" : "255604002",
|
"code" : "255604002",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -106,7 +102,6 @@ v: {
|
||||||
"code" : "255604002",
|
"code" : "255604002",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -128,7 +123,6 @@ v: {
|
||||||
"code" : "255604002",
|
"code" : "255604002",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -151,7 +145,6 @@ v: {
|
||||||
"code" : "409002",
|
"code" : "409002",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -173,7 +166,6 @@ v: {
|
||||||
"code" : "6736007",
|
"code" : "6736007",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -195,7 +187,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Wrong Display Name 'Moderate' for http://snomed.info/sct#6736007 - should be one of 4 choices: 'Midgrade', 'Moderate (severity modifier) (qualifier value)', 'Moderate (severity modifier)' or 'Moderate severity' (for the language(s) '--') (from Tx-Server)",
|
"error" : "Wrong Display Name 'Moderate' for http://snomed.info/sct#6736007 - should be one of 4 choices: 'Midgrade', 'Moderate (severity modifier) (qualifier value)', 'Moderate (severity modifier)' or 'Moderate severity' (for the language(s) '--') (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -217,7 +208,6 @@ v: {
|
||||||
"code" : "6736007",
|
"code" : "6736007",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -240,7 +230,6 @@ v: {
|
||||||
"code" : "437009",
|
"code" : "437009",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -263,7 +252,6 @@ v: {
|
||||||
"code" : "9846003",
|
"code" : "9846003",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -286,7 +274,6 @@ v: {
|
||||||
"code" : "189009",
|
"code" : "189009",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -309,7 +296,6 @@ v: {
|
||||||
"code" : "911003",
|
"code" : "911003",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -332,7 +318,6 @@ v: {
|
||||||
"code" : "112144000",
|
"code" : "112144000",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -355,7 +340,6 @@ v: {
|
||||||
"code" : "80943009",
|
"code" : "80943009",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -378,7 +362,6 @@ v: {
|
||||||
"code" : "77176002",
|
"code" : "77176002",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -401,7 +384,6 @@ v: {
|
||||||
"code" : "38341003",
|
"code" : "38341003",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -424,7 +406,6 @@ v: {
|
||||||
"code" : "1419004",
|
"code" : "1419004",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -482,7 +463,6 @@ v: {
|
||||||
"code" : "93880001",
|
"code" : "93880001",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -505,7 +485,6 @@ v: {
|
||||||
"code" : "248986005",
|
"code" : "248986005",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -528,7 +507,6 @@ v: {
|
||||||
"code" : "161714006",
|
"code" : "161714006",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -551,7 +529,6 @@ v: {
|
||||||
"code" : "161713000",
|
"code" : "161713000",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -574,7 +551,6 @@ v: {
|
||||||
"code" : "445872007",
|
"code" : "445872007",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -597,7 +573,6 @@ v: {
|
||||||
"code" : "722446000",
|
"code" : "722446000",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -620,7 +595,6 @@ v: {
|
||||||
"code" : "371531000",
|
"code" : "371531000",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -643,7 +617,6 @@ v: {
|
||||||
"code" : "4241000179101",
|
"code" : "4241000179101",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -666,7 +639,6 @@ v: {
|
||||||
"code" : "422735006",
|
"code" : "422735006",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -688,7 +660,6 @@ v: {
|
||||||
"code" : "440545006",
|
"code" : "440545006",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -711,7 +682,6 @@ v: {
|
||||||
"code" : "324252006",
|
"code" : "324252006",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -747,7 +717,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Wrong Display Name 'Traveller's Diarrhea (disorder)' for http://snomed.info/sct#11840006 - should be one of 4 choices: 'Traveler's diarrhea', 'Turista', 'Traveler's diarrhoea' or 'Traveler's diarrhea (disorder)' (for the language(s) '--') (from Tx-Server)",
|
"error" : "Wrong Display Name 'Traveller's Diarrhea (disorder)' for http://snomed.info/sct#11840006 - should be one of 4 choices: 'Traveler's diarrhea', 'Turista', 'Traveler's diarrhoea' or 'Traveler's diarrhea (disorder)' (for the language(s) '--') (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -770,7 +739,6 @@ v: {
|
||||||
"code" : "21522001",
|
"code" : "21522001",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -793,7 +761,6 @@ v: {
|
||||||
"code" : "311504000",
|
"code" : "311504000",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -816,7 +783,6 @@ v: {
|
||||||
"code" : "26643006",
|
"code" : "26643006",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -839,7 +805,6 @@ v: {
|
||||||
"code" : "421521009",
|
"code" : "421521009",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -862,7 +827,6 @@ v: {
|
||||||
"code" : "602001",
|
"code" : "602001",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -899,7 +863,6 @@ v: {
|
||||||
"code" : "8821006",
|
"code" : "8821006",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -921,7 +884,6 @@ v: {
|
||||||
"code" : "112144000",
|
"code" : "112144000",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -943,7 +905,6 @@ v: {
|
||||||
"code" : "112144000",
|
"code" : "112144000",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -965,7 +926,6 @@ v: {
|
||||||
"code" : "722446000",
|
"code" : "722446000",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -987,7 +947,6 @@ v: {
|
||||||
"code" : "722446000",
|
"code" : "722446000",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1009,7 +968,6 @@ v: {
|
||||||
"code" : "371531000",
|
"code" : "371531000",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1031,7 +989,6 @@ v: {
|
||||||
"code" : "371531000",
|
"code" : "371531000",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1053,7 +1010,6 @@ v: {
|
||||||
"code" : "4241000179101",
|
"code" : "4241000179101",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1075,7 +1031,6 @@ v: {
|
||||||
"code" : "4241000179101",
|
"code" : "4241000179101",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1097,7 +1052,6 @@ v: {
|
||||||
"code" : "422735006",
|
"code" : "422735006",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1119,7 +1073,6 @@ v: {
|
||||||
"code" : "422735006",
|
"code" : "422735006",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1140,7 +1093,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "The provided code 'http://snomed.info/sct#77176002' is not in the value set 'https://mednet.swiss/fhir/ValueSet/mni-obs-bloodGroup--0|0.5.0' (from Tx-Server)",
|
"error" : "The provided code 'http://snomed.info/sct#77176002' is not in the value set 'https://mednet.swiss/fhir/ValueSet/mni-obs-bloodGroup--0|0.5.0' (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1161,7 +1113,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "The provided code 'http://snomed.info/sct#38341003' is not in the value set 'https://mednet.swiss/fhir/ValueSet/mni-obs-bloodGroup--0|0.5.0' (from Tx-Server)",
|
"error" : "The provided code 'http://snomed.info/sct#38341003' is not in the value set 'https://mednet.swiss/fhir/ValueSet/mni-obs-bloodGroup--0|0.5.0' (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1185,7 +1136,6 @@ v: {
|
||||||
"code" : "454281000124100",
|
"code" : "454281000124100",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/731000124108/version/20230301",
|
"version" : "http://snomed.info/sct/731000124108/version/20230301",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1207,7 +1157,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Wrong Display Name 'Progress note' for http://snomed.info/sct#371532007 - should be one of 3 choices: 'Progress report', 'Report of subsequent visit' or 'Progress report (record artifact)' (for the language(s) '--') (from Tx-Server)",
|
"error" : "Wrong Display Name 'Progress note' for http://snomed.info/sct#371532007 - should be one of 3 choices: 'Progress report', 'Report of subsequent visit' or 'Progress report (record artifact)' (for the language(s) '--') (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1230,7 +1179,6 @@ v: {
|
||||||
"code" : "371525003",
|
"code" : "371525003",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1252,7 +1200,6 @@ v: {
|
||||||
"code" : "371532007",
|
"code" : "371532007",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1274,7 +1221,6 @@ v: {
|
||||||
"code" : "371532007",
|
"code" : "371532007",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1296,7 +1242,6 @@ v: {
|
||||||
"code" : "371525003",
|
"code" : "371525003",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1318,7 +1263,6 @@ v: {
|
||||||
"code" : "371525003",
|
"code" : "371525003",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1341,7 +1285,6 @@ v: {
|
||||||
"code" : "419891008",
|
"code" : "419891008",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1364,7 +1307,6 @@ v: {
|
||||||
"code" : "371525003",
|
"code" : "371525003",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1387,7 +1329,6 @@ v: {
|
||||||
"code" : "17621005",
|
"code" : "17621005",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1410,7 +1351,6 @@ v: {
|
||||||
"code" : "722172003",
|
"code" : "722172003",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1433,7 +1373,6 @@ v: {
|
||||||
"code" : "394609007",
|
"code" : "394609007",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1456,7 +1395,6 @@ v: {
|
||||||
"code" : "71388002",
|
"code" : "71388002",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1502,7 +1440,6 @@ v: {
|
||||||
"code" : "410534003",
|
"code" : "410534003",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1525,7 +1462,6 @@ v: {
|
||||||
"code" : "10828004",
|
"code" : "10828004",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1548,7 +1484,6 @@ v: {
|
||||||
"code" : "233588003",
|
"code" : "233588003",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1571,7 +1506,6 @@ v: {
|
||||||
"code" : "324689003",
|
"code" : "324689003",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1594,7 +1528,6 @@ v: {
|
||||||
"code" : "442311008",
|
"code" : "442311008",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1617,7 +1550,6 @@ v: {
|
||||||
"code" : "840539006",
|
"code" : "840539006",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1639,7 +1571,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Wrong Display Name 'COVID-19' for http://snomed.info/sct#840535000 - should be one of 7 choices: 'Antibody to 2019 novel coronavirus', 'Antibody to 2019-nCoV', 'Antibody to severe acute respiratory syndrome coronavirus 2 (substance)', 'Antibody to severe acute respiratory syndrome coronavirus 2', 'Antibody to SARS-CoV-2', 'Severe acute respiratory syndrome coronavirus 2 Ab' or 'Severe acute respiratory syndrome coronavirus 2 antibody' (for the language(s) '--') (from Tx-Server)",
|
"error" : "Wrong Display Name 'COVID-19' for http://snomed.info/sct#840535000 - should be one of 7 choices: 'Antibody to 2019 novel coronavirus', 'Antibody to 2019-nCoV', 'Antibody to severe acute respiratory syndrome coronavirus 2 (substance)', 'Antibody to severe acute respiratory syndrome coronavirus 2', 'Antibody to SARS-CoV-2', 'Severe acute respiratory syndrome coronavirus 2 Ab' or 'Severe acute respiratory syndrome coronavirus 2 antibody' (for the language(s) '--') (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1662,7 +1593,6 @@ v: {
|
||||||
"code" : "840535000",
|
"code" : "840535000",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1685,7 +1615,6 @@ v: {
|
||||||
"code" : "32485007",
|
"code" : "32485007",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1708,7 +1637,6 @@ v: {
|
||||||
"code" : "32713005",
|
"code" : "32713005",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1730,7 +1658,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Unable to find code 10821000202101 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '10821000202101' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#10821000202101' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
"error" : "Unable to find code 10821000202101 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '10821000202101' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#10821000202101' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1752,7 +1679,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Wrong Display Name 'Diagnostisk med biopsi' for http://snomed.info/sct#446745002 - should be one of 2 choices: 'Colonoscopy and biopsy of colon (procedure)' or 'Colonoscopy and biopsy of colon' (for the language(s) '--') (from Tx-Server)",
|
"error" : "Wrong Display Name 'Diagnostisk med biopsi' for http://snomed.info/sct#446745002 - should be one of 2 choices: 'Colonoscopy and biopsy of colon (procedure)' or 'Colonoscopy and biopsy of colon' (for the language(s) '--') (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1775,7 +1701,6 @@ v: {
|
||||||
"code" : "73761001",
|
"code" : "73761001",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1797,7 +1722,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Unable to find code 8921000202108 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '8921000202108' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#8921000202108' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
"error" : "Unable to find code 8921000202108 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '8921000202108' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#8921000202108' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1819,7 +1743,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Unable to find code 8951000202101 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '8951000202101' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#8951000202101' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
"error" : "Unable to find code 8951000202101 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '8951000202101' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#8951000202101' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1842,7 +1765,6 @@ v: {
|
||||||
"code" : "300577008",
|
"code" : "300577008",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1864,7 +1786,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Unable to find code 10291000202102 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '10291000202102' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#10291000202102' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
"error" : "Unable to find code 10291000202102 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '10291000202102' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#10291000202102' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1887,7 +1808,6 @@ v: {
|
||||||
"code" : "722818007",
|
"code" : "722818007",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1909,7 +1829,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Unable to find code 8901000202102 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '8901000202102' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#8901000202102' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
"error" : "Unable to find code 8901000202102 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '8901000202102' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#8901000202102' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1932,7 +1851,6 @@ v: {
|
||||||
"code" : "10291000132101",
|
"code" : "10291000132101",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1954,7 +1872,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Unable to find code 8911000202100 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '8911000202100' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#8911000202100' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
"error" : "Unable to find code 8911000202100 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '8911000202100' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#8911000202100' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1977,7 +1894,6 @@ v: {
|
||||||
"code" : "10301000132102",
|
"code" : "10301000132102",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -1999,7 +1915,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Unable to find code 8891000202103 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '8891000202103' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#8891000202103' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
"error" : "Unable to find code 8891000202103 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '8891000202103' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#8891000202103' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2022,7 +1937,6 @@ v: {
|
||||||
"code" : "10311000132100",
|
"code" : "10311000132100",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2044,7 +1958,6 @@ v: {
|
||||||
"code" : "10291000132101",
|
"code" : "10291000132101",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2066,7 +1979,6 @@ v: {
|
||||||
"code" : "10301000132102",
|
"code" : "10301000132102",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2088,7 +2000,6 @@ v: {
|
||||||
"code" : "10311000132100",
|
"code" : "10311000132100",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2110,7 +2021,6 @@ v: {
|
||||||
"code" : "246206008",
|
"code" : "246206008",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2132,7 +2042,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Unable to find code 15991000202102 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '15991000202102' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#15991000202102' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
"error" : "Unable to find code 15991000202102 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '15991000202102' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#15991000202102' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2154,7 +2063,6 @@ v: {
|
||||||
"code" : "17621005",
|
"code" : "17621005",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2177,7 +2085,6 @@ v: {
|
||||||
"code" : "712510007",
|
"code" : "712510007",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2199,7 +2106,6 @@ v: {
|
||||||
"code" : "32485007",
|
"code" : "32485007",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2221,7 +2127,6 @@ v: {
|
||||||
"code" : "32713005",
|
"code" : "32713005",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2242,7 +2147,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Unable to find code 10821000202101 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '10821000202101' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#10821000202101' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
"error" : "Unable to find code 10821000202101 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '10821000202101' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#10821000202101' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2264,7 +2168,6 @@ v: {
|
||||||
"code" : "446745002",
|
"code" : "446745002",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2285,7 +2188,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Unable to find code 8921000202108 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '8921000202108' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#8921000202108' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
"error" : "Unable to find code 8921000202108 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '8921000202108' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#8921000202108' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2306,7 +2208,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Unable to find code 8951000202101 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '8951000202101' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#8951000202101' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
"error" : "Unable to find code 8951000202101 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '8951000202101' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#8951000202101' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2328,7 +2229,6 @@ v: {
|
||||||
"code" : "712510007",
|
"code" : "712510007",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2350,7 +2250,6 @@ v: {
|
||||||
"code" : "372756006",
|
"code" : "372756006",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2372,7 +2271,6 @@ v: {
|
||||||
"code" : "387458008",
|
"code" : "387458008",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2395,7 +2293,6 @@ v: {
|
||||||
"code" : "372756006",
|
"code" : "372756006",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2418,7 +2315,6 @@ v: {
|
||||||
"code" : "387458008",
|
"code" : "387458008",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2486,7 +2382,6 @@ v: {
|
||||||
"code" : "276885007",
|
"code" : "276885007",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2509,7 +2404,6 @@ v: {
|
||||||
"code" : "58108001",
|
"code" : "58108001",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome",
|
"resourceType" : "OperationOutcome",
|
||||||
"issue" : [{
|
"issue" : [{
|
||||||
|
@ -2601,7 +2495,6 @@ v: {
|
||||||
"code" : "119339001",
|
"code" : "119339001",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2623,7 +2516,6 @@ v: {
|
||||||
"code" : "5933001",
|
"code" : "5933001",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2691,7 +2583,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Wrong Display Name 'Paracetamol 500mg tablets' for http://snomed.info/sct#322236009 - should be one of 3 choices: 'Acetaminophen 500 mg oral tablet', 'Paracetamol 500 mg oral tablet' or 'Product containing precisely paracetamol 500 milligram/1 each conventional release oral tablet (clinical drug)' (for the language(s) '--') (from Tx-Server)",
|
"error" : "Wrong Display Name 'Paracetamol 500mg tablets' for http://snomed.info/sct#322236009 - should be one of 3 choices: 'Acetaminophen 500 mg oral tablet', 'Paracetamol 500 mg oral tablet' or 'Product containing precisely paracetamol 500 milligram/1 each conventional release oral tablet (clinical drug)' (for the language(s) '--') (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2713,7 +2604,6 @@ v: {
|
||||||
"code" : "428673006",
|
"code" : "428673006",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2735,7 +2625,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Unable to find code 35901911000001104 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '35901911000001104' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#35901911000001104' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
"error" : "Unable to find code 35901911000001104 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '35901911000001104' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#35901911000001104' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2757,7 +2646,6 @@ v: {
|
||||||
"code" : "258773002",
|
"code" : "258773002",
|
||||||
"system" : "http://snomed.info/sct",
|
"system" : "http://snomed.info/sct",
|
||||||
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2779,7 +2667,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Wrong Display Name 'Ibuprofen 200mg tablets' for http://snomed.info/sct#329652003 - should be one of 2 choices: 'Ibuprofen 200 mg oral tablet' or 'Product containing precisely ibuprofen 200 milligram/1 each conventional release oral tablet (clinical drug)' (for the language(s) '--') (from Tx-Server)",
|
"error" : "Wrong Display Name 'Ibuprofen 200mg tablets' for http://snomed.info/sct#329652003 - should be one of 2 choices: 'Ibuprofen 200 mg oral tablet' or 'Product containing precisely ibuprofen 200 milligram/1 each conventional release oral tablet (clinical drug)' (for the language(s) '--') (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2801,7 +2688,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Unable to find code 39695211000001102 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '39695211000001102' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#39695211000001102' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
"error" : "Unable to find code 39695211000001102 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '39695211000001102' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#39695211000001102' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2823,7 +2709,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Unable to find code 56248011000036107 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '56248011000036107' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#56248011000036107' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
"error" : "Unable to find code 56248011000036107 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '56248011000036107' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#56248011000036107' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2844,7 +2729,6 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Unable to find code 1 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '1' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#1' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
"error" : "Unable to find code 1 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '1' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#1' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
"unknown-systems" : "",
|
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
}
|
}
|
||||||
|
@ -2865,6 +2749,74 @@ v: {
|
||||||
"severity" : "error",
|
"severity" : "error",
|
||||||
"error" : "Unable to find code 2 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '2' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#2' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
"error" : "Unable to find code 2 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20230731); Unknown Code '2' in the system 'http://snomed.info/sct'; The provided code 'http://snomed.info/sct#2' is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)",
|
||||||
"class" : "UNKNOWN",
|
"class" : "UNKNOWN",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"system" : "http://snomed.info/sct",
|
||||||
|
"code" : "38341003",
|
||||||
|
"display" : "HT - Hypertension"
|
||||||
|
}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"display" : "High blood pressure",
|
||||||
|
"code" : "38341003",
|
||||||
|
"system" : "http://snomed.info/sct",
|
||||||
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
|
"unknown-systems" : "",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"system" : "http://snomed.info/sct",
|
||||||
|
"code" : "42343007",
|
||||||
|
"display" : "Congestive heart failure"
|
||||||
|
}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"display" : "Congestive heart failure",
|
||||||
|
"code" : "42343007",
|
||||||
|
"system" : "http://snomed.info/sct",
|
||||||
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
|
"unknown-systems" : "",
|
||||||
|
"issues" : {
|
||||||
|
"resourceType" : "OperationOutcome"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-------------------------------------------------------------------------------------
|
||||||
|
{"code" : {
|
||||||
|
"system" : "http://snomed.info/sct",
|
||||||
|
"code" : "9014002",
|
||||||
|
"display" : "Psoriasis"
|
||||||
|
}, "valueSet" :null, "langs":"", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
|
||||||
|
"resourceType" : "Parameters",
|
||||||
|
"parameter" : [{
|
||||||
|
"name" : "profile-url",
|
||||||
|
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
|
||||||
|
}]
|
||||||
|
}}####
|
||||||
|
v: {
|
||||||
|
"display" : "Psoriasis",
|
||||||
|
"code" : "9014002",
|
||||||
|
"system" : "http://snomed.info/sct",
|
||||||
|
"version" : "http://snomed.info/sct/900000000000207008/version/20230731",
|
||||||
"unknown-systems" : "",
|
"unknown-systems" : "",
|
||||||
"issues" : {
|
"issues" : {
|
||||||
"resourceType" : "OperationOutcome"
|
"resourceType" : "OperationOutcome"
|
||||||
|
|
9
pom.xml
9
pom.xml
|
@ -20,7 +20,7 @@
|
||||||
<properties>
|
<properties>
|
||||||
<guava_version>32.0.1-jre</guava_version>
|
<guava_version>32.0.1-jre</guava_version>
|
||||||
<hapi_fhir_version>6.4.1</hapi_fhir_version>
|
<hapi_fhir_version>6.4.1</hapi_fhir_version>
|
||||||
<validator_test_case_version>1.4.1</validator_test_case_version>
|
<validator_test_case_version>1.4.2-SNAPSHOT</validator_test_case_version>
|
||||||
<jackson_version>2.15.2</jackson_version>
|
<jackson_version>2.15.2</jackson_version>
|
||||||
<junit_jupiter_version>5.9.2</junit_jupiter_version>
|
<junit_jupiter_version>5.9.2</junit_jupiter_version>
|
||||||
<junit_platform_launcher_version>1.8.2</junit_platform_launcher_version>
|
<junit_platform_launcher_version>1.8.2</junit_platform_launcher_version>
|
||||||
|
@ -283,6 +283,13 @@
|
||||||
<artifactId>xpp3</artifactId>
|
<artifactId>xpp3</artifactId>
|
||||||
<version>1.1.6</version>
|
<version>1.1.6</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.nimbusds</groupId>
|
||||||
|
<artifactId>nimbus-jose-jwt</artifactId>
|
||||||
|
<version>9.30.2</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue