#820 Add warnings when potential matches are found when performing reference resolution in bundles
This commit is contained in:
parent
655fc8b6ca
commit
12a1dbfc05
|
@ -701,6 +701,9 @@ public class I18nConstants {
|
|||
public static final String TYPE_SPECIFIC_CHECKS_DT_BASE64_NO_WS_ERROR = "TYPE_SPECIFIC_CHECKS_DT_BASE64_NO_WS_ERROR";
|
||||
public static final String TYPE_SPECIFIC_CHECKS_DT_BASE64_NO_WS_WARNING = "TYPE_SPECIFIC_CHECKS_DT_BASE64_NO_WS_WARNING";
|
||||
public static final String TX_SERVER_NO_BATCH_RESPONSE = "TX_SERVER_NO_BATCH_RESPONSE";
|
||||
public static final String BUNDLE_POSSSIBLE_MATCHES = "BUNDLE_POSSSIBLE_MATCHES";
|
||||
public static final String BUNDLE_BUNDLE_POSSIBLE_MATCH_NO_FU = "BUNDLE_BUNDLE_POSSIBLE_MATCH_NO_FU";
|
||||
public static final String BUNDLE_BUNDLE_POSSIBLE_MATCH_WRONG_FU = "BUNDLE_BUNDLE_POSSIBLE_MATCH_WRONG_FU";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -851,6 +851,9 @@ public class NpmPackage {
|
|||
|
||||
public InputStream loadExampleResource(String type, String id) throws IOException {
|
||||
NpmPackageFolder f = folders.get("example");
|
||||
if (f == null) {
|
||||
f = folders.get("package/example");
|
||||
}
|
||||
if (f != null) {
|
||||
JsonArray files = f.index.getAsJsonArray("files");
|
||||
for (JsonElement e : files) {
|
||||
|
|
|
@ -108,7 +108,7 @@ public class BaseTestingUtilities {
|
|||
}
|
||||
|
||||
public static String tempFolder(String name) throws IOException {
|
||||
String path = ToolGlobalSettings.hasTempPath() ? ToolGlobalSettings.getTempPath() : Utilities.path("[tmp]", name);
|
||||
String path = Utilities.path(ToolGlobalSettings.hasTempPath() ? ToolGlobalSettings.getTempPath() : "[tmp]", name);
|
||||
Utilities.createDirectory(path);
|
||||
return path;
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ Reference_REF_BadTargetType = Invalid Resource target type. Found {0}, but expec
|
|||
Reference_REF_BadTargetType2 = The type ''{0}'' implied by the reference URL {1} is not a valid Target for this element (must be one of {2})
|
||||
Reference_REF_CantMatchChoice = Unable to find a match for profile {0} among choices: {1}
|
||||
Reference_REF_CantMatchType = Unable to find a match for profile {0} (by type) among choices: {1}
|
||||
Reference_REF_CantResolve = Unable to resolve resource ''{0}''
|
||||
Reference_REF_CantResolve = Unable to resolve resource with reference ''{0}''
|
||||
Reference_REF_CantResolveProfile = Unable to resolve the profile reference ''{0}''
|
||||
Reference_REF_Format1 = Relative URLs must be of the format [ResourceName]/[id], or a search URL is allowed ([type]?parameters. Encountered {0})
|
||||
Reference_REF_Format2 = Relative URLs must be of the format [ResourceName]/[id]. Encountered {0}
|
||||
|
@ -280,7 +280,7 @@ Unable_to_locate_the_profile__in_order_to_validate_against_it = Unable to locate
|
|||
Reference__refers_to_a__not_a_ValueSet = Reference {0} refers to a {1} not a ValueSet
|
||||
Not_done_yet_ValidatorHostServicesconformsToProfile_when_item_is_not_an_element = Not done yet (ValidatorHostServices.conformsToProfile), when item is not an element
|
||||
Not_supported_yet = Not supported yet
|
||||
Unable_to_resolve_ = Unable to resolve {0}
|
||||
Unable_to_resolve_ = Unable to resolve the reference {0}
|
||||
Not_done_yet__resolve__locally_2 = Not done yet - resolve {0} locally (2)
|
||||
Not_done_yet_ValidatorHostServicesexecuteFunction = Not done yet (ValidatorHostServices.executeFunction)
|
||||
Not_done_yet_ValidatorHostServicescheckFunction = Not done yet (ValidatorHostServices.checkFunction)
|
||||
|
@ -711,3 +711,6 @@ TYPE_SPECIFIC_CHECKS_DT_BASE64_NO_WS_WARNING = Base64 encoded values SHOULD not
|
|||
SD_DERIVATION_KIND_MISMATCH = The structure definition constrains a kind of {0}, but has a different kind ({1})
|
||||
VALUESET_IMPORT_UNION_INTERSECTION = This value set has a single include with multiple imported value sets. Per issue https://jira.hl7.org/browse/FHIR-25179, there has been confusion in the past whether these value sets are unioned or intersectioned. If this value set is contained in a package published prior to March 31 2022, it will be treated as a union, otherwise it will be treated as an intersection. If want a union, split the value set imports across multiple includes
|
||||
TX_SERVER_NO_BATCH_RESPONSE = The server return null from a batch validation request
|
||||
BUNDLE_POSSSIBLE_MATCHES = The bundle contains no match for {1} by the rules of Bundle reference resolution, but it has multiple resources that match {0} by resource type and id
|
||||
BUNDLE_BUNDLE_POSSIBLE_MATCH_NO_FU = Entry {0} matches the reference {1} by type and id but it does not match the full target URL {2} 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
|
||||
|
|
|
@ -950,8 +950,34 @@ public class BaseValidator implements IValidationContextResourceLoader {
|
|||
|
||||
if (match != null && resourceType != null)
|
||||
rule(errors, IssueType.REQUIRED, -1, -1, path, match.getType().equals(resourceType), I18nConstants.REFERENCE_REF_RESOURCETYPE, ref, match.getType());
|
||||
if (match == null)
|
||||
if (match == null) {
|
||||
warning(errors, IssueType.REQUIRED, -1, -1, path, !ref.startsWith("urn"), I18nConstants.BUNDLE_BUNDLE_NOT_LOCAL, ref);
|
||||
if (!Utilities.isAbsoluteUrl(ref)) {
|
||||
String[] p = ref.split("\\/");
|
||||
List<Element> ml = new ArrayList<>();
|
||||
if (p.length >= 2 && Utilities.existsInList(p[0], context.getResourceNames()) && Utilities.isValidId(p[1])) {
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
Element we = entries.get(i);
|
||||
Element r = we.getNamedChild(RESOURCE);
|
||||
if (r != null && p[0].equals(r.fhirType()) && p[1].equals(r.getNamedChildValue("id")) ) {
|
||||
ml.add(we);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ml.size() > 1) {
|
||||
warning(errors, IssueType.REQUIRED, -1, -1, path, false, I18nConstants.BUNDLE_POSSSIBLE_MATCHES, ref, targetUrl);
|
||||
}
|
||||
for (Element e : ml) {
|
||||
String fu = e.getChildValue(FULL_URL);
|
||||
int i = entries.indexOf(e);
|
||||
if (fu == null) {
|
||||
warning(errors, IssueType.REQUIRED, -1, -1, path, false, I18nConstants.BUNDLE_BUNDLE_POSSIBLE_MATCH_NO_FU, i, ref, targetUrl);
|
||||
} else {
|
||||
warning(errors, IssueType.REQUIRED, -1, -1, path, false, I18nConstants.BUNDLE_BUNDLE_POSSIBLE_MATCH_WRONG_FU, i, ref, fu, targetUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return match == null ? null : new IndexedElement(matchIndex, match, entries.get(matchIndex));
|
||||
}
|
||||
|
||||
|
|
|
@ -627,6 +627,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP
|
|||
igLoader.loadIg(getIgs(), getBinaries(), SHCParser.CURRENT_PACKAGE, true);
|
||||
}
|
||||
validator.setJurisdiction(jurisdiction);
|
||||
validator.setLogProgress(true);
|
||||
return validator;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ public class ComparisonService {
|
|||
|
||||
public static void compareStructureDefinitions(String dest, ValidationEngine validator, String left, String right, StructureDefinition resLeft, StructureDefinition resRight) throws IOException, FHIRException, EOperationOutcome {
|
||||
System.out.println("Comparing StructureDefinitions " + left + " to " + right);
|
||||
ComparisonSession session = new ComparisonSession(validator.getContext(), validator.getContext(), "Comparing Profiles", null);
|
||||
ComparisonSession session = new ComparisonSession(validator.getContext(), validator.getContext(), "Comparing Profiles", null, null);
|
||||
session.compare(resLeft, resRight);
|
||||
|
||||
System.out.println("Generating output to " + dest + "...");
|
||||
|
|
|
@ -424,6 +424,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
private QuestionnaireMode questionnaireMode;
|
||||
private ValidationOptions baseOptions = new ValidationOptions();
|
||||
private Map<String, CanonicalResourceLookupResult> crLookups = new HashMap<>();
|
||||
private boolean logProgress;
|
||||
|
||||
public InstanceValidator(IWorkerContext theContext, IEvaluationContext hostServices, XVerExtensionManager xverManager) {
|
||||
super(theContext, xverManager);
|
||||
|
@ -2980,8 +2981,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
if (refType.equals("contained") || refType.equals("bundled")) {
|
||||
pol = ReferenceValidationPolicy.CHECK_VALID;
|
||||
} else {
|
||||
if (policyAdvisor == null) pol = ReferenceValidationPolicy.IGNORE;
|
||||
else pol = policyAdvisor.policyForReference(this, hostContext.getAppContext(), path, ref);
|
||||
if (policyAdvisor == null) {
|
||||
pol = ReferenceValidationPolicy.IGNORE;
|
||||
} else {
|
||||
pol = policyAdvisor.policyForReference(this, hostContext.getAppContext(), path, ref);
|
||||
}
|
||||
}
|
||||
|
||||
if (pol.checkExists()) {
|
||||
|
@ -4397,7 +4401,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
// this method is reentrant, but also the right place to tell the user what is going on if it's the root.
|
||||
// if we're not at the root, we don't report progress
|
||||
pctOwned = true;
|
||||
pct = new PercentageTracker(resource.countDescendents()+1, resource.fhirType(), defn.getUrl());
|
||||
pct = new PercentageTracker(resource.countDescendents()+1, resource.fhirType(), defn.getUrl(), logProgress);
|
||||
}
|
||||
if (BUNDLE.equals(element.fhirType())) {
|
||||
if (debug) {
|
||||
|
@ -4467,7 +4471,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
stack.resetIds();
|
||||
if (pctOwned) {
|
||||
pct = new PercentageTracker(resource.countDescendents(), resource.fhirType(), sd.getUrl());
|
||||
pct = new PercentageTracker(resource.countDescendents(), resource.fhirType(), sd.getUrl(), logProgress);
|
||||
}
|
||||
startInner(hostContext, errors, resource, element, sd, stack, false, pct);
|
||||
if (pctOwned) {
|
||||
|
@ -4490,7 +4494,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
stack.resetIds();
|
||||
if (pctOwned) {
|
||||
pct = new PercentageTracker(resource.countDescendents(), resource.fhirType(), sd.getUrl());
|
||||
pct = new PercentageTracker(resource.countDescendents(), resource.fhirType(), sd.getUrl(), logProgress);
|
||||
}
|
||||
startInner(hostContext, errors, resource, element, sd, stack, false, pct);
|
||||
if (pctOwned) {
|
||||
|
@ -6072,4 +6076,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
return this;
|
||||
}
|
||||
|
||||
public boolean isLogProgress() {
|
||||
return logProgress;
|
||||
}
|
||||
|
||||
public void setLogProgress(boolean logProgress) {
|
||||
this.logProgress = logProgress;
|
||||
}
|
||||
|
||||
}
|
|
@ -7,18 +7,30 @@ public class PercentageTracker {
|
|||
private int total;
|
||||
private int last;
|
||||
private int current;
|
||||
private boolean log;
|
||||
private String url;
|
||||
|
||||
private static int instance;
|
||||
|
||||
public PercentageTracker(int total, String fhirType, String url) {
|
||||
public PercentageTracker(int total, String fhirType, String url, boolean log) {
|
||||
this.total = total;
|
||||
instance++;
|
||||
last = 0;
|
||||
System.out.print("Validate "+fhirType+" against "+url);
|
||||
this.log = log;
|
||||
this.url = url;
|
||||
if (log) {
|
||||
System.out.print("Validate "+fhirType+" against "+url);
|
||||
}
|
||||
}
|
||||
|
||||
public void done() {
|
||||
System.out.println("|");
|
||||
if (log) {
|
||||
System.out.println("|");
|
||||
}
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void seeElement(Element e) {
|
||||
|
@ -28,10 +40,14 @@ public class PercentageTracker {
|
|||
int pct = total == 0 ? 0: (current*100) / total;
|
||||
if (pct > last + 2) {
|
||||
while (last + 2 < pct) {
|
||||
System.out.print(".");
|
||||
if (log) {
|
||||
System.out.print(".");
|
||||
}
|
||||
last = last + 2;
|
||||
if (last % 20 == 0) {
|
||||
System.out.print(""+last);
|
||||
if (log) {
|
||||
System.out.print(""+last);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ public class ComparisonTests {
|
|||
CanonicalResource left = load("left");
|
||||
CanonicalResource right = load("right");
|
||||
|
||||
ComparisonSession session = new ComparisonSession(context, context, "Comparison Tests", null);
|
||||
ComparisonSession session = new ComparisonSession(context, context, "Comparison Tests", null, null);
|
||||
|
||||
if (left instanceof CodeSystem && right instanceof CodeSystem) {
|
||||
CodeSystemComparer cs = new CodeSystemComparer(session);
|
||||
|
|
|
@ -1292,3 +1292,43 @@ v: {
|
|||
"system" : "http://loinc.org"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
||||
{"code" : {
|
||||
"system" : "http://loinc.org",
|
||||
"code" : "11502-2"
|
||||
}, "url": "http://hl7.org/fhir/ValueSet/doc-typecodes--0", "version": "4.0.1", "lang":"null", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false"}####
|
||||
v: {
|
||||
"display" : "Laboratory report",
|
||||
"code" : "11502-2",
|
||||
"system" : "http://loinc.org"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
||||
{"code" : {
|
||||
"system" : "http://loinc.org",
|
||||
"code" : "11502-2"
|
||||
}, "url": "http://hl7.org/fhir/ValueSet/doc-typecodes", "version": "4.0.1", "lang":"null", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "versionFlexible":"false"}####
|
||||
v: {
|
||||
"display" : "Laboratory report",
|
||||
"code" : "11502-2",
|
||||
"system" : "http://loinc.org"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
||||
{"code" : {
|
||||
"system" : "http://loinc.org",
|
||||
"code" : "11502-2"
|
||||
}, "valueSet" :null, "lang":"null", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"true"}####
|
||||
v: {
|
||||
"display" : "Laboratory report",
|
||||
"code" : "11502-2",
|
||||
"system" : "http://loinc.org"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
||||
{"code" : {
|
||||
"system" : "http://loinc.org",
|
||||
"code" : "11502-2"
|
||||
}, "valueSet" :null, "lang":"null", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false"}####
|
||||
v: {
|
||||
"display" : "Laboratory report",
|
||||
"code" : "11502-2",
|
||||
"system" : "http://loinc.org"
|
||||
}
|
||||
-------------------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue