* 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:
parent
401b73c700
commit
3ba81328cc
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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()));
|
||||
|
|
Loading…
Reference in New Issue