diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/analytics/PackageVisitor.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/analytics/PackageVisitor.java index 64a1f0055..442bdc68c 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/analytics/PackageVisitor.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/analytics/PackageVisitor.java @@ -92,6 +92,13 @@ public class PackageVisitor { this.resourceTypes = resourceTypes; } + public void setResourceTypes(String... resourceTypes) { + this.resourceTypes = new ArrayList(); + for (String s : resourceTypes) { + this.resourceTypes.add(s); + } + } + public List getVersions() { return versions; } @@ -200,7 +207,7 @@ public class PackageVisitor { } if (step == 0 || step == 3) { - JsonObject json = JsonParser.parseObjectFromUrl("https://raw.githubusercontent.com/FHIR/ig-registry/master/fhir-ig-list.json"); + JsonObject json = JsonParser.parseObjectFromUrl("https://fhir.github.io/ig-registry/fhir-ig-list.json"); i = 0; List objects = json.getJsonObjects("guides"); for (JsonObject o : objects) { @@ -315,11 +322,11 @@ public class PackageVisitor { for (PackageInfo i : pc.search(null, null, null, false)) { list.add(i.getId()); } - JsonObject json = JsonParser.parseObjectFromUrl("https://raw.githubusercontent.com/FHIR/ig-registry/master/fhir-ig-list.json"); + JsonObject json = JsonParser.parseObjectFromUrl("https://fhir.github.io/ig-registry/fhir-ig-list.json"); for (JsonObject ig : json.getJsonObjects("guides")) { list.add(ig.asString("npm-name")); } - json = JsonParser.parseObjectFromUrl("https://raw.githubusercontent.com/FHIR/ig-registry/master/package-feeds.json"); + json = JsonParser.parseObjectFromUrl("https://fhir.github.io/ig-registry/package-feeds.json"); for (JsonObject feed : json.getJsonObjects("feeds")) { processFeed(list, feed.asString("url")); } diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/resources40_50/ExampleScenario40_50.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/resources40_50/ExampleScenario40_50.java index 500b08096..0f8cb055e 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/resources40_50/ExampleScenario40_50.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/resources40_50/ExampleScenario40_50.java @@ -441,8 +441,9 @@ public class ExampleScenario40_50 { tgt.setPauseElement(Boolean40_50.convertBoolean(src.getPauseElement())); if (src.hasOperation()) tgt.setOperation(convertExampleScenarioProcessStepOperationComponent(src.getOperation(), src.getNumber())); - else + else if (src.hasNumber()) { tgt.addExtension(PROCESS_STEP_NUMBER, String40_50.convertString(src.getNumberElement())); + } for (org.hl7.fhir.r5.model.ExampleScenario.ExampleScenarioProcessStepAlternativeComponent t : src.getAlternative()) tgt.addAlternative(convertExampleScenarioProcessStepAlternativeComponent(t)); return tgt; diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/misc/VSACFinder.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/misc/VSACFinder.java new file mode 100644 index 000000000..9d9f49e7a --- /dev/null +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/misc/VSACFinder.java @@ -0,0 +1,148 @@ +package org.hl7.fhir.convertors.misc; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.xml.parsers.ParserConfigurationException; + +import org.hl7.fhir.convertors.analytics.PackageVisitor; +import org.hl7.fhir.convertors.analytics.PackageVisitor.IPackageVisitorProcessor; +import org.hl7.fhir.convertors.analytics.PackageVisitor.PackageContext; +import org.hl7.fhir.exceptions.FHIRException; +import org.hl7.fhir.r5.utils.EOperationOutcome; +import org.hl7.fhir.utilities.CSVReader; +import org.hl7.fhir.utilities.Utilities; +import org.hl7.fhir.utilities.json.model.JsonObject; +import org.hl7.fhir.utilities.json.parser.JsonParser; +import org.hl7.fhir.utilities.npm.NpmPackage; +import org.hl7.fhir.utilities.npm.PackageServer; +import org.xml.sax.SAXException; + +public class VSACFinder implements IPackageVisitorProcessor { + + public static void main(String[] args) throws FHIRException, IOException, ParserConfigurationException, SAXException, EOperationOutcome { + new VSACFinder().execute(); + + } + + private class VsacVS { + private String oid; + private String steward; + private String status; + private Set used = new HashSet<>(); + + public void use(String pid) { + used.add(pid); + } + } + + private Map oids = new HashMap<>(); + + private void execute() throws FHIRException, IOException, ParserConfigurationException, SAXException, EOperationOutcome { + loadVSACOids(); + PackageVisitor pv = new PackageVisitor(); + pv.setCorePackages(false); + pv.setClientPackageServer(PackageServer.secondaryServer()); + pv.setResourceTypes("StructureDefinition", "ValueSet"); + pv.setProcessor(this); + pv.visitPackages(); + for (String oid : Utilities.sorted(oids.keySet())) { + VsacVS vs = oids.get(oid); + if (!vs.used.isEmpty()) { + System.out.println("* "+oid+" ("+vs.status+") @ "+vs.steward+" used by "+vs.used.toString()); + } + } + } + + private void loadVSACOids() throws FHIRException, FileNotFoundException, IOException { + CSVReader csv = new CSVReader(new FileInputStream("/Users/grahamegrieve/Downloads/valuesets.csv")); + csv.readHeaders(); + while (csv.line()) { + VsacVS vvs = new VsacVS(); + vvs.oid = csv.cell("OID"); + vvs.steward = csv.cell("Steward"); + vvs.status = csv.cell("Expansion Status"); + oids.put("http://cts.nlm.nih.gov/fhir/ValueSet/"+vvs.oid, vvs); + } + } + + @Override + public Object startPackage(PackageContext context) throws FHIRException, IOException, EOperationOutcome { + if (usesVSAC(context.getNpm())) { + System.out.println(context.getPid()+" uses VSAC"); + return this; + } else { + return null; + } + } + + private boolean usesVSAC(NpmPackage npm) { + if (npm != null) { + for (String s : npm.dependencies()) { + if (s.contains("vsac")) { + return true; + } + } + } + return false; + } + + @Override + public void processResource(PackageContext context, Object clientContext, String type, String id, byte[] content) + throws FHIRException, IOException, EOperationOutcome { + if (clientContext != null) { + JsonObject r = JsonParser.parseObject(content); + if ("StructureDefinition".equals(type)) { + JsonObject diff = r.getJsonObject("differential"); + if (diff != null) { + for (JsonObject ed : diff.getJsonObjects("element")) { + JsonObject b = ed.getJsonObject("binding"); + if (b != null) { + String url = b.asString("valueSet"); + checkVSUrl(context, url); + } + } + } + } else { + JsonObject compose = r.getJsonObject("compose"); + if (compose != null) { + for (JsonObject inc : compose.getJsonObjects("include")) { + for (String url : inc.getStrings("valueSet")) { + checkVSUrl(context, url); + } + } + for (JsonObject inc : compose.getJsonObjects("exclude")) { + for (String url : inc.getStrings("valueSet")) { + if (url.startsWith("http://cts.nlm.nih.gov/fhir/ValueSet/")) { + checkVSUrl(context, url); + } + } + } + } + } + } + } + + private void checkVSUrl(PackageContext context, String url) { + if (url.startsWith("http://cts.nlm.nih.gov/fhir/ValueSet/")) { + VsacVS vs = oids.get(url); + if (vs != null) { + vs.use(context.getPid()); + } + } + } + + @Override + public void finishPackage(PackageContext context) throws FHIRException, IOException, EOperationOutcome { + } + + @Override + public void alreadyVisited(String pid) throws FHIRException, IOException, EOperationOutcome { + } + +} diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java index 8c3f2a3e7..a4bfb0e1b 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java @@ -2176,9 +2176,9 @@ public class ProfileUtilities { protected boolean discriminatorMatches(List diff, List base) { if (diff.isEmpty() || base.isEmpty()) return true; - if (diff.size() != base.size()) + if (diff.size() < base.size()) return false; - for (int i = 0; i < diff.size(); i++) + for (int i = 0; i < base.size(); i++) if (!matches(diff.get(i), base.get(i))) return false; return true; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/LanguageUtils.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/LanguageUtils.java index 59598312c..b2c3646bd 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/LanguageUtils.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/LanguageUtils.java @@ -21,6 +21,7 @@ import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingAdditiona import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionConstraintComponent; import org.hl7.fhir.r5.model.Extension; import org.hl7.fhir.r5.model.MarkdownType; +import org.hl7.fhir.r5.model.PrimitiveType; import org.hl7.fhir.r5.model.Property; import org.hl7.fhir.r5.model.Resource; import org.hl7.fhir.r5.model.StringType; @@ -35,6 +36,7 @@ import org.hl7.fhir.utilities.i18n.LanguageFileProducer; import org.hl7.fhir.utilities.i18n.LanguageFileProducer.LanguageProducerLanguageSession; import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TextUnit; import org.hl7.fhir.utilities.i18n.LanguageFileProducer.TranslationUnit; +import org.hl7.fhir.utilities.json.model.JsonElement; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; @@ -665,4 +667,30 @@ public class LanguageUtils { } return true; } + + public boolean hasTranslation(org.hl7.fhir.r5.model.Element e, String lang) { + return getTranslation(e, lang) != null; + } + + public String getTranslation(org.hl7.fhir.r5.model.Element e, String lang) { + for (Extension ext : e.getExtensionsByUrl(ToolingExtensions.EXT_TRANSLATION)) { + String l = ext.getExtensionString("lang"); + String v = ext.getExtensionString("content"); + if (langsMatch(l, lang) && v != null) { + return v; + } + } + return null; + } + + public String getTranslationOrBase(PrimitiveType e, String lang) { + for (Extension ext : e.getExtensionsByUrl(ToolingExtensions.EXT_TRANSLATION)) { + String l = ext.getExtensionString("lang"); + String v = ext.getExtensionString("content"); + if (langsMatch(l, lang) && v != null) { + return v; + } + } + return e.primitiveValue(); + } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ExampleScenarioRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ExampleScenarioRenderer.java index de13a0789..e09d322fc 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ExampleScenarioRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ExampleScenarioRenderer.java @@ -30,6 +30,7 @@ import org.hl7.fhir.r5.renderers.utils.RenderingContext; import org.hl7.fhir.r5.renderers.utils.RenderingContext.KnownLinkType; import org.hl7.fhir.r5.renderers.utils.ResourceWrapper; import org.hl7.fhir.r5.utils.EOperationOutcome; +import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.xhtml.XhtmlDocument; import org.hl7.fhir.utilities.xhtml.XhtmlNode; @@ -80,19 +81,24 @@ public class ExampleScenarioRenderer extends TerminologyRenderer { } } } catch (Exception e) { + e.printStackTrace(); throw new FHIRException(context.formatPhrase(RenderingContext.EX_SCEN_ERR_REN, scen.getUrl(), e) + " "); } } public String renderDiagram(RenderingStatus status, ResourceWrapper res, ExampleScenario scen) throws IOException { - String plantUml = toPlantUml(status, res, scen); - SourceStringReader reader = new SourceStringReader(plantUml); - final ByteArrayOutputStream os = new ByteArrayOutputStream(); - reader.outputImage(os, new FileFormatOption(FileFormat.SVG)); - os.close(); + try { + String plantUml = toPlantUml(status, res, scen); + SourceStringReader reader = new SourceStringReader(plantUml); + final ByteArrayOutputStream os = new ByteArrayOutputStream(); + reader.outputImage(os, new FileFormatOption(FileFormat.SVG)); + os.close(); - final String svg = new String(os.toByteArray(), Charset.forName("UTF-8")); - return svg; + final String svg = new String(os.toByteArray(), Charset.forName("UTF-8")); + return svg; + } catch (Exception e) { + return "

"+Utilities.escapeXml(e.getMessage())+"

"; + } } protected String toPlantUml(RenderingStatus status, ResourceWrapper res, ExampleScenario scen) throws IOException { @@ -197,12 +203,14 @@ public class ExampleScenarioRenderer extends TerminologyRenderer { private String handleDeactivation(String actorId, boolean active, Map actorsActive, Map actorKeys) { String plantUml = ""; Boolean actorWasActive = actorsActive.get(actorId); - if (!active && actorWasActive) { - plantUml += "deactivate " + actorKeys.get(actorId) + "\r\n"; - } - if (active != actorWasActive) { - actorsActive.remove(actorId); - actorsActive.put(actorId, Boolean.valueOf(active)); + if (actorWasActive != null) { + if (!active && actorWasActive) { + plantUml += "deactivate " + actorKeys.get(actorId) + "\r\n"; + } + if (active != actorWasActive) { + actorsActive.remove(actorId); + actorsActive.put(actorId, Boolean.valueOf(active)); + } } return plantUml; } @@ -505,9 +513,9 @@ public class ExampleScenarioRenderer extends TerminologyRenderer { if (instanceRef==null || instanceRef.getInstanceReference()==null) return; ExampleScenarioInstanceComponent instance = instances.get(instanceRef.getInstanceReference()); - if (instance==null) - throw new FHIRException(context.formatPhrase(RenderingContext.EX_SCEN_UN_INST, instanceRef.getInstanceReference())+" "); - if (instanceRef.hasVersionReference()) { + if (instance==null) { + instanceCell.b().tx("Bad reference: "+instanceRef.getInstanceReference()); + } else if (instanceRef.hasVersionReference()) { ExampleScenarioInstanceVersionComponent theVersion = null; for (ExampleScenarioInstanceVersionComponent version: instance.getVersion()) { if (version.getKey().equals(instanceRef.getVersionReference())) { diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/utils/RenderingContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/utils/RenderingContext.java index 687d7c672..de7cc58fc 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/utils/RenderingContext.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/utils/RenderingContext.java @@ -72,6 +72,28 @@ import org.hl7.fhir.utilities.validation.ValidationOptions; */ public class RenderingContext extends RenderingI18nContext { + public static class RenderingContextLangs { + + private RenderingContext defLangRC; + private Map langs = new HashMap<>(); + + public RenderingContextLangs(RenderingContext defLangRC) { + this.defLangRC = defLangRC; + } + + public void seeLang(String lang, RenderingContext rc) { + this.langs.put(lang, rc); + } + + public RenderingContext get(String lang) { + if (lang == null || !langs.containsKey(lang)) { + return defLangRC; + } else { + return langs.get(lang); + } + } + } + // provides liquid templates, if they are available for the content public interface ILiquidTemplateProvider { String findTemplate(RenderingContext rcontext, DomainResource r); 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 9925a2acb..d9efb0e6e 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 @@ -1116,4 +1116,5 @@ public class I18nConstants { public static final String SD_ED_ADDITIONAL_BINDING_USAGE_UNKNOWN = "SD_ED_ADDITIONAL_BINDING_USAGE_UNKNOWN"; public static final String SD_ED_ADDITIONAL_BINDING_USAGE_INVALID_ELEMENT = "SD_ED_ADDITIONAL_BINDING_USAGE_INVALID_ELEMENT"; public static final String SD_ED_ADDITIONAL_BINDING_USAGE_INVALID_TYPE = "SD_ED_ADDITIONAL_BINDING_USAGE_INVALID_TYPE"; + public static final String CODESYSTEM_CS_COMPLETE_AND_EMPTY = "CODESYSTEM_CS_COMPLETE_AND_EMPTY"; } diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/RenderingI18nContext.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/RenderingI18nContext.java index 9a2b52a5a..34dd08e2d 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/RenderingI18nContext.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/RenderingI18nContext.java @@ -919,7 +919,20 @@ public class RenderingI18nContext extends I18nBase { public static final String DATA_REND_ATT_DATA = "DATA_REND_ATT_DATA"; public static final String GENERAL_DATA_DISPLAY_PROPERTY = "GENERAL_DATA_DISPLAY_PROPERTY"; public static final String DATA_REND_CURRENCY = "DATA_REND_CURRENCY"; - + public static final String _NA = "_NA"; + public static final String FMM_TABLE = "FMM_TABLE"; + public static final String KIND_EXTENSION = "KIND_EXTENSION"; + public static final String KIND_LOGICAL = "KIND_LOGICAL"; + public static final String KIND_PROFILE = "KIND_PROFILE"; + public static final String IP_NONE = "IP_NONE"; + public static final String IP_NONE_EXT = "IP_NONE_EXT"; + public static final String IP_INTRO = "IP_INTRO"; + public static final String MATURITY_PUBLISHER = "MATURITY_PUBLISHER"; + public static final String MATURITY_STATUS = "MATURITY_STATUS"; + public static final String MATURITY_MATURITY = "MATURITY_MATURITY"; + public static final String MATURITY_STDS_STATUS = "MATURITY_STDS_STATUS"; + + protected String getMessagesSourceFileName() { return "rendering-phrases"; } @@ -937,4 +950,5 @@ public class RenderingI18nContext extends I18nBase { public String formatPhrasePlural(Integer plural, String theMessage, Object... theMessageArguments) { return formatMessagePlural(plural, theMessage, theMessageArguments); } + } diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/FilesystemPackageCacheManager.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/FilesystemPackageCacheManager.java index 206d90782..e8eca8f80 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/FilesystemPackageCacheManager.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/FilesystemPackageCacheManager.java @@ -472,7 +472,7 @@ public class FilesystemPackageCacheManager extends BasePackageCacheManager imple * @throws IOException If the package cannot be loaded */ @Override - public NpmPackage loadPackageFromCacheOnly(String id, String version) throws IOException { + public NpmPackage loadPackageFromCacheOnly(String id, @Nullable String version) throws IOException { if (!Utilities.noString(version) && version.startsWith("file:")) { return loadPackageFromFile(id, version.substring(5)); diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/PackageClient.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/PackageClient.java index 1dbab8248..4bf827356 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/PackageClient.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/PackageClient.java @@ -273,7 +273,7 @@ public class PackageClient { public List listFromRegistry(String name, String canonical, String fhirVersion) throws IOException { List result = new ArrayList<>(); - JsonObject packages = JsonParser.parseObjectFromUrl("https://raw.githubusercontent.com/FHIR/ig-registry/master/fhir-ig-list.json?nocache=" + System.currentTimeMillis()); + JsonObject packages = JsonParser.parseObjectFromUrl("https://fhir.github.io/ig-registry/fhir-ig-list.json?nocache=" + System.currentTimeMillis()); for (JsonObject o : packages.getJsonObjects("guides")) { if (o.has("canonical")) { final PackageInfo packageInfo = getPackageInfoFromJSON(o, name, canonical, fhirVersion); diff --git a/org.hl7.fhir.utilities/src/main/resources/Messages.properties b/org.hl7.fhir.utilities/src/main/resources/Messages.properties index 4c4e156d9..df16be4b8 100644 --- a/org.hl7.fhir.utilities/src/main/resources/Messages.properties +++ b/org.hl7.fhir.utilities/src/main/resources/Messages.properties @@ -642,7 +642,7 @@ SECURITY_STRING_CONTENT_ERROR = The string value contains text that looks like e SECURITY_STRING_CONTENT_WARNING = The string value contains text that looks like embedded HTML tags. If this content is rendered to HTML without appropriate post-processing, it may be a security risk SLICING_CANNOT_BE_EVALUATED = Slicing cannot be evaluated: {0} SM_DEPENDENT_PARAM_MODE_MISMATCH = The parameter {0} refers to the variable {1} but it''s mode is {2} which is not the same as the mode required for the group {3} -SM_DEPENDENT_PARAM_NOT_FOUND = The {1} parameter ''{0}'' was not found +SM_DEPENDENT_PARAM_NOT_FOUND = The {1} parameter ''{0}'' was not found. Known variables: {2} SM_DEPENDENT_PARAM_TYPE_MISMATCH = The parameter ''{0}'' refers to the variable ''{1}'' but it''s type is ''{2}'' which is not compatible with the type required for the group ''{3}'', which is ''{4}'' (from map ''{5}'') SM_DEPENDENT_PARAM_TYPE_MISMATCH_DUPLICATE = The group {0} has already been used with different parameters, so the type checking may be incorrect (other = [{1}]; this = [{2}]) SM_GROUP_INPUT_DUPLICATE = The name {0} is already used @@ -1149,3 +1149,4 @@ VALIDATION_NO_EXPERIMENTAL_CONTENT = Experimental content is not allowed in this SD_ED_ADDITIONAL_BINDING_USAGE_UNKNOWN = The Usage Context {0}#{1} is not recognised and may not be correct SD_ED_ADDITIONAL_BINDING_USAGE_INVALID_ELEMENT = The Usage Context {0}#{1} is a reference to an element that does not exist SD_ED_ADDITIONAL_BINDING_USAGE_INVALID_TYPE = The Usage Context value must be of type {1} not {0} +CODESYSTEM_CS_COMPLETE_AND_EMPTY = When a CodeSystem has content = ''complete'', it doesn't make sense for there to be no concepts defined diff --git a/org.hl7.fhir.utilities/src/main/resources/rendering-phrases.properties b/org.hl7.fhir.utilities/src/main/resources/rendering-phrases.properties index 39aa5cab8..488c15fc4 100644 --- a/org.hl7.fhir.utilities/src/main/resources/rendering-phrases.properties +++ b/org.hl7.fhir.utilities/src/main/resources/rendering-phrases.properties @@ -923,3 +923,15 @@ DATA_REND_ATT_URL = {0} @ {1} DATA_REND_ATT_DATA = {0}: {1} GENERAL_DATA_DISPLAY_PROPERTY = {0}: {1} DATA_REND_CURRENCY = {1} {0} +_NA = n/a +FMM_TABLE =
Maturity Level: {0} {2}
+KIND_EXTENSION = extension +KIND_LOGICAL = logical model +KIND_PROFILE = profile +IP_NONE = No use of external IP +IP_NONE_EXT = No use of external IP (other than from the FHIR specification) +IP_INTRO = This {0} includes IP covered under the following statements. +MATURITY_PUBLISHER = Publisher: {0} +MATURITY_STATUS = Status +MATURITY_MATURITY = Maturity Level: {0} +MATURITY_STDS_STATUS = Standards Status: {0} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java index 13b4304ca..abd405760 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java @@ -382,9 +382,9 @@ public class BaseValidator implements IValidationContextResourceLoader, IMessagi * Set this parameter to false if the validation does not pass * @return Returns thePass (in other words, returns true if the rule did not fail validation) */ - protected boolean slicingHint(List errors, String ruleDate, IssueType type, int line, int col, String path, boolean thePass, boolean isCritical, String msg, String html, String[] text, List sliceInfo) { + protected boolean slicingHint(List errors, String ruleDate, IssueType type, int line, int col, String path, boolean thePass, boolean isCritical, String msg, String html, String[] text, List sliceInfo, String id) { if (!thePass && doingHints()) { - addValidationMessage(errors, ruleDate, type, line, col, path, msg, IssueSeverity.INFORMATION, null).setSlicingHint(true).setSliceHtml(html, text).setCriticalSignpost(isCritical).setSliceInfo(sliceInfo); + addValidationMessage(errors, ruleDate, type, line, col, path, msg, IssueSeverity.INFORMATION, id).setSlicingHint(true).setSliceHtml(html, text).setCriticalSignpost(isCritical).setSliceInfo(sliceInfo); } return thePass; } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/IgLoader.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/IgLoader.java index 9f64cdc62..22c05b678 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/IgLoader.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/IgLoader.java @@ -518,9 +518,9 @@ public class IgLoader implements IValidationEngineLoader { if (pi != null) System.out.println(" ... Using version " + pi.version()); } else - pi = getPackageCacheManager().loadPackageFromCacheOnly(id, version); + pi = getPackageCacheManager().loadPackage(id, version); if (pi == null) { - return resolvePackage(id, version, loadInContext); + throw new FHIRException("Unable to find package "+src); } else return loadPackage(pi, loadInContext); } @@ -670,9 +670,9 @@ public class IgLoader implements IValidationEngineLoader { if (pi != null) System.out.println(" ... Using version " + pi.version()); } else - pi = getPackageCacheManager().loadPackageFromCacheOnly(id, version); + pi = getPackageCacheManager().loadPackage(id, version); if (pi == null) { - return resolvePackageForVersion(id, version); + throw new FHIRException("Unable to resolve package "+src); } else { return pi.fhirVersion(); } 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 46f5d948b..13cd9c10f 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 @@ -106,8 +106,8 @@ import org.hl7.fhir.validation.cli.utils.ProfileLoader; import org.hl7.fhir.validation.cli.utils.QuestionnaireMode; import org.hl7.fhir.validation.cli.utils.SchemaValidator; import org.hl7.fhir.validation.cli.utils.ValidationLevel; -import org.hl7.fhir.validation.instance.BasePolicyAdvisorForFullValidation; import org.hl7.fhir.validation.instance.InstanceValidator; +import org.hl7.fhir.validation.instance.advisor.BasePolicyAdvisorForFullValidation; import org.hl7.fhir.validation.instance.utils.ValidationContext; import org.hl7.fhir.utilities.ByteProvider; import org.xml.sax.SAXException; @@ -218,6 +218,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP @Getter @Setter private boolean noUnicodeBiDiControlChars; @Getter @Setter private boolean securityChecks; @Getter @Setter private boolean crumbTrails; + @Getter @Setter private boolean showMessageIds; @Getter @Setter private boolean forPublication; @Getter @Setter private boolean allowExampleUrls; @Getter @Setter private boolean showMessagesFromReferences; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java index a38b14fbb..6d5e0cb4a 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java @@ -120,6 +120,9 @@ public class CliContext { @JsonProperty("crumbTrails") private boolean crumbTrails = false; + @JsonProperty("showMessageIds") + private boolean showMessageIds = false; + @JsonProperty("forPublication") private boolean forPublication = false; @@ -719,6 +722,14 @@ public class CliContext { this.crumbTrails = crumbTrails; } + public boolean isShowMessageIds() { + return showMessageIds; + } + + public void setShowMessageIds(boolean showMessageIds) { + this.showMessageIds = showMessageIds; + } + public boolean isForPublication() { return forPublication; } @@ -827,6 +838,7 @@ public class CliContext { Objects.equals(profiles, that.profiles) && Objects.equals(sources, that.sources) && Objects.equals(crumbTrails, that.crumbTrails) && + Objects.equals(showMessageIds, that.showMessageIds) && Objects.equals(forPublication, that.forPublication)&& Objects.equals(allowExampleUrls, that.allowExampleUrls) && Objects.equals(showTimes, that.showTimes) && @@ -847,7 +859,7 @@ public class CliContext { public int hashCode() { return Objects.hash(baseEngine, doNative, extensions, hintAboutNonMustSupport, recursive, doDebug, assumeValidRestReferences, canDoNative, noInternalCaching, noExtensibleBindingMessages, noInvariants, displayWarnings, wantInvariantsInMessages, map, output, outputSuffix, htmlOutput, txServer, sv, txLog, txCache, mapLog, lang, srcLang, tgtLang, fhirpath, snomedCT, - targetVer, igs, questionnaireMode, level, profiles, sources, inputs, mode, locale, locations, crumbTrails, forPublication, showTimes, allowExampleUrls, outputStyle, jurisdiction, noUnicodeBiDiControlChars, + targetVer, igs, questionnaireMode, level, profiles, sources, inputs, mode, locale, locations, crumbTrails, showMessageIds, forPublication, showTimes, allowExampleUrls, outputStyle, jurisdiction, noUnicodeBiDiControlChars, watchMode, watchScanDelay, watchSettleTime, bestPracticeLevel, unknownCodeSystemsCauseErrors, noExperimentalContent, htmlInMarkdownCheck, allowDoubleQuotesInFHIRPath, checkIPSCodes); } @@ -892,6 +904,7 @@ public class CliContext { ", mode=" + mode + ", securityChecks=" + securityChecks + ", crumbTrails=" + crumbTrails + + ", showMessageIds=" + showMessageIds + ", forPublication=" + forPublication + ", outputStyle=" + outputStyle + ", jurisdiction=" + jurisdiction + diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/renderers/CSVRenderer.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/renderers/CSVRenderer.java index dff3fbc20..08b6ca1eb 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/renderers/CSVRenderer.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/renderers/CSVRenderer.java @@ -10,7 +10,7 @@ public class CSVRenderer extends ValidationOutputRenderer { @Override public void start(boolean moreThanOne) { super.start(moreThanOne); - dst.println("file, line, col, level, message"); + dst.println("file, line, col, level, message"+(showMessageIds ? "message-id" : "")); } @Override @@ -19,7 +19,8 @@ public class CSVRenderer extends ValidationOutputRenderer { for (OperationOutcome.OperationOutcomeIssueComponent issue : oo.getIssue()) { int line = ToolingExtensions.readIntegerExtension(issue, ToolingExtensions.EXT_ISSUE_LINE, -1); int col = ToolingExtensions.readIntegerExtension(issue, ToolingExtensions.EXT_ISSUE_COL, -1); - dst.println(file+", " + (line == -1 ? "" : Integer.toString(line)) + ", " + (col == -1 ? "" : Integer.toString(col))+", "+issue.getSeverity().getDisplay()+", \""+issue.getDetails().getText()+"\""); + dst.println(file+", " + (line == -1 ? "" : Integer.toString(line)) + ", " + (col == -1 ? "" : Integer.toString(col))+", "+issue.getSeverity().getDisplay()+", \""+issue.getDetails().getText()+"\""+ + (showMessageIds ? "," +issue.getExtensionString("http://hl7.org/fhir/StructureDefinition/operationoutcome-message-id") : "")); } } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/renderers/CompactRenderer.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/renderers/CompactRenderer.java index 9b0a561a9..4dad937b0 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/renderers/CompactRenderer.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/renderers/CompactRenderer.java @@ -54,7 +54,9 @@ public class CompactRenderer extends ValidationOutputRenderer { String path = issue.hasExpression() ? issue.getExpression().get(0).asStringValue() : "n/a"; int line = ToolingExtensions.readIntegerExtension(issue, ToolingExtensions.EXT_ISSUE_LINE, -1); int col = ToolingExtensions.readIntegerExtension(issue, ToolingExtensions.EXT_ISSUE_COL, -1); - lines.add(Utilities.padLeft(Integer.toString(line), '0', 8) + ":" + Utilities.padLeft(Integer.toString(col), '0', 8)+":"+path+"|["+Integer.toString(line) + ", " + Integer.toString(col)+"] "+path+": "+issue.getSeverity().getDisplay()+" - "+issue.getDetails().getText()); + lines.add(Utilities.padLeft(Integer.toString(line), '0', 8) + ":" + Utilities.padLeft(Integer.toString(col), '0', 8)+":"+ + path+"|["+Integer.toString(line) + ", " + Integer.toString(col)+"] "+path+": "+issue.getSeverity().getDisplay()+" - "+issue.getDetails().getText()+ + renderMessageId(issue)); } Collections.sort(lines); for (String s : lines) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/renderers/DefaultRenderer.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/renderers/DefaultRenderer.java index 1e496d984..ff5919a3d 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/renderers/DefaultRenderer.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/renderers/DefaultRenderer.java @@ -34,7 +34,7 @@ public class DefaultRenderer extends ValidationOutputRenderer { } dst.println((error == 0 ? "Success" : "*FAILURE*") + ": " + Integer.toString(error) + " errors, " + Integer.toString(warn) + " warnings, " + Integer.toString(info) + " notes"); for (OperationOutcome.OperationOutcomeIssueComponent issue : oo.getIssue()) { - dst.println(getIssueSummary(issue)); + dst.println(getIssueSummary(issue)+renderMessageId(issue)); ValidationMessage vm = (ValidationMessage) issue.getUserData("source.msg"); if (vm != null && vm.sliceText != null && (crumbTrails || vm.isCriticalSignpost())) { for (String s : vm.sliceText) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/renderers/ValidationOutputRenderer.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/renderers/ValidationOutputRenderer.java index b8b65203c..6467ee1d5 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/renderers/ValidationOutputRenderer.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/renderers/ValidationOutputRenderer.java @@ -13,6 +13,7 @@ public abstract class ValidationOutputRenderer { protected boolean crumbTrails; protected boolean moreThanOne; protected PrintStream dst; + protected boolean showMessageIds; public boolean isCrumbTrails() { return crumbTrails; @@ -22,6 +23,14 @@ public abstract class ValidationOutputRenderer { this.crumbTrails = crumbTrails; } + public boolean isShowMessageIds() { + return showMessageIds; + } + + public void setShowMessageIds(boolean showMessageIds) { + this.showMessageIds = showMessageIds; + } + public String getRunDate() { return runDate; } @@ -56,4 +65,10 @@ public abstract class ValidationOutputRenderer { public abstract String getStyleCode(); public abstract void setFolder(File dir); + + + protected String renderMessageId(OperationOutcome.OperationOutcomeIssueComponent issue) { + return showMessageIds ? " {" +issue.getExtensionString("http://hl7.org/fhir/StructureDefinition/operationoutcome-message-id")+"}" : ""; + } + } 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 14ce091f4..a239fd2d4 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 @@ -42,7 +42,7 @@ import org.hl7.fhir.utilities.json.parser.JsonParser; import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; import org.hl7.fhir.utilities.npm.NpmPackage; import org.hl7.fhir.validation.cli.utils.Common; -import org.hl7.fhir.validation.instance.BasePolicyAdvisorForFullValidation; +import org.hl7.fhir.validation.instance.advisor.BasePolicyAdvisorForFullValidation; import javax.annotation.Nonnull; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java index a764d18d8..644926361 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/ValidationService.java @@ -240,6 +240,7 @@ public class ValidationService { PrintStream dst = null; ValidationOutputRenderer renderer = makeValidationOutputRenderer(cliContext); renderer.setCrumbTrails(validator.isCrumbTrails()); + renderer.setShowMessageIds(validator.isShowMessageIds()); renderer.setRunDate(runDate); if (renderer.isSingleFile()) { if (cliContext.getOutput() == null) { @@ -574,6 +575,7 @@ public class ValidationService { validationEngine.setWantInvariantInMessage(cliContext.isWantInvariantsInMessages()); validationEngine.setSecurityChecks(cliContext.isSecurityChecks()); validationEngine.setCrumbTrails(cliContext.isCrumbTrails()); + validationEngine.setShowMessageIds(cliContext.isShowMessageIds()); validationEngine.setForPublication(cliContext.isForPublication()); validationEngine.setShowTimes(cliContext.isShowTimes()); validationEngine.setAllowExampleUrls(cliContext.isAllowExampleUrls()); diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Params.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Params.java index 0b220f5f8..8f646e86b 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Params.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Params.java @@ -80,6 +80,7 @@ public class Params { public static final String WANT_INVARIANTS_IN_MESSAGES = "-want-invariants-in-messages"; public static final String SECURITY_CHECKS = "-security-checks"; public static final String CRUMB_TRAIL = "-crumb-trails"; + public static final String SHOW_MESSAGE_IDS = "-show-message-ids"; public static final String FOR_PUBLICATION = "-forPublication"; public static final String VERBOSE = "-verbose"; public static final String SHOW_TIMES = "-show-times"; @@ -318,6 +319,8 @@ public class Params { cliContext.setSecurityChecks(true); } else if (args[i].equals(CRUMB_TRAIL)) { cliContext.setCrumbTrails(true); + } else if (args[i].equals(SHOW_MESSAGE_IDS)) { + cliContext.setShowMessageIds(true); } else if (args[i].equals(FOR_PUBLICATION)) { cliContext.setForPublication(true); } else if (args[i].equals(UNKNOWN_CODESYSTEMS_CAUSE_ERROR)) { @@ -326,6 +329,7 @@ public class Params { cliContext.setNoExperimentalContent(true); } else if (args[i].equals(VERBOSE)) { cliContext.setCrumbTrails(true); + cliContext.setShowMessageIds(true); } else if (args[i].equals(ALLOW_EXAMPLE_URLS)) { String bl = args[++i]; if ("true".equals(bl)) { 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 9ea21787d..0ee9c5191 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 @@ -201,6 +201,7 @@ import org.hl7.fhir.validation.cli.model.HtmlInMarkdownCheck; import org.hl7.fhir.validation.cli.utils.QuestionnaireMode; import org.hl7.fhir.validation.codesystem.CodingsObserver; import org.hl7.fhir.validation.instance.InstanceValidator.BindingContext; +import org.hl7.fhir.validation.instance.advisor.BasePolicyAdvisorForFullValidation; import org.hl7.fhir.validation.instance.type.BundleValidator; import org.hl7.fhir.validation.instance.type.CodeSystemValidator; import org.hl7.fhir.validation.instance.type.ConceptMapValidator; @@ -7072,7 +7073,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat context.formatMessage(I18nConstants.THIS_ELEMENT_DOES_NOT_MATCH_ANY_KNOWN_SLICE_, profile == null ? "" : "defined in the profile " + profile.getVersionedUrl()), context.formatMessage(I18nConstants.THIS_ELEMENT_DOES_NOT_MATCH_ANY_KNOWN_SLICE_, profile == null ? "" : context.formatMessage(I18nConstants.DEFINED_IN_THE_PROFILE) + " "+profile.getVersionedUrl()) + errorSummaryForSlicingAsHtml(ei.sliceInfo), - errorSummaryForSlicingAsText(ei.sliceInfo), ei.sliceInfo); + errorSummaryForSlicingAsText(ei.sliceInfo), ei.sliceInfo, I18nConstants.THIS_ELEMENT_DOES_NOT_MATCH_ANY_KNOWN_SLICE_); } } else if (ei.definition.getSlicing().getRules().equals(ElementDefinition.SlicingRules.CLOSED)) { bh.see(rule(errors, NO_RULE_DATE, IssueType.INVALID, ei.line(), ei.col(), ei.getPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_NOTSLICE, (profile == null ? "" : " defined in the profile " + profile.getVersionedUrl()), errorSummaryForSlicing(ei.sliceInfo))); diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java index 81cd30b72..630913d64 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java @@ -23,8 +23,8 @@ public class SpecialExtensions { "http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support", "http://hl7.org/fhir/StructureDefinition/instance-name", "http://hl7.org/fhir/StructureDefinition/instance-description", - "http://hl7.org/fhir/build/StructureDefinition/definition", // wrongly defined in used in early R4B/R5 builds - changed to http://hl7.org/build/fhir/StructureDefinition/binding-definition - "http://hl7.org/fhir/build/StructureDefinition/binding-definition", // wrongly defined in used in early R4B/R5 builds - changed to http://hl7.org/build/fhir/StructureDefinition/binding-definition + "http://hl7.org/fhir/build/StructureDefinition/definition", // wrongly defined in used in R4B/R5 builds - changed to http://hl7.org/fhir/tools/StructureDefinition/binding-definition + "http://hl7.org/fhir/build/StructureDefinition/binding-definition", // wrongly defined in used in R4B/R5 builds - http://hl7.org/fhir/tools/StructureDefinition/binding-definition "http://hl7.org/fhir/StructureDefinition/codesystem-properties-mode", "http://hl7.org/fhir/StructureDefinition/structuredefinition-rdf-type", "http://hl7.org/fhir/StructureDefinition/structuredefinition-conformance-derivedFrom", // this is defined in R5, but needed earlier diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/BasePolicyAdvisorForFullValidation.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/advisor/BasePolicyAdvisorForFullValidation.java similarity index 99% rename from org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/BasePolicyAdvisorForFullValidation.java rename to org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/advisor/BasePolicyAdvisorForFullValidation.java index d3046ab93..4fd00c536 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/BasePolicyAdvisorForFullValidation.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/advisor/BasePolicyAdvisorForFullValidation.java @@ -1,4 +1,4 @@ -package org.hl7.fhir.validation.instance; +package org.hl7.fhir.validation.instance.advisor; import java.util.ArrayList; import java.util.EnumSet; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/advisor/JsonDrivenPolicyAdvisor.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/advisor/JsonDrivenPolicyAdvisor.java new file mode 100644 index 000000000..abaed6596 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/advisor/JsonDrivenPolicyAdvisor.java @@ -0,0 +1,77 @@ +package org.hl7.fhir.validation.instance.advisor; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.EnumSet; +import java.util.List; + +import org.hl7.fhir.r5.elementmodel.Element; +import org.hl7.fhir.r5.elementmodel.Element.SpecialElement; +import org.hl7.fhir.r5.model.ElementDefinition; +import org.hl7.fhir.r5.model.StructureDefinition; +import org.hl7.fhir.r5.model.ValueSet; +import org.hl7.fhir.r5.utils.validation.IMessagingServices; +import org.hl7.fhir.r5.utils.validation.IResourceValidator; +import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor; +import org.hl7.fhir.r5.utils.validation.constants.BindingKind; +import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPolicy; +import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy; +import org.hl7.fhir.utilities.json.JsonException; +import org.hl7.fhir.utilities.json.model.JsonObject; +import org.hl7.fhir.utilities.json.parser.JsonParser; +import org.hl7.fhir.utilities.validation.ValidationMessage; + +public class JsonDrivenPolicyAdvisor implements IValidationPolicyAdvisor { + + private JsonObject config; + private IValidationPolicyAdvisor base; + + public JsonDrivenPolicyAdvisor(IValidationPolicyAdvisor base, JsonObject config) { + this.base = base; + this.config = config; + } + + public JsonDrivenPolicyAdvisor(String config) throws JsonException, IOException { + this.config = JsonParser.parseObject(config, true); + } + + public JsonDrivenPolicyAdvisor(File config) throws JsonException, IOException { + this.config = JsonParser.parseObject(new FileInputStream(config), true); + } + + public JsonDrivenPolicyAdvisor(FileInputStream config) throws JsonException, IOException { + this.config = JsonParser.parseObject(config, true); + } + + @Override + public ReferenceValidationPolicy policyForReference(IResourceValidator validator, Object appContext, String path, String url) { + return base.policyForReference(validator, appContext, path, url); + } + + @Override + public ContainedReferenceValidationPolicy policyForContained(IResourceValidator validator, Object appContext, StructureDefinition structure, ElementDefinition element, String containerType, String containerId, SpecialElement containingResourceType, String path, String url) { + return base.policyForContained(validator, appContext, structure, element, containerType, containerId, containingResourceType, path, url); + } + + @Override + public EnumSet policyForResource(IResourceValidator validator, Object appContext, StructureDefinition type, String path) { + return base.policyForResource(validator, appContext, type, path); + } + + @Override + public EnumSet policyForElement(IResourceValidator validator, Object appContext, StructureDefinition structure, ElementDefinition element, String path) { + return base.policyForElement(validator, appContext, structure, element, path); + } + + @Override + public EnumSet policyForCodedContent(IResourceValidator validator, Object appContext, String stackPath, ElementDefinition definition, StructureDefinition structure, BindingKind kind, AdditionalBindingPurpose purpose, ValueSet valueSet, List systems) { + return base.policyForCodedContent(validator, appContext, stackPath, definition, structure, kind, purpose, valueSet, systems); + } + + @Override + public List getImpliedProfilesForResource(IResourceValidator validator, Object appContext, String stackPath, ElementDefinition definition, StructureDefinition structure, Element resource, boolean valid, IMessagingServices msgServices, List messages) { + return base.getImpliedProfilesForResource(validator, appContext, stackPath, definition, structure, resource, valid, msgServices, messages); + } + +} diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/CodeSystemValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/CodeSystemValidator.java index e87456b7c..193f9575a 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/CodeSystemValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/CodeSystemValidator.java @@ -571,6 +571,8 @@ public class CodeSystemValidator extends BaseValidator { } } + warning(errors, "2024-10-03", IssueType.BUSINESSRULE, stack.getLiteralPath(), !(count == 0 && "complete".equals(content)), I18nConstants.CODESYSTEM_CS_COMPLETE_AND_EMPTY); + if (cs.hasChild("count", false)) { int statedCount = Utilities.parseInt(cs.getNamedChildValue("count", false), -1); if (statedCount > -1 && content != null) { // error elsewhere diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java index 9047eca09..b65fbcbc4 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java @@ -181,7 +181,7 @@ public class StructureMapValidator extends BaseValidator { } public String summary() { - return mode+" "+getWorkingType()+" "+name; + return name+" : "+getWorkingType()+" ("+mode+")"; } public boolean matches(VariableDefn other) { @@ -215,6 +215,13 @@ public class StructureMapValidator extends BaseValidator { } } + public void copyType(VariableDefn source) { + this.max = source.max; + this.sd = source.sd; + this.ed = source.ed; + this.type = source.type; + } + } public class VariableSet { @@ -332,6 +339,7 @@ public class StructureMapValidator extends BaseValidator { public boolean validateStructureMap(ValidationContext valContext, List errors, Element src, NodeStack stack) { boolean ok = true; + List imports = src.getChildrenByName("import"); int cc = 0; for (Element import_ : imports) { @@ -649,6 +657,20 @@ public class StructureMapValidator extends BaseValidator { } // check condition // check check + } else { + String variable = source.getChildValue("variable"); + VariableDefn vn = null; + if (hint(errors, "2023-03-01", IssueType.INVALID, source.line(), source.col(), stack.getLiteralPath(), variable != null, I18nConstants.SM_RULE_SOURCE_UNASSIGNED)) { + if (rule(errors, "2023-03-01", IssueType.INVALID, source.line(), source.col(), stack.getLiteralPath(), idIsValid(variable), I18nConstants.SM_NAME_INVALID, variable)) { + vn = variables.add(variable, v.getMode()); // may overwrite + vn.copyType(v); + if (loopCounter == 0) { + ruleInfo.setDefVariable(variable); + } + } else { + ok = false; + } + } } } else { String variable = source.getChildValue("variable"); @@ -1237,7 +1259,8 @@ public class StructureMapValidator extends BaseValidator { // target can transition to the source v = getParameter(errors, param, pstack, variables, StructureMapInputMode.TARGET); } - if (rule(errors, "2023-06-27", IssueType.INVALID, param.line(), param.col(), pstack.getLiteralPath(), v != null, I18nConstants.SM_DEPENDENT_PARAM_NOT_FOUND, pname, input.getMode().toCode())) { + + if (rule(errors, "2023-06-27", IssueType.INVALID, param.line(), param.col(), pstack.getLiteralPath(), v != null, I18nConstants.SM_DEPENDENT_PARAM_NOT_FOUND, pname, input.getMode().toCode(), variables.summary())) { if (rule(errors, "2023-03-01", IssueType.INVALID, param.line(), param.col(), pstack.getLiteralPath(), v.mode.equals(input.getMode().toCode()) || (v.mode.equals("target") && input.getMode() == StructureMapInputMode.SOURCE), I18nConstants.SM_DEPENDENT_PARAM_MODE_MISMATCH, param.getChildValue("name"), v.mode, input.getMode().toCode(), grp.getTargetGroup().getName()) && rule(errors, "2023-03-01", IssueType.INVALID, param.line(), param.col(), pstack.getLiteralPath(), typesMatch(v, iType), I18nConstants.SM_DEPENDENT_PARAM_TYPE_MISMATCH, diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ValueSetValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ValueSetValidator.java index d71692825..47bc5b25d 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ValueSetValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ValueSetValidator.java @@ -128,6 +128,7 @@ public class ValueSetValidator extends BaseValidator { } private static final int TOO_MANY_CODES_TO_VALIDATE = 1000; + private static final int VALIDATION_BATCH_SIZE = 300; private CodeSystemChecker getSystemValidator(String system, List errors) { if (system == null) { @@ -319,36 +320,26 @@ public class ValueSetValidator extends BaseValidator { int cc = 0; List batch = new ArrayList<>(); boolean first = true; - for (Element concept : concepts) { - // we treat the first differently because we want to know if the system is worth validating. if it is, then we batch the rest - if (first) { - systemOk = validateValueSetIncludeConcept(errors, concept, stack, stack.push(concept, cc, null, null), system, version, csChecker); - first = false; - } else if (systemOk) { - batch.add(prepareValidateValueSetIncludeConcept(errors, concept, stack.push(concept, cc, null, null), system, version, csChecker)); - } - cc++; - } - if (((InstanceValidator) parent).isValidateValueSetCodesOnTxServer() && batch.size() > 0 & !context.isNoTerminologyServer()) { - if (batch.size() > TOO_MANY_CODES_TO_VALIDATE) { - ok = hint(errors, "2023-09-06", IssueType.BUSINESSRULE, stack, false, I18nConstants.VALUESET_INC_TOO_MANY_CODES, batch.size()) && ok; - } else { - long t = System.currentTimeMillis(); - if (parent.isDebug()) { - System.out.println(" : Validate "+batch.size()+" codes from "+system+" for "+vsid); - } + if (concepts.size() > TOO_MANY_CODES_TO_VALIDATE) { + hint(errors, "2023-09-06", IssueType.BUSINESSRULE, stack, false, I18nConstants.VALUESET_INC_TOO_MANY_CODES, batch.size()); + } else { + if (((InstanceValidator) parent).isValidateValueSetCodesOnTxServer() && !context.isNoTerminologyServer()) { try { - context.validateCodeBatch(ValidationOptions.defaults().withExampleOK(), batch, null); - if (parent.isDebug()) { - System.out.println(" : .. "+(System.currentTimeMillis()-t)+"ms"); - } - for (VSCodingValidationRequest cv : batch) { - if (version == null) { - warningOrHint(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, cv.getStack().getLiteralPath(), cv.getResult().isOk(), !retired, I18nConstants.VALUESET_INCLUDE_INVALID_CONCEPT_CODE, system, cv.getCoding().getCode(), cv.getResult().getMessage()); - } else { - warningOrHint(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, cv.getStack().getLiteralPath(), cv.getResult().isOk(), !retired, I18nConstants.VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER, system, version, cv.getCoding().getCode(), cv.getResult().getMessage()); + for (Element concept : concepts) { + // we treat the first differently because we want to know if the system is worth validating. if it is, then we batch the rest + if (first) { + systemOk = validateValueSetIncludeConcept(errors, concept, stack, stack.push(concept, cc, null, null), system, version, csChecker); + first = false; + } else if (systemOk) { + batch.add(prepareValidateValueSetIncludeConcept(errors, concept, stack.push(concept, cc, null, null), system, version, csChecker)); + if (batch.size() > VALIDATION_BATCH_SIZE) { + executeValidationBatch(errors, vsid, retired, system, version, batch); + batch.clear(); + } } - } + cc++; + } + executeValidationBatch(errors, vsid, retired, system, version, batch); } catch (Exception e) { ok = false; VSCodingValidationRequest cv = batch.get(0); @@ -356,7 +347,6 @@ public class ValueSetValidator extends BaseValidator { } } } - int cf = 0; for (Element filter : filters) { ok = validateValueSetIncludeFilter(errors, filter, stack.push(filter, cf, null, null), system, version, cs, csChecker) & ok; @@ -369,6 +359,27 @@ public class ValueSetValidator extends BaseValidator { return ok; } + private void executeValidationBatch(List errors, String vsid, boolean retired, String system, + String version, List batch) { + if (batch.size() > 0) { + long t = System.currentTimeMillis(); + if (parent.isDebug()) { + System.out.println(" : Validate "+batch.size()+" codes from "+system+" for "+vsid); + } + context.validateCodeBatch(ValidationOptions.defaults().withExampleOK(), batch, null); + if (parent.isDebug()) { + System.out.println(" : .. "+(System.currentTimeMillis()-t)+"ms"); + } + for (VSCodingValidationRequest cv : batch) { + if (version == null) { + warningOrHint(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, cv.getStack().getLiteralPath(), cv.getResult().isOk(), !retired, I18nConstants.VALUESET_INCLUDE_INVALID_CONCEPT_CODE, system, cv.getCoding().getCode(), cv.getResult().getMessage()); + } else { + warningOrHint(errors, NO_RULE_DATE, IssueType.BUSINESSRULE, cv.getStack().getLiteralPath(), cv.getResult().isOk(), !retired, I18nConstants.VALUESET_INCLUDE_INVALID_CONCEPT_CODE_VER, system, version, cv.getCoding().getCode(), cv.getResult().getMessage()); + } + } + } + } + private boolean validateValueSetIncludeConcept(List errors, Element concept, NodeStack stackInc, NodeStack stack, String system, String version, CodeSystemChecker slv) { String code = concept.getChildValue("code"); diff --git a/org.hl7.fhir.validation/src/main/resources/help/advisor.txt b/org.hl7.fhir.validation/src/main/resources/help/advisor.txt new file mode 100644 index 000000000..7d35eaad5 --- /dev/null +++ b/org.hl7.fhir.validation/src/main/resources/help/advisor.txt @@ -0,0 +1,205 @@ +# Introduction + +This document describes the use of the advisor format that advises the validator which rules to enforce. +By default the validator enforces the entire FHIR specification as described. Implementers simply wishing +to know whether a resource is valid or not should not be using this functionality. + +The advisor functionality exists to assist implementers who are using the validator in pipelines where +known issues are tolerated and suppressed. Usually this arises because additional rules were added in +later validator versions after design decision had been made, and the specific issues cannot be rectified, +though there are other reasons. + +Warning: Implementers use this functionality to hide known issues with their resources. + +use the command line parameter ```-rules {filename}``` to make a set of rules apply. + +There are two ways to turn off validation rules: + +* Suppressing output messages +* Controlling what validation runs + +## Suppressing Output Messages + +This approach is conceptually simple: the entire validation is executed, and then +messages are filtered from the output based on their messageId. + +The messageId is not usually shown; use the command line parameter ```-show-message-ids``` to show +the messageIds in the output. + +Some notes on this approach: + +* This turns off all uses of that message id - there's no way to be selective about what context they occur in +* the messageId is directly tied to the format of the message. For some messages, there are multiple variants of the message, each with their own id, and these all need to be suppressed +* message ids are stable, but sometimes an existing message is improved in some contexts, and new message ids are introduced in later versions +* the underlying validation still happens, even when the messages are suppressed + + +## Controlling what validation runs + +An alternative approach is to control what parts of the validation logic are executed. +As each step of the validation process occurs, the validator looks in the advisor file +to see whether any applicable rules apply at the point it is at, and proceeds as advised +by the rules in the advisor file. + +# Validation Rules + +The validator uses several different kinds of rules: + +* resource: what to do when validating a resource +* element: what to do when validating an element +* invariant: what to when checking an invariant +* coded: what to do when validating a coded element (e.g. an element with a binding) +* reference: what to do when validating a reference to another resource +* contained: what to do when validating a contained resource + +Each rule comes with a set of filters that decide whether the rule applies in a given context, and a set of options to choose from + +## resource + +What to do when validating a resource + +Filters: +* path: the path in/from the validated resource where this resource is found. For the validated resource itself, this is the type of the resource, but for contained/referenced resource etc, this can be a complex path +* type: the type of the resource e.g. Patient + +Options: +* base: validate against the base standard +* stated: validate against the profiles stated in the parameters to the validator +* meta: validate against the profiles stated in the meta element +* global: validate against the known global profiles + +## element + +What to do when validating an element + +Filters: +* path: the path in/from the validated resource where this element is found +* Structure: the url|version for the applicable profile (may be a the base definition of a resource) +* id: the element id in the profile + +Options: +* cardinality: check the element against it's stated cardinality +* invariants: check the element against it's applicable invariants +* bindings: check the element against it's applicable bindings (including additional bindings) +* fixed: check the element against it's applicable fixed/pattern values + +Note that slicing determination happens irrespective of these options + +## invariant + +What do when evaluating an invariant + +Filters: +* path: the path in/from the validated resource where this element is found +* Structure: the url|version for the applicable profile (may be a the base definition of a resource) +* id: the element id in the profile +* key: the key assigned to the invariant + +Options: +* check: check the invariant +* warning: downgrade to a warning (if it's an error) + + +## coded + +What to do when validating an element with a binding (including additional bindings) + +Filters: +* path: the path in/from the validated resource where this element is found +* Structure: the url|version for the applicable profile (may be a the base definition of a resource) +* id: the element id in the profile +* type: the data type of the element +* kind: the binding strength (required, extensible, preferred) +* valueSet: the url|version of the valueSet in the binding +* system: a code system in the coded element (note: system isn't known at the decision point for `code` datatypes) + +Options: +* concepts: check that the concepts are valid +* displays: check that the displays are valid +* status: check the status of the applicable value sets and code systems + +## reference + +what to do when validating a reference + +Filters: +* path: the path in/from the validated resource where this element is found +* Structure: the url|version for the applicable profile (may be a the base definition of a resource) +* id: the element id in the profile +* url: the reference itself + +Options: +* exists: check that the reference can be resolved +* type: check that the reference resolves to something of the correct type +* valid: validate the target of the reference against any applicable profiles + +## contained + +what to do when validating a contained resource + +Filters: +* path: the path in/from the validated resource where this contained resource is found +* kind: the kind of containment (bundled, contained, parameter, outcome) +* type: the type of the resource e.g. Patient +* id: the id of the resource + +Options: +* valid: validate the contained resource + + +# Format + +There are two supported formats: text, and json. + +Each format presents a list of rules. Rules are evaluated in order, and the first matching rule (all filters are true, or no filters) is used. +For each rule, zero or more filters are provided, and a set of options (which may be empty) is specified. + +## Text Format + +The file begins with zero or more suppression statements: + +``` +- VALIDATION_VAL_STATUS_INCONSISTENT_HINT +- MSG_DEPRECATED # comments are allowed +# comments are allowed here too +- This_element_does_not_match_any_known_slice_ +``` + +Then there is zero or more rules. Each rule is a line of text. The line starts with the kind of rule, then a list of name=value pairs for the filters, followed by an ':', and then zero or more options separated by spaces: + +``` +element (path=Patient.identifier.*): cardinality fixed # comments +``` + +Comments can also be on empty lines e.g. lines with no rules: + +``` +# comment +``` + +## Json format + +```json +{ + "suppress" : ["VALIDATION_VAL_STATUS_INCONSISTENT_HINT", "MSG_DEPRECATED", "This_element_does_not_match_any_known_slice_"], + "rules" : [{ + "type" : "element", + "filters" : [{ + "name" : "path", + "value" : "path=Patient.identifier.*" + }], + "options" : ["cardinality", "fixed"] + }] +``` + +other properties are ignored, so comments etc can be introduced with any other property name + +## Filter matching + +Except for the path, filter matching is string based, using * as the wild card. A filter starting with ^ is treated as a regex that the filter value must match. + +In the path, matching is based on segments, broken up by ```.```. If the path syntax in the filter rule doesn't specify an index, it applies to all occurrences. Indexes can be specified as +integer offsets. No selection criteria such as FHIRPath can be used + +# Examples + 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 c43b88da0..929b97395 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 @@ -93,8 +93,8 @@ import org.hl7.fhir.validation.ValidationEngine; import org.hl7.fhir.validation.ValidatorUtils; import org.hl7.fhir.validation.cli.model.HtmlInMarkdownCheck; import org.hl7.fhir.validation.cli.services.StandAloneValidatorFetcher; -import org.hl7.fhir.validation.instance.BasePolicyAdvisorForFullValidation; import org.hl7.fhir.validation.instance.InstanceValidator; +import org.hl7.fhir.validation.instance.advisor.BasePolicyAdvisorForFullValidation; import org.hl7.fhir.validation.tests.utilities.TestUtilities; import org.junit.AfterClass; import org.junit.Assert; diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/utilities/TestUtilities.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/utilities/TestUtilities.java index b91d9dd05..e40e4eda3 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/utilities/TestUtilities.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/utilities/TestUtilities.java @@ -11,7 +11,7 @@ import org.hl7.fhir.utilities.tests.TestConfig; import org.hl7.fhir.utilities.tests.TestConstants; import org.hl7.fhir.validation.ValidationEngine; import org.hl7.fhir.validation.cli.services.StandAloneValidatorFetcher; -import org.hl7.fhir.validation.instance.BasePolicyAdvisorForFullValidation; +import org.hl7.fhir.validation.instance.advisor.BasePolicyAdvisorForFullValidation; public class TestUtilities { diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/validationService/http___covidcare.au_app_alert.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/validationService/http___covidcare.au_app_alert.cache new file mode 100644 index 000000000..895f9ab4e --- /dev/null +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/validationService/http___covidcare.au_app_alert.cache @@ -0,0 +1,47 @@ +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://covidcare.au/app/alert", + "code" : "trendNegative", + "display" : "CovidCare: Vital signs trend negative alert: re-check recommended" +}, "valueSet" :null, "langs":"en", "useServer":"true", "useClient":"false", "guessSystem":"false", "activeOnly":"false", "membershipOnly":"false", "displayWarningMode":"false", "versionFlexible":"true", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }, + { + "name" : "system-version", + "valueCanonical" : "http://snomed.info/sct|http://snomed.info/sct/900000000000207008" + }] +}}#### +v: { + "code" : "trendNegative", + "system" : "http://covidcare.au/app/alert", + "severity" : "error", + "error" : "A definition for CodeSystem 'http://covidcare.au/app/alert' could not be found, so the code cannot be validated", + "class" : "CODESYSTEM_UNSUPPORTED", + "server" : "http://tx-dev.fhir.org/r4", + "unknown-systems" : "http://covidcare.au/app/alert", + "issues" : { + "resourceType" : "OperationOutcome", + "issue" : [{ + "extension" : [{ + "url" : "http://hl7.org/fhir/StructureDefinition/operationoutcome-issue-server", + "valueUrl" : "http://tx-dev.fhir.org/r4" + }], + "severity" : "error", + "code" : "not-found", + "details" : { + "coding" : [{ + "system" : "http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", + "code" : "not-found" + }], + "text" : "A definition for CodeSystem 'http://covidcare.au/app/alert' could not be found, so the code cannot be validated" + }, + "location" : ["Coding.system"], + "expression" : ["Coding.system"] + }] +} + +} +------------------------------------------------------------------------------------- diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/validationService/version.ctl b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/validationService/version.ctl new file mode 100644 index 000000000..bf0d87ab1 --- /dev/null +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/validationService/version.ctl @@ -0,0 +1 @@ +4 \ No newline at end of file diff --git a/pom.xml b/pom.xml index e3fa0de1b..632e1337a 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ 1.26.0 32.0.1-jre 6.4.1 - 1.5.24 + 1.5.25-SNAPSHOT 2.17.0 5.9.2 1.8.2