mirror of
https://github.com/hapifhir/org.hl7.fhir.core.git
synced 2025-02-10 14:54:46 +00:00
improve language on constraint error message + add expression checking for SQL on FHIR project
This commit is contained in:
parent
af0f9bc765
commit
9da31ae8ad
@ -1003,6 +1003,9 @@ public class I18nConstants {
|
|||||||
public static final String CONCEPTMAP_VS_CONCEPT_CODE_UNKNOWN_SYSTEM = "CONCEPTMAP_VS_CONCEPT_CODE_UNKNOWN_SYSTEM";
|
public static final String CONCEPTMAP_VS_CONCEPT_CODE_UNKNOWN_SYSTEM = "CONCEPTMAP_VS_CONCEPT_CODE_UNKNOWN_SYSTEM";
|
||||||
public static final String LOGICAL_MODEL_NAME_MISMATCH = "LOGICAL_MODEL_NAME_MISMATCH";
|
public static final String LOGICAL_MODEL_NAME_MISMATCH = "LOGICAL_MODEL_NAME_MISMATCH";
|
||||||
public static final String LOGICAL_MODEL_QNAME_MISMATCH = "LOGICAL_MODEL_QNAME_MISMATCH";
|
public static final String LOGICAL_MODEL_QNAME_MISMATCH = "LOGICAL_MODEL_QNAME_MISMATCH";
|
||||||
|
public static final String FHIRPATH_CHOICE_NO_TYPE_SPECIFIER = "FHIRPATH_CHOICE_NO_TYPE_SPECIFIER";
|
||||||
|
public static final String FHIRPATH_CHOICE_SPURIOUS_TYPE_SPECIFIER = "FHIRPATH_CHOICE_SPURIOUS_TYPE_SPECIFIER";
|
||||||
|
public static final String FHIRPATH_NOT_A_COLLECTION = "FHIRPATH_NOT_A_COLLECTION";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
package org.hl7.fhir.utilities.validation;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.hl7.fhir.utilities.json.JsonException;
|
||||||
|
import org.hl7.fhir.utilities.json.model.JsonObject;
|
||||||
|
|
||||||
|
public interface IDigitalSignatureServices {
|
||||||
|
|
||||||
|
JsonObject fetchJWKS(String address) throws JsonException, IOException;
|
||||||
|
}
|
@ -736,8 +736,8 @@ BUNDLE_SEARCH_ENTRY_WRONG_RESOURCE_TYPE_MODE = This is not a matching resource t
|
|||||||
BUNDLE_SEARCH_ENTRY_WRONG_RESOURCE_TYPE_OUTCOME = This is not an OperationOutcome ({0})
|
BUNDLE_SEARCH_ENTRY_WRONG_RESOURCE_TYPE_OUTCOME = This is not an OperationOutcome ({0})
|
||||||
BUNDLE_SEARCH_ENTRY_WRONG_RESOURCE_TYPE_NO_MODE = This is not a matching resource type for the specified search (is a search mode needed?) ({0} expecting {1})
|
BUNDLE_SEARCH_ENTRY_WRONG_RESOURCE_TYPE_NO_MODE = This is not a matching resource type for the specified search (is a search mode needed?) ({0} expecting {1})
|
||||||
BUNDLE_SEARCH_NO_MODE = SearchSet bundles should have search modes on the entries
|
BUNDLE_SEARCH_NO_MODE = SearchSet bundles should have search modes on the entries
|
||||||
INV_FAILED = Rule {0} Failed
|
INV_FAILED = Constraint failed: {0}
|
||||||
INV_FAILED_SOURCE = Rule {0} Failed (defined in {1})
|
INV_FAILED_SOURCE = Constraint failed: {0} (defined in {1})
|
||||||
PATTERN_CHECK_STRING = The pattern [{0}] defined in the profile {1} not found. Issues: {2}
|
PATTERN_CHECK_STRING = The pattern [{0}] defined in the profile {1} not found. Issues: {2}
|
||||||
TYPE_SPECIFIC_CHECKS_DT_URL_EXAMPLE = Example URLs are not allowed in this context ({0})
|
TYPE_SPECIFIC_CHECKS_DT_URL_EXAMPLE = Example URLs are not allowed in this context ({0})
|
||||||
UNICODE_BIDI_CONTROLS_CHARS_DISALLOWED = The Unicode sequence has bi-di control characters which are not allowed in this context: {0}
|
UNICODE_BIDI_CONTROLS_CHARS_DISALLOWED = The Unicode sequence has bi-di control characters which are not allowed in this context: {0}
|
||||||
@ -1060,3 +1060,7 @@ TYPE_SPECIFIC_CHECKS_DT_QTY_UCUM_ANNOTATIONS_NOT_IN_UNIT = UCUM Codes that conta
|
|||||||
TYPE_SPECIFIC_CHECKS_DT_QTY_UCUM_ANNOTATIONS = UCUM Codes that contain human readable annotations like {0} can be misleading (e.g. they are ignored when comparing units). Best Practice is not to depend on annotations in the UCUM code, so this usage should be checked
|
TYPE_SPECIFIC_CHECKS_DT_QTY_UCUM_ANNOTATIONS = UCUM Codes that contain human readable annotations like {0} can be misleading (e.g. they are ignored when comparing units). Best Practice is not to depend on annotations in the UCUM code, so this usage should be checked
|
||||||
LOGICAL_MODEL_NAME_MISMATCH = The name ''{0}'' does not match the expected name ''{1}''
|
LOGICAL_MODEL_NAME_MISMATCH = The name ''{0}'' does not match the expected name ''{1}''
|
||||||
LOGICAL_MODEL_QNAME_MISMATCH = The QName ''{0}'' does not match the expected QName ''{1}''
|
LOGICAL_MODEL_QNAME_MISMATCH = The QName ''{0}'' does not match the expected QName ''{1}''
|
||||||
|
FHIRPATH_CHOICE_NO_TYPE_SPECIFIER = The expression ''{0}'' refers to an element that is a choice, but doesn''t have an .ofType() so that SQL view runners can pre-determine the full element name
|
||||||
|
FHIRPATH_CHOICE_SPURIOUS_TYPE_SPECIFIER = The expression ''{0}'' refers to an element that is not a choice, but has an .ofType(). SQL view runners are likely to pre-determine an incorrect full element name
|
||||||
|
FHIRPATH_NOT_A_COLLECTION = Found a use of a collection operator on something that is not a collection at ''{0}'' - check that there's no mistakes in the expression syntax
|
||||||
|
|
||||||
|
@ -185,6 +185,7 @@ import org.hl7.fhir.utilities.VersionUtilities;
|
|||||||
import org.hl7.fhir.utilities.VersionUtilities.VersionURLInfo;
|
import org.hl7.fhir.utilities.VersionUtilities.VersionURLInfo;
|
||||||
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
import org.hl7.fhir.utilities.i18n.I18nConstants;
|
||||||
import org.hl7.fhir.utilities.json.model.JsonObject;
|
import org.hl7.fhir.utilities.json.model.JsonObject;
|
||||||
|
import org.hl7.fhir.utilities.validation.IDigitalSignatureServices;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
import org.hl7.fhir.utilities.validation.ValidationMessage;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
|
||||||
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
|
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
|
||||||
@ -493,6 +494,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||||||
public List<ValidatedFragment> validatedContent;
|
public List<ValidatedFragment> validatedContent;
|
||||||
public boolean testMode;
|
public boolean testMode;
|
||||||
private boolean example ;
|
private boolean example ;
|
||||||
|
private IDigitalSignatureServices signatureServices;
|
||||||
|
|
||||||
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);
|
||||||
@ -710,6 +712,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||||||
if (parser instanceof JsonParser) {
|
if (parser instanceof JsonParser) {
|
||||||
((JsonParser) parser).setAllowComments(allowComments);
|
((JsonParser) parser).setAllowComments(allowComments);
|
||||||
}
|
}
|
||||||
|
parser.setSignatureServices(signatureServices);
|
||||||
|
|
||||||
long t = System.nanoTime();
|
long t = System.nanoTime();
|
||||||
validatedContent = null;
|
validatedContent = null;
|
||||||
try {
|
try {
|
||||||
@ -5586,9 +5590,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||||||
long t = System.nanoTime();
|
long t = System.nanoTime();
|
||||||
StructureDefinition profile = this.context.fetchResource(StructureDefinition.class, typeForResource.getProfile().get(0).asStringValue(), parentProfile);
|
StructureDefinition profile = this.context.fetchResource(StructureDefinition.class, typeForResource.getProfile().get(0).asStringValue(), parentProfile);
|
||||||
timeTracker.sd(t);
|
timeTracker.sd(t);
|
||||||
trackUsage(profile, valContext, element);
|
|
||||||
if (rule(errors, NO_RULE_DATE, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(),
|
if (rule(errors, NO_RULE_DATE, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(),
|
||||||
profile != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOPROFILE_EXPL, special.toHuman(), resourceName, typeForResource.getProfile().get(0).asStringValue())) {
|
profile != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOPROFILE_EXPL, special == null ? "??" : special.toHuman(), resourceName, typeForResource.getProfile().get(0).asStringValue())) {
|
||||||
|
trackUsage(profile, valContext, element);
|
||||||
ok = validateResource(hc, errors, resource, element, profile, idstatus, stack, pct, mode) && ok;
|
ok = validateResource(hc, errors, resource, element, profile, idstatus, stack, pct, mode) && ok;
|
||||||
} else {
|
} else {
|
||||||
ok = false;
|
ok = false;
|
||||||
@ -5841,6 +5845,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||||||
boolean ok = true;
|
boolean ok = true;
|
||||||
List<String> profiles = new ArrayList<String>();
|
List<String> profiles = new ArrayList<String>();
|
||||||
String type = null;
|
String type = null;
|
||||||
|
String typeName = null;
|
||||||
ElementDefinition typeDefn = null;
|
ElementDefinition typeDefn = null;
|
||||||
checkMustSupport(profile, ei);
|
checkMustSupport(profile, ei);
|
||||||
long s = System.currentTimeMillis();
|
long s = System.currentTimeMillis();
|
||||||
@ -5848,21 +5853,29 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||||||
if (checkDefn.getType().size() == 1 && !"*".equals(checkDefn.getType().get(0).getWorkingCode()) && !"Element".equals(checkDefn.getType().get(0).getWorkingCode())
|
if (checkDefn.getType().size() == 1 && !"*".equals(checkDefn.getType().get(0).getWorkingCode()) && !"Element".equals(checkDefn.getType().get(0).getWorkingCode())
|
||||||
&& !"BackboneElement".equals(checkDefn.getType().get(0).getWorkingCode())) {
|
&& !"BackboneElement".equals(checkDefn.getType().get(0).getWorkingCode())) {
|
||||||
type = checkDefn.getType().get(0).getWorkingCode();
|
type = checkDefn.getType().get(0).getWorkingCode();
|
||||||
|
typeName = type;
|
||||||
|
if (Utilities.isAbsoluteUrl(type)) {
|
||||||
|
StructureDefinition sdt = context.fetchTypeDefinition(type);
|
||||||
|
if (sdt != null) {
|
||||||
|
typeName = sdt.getTypeName();
|
||||||
|
}
|
||||||
|
}
|
||||||
String stype = ei.getElement().fhirType();
|
String stype = ei.getElement().fhirType();
|
||||||
if (!stype.equals(type)) {
|
if (!stype.equals(type)) {
|
||||||
if (checkDefn.isChoice()) {
|
if (checkDefn.isChoice()) {
|
||||||
if (extensionUrl != null && !isAbsolute(extensionUrl)) {
|
if (extensionUrl != null && !isAbsolute(extensionUrl)) {
|
||||||
ok = rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), ei.getPath(), false, I18nConstants.EXTENSION_PROF_TYPE, profile.getVersionedUrl(), type, stype) && ok;
|
ok = rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), ei.getPath(), false, I18nConstants.EXTENSION_PROF_TYPE, profile.getVersionedUrl(), type, stype) && ok;
|
||||||
} else if (!isAbstractType(type) && !"Extension".equals(profile.getType())) {
|
} else if (!isAbstractType(type) && !"Extension".equals(profile.getType())) {
|
||||||
ok = rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), ei.getPath(), stype.equals(type), I18nConstants.EXTENSION_PROF_TYPE, profile.getVersionedUrl(), type, stype) && ok;
|
ok = rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), ei.getPath(), stype.equals(typeName), I18nConstants.EXTENSION_PROF_TYPE, profile.getVersionedUrl(), type, stype) && ok;
|
||||||
}
|
}
|
||||||
} else if (!isAbstractType(type)) {
|
} else if (!isAbstractType(type)) {
|
||||||
ok = rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), ei.getPath(), stype.equals(type) ||
|
ok = rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), ei.getPath(), stype.equals(typeName) ||
|
||||||
(Utilities.existsInList(type, "string", "id") && Utilities.existsInList(stype, "string", "id")), // work around a r4 problem with id/string
|
(Utilities.existsInList(type, "string", "id") && Utilities.existsInList(stype, "string", "id")), // work around a r4 problem with id/string
|
||||||
I18nConstants.EXTENSION_PROF_TYPE, profile.getVersionedUrl(), type, stype) && ok;
|
I18nConstants.EXTENSION_PROF_TYPE, profile.getVersionedUrl(), type, stype) && ok;
|
||||||
} else if (!isResource(type)) {
|
} else if (!isResource(type)) {
|
||||||
// System.out.println("update type "+type+" to "+stype+"?");
|
// System.out.println("update type "+type+" to "+stype+"?");
|
||||||
type = stype;
|
type = stype;
|
||||||
|
typeName = type;
|
||||||
} else {
|
} else {
|
||||||
// this will be sorted out in contains ... System.out.println("update type "+type+" to "+stype+"?");
|
// this will be sorted out in contains ... System.out.println("update type "+type+" to "+stype+"?");
|
||||||
}
|
}
|
||||||
@ -5878,8 +5891,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||||||
String prefix = tail(checkDefn.getPath());
|
String prefix = tail(checkDefn.getPath());
|
||||||
assert prefix.endsWith("[x]");
|
assert prefix.endsWith("[x]");
|
||||||
type = ei.getName().substring(prefix.length() - 3);
|
type = ei.getName().substring(prefix.length() - 3);
|
||||||
if (isPrimitiveType(type))
|
typeName = type;
|
||||||
|
if (isPrimitiveType(type)) {
|
||||||
type = Utilities.uncapitalize(type);
|
type = Utilities.uncapitalize(type);
|
||||||
|
typeName = type;
|
||||||
|
}
|
||||||
if (checkDefn.getType().get(0).hasProfile()) {
|
if (checkDefn.getType().get(0).hasProfile()) {
|
||||||
for (CanonicalType p : checkDefn.getType().get(0).getProfile()) {
|
for (CanonicalType p : checkDefn.getType().get(0).getProfile()) {
|
||||||
profiles.add(p.getValue());
|
profiles.add(p.getValue());
|
||||||
@ -5892,13 +5908,16 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||||||
|
|
||||||
if (checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR)) {
|
if (checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR)) {
|
||||||
type = ei.getElement().getType();
|
type = ei.getElement().getType();
|
||||||
|
typeName = type;
|
||||||
} else if (ei.getElement().isResource()) {
|
} else if (ei.getElement().isResource()) {
|
||||||
type = ei.getElement().fhirType();
|
type = ei.getElement().fhirType();
|
||||||
|
typeName = type;
|
||||||
} else {
|
} else {
|
||||||
prefix = prefix.substring(0, prefix.length() - 3);
|
prefix = prefix.substring(0, prefix.length() - 3);
|
||||||
for (TypeRefComponent t : checkDefn.getType())
|
for (TypeRefComponent t : checkDefn.getType())
|
||||||
if ((prefix + Utilities.capitalize(t.getWorkingCode())).equals(ei.getName())) {
|
if ((prefix + Utilities.capitalize(t.getWorkingCode())).equals(ei.getName())) {
|
||||||
type = t.getWorkingCode();
|
type = t.getWorkingCode();
|
||||||
|
typeName = type;
|
||||||
// Excluding reference is a kludge to get around versioning issues
|
// Excluding reference is a kludge to get around versioning issues
|
||||||
if (t.hasProfile() && !type.equals("Reference"))
|
if (t.hasProfile() && !type.equals("Reference"))
|
||||||
profiles.add(t.getProfile().get(0).getValue());
|
profiles.add(t.getProfile().get(0).getValue());
|
||||||
@ -5906,9 +5925,10 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||||||
}
|
}
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
TypeRefComponent trc = checkDefn.getType().get(0);
|
TypeRefComponent trc = checkDefn.getType().get(0);
|
||||||
if (trc.getWorkingCode().equals("Reference"))
|
if (trc.getWorkingCode().equals("Reference")) {
|
||||||
type = "Reference";
|
type = "Reference";
|
||||||
else
|
typeName = type;
|
||||||
|
} else
|
||||||
ok = rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, ei.line(), ei.col(), stack.getLiteralPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_NOTYPE, ei.getName(), describeTypes(checkDefn.getType())) && ok;
|
ok = rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, ei.line(), ei.col(), stack.getLiteralPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_NOTYPE, ei.getName(), describeTypes(checkDefn.getType())) && ok;
|
||||||
}
|
}
|
||||||
} else if (checkDefn.getContentReference() != null) {
|
} else if (checkDefn.getContentReference() != null) {
|
||||||
@ -5933,6 +5953,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||||||
ei.definition = ei.definition;
|
ei.definition = ei.definition;
|
||||||
}
|
}
|
||||||
type = null;
|
type = null;
|
||||||
|
typeName = type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NodeStack localStack = stack.push(ei.getElement(), "*".equals(ei.getDefinition().getBase().getMax()) && ei.count == -1 ? 0 : ei.count, checkDefn, type == null ? typeDefn : resolveType(type, checkDefn.getType()));
|
NodeStack localStack = stack.push(ei.getElement(), "*".equals(ei.getDefinition().getBase().getMax()) && ei.count == -1 ? 0 : ei.count, checkDefn, type == null ? typeDefn : resolveType(type, checkDefn.getType()));
|
||||||
@ -7115,4 +7136,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||||||
this.example = example;
|
this.example = example;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IDigitalSignatureServices getSignatureServices() {
|
||||||
|
return signatureServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSignatureServices(IDigitalSignatureServices signatureServices) {
|
||||||
|
this.signatureServices = signatureServices;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user