* More rules around URL validation, instead of just marking them as errors

* Don't report errors for extensible bindings when profiles apply required bindings
* fix rendering issue with profile references
* only use c:\temp if it's writeable
This commit is contained in:
Grahame Grieve 2020-12-24 13:21:30 +11:00
parent 401b73c700
commit 3ba81328cc
8 changed files with 177 additions and 16 deletions

View File

@ -0,0 +1,7 @@
Validator:
* More rules around URL validation, instead of just marking them as errors
* Don't report errors for extensible bindings when profiles apply required bindings
Other code changes:
* fix rendering issue with profile references
* only use c:\temp for logs if it's writeable

View File

@ -3313,7 +3313,7 @@ public class ProfileUtilities extends TranslatingUtilities {
c.getPieces().add(gen.new Piece("#"+ed.getElement().getPath(), tail(ed.getElement().getPath()), ed.getElement().getPath()));
} else {
c.getPieces().add(gen.new Piece(null, translate("sd.table", "See ", ed.getElement().getPath()), null));
c.getPieces().add(gen.new Piece(ed.getSource().getUserString("path")+"#"+ed.getElement().getPath(), tail(ed.getElement().getPath())+" ("+ed.getSource().getType()+")", ed.getElement().getPath()));
c.getPieces().add(gen.new Piece(corePath+ed.getSource().getUserString("path")+"#"+ed.getElement().getPath(), tail(ed.getElement().getPath())+" ("+ed.getSource().getType()+")", ed.getElement().getPath()));
}
}
return c;

View File

@ -639,7 +639,7 @@ public class Utilities {
return false;
}
File tmp = new File("c:\\temp");
return tmp.exists() && tmp.isDirectory();
return tmp.exists() && tmp.isDirectory() && tmp.canWrite();
}
public static String pathURL(String... args) {

View File

@ -493,6 +493,8 @@ public class I18nConstants {
public static final String TYPE_SPECIFIC_CHECKS_DT_URI_UUID = "Type_Specific_Checks_DT_URI_UUID";
public static final String TYPE_SPECIFIC_CHECKS_DT_URI_WS = "Type_Specific_Checks_DT_URI_WS";
public static final String TYPE_SPECIFIC_CHECKS_DT_URL_RESOLVE = "Type_Specific_Checks_DT_URL_Resolve";
public static final String TYPE_SPECIFIC_CHECKS_DT_CANONICAL_TYPE = "TYPE_SPECIFIC_CHECKS_DT_CANONICAL_TYPE";
public static final String TYPE_SPECIFIC_CHECKS_DT_CANONICAL_RESOLVE = "TYPE_SPECIFIC_CHECKS_DT_CANONICAL_RESOLVE";
public static final String TYPE_SPECIFIC_CHECKS_DT_UUID_STRAT = "Type_Specific_Checks_DT_UUID_Strat";
public static final String TYPE_SPECIFIC_CHECKS_DT_UUID_VAID = "Type_Specific_Checks_DT_UUID_Vaid";
public static final String UNABLE_TO_CONNECT_TO_TERMINOLOGY_SERVER = "Unable_to_connect_to_terminology_server";

View File

@ -153,7 +153,7 @@ Terminology_TX_NoValid_13 = The Coding provided ({2}) is not in the value set {0
Terminology_TX_NoValid_14 = The Coding provided ({2}) is not in the value set {0}, and a code is recommended to come from this value set. {1}
Terminology_TX_NoValid_15 = The value provided (''{0}'') could not be validated in the absence of a terminology server
Terminology_TX_NoValid_16 = The value provided (''{0}'') is not in the value set {1} ({2}), and a code is required from this value set){3}
Terminology_TX_NoValid_17 = The value provided (''{0}'') is not in the value set {1} ({2}), and a code should come from this value set unless it has no suitable code and the validator cannot judge what is suitable){3}
Terminology_TX_NoValid_17 = The value provided (''{0}'') is not in the value set {1} ({2}), and a code should come from this value set unless it has no suitable code and the validator cannot judge what is suitable) {3}
Terminology_TX_NoValid_18 = The value provided (''{0}'') is not in the value set {1} ({2}), and a code is recommended to come from this value set){3}
Terminology_TX_NoValid_2 = None of the codes provided are in the value set {0} ({1}), and a code should come from this value set unless it has no suitable code and the validator cannot judge what is suitable) (codes = {2})
Terminology_TX_NoValid_3 = None of the codes provided are in the value set {0} ({1}), and a code is recommended to come from this value set) (codes = {2})
@ -634,3 +634,5 @@ SD_ED_BIND_NOT_VS = The valueSet reference {1} on element {0} points to somethin
SD_ED_BIND_NO_BINDABLE = The element {0} has a binding, but no bindable types are present {1}
DISCRIMINATOR_BAD_PATH = Error processing path expression for disciminator: {0} (src = ''{1}'')
SLICING_CANNOT_BE_EVALUATED = Slicing cannot be evaluated: {0}
TYPE_SPECIFIC_CHECKS_DT_CANONICAL_RESOLVE = Canonical URL ''{0}'' does not resolve
TYPE_SPECIFIC_CHECKS_DT_CANONICAL_TYPE = Canonical URL ''{0}'' refers to a resource that has the wrong type. Found {1} expecting one of {2}

