From 7de14f172e664a795fbcdb399ed45986e49f0aa9 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Sat, 5 Dec 2020 08:11:52 +1100 Subject: [PATCH] Fix validation issues for StructureDefinitions (#396) --- .../hl7/fhir/r5/utils/IResourceValidator.java | 2 +- .../hl7/fhir/utilities/VersionUtilities.java | 4 +- .../fhir/utilities/i18n/I18nConstants.java | 6 ++ .../src/main/resources/Messages.properties | 8 +- .../hl7/fhir/validation/ValidationEngine.java | 25 +++++- .../services/StandAloneValidatorFetcher.java | 79 ++++++++++++++++++- .../instance/InstanceValidator.java | 47 ++++++++--- .../type/StructureDefinitionValidator.java | 4 +- .../validation/tests/ValidationTests.java | 2 +- 9 files changed, 157 insertions(+), 20 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/IResourceValidator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/IResourceValidator.java index 4bfa7c2f7..fe3a66f8c 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/IResourceValidator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/IResourceValidator.java @@ -109,7 +109,7 @@ public interface IResourceValidator { Element fetch(Object appContext, String url) throws FHIRFormatError, DefinitionException, FHIRException, IOException; ReferenceValidationPolicy validationPolicy(Object appContext, String path, String url); - boolean resolveURL(Object appContext, String path, String url) throws IOException, FHIRException; + boolean resolveURL(Object appContext, String path, String url, String type) throws IOException, FHIRException; byte[] fetchRaw(String url) throws MalformedURLException, IOException; // for attachment checking diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java index 41dc1bdd5..bc5dfc0b0 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java @@ -364,6 +364,7 @@ public class VersionUtilities { res.add("TestScript"); } if (isR3Ver(version)) { + res.add("CodeSystem"); res.add("CapabilityStatement"); res.add("StructureDefinition"); res.add("ImplementationGuide"); @@ -388,6 +389,7 @@ public class VersionUtilities { } if (isR4Ver(version)) { + res.add("CodeSystem"); res.add("ActivityDefinition"); res.add("CapabilityStatement"); res.add("ChargeItemDefinition"); @@ -419,7 +421,7 @@ public class VersionUtilities { res.add("ValueSet"); } - if (isR5Ver(version)) { + if (isR5Ver(version) || "current".equals(version)) { res.add("ActivityDefinition"); res.add("CapabilityStatement"); diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java index 81dce36fd..c3df01d3f 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java @@ -350,6 +350,7 @@ public class I18nConstants { public static final String SD_ED_TYPE_PROFILE_UNKNOWN = "SD_ED_TYPE_PROFILE_UNKNOWN"; public static final String SD_ED_TYPE_PROFILE_NOTYPE = "SD_ED_TYPE_PROFILE_NOTYPE"; public static final String SD_ED_TYPE_PROFILE_WRONG = "SD_ED_TYPE_PROFILE_WRONG"; + public static final String SD_ED_TYPE_PROFILE_WRONG_TARGET = "SD_ED_TYPE_PROFILE_WRONG_TARGET"; public static final String SD_ED_TYPE_NO_TARGET_PROFILE = "SD_ED_TYPE_NO_TARGET_PROFILE"; public static final String SEARCHPARAMETER_BASE_WRONG = "SEARCHPARAMETER_BASE_WRONG"; public static final String SEARCHPARAMETER_EXP_WRONG = "SEARCHPARAMETER_EXP_WRONG"; @@ -593,6 +594,11 @@ public class I18nConstants { public static final String XHTML_URL_EMPTY = "XHTML_URL_EMPTY"; public static final String XHTML_URL_INVALID = "XHTML_URL_INVALID"; public static final String XHTML_URL_INVALID_CHARS = "XHTML_URL_INVALID_CHARS"; + public static final String XHTML_URL_DATA_NO_DATA = "XHTML_URL_DATA_NO_DATA"; + public static final String XHTML_URL_DATA_DATA_INVALID_COMMA = "XHTML_URL_DATA_DATA_INVALID_COMMA"; + public static final String XHTML_URL_DATA_DATA_INVALID = "XHTML_URL_DATA_DATA_INVALID"; + public static final String XHTML_URL_DATA_MIMETYPE = "XHTML_URL_DATA_MIMETYPE"; + public static final String XHTML_XHTML_ATTRIBUTE_ILLEGAL = "XHTML_XHTML_Attribute_Illegal"; public static final String XHTML_XHTML_DOCTYPE_ILLEGAL = "XHTML_XHTML_DOCTYPE_ILLEGAL"; public static final String XHTML_XHTML_ELEMENT_ILLEGAL = "XHTML_XHTML_Element_Illegal"; diff --git a/org.hl7.fhir.utilities/src/main/resources/Messages.properties b/org.hl7.fhir.utilities/src/main/resources/Messages.properties index 133ad27fd..875dcc95a 100644 --- a/org.hl7.fhir.utilities/src/main/resources/Messages.properties +++ b/org.hl7.fhir.utilities/src/main/resources/Messages.properties @@ -443,7 +443,7 @@ documentmsg = (document) xml_attr_value_invalid = The XML Attribute {0} has an illegal character xml_encoding_invalid = The XML encoding is invalid (must be UTF-8) xml_stated_encoding_invalid = The XML encoding stated in the header is invalid (must be ''UTF-8'' if stated) -XHTML_URL_INVALID = The URL {0} is not valid ({1}) +XHTML_URL_INVALID = The URL is not valid because ''({1})'' : {0} MEASURE_MR_GRP_NO_CODE = Group should have a code that matches the group definition in the measure MEASURE_MR_GRP_UNK_CODE = The code for this group has no match in the measure definition MEASURE_MR_GRP_DUPL_CODE = The code for this group is duplicated with another group @@ -619,8 +619,12 @@ Unable_to_connect_to_terminology_server = Unable to connect to terminology serve SD_ED_TYPE_PROFILE_UNKNOWN = Unable to resolve profile {0} SD_ED_TYPE_PROFILE_NOTYPE = Found profile {0}, but unable to determine the type it applies it SD_ED_TYPE_PROFILE_WRONG = Profile {0} is for type {1}, but the {3} element has type {2} +SD_ED_TYPE_PROFILE_WRONG_TARGET = Profile {0} is for type {1}, which is not a {4} (which is required because the {3} element has type {2}) SD_ED_TYPE_NO_TARGET_PROFILE = Type {0} does not allow for target Profiles TERMINOLOGY_TX_NOSVC_BOUND_REQ = Could not confirm that the codes provided are from the required value set {0} because there is no terminology service TERMINOLOGY_TX_NOSVC_BOUND_EXT = Could not confirm that the codes provided are from the extensible value set {0} because there is no terminology service ARRAY_CANNOT_BE_EMPTY = Array cannot be empty - the property should not be present if it has no values - \ No newline at end of file +XHTML_URL_DATA_NO_DATA = No data found in data: URL +XHTML_URL_DATA_DATA_INVALID_COMMA = Comma found in data portion of data URL: {0} +XHTML_URL_DATA_DATA_INVALID = The data should be valid base64 content for a data: URL: {0} +XHTML_URL_DATA_MIMETYPE = The mimetype potion of the data: URL is not valid ({1}) in URL: {0} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java index b64e79031..6dfb61a11 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java @@ -104,6 +104,7 @@ import org.hl7.fhir.utilities.TimeTracker; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.i18n.I18nConstants; +import org.hl7.fhir.utilities.json.JSONUtil; import org.hl7.fhir.utilities.json.JsonTrackingParser; import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; import org.hl7.fhir.utilities.npm.NpmPackage; @@ -114,6 +115,7 @@ 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.utilities.xhtml.XhtmlComposer; +import org.hl7.fhir.utilities.xml.XMLUtil; import org.hl7.fhir.validation.BaseValidator.ValidationControl; import org.hl7.fhir.validation.ValidationEngine.ValidationRecord; import org.hl7.fhir.validation.cli.model.ScanOutputItem; @@ -122,6 +124,9 @@ import org.hl7.fhir.validation.cli.utils.*; import org.hl7.fhir.validation.instance.InstanceValidator; import org.w3c.dom.Document; import org.xml.sax.SAXException; +import org.xmlpull.v1.builder.XmlDocument; + +import com.google.gson.JsonObject; /* @@ -1310,6 +1315,22 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst if (s.contains("http://hl7.org/fhir/1.4")) { versions.see("1.4", "Profile in "+ref); } + try { + if (s.startsWith("{")) { + JsonObject json = JsonTrackingParser.parse(s, null); + if (json.has("fhirVersion")) { + versions.see(VersionUtilities.getMajMin(JSONUtil.str(json, "fhirVersion")), "fhirVersion in "+ref); + } + } else { + Document doc = parseXml(cnt.focus); + String v = XMLUtil.getNamedChildValue(doc.getDocumentElement(), "fhirVersion"); + if (v != null) { + versions.see(VersionUtilities.getMajMin(v), "fhirVersion in "+ref); + } + } + } catch (Exception e) { + // nothing + } } } @@ -1883,7 +1904,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst } @Override - public boolean resolveURL(Object appContext, String path, String url) throws IOException, FHIRException { + public boolean resolveURL(Object appContext, String path, String url, String type) throws IOException, FHIRException { if (!url.startsWith("http://") && !url.startsWith("https://")) { // ignore these return true; } @@ -1898,7 +1919,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst return true; } if (fetcher != null) { - return fetcher.resolveURL(appContext, path, url); + return fetcher.resolveURL(appContext, path, url, type); }; return false; } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/StandAloneValidatorFetcher.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/StandAloneValidatorFetcher.java index 6015f4ef2..a544230b8 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/StandAloneValidatorFetcher.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/StandAloneValidatorFetcher.java @@ -3,6 +3,8 @@ package org.hl7.fhir.validation.cli.services; import java.io.IOException; import java.net.MalformedURLException; import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.List; import java.util.Locale; import org.hl7.fhir.convertors.txClient.TerminologyClientFactory; @@ -18,10 +20,16 @@ import org.hl7.fhir.r5.utils.IResourceValidator.ReferenceValidationPolicy; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.VersionUtilities.VersionURLInfo; +import org.hl7.fhir.utilities.json.JSONUtil; +import org.hl7.fhir.utilities.json.JsonTrackingParser; import org.hl7.fhir.utilities.npm.BasePackageCacheManager; import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; import org.hl7.fhir.utilities.npm.NpmPackage; +import com.google.gson.JsonObject; + +import ca.uhn.fhir.util.JsonUtil; + public class StandAloneValidatorFetcher implements IValidatorResourceFetcher { public interface IPackageInstaller { @@ -29,6 +37,7 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher { void loadPackage(String id, String ver) throws IOException, FHIRException; } + List mappingsUris = new ArrayList<>(); private FilesystemPackageCacheManager pcm; private IWorkerContext context; private IPackageInstaller installer; @@ -51,11 +60,19 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher { } @Override - public boolean resolveURL(Object appContext, String path, String url) throws IOException, FHIRException { + public boolean resolveURL(Object appContext, String path, String url, String type) throws IOException, FHIRException { if (!Utilities.isAbsoluteUrl(url)) { return false; } + if (url.contains("|")) { + url = url.substring(0, url.lastIndexOf("|")); + } + + if (type.equals("uri") && isMappingUri(url)) { + return true; + } + // if we've got to here, it's a reference to a FHIR URL. We're going to try to resolve it on the fly String pid = null; String ver = null; @@ -94,10 +111,70 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher { } } + // we don't bother with urls outside fhir space in the standalone validator - we assume they are valid return !url.startsWith("http://hl7.org/fhir"); } + private boolean isMappingUri(String url) { + if (mappingsUris.isEmpty()) { + JsonObject json; + try { + json = JsonTrackingParser.fetchJson("http://hl7.org/fhir/mappingspaces.json"); + for (JsonObject ms : JSONUtil.objects(json, "spaces")) { + mappingsUris.add(JSONUtil.str(ms, "url")); + } + } catch (IOException e) { + // frozen R4 list + mappingsUris.add("http://hl7.org/fhir/fivews"); + mappingsUris.add("http://hl7.org/fhir/workflow"); + mappingsUris.add("http://hl7.org/fhir/interface"); + mappingsUris.add("http://hl7.org/v2"); + mappingsUris.add("http://loinc.org"); + mappingsUris.add("http://snomed.org/attributebinding"); + mappingsUris.add("http://snomed.info/conceptdomain"); + mappingsUris.add("http://hl7.org/v3/cda"); + mappingsUris.add("http://hl7.org/v3"); + mappingsUris.add("http://nema.org/dicom"); + mappingsUris.add("http://w3.org/vcard"); + mappingsUris.add("http://ihe.net/xds"); + mappingsUris.add("http://www.w3.org/ns/prov"); + mappingsUris.add("http://ietf.org/rfc/2445"); + mappingsUris.add("http://www.omg.org/spec/ServD/1.0/"); + mappingsUris.add("http://metadata-standards.org/11179/"); + mappingsUris.add("http://ihe.net/data-element-exchange"); + mappingsUris.add("http://openehr.org"); + mappingsUris.add("http://siframework.org/ihe-sdc-profile"); + mappingsUris.add("http://siframework.org/cqf"); + mappingsUris.add("http://www.cdisc.org/define-xml"); + mappingsUris.add("http://www.cda-adc.ca/en/services/cdanet/"); + mappingsUris.add("http://www.pharmacists.ca/"); + mappingsUris.add("http://www.healthit.gov/quality-data-model"); + mappingsUris.add("http://hl7.org/orim"); + mappingsUris.add("http://hl7.org/fhir/w5"); + mappingsUris.add("http://hl7.org/fhir/logical"); + mappingsUris.add("http://hl7.org/fhir/auditevent"); + mappingsUris.add("http://hl7.org/fhir/provenance"); + mappingsUris.add("http://hl7.org/qidam"); + mappingsUris.add("http://cap.org/ecc"); + mappingsUris.add("http://fda.gov/UDI"); + mappingsUris.add("http://hl7.org/fhir/object-implementation"); + mappingsUris.add("http://github.com/MDMI/ReferentIndexContent"); + mappingsUris.add("http://ncpdp.org/SCRIPT10_6"); + mappingsUris.add("http://clinicaltrials.gov"); + mappingsUris.add("http://hl7.org/fhir/rr"); + mappingsUris.add("http://www.hl7.org/v3/PORX_RM020070UV"); + mappingsUris.add("https://bridgmodel.nci.nih.gov"); + mappingsUris.add("http://hl7.org/fhir/composition"); + mappingsUris.add("http://hl7.org/fhir/documentreference"); + mappingsUris.add("https://en.wikipedia.org/wiki/Identification_of_medicinal_products"); + mappingsUris.add("urn:iso:std:iso:11073:10201"); + mappingsUris.add("urn:iso:std:iso:11073:10207"); + } + } + return mappingsUris.contains(url); + } + private String findBaseUrl(String url) { String[] p = url.split("\\/"); for (int i = 1; i< p.length; i++) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java index 0b4c397ab..388b46190 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java @@ -1927,11 +1927,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat // for now, no validation. Need to think about authority. } else { // now, do we check the URI target? - if (fetcher != null) { + if (fetcher != null && !type.equals("uuid")) { boolean found; try { - found = isDefinitionURL(url) || (allowExamples && (url.contains("example.org") || url.contains("acme.com")) || url.contains("acme.org")) || (url.startsWith("http://hl7.org/fhir/tools")) || fetcher.resolveURL(appContext, path, url) || - SpecialExtensions.isKnownExtension(url) || isXverUrl(url); + found = isDefinitionURL(url) || (allowExamples && (url.contains("example.org") || url.contains("acme.com")) || url.contains("acme.org")) || (url.startsWith("http://hl7.org/fhir/tools")) || + SpecialExtensions.isKnownExtension(url) || isXverUrl(url) || fetcher.resolveURL(appContext, path, url, type); } catch (IOException e1) { found = false; } @@ -2228,19 +2228,46 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat return context.formatMessage(I18nConstants.XHTML_URL_EMPTY); } - Set invalidChars = new HashSet<>(); - for (char ch : value.toCharArray()) { - if (!(Character.isDigit(ch) || Character.isAlphabetic(ch) || Utilities.existsInList(ch, ';', '?', ':', '@', '&', '=', '+', '$', '.', ',', '/', '%', '-', '_', '~', '#', '[', ']', '!', '\'', '(', ')', '*' ))) { - invalidChars.add(ch); + if (value.startsWith("data:")) { + String[] p = value.substring(5).split("\\,"); + if (p.length < 2) { + return context.formatMessage(I18nConstants.XHTML_URL_DATA_NO_DATA, value); + } else if (p.length > 2) { + return context.formatMessage(I18nConstants.XHTML_URL_DATA_DATA_INVALID_COMMA, value); + } else if (!p[0].endsWith(";base64") || !isValidBase64(p[1])) { + return context.formatMessage(I18nConstants.XHTML_URL_DATA_DATA_INVALID, value); + } else { + if (p[0].startsWith(" ")) { + p[0] = p[0].trim(); + } + String mMsg = checkValidMimeType(p[0].substring(0, p[0].lastIndexOf(";"))); + if (mMsg != null) { + return context.formatMessage(I18nConstants.XHTML_URL_DATA_MIMETYPE, value, mMsg); + } } - } - if (invalidChars.isEmpty()) { return null; } else { - return context.formatMessage(I18nConstants.XHTML_URL_INVALID_CHARS, invalidChars.toString()); + Set invalidChars = new HashSet<>(); + for (char ch : value.toCharArray()) { + if (!(Character.isDigit(ch) || Character.isAlphabetic(ch) || Utilities.existsInList(ch, ';', '?', ':', '@', '&', '=', '+', '$', '.', ',', '/', '%', '-', '_', '~', '#', '[', ']', '!', '\'', '(', ')', '*' ))) { + invalidChars.add(ch); + } + } + if (invalidChars.isEmpty()) { + return null; + } else { + return context.formatMessage(I18nConstants.XHTML_URL_INVALID_CHARS, invalidChars.toString()); + } } } + private String checkValidMimeType(String mt) { + if (!mt.matches("^(\\w+|\\*)\\/(\\w+|\\*)((;\\s*(\\w+)=\\s*(\\S+))?)$")) { + return "Mime type invalid"; + } + return null; + } + private void checkInnerNS(List errors, Element e, String path, List list) { for (XhtmlNode node : list) { if (node.getNodeType() == NodeType.Element) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java index 124ade72c..5a6d5e852 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java @@ -223,7 +223,7 @@ public class StructureDefinitionValidator extends BaseValidator { if (t == null) { rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), code.equals(t), I18nConstants.SD_ED_TYPE_PROFILE_NOTYPE, p); } else { - rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), sd.getKind() == StructureDefinitionKind.RESOURCE, I18nConstants.SD_ED_TYPE_PROFILE_WRONG, p, t, code, path); + rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), sd.getKind() == StructureDefinitionKind.RESOURCE, I18nConstants.SD_ED_TYPE_PROFILE_WRONG_TARGET, p, t, code, path, "Resource"); } } } else if (code.equals("canonical")) { @@ -232,7 +232,7 @@ public class StructureDefinitionValidator extends BaseValidator { if (t == null) { rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), code.equals(t), I18nConstants.SD_ED_TYPE_PROFILE_NOTYPE, p); } else { - rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), VersionUtilities.getCanonicalResourceNames(context.getVersion()).contains(t), I18nConstants.SD_ED_TYPE_PROFILE_WRONG, p, t, code, path); + rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), VersionUtilities.getCanonicalResourceNames(context.getVersion()).contains(t), I18nConstants.SD_ED_TYPE_PROFILE_WRONG_TARGET, p, t, code, path, "Canonical Resource"); } } } else { diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTests.java index 595e223c6..f96f07554 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/ValidationTests.java @@ -490,7 +490,7 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe } @Override - public boolean resolveURL(Object appContext, String path, String url) throws IOException, FHIRException { + public boolean resolveURL(Object appContext, String path, String url, String type) throws IOException, FHIRException { return !url.contains("example.org") && !url.startsWith("http://hl7.org/fhir/invalid"); }