View File

@ -84,10 +84,28 @@ import org.hl7.fhir.utilities.validation.ValidationMessage;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity;
import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
import org.hl7.fhir.validation.BaseValidator.TrackedLocationRelatedMessage;
import org.hl7.fhir.validation.instance.utils.IndexedElement;
public class BaseValidator {
public class TrackedLocationRelatedMessage {
private Object location;
private ValidationMessage vmsg;
public TrackedLocationRelatedMessage(Object location, ValidationMessage vmsg) {
super();
this.location = location;
this.vmsg = vmsg;
}
public Object getLocation() {
return location;
}
public ValidationMessage getVmsg() {
return vmsg;
}
}
public class ValidationControl {
private boolean allowed;
private IssueSeverity level;
@ -122,8 +140,10 @@ public class BaseValidator {
protected IWorkerContext context;
protected TimeTracker timeTracker = new TimeTracker();
protected XVerExtensionManager xverManager;
public BaseValidator(IWorkerContext context, XVerExtensionManager xverManager) {
protected List<TrackedLocationRelatedMessage> trackedMessages = new ArrayList<>();
protected List<ValidationMessage> messagesToRemove = new ArrayList<>();
public BaseValidator(IWorkerContext context, XVerExtensionManager xverManager) {
super();
this.context = context;
this.xverManager = xverManager;
@ -493,7 +513,38 @@ public class BaseValidator {
return thePass;
}
/**
* Test a rule and add a {@link IssueSeverity#WARNING} validation message if the validation fails. Also, keep track of it later in case we want to remove it if we find a required binding for this element later
*
* @param thePass
* Set this parameter to <code>false</code> if the validation does not pass
* @return Returns <code>thePass</code> (in other words, returns <code>true</code> if the rule did not fail validation)
*/
protected boolean txWarningForLaterRemoval(Object location, List<ValidationMessage> errors, String txLink, IssueType type, int line, int col, String path, boolean thePass, String msg, Object... theMessageArguments) {
if (!thePass) {
String nmsg = context.formatMessage(msg, theMessageArguments);
ValidationMessage vmsg = new ValidationMessage(Source.TerminologyEngine, type, line, col, path, nmsg, IssueSeverity.WARNING).setTxLink(txLink).setMessageId(msg);
if (checkMsgId(msg, vmsg)) {
errors.add(vmsg);
}
trackedMessages.add(new TrackedLocationRelatedMessage(location, vmsg));
}
return thePass;
}
protected void removeTrackedMessagesForLocation(List<ValidationMessage> errors, Object location, String path) {
List<TrackedLocationRelatedMessage> messages = new ArrayList<>();
for (TrackedLocationRelatedMessage m : trackedMessages) {
if (m.getLocation() == location) {
messages.add(m);
messagesToRemove.add(m.getVmsg());
}
}
trackedMessages.removeAll(messages);
}
protected boolean warningOrError(boolean isError, List<ValidationMessage> errors, IssueType type, int line, int col, String path, boolean thePass, String msg, Object... theMessageArguments) {
if (!thePass) {
String nmsg = context.formatMessage(msg, theMessageArguments);

View File

@ -1710,7 +1710,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst
if (resource != null) {
return ReferenceValidationPolicy.CHECK_VALID;
}
if (!url.startsWith("http://hl7.org/fhir")) {
if (!(url.contains("hl7.org") || url.contains("fhir.org"))) {
return ReferenceValidationPolicy.IGNORE;
} else if (fetcher != null) {
return fetcher.validationPolicy(appContext, path, url);
@ -1748,6 +1748,14 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst
@Override
public CanonicalResource fetchCanonicalResource(String url) throws URISyntaxException {
Resource res = context.fetchResource(Resource.class, url);
if (res != null) {
if (res instanceof CanonicalResource) {
return (CanonicalResource) res;
} else {
return null;
}
}
return fetcher != null ? fetcher.fetchCanonicalResource(url) : null;
}

View File

@ -691,6 +691,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
fetchCache.clear();
fetchCache.put(element.fhirType() + "/" + element.getIdBase(), element);
resourceTracker.clear();
trackedMessages.clear();
messagesToRemove.clear();
executionId = UUID.randomUUID().toString();
baseOnly = profiles.isEmpty();
setParents(element);
@ -706,6 +708,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
if (hintAboutNonMustSupport) {
checkElementUsage(errors, element, new NodeStack(context, element, validationLanguage));
}
errors.removeAll(messagesToRemove);
timeTracker.overall(t);
}
@ -990,6 +993,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
// Check whether the codes are appropriate for the type of binding we have
boolean bindingsOk = true;
if (binding.getStrength() != BindingStrength.EXAMPLE) {
if (binding.getStrength() == BindingStrength.REQUIRED) {
removeTrackedMessagesForLocation(errors, element, path);
}
boolean atLeastOneSystemIsSupported = false;
for (Coding nextCoding : cc.getCoding()) {
String nextSystem = nextCoding.getSystem();
@ -1018,7 +1024,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), cc, stack);
else if (!noExtensibleWarnings)
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_2, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
txWarningForLaterRemoval(element, errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_2, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
} else if (binding.getStrength() == BindingStrength.PREFERRED) {
if (baseOnly) {
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_3, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
@ -1031,7 +1037,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), cc, stack);
if (!noExtensibleWarnings)
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_2, describeReference(binding.getValueSet()), valueset.getUrl(), ccSummary(cc));
txWarningForLaterRemoval(element, errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_2, describeReference(binding.getValueSet()), valueset.getUrl(), ccSummary(cc));
} else if (binding.getStrength() == BindingStrength.PREFERRED) {
if (baseOnly) {
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_3, describeReference(binding.getValueSet()), valueset.getUrl(), ccSummary(cc));
@ -1080,6 +1086,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
return res;
}
private boolean checkTerminologyCodeableConcept(List<ValidationMessage> errors, String path, Element element, StructureDefinition profile, ElementDefinition theElementCntext, NodeStack stack, StructureDefinition logical) {
boolean res = true;
if (!noTerminologyChecks && theElementCntext != null && theElementCntext.hasBinding()) {
@ -1105,6 +1112,10 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
// Check whether the codes are appropriate for the type of binding we have
boolean bindingsOk = true;
if (binding.getStrength() != BindingStrength.EXAMPLE) {
if (binding.getStrength() == BindingStrength.REQUIRED) {
removeTrackedMessagesForLocation(errors, element, path);
}
boolean atLeastOneSystemIsSupported = false;
for (Coding nextCoding : cc.getCoding()) {
String nextSystem = nextCoding.getSystem();
@ -1127,7 +1138,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), cc, stack);
else if (!noExtensibleWarnings)
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_2, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
txWarningForLaterRemoval(element, errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_2, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
} else if (binding.getStrength() == BindingStrength.PREFERRED) {
if (baseOnly) {
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_3, describeReference(binding.getValueSet()), vr.getErrorClass().toString());
@ -1140,7 +1151,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), cc, stack);
if (!noExtensibleWarnings)
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_2, describeReference(binding.getValueSet()), valueset.getUrl(), ccSummary(cc));
txWarningForLaterRemoval(element, errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_2, describeReference(binding.getValueSet()), valueset.getUrl(), ccSummary(cc));
} else if (binding.getStrength() == BindingStrength.PREFERRED) {
if (baseOnly) {
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_3, describeReference(binding.getValueSet()), valueset.getUrl(), ccSummary(cc));
@ -1212,6 +1223,10 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
if (binding.getStrength() != BindingStrength.EXAMPLE) {
vr = checkCodeOnServer(stack, valueset, c, true);
}
if (binding.getStrength() == BindingStrength.REQUIRED) {
removeTrackedMessagesForLocation(errors, element, path);
}
timeTracker.tx(t);
if (vr != null && !vr.isOk()) {
if (vr.IsNoService())
@ -1223,7 +1238,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), c, stack);
else if (!noExtensibleWarnings)
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_5, describeReference(binding.getValueSet(), valueset));
txWarningForLaterRemoval(element, errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_5, describeReference(binding.getValueSet(), valueset));
} else if (binding.getStrength() == BindingStrength.PREFERRED) {
if (baseOnly) {
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_6, describeReference(binding.getValueSet(), valueset));
@ -1432,6 +1447,10 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
vr = checkCodeOnServer(stack, valueset, c, true);
}
timeTracker.tx(t);
if (binding.getStrength() == BindingStrength.REQUIRED) {
removeTrackedMessagesForLocation(errors, element, path);
}
if (vr != null && !vr.isOk()) {
if (vr.IsNoService())
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_BINDING_NOSERVER);
@ -1442,7 +1461,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), c, stack);
else if (!noExtensibleWarnings)
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_5, describeReference(binding.getValueSet(), valueset));
txWarningForLaterRemoval(element, errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_5, describeReference(binding.getValueSet(), valueset));
} else if (binding.getStrength() == BindingStrength.PREFERRED) {
if (baseOnly) {
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_CONFIRM_6, describeReference(binding.getValueSet(), valueset));
@ -1453,8 +1472,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
else if (binding.getStrength() == BindingStrength.EXTENSIBLE) {
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), c, stack);
else
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_13, describeReference(binding.getValueSet(), valueset), getErrorMessage(vr.getMessage()), c.getSystem()+"#"+c.getCode());
else if (!noExtensibleWarnings) {
txWarningForLaterRemoval(element, errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_13, describeReference(binding.getValueSet(), valueset), getErrorMessage(vr.getMessage()), c.getSystem()+"#"+c.getCode());
}
} else if (binding.getStrength() == BindingStrength.PREFERRED) {
if (baseOnly) {
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_14, describeReference(binding.getValueSet(), valueset), getErrorMessage(vr.getMessage()), theSystem+"#"+theCode);
@ -1935,7 +1955,40 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
} catch (IOException e1) {
found = false;
}
rule(errors, IssueType.INVALID, e.line(), e.col(), path, found, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_URL_RESOLVE, url);
if (!found) {
if (type.equals("canonical")) {
ReferenceValidationPolicy rp = fetcher.validationPolicy(appContext, path, url);
if (rp == ReferenceValidationPolicy.CHECK_EXISTS || rp == ReferenceValidationPolicy.CHECK_EXISTS_AND_TYPE) {
rule(errors, IssueType.INVALID, e.line(), e.col(), path, found, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_CANONICAL_RESOLVE, url);
} else {
hint(errors, IssueType.INVALID, e.line(), e.col(), path, found, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_CANONICAL_RESOLVE, url);
}
} else {
if (url.contains("hl7.org") || url.contains("fhir.org")) {
rule(errors, IssueType.INVALID, e.line(), e.col(), path, found, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_URL_RESOLVE, url);
} else {
warning(errors, IssueType.INVALID, e.line(), e.col(), path, found, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_URL_RESOLVE, url);
}
}
} else {
if (type.equals("canonical")) {
ReferenceValidationPolicy rp = fetcher.validationPolicy(appContext, path, url);
if (rp == ReferenceValidationPolicy.CHECK_EXISTS_AND_TYPE || rp == ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS || rp == ReferenceValidationPolicy.CHECK_VALID) {
try {
Resource r = fetcher.fetchCanonicalResource(url);
if (r == null) {
rule(errors, IssueType.INVALID, e.line(), e.col(), path, found, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_CANONICAL_RESOLVE, url);
} else if (rule(errors, IssueType.INVALID, e.line(), e.col(), path, isCorrectCanonicalType(r, context), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_CANONICAL_TYPE, url, r.fhirType(), listExpectedCanonicalTypes(context))) {
if (rp == ReferenceValidationPolicy.CHECK_VALID) {
// todo....
}
}
} catch (Exception ex) {
// won't happen
}
}
}
}
}
}
}
@ -2083,6 +2136,41 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
// for nothing to check
}
private List<String> listExpectedCanonicalTypes(ElementDefinition context) {
List<String> res = new ArrayList<>();
TypeRefComponent tr = context.getType("canonical");
if (tr != null) {
for (CanonicalType p : tr.getTargetProfile()) {
String url = p.getValue();
if (url != null && url.startsWith("http://hl7.org/fhir/StructureDefinition/")) {
res.add(url.substring("http://hl7.org/fhir/StructureDefinition/".length()));
}
}
}
return res;
}
private boolean isCorrectCanonicalType(Resource r, ElementDefinition context) {
TypeRefComponent tr = context.getType("canonical");
if (tr != null) {
for (CanonicalType p : tr.getTargetProfile()) {
if (isCorrectCanonicalType(r, p)) {
return true;
}
}
}
return false;
}
private boolean isCorrectCanonicalType(Resource r, CanonicalType p) {
String url = p.getValue();
if (url != null && url.startsWith("http://hl7.org/fhir/StructureDefinition/")) {
url = url.substring("http://hl7.org/fhir/StructureDefinition/".length());
return Utilities.existsInList(url, "Resource", "CanonicalResource") || url.equals(r.fhirType());
}
return false;
}
private boolean isCanonicalURLElement(Element e) {
if (e.getProperty() == null || e.getProperty().getDefinition() == null) {
return false;
@ -2301,6 +2389,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
vr = checkCodeOnServer(stack, vs, value, options);
}
timeTracker.tx(t);
if (binding.getStrength() == BindingStrength.REQUIRED) {
removeTrackedMessagesForLocation(errors, element, path);
}
if (vr != null && !vr.isOk()) {
if (vr.IsNoService())
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_15, value);
@ -2310,7 +2401,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
if (binding.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"))
checkMaxValueSet(errors, path, element, profile, ToolingExtensions.readStringExtension(binding, "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"), value, stack);
else if (!noExtensibleWarnings)
txWarning(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_17, value, describeReference(binding.getValueSet()), vs.getUrl(), getErrorMessage(vr.getMessage()));
txWarningForLaterRemoval(element, errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_17, value, describeReference(binding.getValueSet()), vs.getUrl(), getErrorMessage(vr.getMessage()));
} else if (binding.getStrength() == BindingStrength.PREFERRED) {
if (baseOnly) {
txHint(errors, vr.getTxLink(), IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_NOVALID_18, value, describeReference(binding.getValueSet()), vs.getUrl(), getErrorMessage(vr.getMessage()));