From d652aa2f300934416c8a9d354c5d8f8499c299b7 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Wed, 23 Oct 2024 22:19:08 +1030 Subject: [PATCH 1/6] Fix NPE processing markdown --- org.hl7.fhir.convertors/pom.xml | 2 +- org.hl7.fhir.dstu2/pom.xml | 2 +- org.hl7.fhir.dstu2016may/pom.xml | 2 +- org.hl7.fhir.dstu3/pom.xml | 2 +- org.hl7.fhir.r4/pom.xml | 2 +- org.hl7.fhir.r4b/pom.xml | 2 +- org.hl7.fhir.r5/pom.xml | 2 +- org.hl7.fhir.report/pom.xml | 2 +- org.hl7.fhir.utilities/pom.xml | 2 +- .../main/java/org/hl7/fhir/utilities/MarkDownProcessor.java | 3 +++ org.hl7.fhir.validation.cli/pom.xml | 2 +- org.hl7.fhir.validation/pom.xml | 2 +- 12 files changed, 14 insertions(+), 11 deletions(-) diff --git a/org.hl7.fhir.convertors/pom.xml b/org.hl7.fhir.convertors/pom.xml index 18f9c2329..c14cecd2f 100644 --- a/org.hl7.fhir.convertors/pom.xml +++ b/org.hl7.fhir.convertors/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.3.33-SNAPSHOT + 6.4.0-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu2/pom.xml b/org.hl7.fhir.dstu2/pom.xml index 674c68fec..52b2bfaa1 100644 --- a/org.hl7.fhir.dstu2/pom.xml +++ b/org.hl7.fhir.dstu2/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.3.33-SNAPSHOT + 6.4.0-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu2016may/pom.xml b/org.hl7.fhir.dstu2016may/pom.xml index 24f4ba34c..1b3ca3086 100644 --- a/org.hl7.fhir.dstu2016may/pom.xml +++ b/org.hl7.fhir.dstu2016may/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.3.33-SNAPSHOT + 6.4.0-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu3/pom.xml b/org.hl7.fhir.dstu3/pom.xml index 495182651..cba125cf4 100644 --- a/org.hl7.fhir.dstu3/pom.xml +++ b/org.hl7.fhir.dstu3/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.3.33-SNAPSHOT + 6.4.0-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.r4/pom.xml b/org.hl7.fhir.r4/pom.xml index c433c70bc..e3c868be7 100644 --- a/org.hl7.fhir.r4/pom.xml +++ b/org.hl7.fhir.r4/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.3.33-SNAPSHOT + 6.4.0-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.r4b/pom.xml b/org.hl7.fhir.r4b/pom.xml index 9f49fa24a..72ef600ee 100644 --- a/org.hl7.fhir.r4b/pom.xml +++ b/org.hl7.fhir.r4b/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.3.33-SNAPSHOT + 6.4.0-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.r5/pom.xml b/org.hl7.fhir.r5/pom.xml index e0927d747..a26bd9f9c 100644 --- a/org.hl7.fhir.r5/pom.xml +++ b/org.hl7.fhir.r5/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.3.33-SNAPSHOT + 6.4.0-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.report/pom.xml b/org.hl7.fhir.report/pom.xml index fca5c8886..cba171cdb 100644 --- a/org.hl7.fhir.report/pom.xml +++ b/org.hl7.fhir.report/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.3.33-SNAPSHOT + 6.4.0-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.utilities/pom.xml b/org.hl7.fhir.utilities/pom.xml index cd8fcfcf6..6e6f8aa00 100644 --- a/org.hl7.fhir.utilities/pom.xml +++ b/org.hl7.fhir.utilities/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.3.33-SNAPSHOT + 6.4.0-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/MarkDownProcessor.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/MarkDownProcessor.java index cddc35c3a..60d4668bd 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/MarkDownProcessor.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/MarkDownProcessor.java @@ -93,6 +93,9 @@ public class MarkDownProcessor { */ // todo: dialect dependency? public boolean isProbablyMarkdown(String content, boolean mdIfParagrapghs) { + if (content == null) { + return false; + } if (mdIfParagrapghs && content.contains("\n")) { return true; } diff --git a/org.hl7.fhir.validation.cli/pom.xml b/org.hl7.fhir.validation.cli/pom.xml index 081ac9e56..977b7bd3a 100644 --- a/org.hl7.fhir.validation.cli/pom.xml +++ b/org.hl7.fhir.validation.cli/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.3.33-SNAPSHOT + 6.4.0-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.validation/pom.xml b/org.hl7.fhir.validation/pom.xml index 8f36b1459..6530c12a3 100644 --- a/org.hl7.fhir.validation/pom.xml +++ b/org.hl7.fhir.validation/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 6.3.33-SNAPSHOT + 6.4.0-SNAPSHOT ../pom.xml From 77580465c7dea5f7b265e06b779dae4ac3e0f357 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Wed, 23 Oct 2024 22:59:32 +1030 Subject: [PATCH 2/6] revise message about unknown usage context on additional binding --- org.hl7.fhir.utilities/src/main/resources/Messages.properties | 2 +- .../validation/instance/type/StructureDefinitionValidator.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/org.hl7.fhir.utilities/src/main/resources/Messages.properties b/org.hl7.fhir.utilities/src/main/resources/Messages.properties index 35bab06be..ea3654b70 100644 --- a/org.hl7.fhir.utilities/src/main/resources/Messages.properties +++ b/org.hl7.fhir.utilities/src/main/resources/Messages.properties @@ -1147,7 +1147,7 @@ NO_VALID_DISPLAY_AT_ALL = Cannot validate display Name ''{0}'' for {1}#{2}: No d SD_BASE_EXPERIMENTAL = The definition builds on ''{0}'' which is experimental, but this definition is not labeled as experimental SD_ED_EXPERIMENTAL_BINDING = The definition for the element ''{0}'' binds to the value set ''{1}'' which is experimental, but this structure is not labeled as experimental VALIDATION_NO_EXPERIMENTAL_CONTENT = Experimental content is not allowed in this context -SD_ED_ADDITIONAL_BINDING_USAGE_UNKNOWN = The Usage Context {0}#{1} is not recognised and may not be correct +SD_ED_ADDITIONAL_BINDING_USAGE_UNKNOWN = The Usage Context {0}#{1} is not recognized so cannot be validated 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.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 30bbdb9af..59082049b 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 @@ -1129,7 +1129,7 @@ public class StructureDefinitionValidator extends BaseValidator { } } } else { - warning(errors, "2024-09-17", IssueType.BUSINESSRULE, stack.getLiteralPath(), false, I18nConstants.SD_ED_ADDITIONAL_BINDING_USAGE_UNKNOWN, system, code); + hint(errors, "2024-09-17", IssueType.BUSINESSRULE, stack.getLiteralPath(), false, I18nConstants.SD_ED_ADDITIONAL_BINDING_USAGE_UNKNOWN, system, code); } } return ok; From 832906da1337238d5443d1c8c772e35a40b70f29 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Wed, 23 Oct 2024 22:59:54 +1030 Subject: [PATCH 3/6] update tests for changes to PE code generation --- .../r4/profilemodel/gen/PECodeGenerator.java | 46 ++++++++++++++++--- .../org/hl7/fhir/r5/profiles/PETests.java | 16 +++---- 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/profilemodel/gen/PECodeGenerator.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/profilemodel/gen/PECodeGenerator.java index 945269162..5292000cd 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/profilemodel/gen/PECodeGenerator.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/profilemodel/gen/PECodeGenerator.java @@ -60,6 +60,29 @@ import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; +/** + * + * The easiest way to generate code is to use the FHIR Validator, which can generate java classes for profiles + * using this code. Parameters: + * + * -codegen -version r4 -ig hl7.fhir.dk.core#3.2.0 -profiles http://hl7.dk/fhir/core/StructureDefinition/dk-core-gln-identifier,http://hl7.dk/fhir/core/StructureDefinition/dk-core-patient -output /Users/grahamegrieve/temp/codegen -package-name org.hl7.fhir.test + * + * Parameter Documentation: + * -codegen: tells the validator to generate code + * -version {r4|5}: which version to generate for + * -ig {name}: loads an IG (and it's dependencies) - see -ig documentation for the validator + * -profiles {list}: a comma separated list of profile URLs to generate code for + * -output {folder}: the folder where to generate the output java class source code + * -package-name {name}: the name of the java package to generate in + * + * options + * -option {name}: a code generation option, one of: + * + * narrative: generate code for the resource narrative (recommended: don't - leave that for the native resource level) + * meta: generate code the what's in meta + * contained: generate code for contained resources + * all-elements: generate code for all elements, not just the key elements (makes the code verbose) + */ public class PECodeGenerator { @@ -229,7 +252,7 @@ public class PECodeGenerator { w(enums, " public enum "+name+" {"); for (int i = 0; i < vse.getValueset().getExpansion().getContains().size(); i++) { ValueSetExpansionContainsComponent cc = vse.getValueset().getExpansion().getContains().get(i); - String code = Utilities.nmtokenize(cc.getCode()).toUpperCase(); + String code = Utilities.javaTokenize(cc.getCode(), true).toUpperCase(); if (cc.getAbstract()) { code = "_"+code; } @@ -375,7 +398,12 @@ public class PECodeGenerator { private void genLoad(boolean isPrim, boolean isAbstract, String name, String sname, String type, String init, String ptype, String ltype, String cname, String csname, boolean isList, boolean isFixed, PEType typeInfo, boolean isEnum) { if (isList) { w(load, " for (PEInstance item : src.children(\""+sname+"\")) {"); - w(load, " "+name+".add(("+type+") item.asDataType());"); + + if ("BackboneElement".equals(type)) { + w(load, " "+name+".add(("+type+") item.asElement());"); + } else { + w(load, " "+name+".add(("+type+") item.asDataType());"); + } w(load, " }"); } else if (isEnum) { w(load, " if (src.hasChild(\""+name+"\")) {"); @@ -384,7 +412,7 @@ public class PECodeGenerator { } else if ("Coding".equals(typeInfo.getName())) { w(load, " "+name+" = "+type+".fromCoding((Coding) src.child(\""+name+"\").asDataType());"); } else { - w(load, " "+name+" = "+type+".fromCode(src.child(\""+name+"\").asDataType()).primitiveValue());"); + w(load, " "+name+" = "+type+".fromCode(src.child(\""+name+"\").asDataType().primitiveValue());"); } w(load, " }"); } else if (isPrim) { @@ -401,8 +429,12 @@ public class PECodeGenerator { w(load, " "+name+" = "+type+".fromSource(src.child(\""+name+"\"));"); w(load, " }"); } else { - w(load, " if (src.hasChild(\""+name+"\")) {"); - w(load, " "+name+" = ("+type+") src.child(\""+name+"\").asDataType();"); + w(load, " if (src.hasChild(\""+name+"\")) {"); + if ("BackboneElement".equals(type)) { + w(load, " "+name+" = ("+type+") src.child(\""+name+"\").asElement();"); + } else { + w(load, " "+name+" = ("+type+") src.child(\""+name+"\").asDataType();"); + } w(load, " }"); } } @@ -424,7 +456,7 @@ public class PECodeGenerator { } else if ("Coding".equals(typeInfo.getName())) { w(save, " tgt.addChild(\""+sname+"\", "+name+".toCoding());"); } else { - w(save, " tgt.addChild(\""+sname+"\", "+name+").toCode();"); + w(save, " tgt.addChild(\""+sname+"\", "+name+".toCode());"); } w(save, " }"); } else if (isPrim) { @@ -593,7 +625,7 @@ public class PECodeGenerator { private IWorkerContext workerContext; private String canonical; private String pkgName; - private String version; + private String version = "r4"; // options: private ExtensionPolicy extensionPolicy; diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/PETests.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/PETests.java index 58e16476a..40e3b7667 100644 --- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/PETests.java +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/profiles/PETests.java @@ -101,7 +101,7 @@ public class PETests { checkElement(children.get(2), "language", "language", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/code", 2, "language"); checkElement(children.get(3), "text", "text", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/Narrative", 3, "text"); checkElement(children.get(4), "contained", "contained", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Resource", 4, "contained"); - checkElement(children.get(5), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension.where(((url = 'http://hl7.org/fhir/test/StructureDefinition/pe-extension-simple') or (url = 'http://hl7.org/fhir/test/StructureDefinition/pe-extension-complex')).not())"); + checkElement(children.get(5), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 2, "extension.where(((url = 'http://hl7.org/fhir/test/StructureDefinition/pe-extension-simple') or (url = 'http://hl7.org/fhir/test/StructureDefinition/pe-extension-complex')).not())"); checkElement(children.get(6), "extension", "simple", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/code", 2, "extension('http://hl7.org/fhir/test/StructureDefinition/pe-extension-simple').value"); checkElement(children.get(7), "extension", "complex", 0, 1, false, "http://hl7.org/fhir/test/StructureDefinition/pe-extension-complex", 4, "extension('http://hl7.org/fhir/test/StructureDefinition/pe-extension-complex')"); checkElement(children.get(8), "identifier", "identifier", 0, 1, false, "http://hl7.org/fhir/StructureDefinition/Identifier", 7, "identifier"); @@ -116,7 +116,7 @@ public class PETests { checkElement(children.get(17), "value[x]", "valueCodeableConcept", 0, 1, false, "http://hl7.org/fhir/test/StructureDefinition/pe-profile2", 4, "value.ofType(CodeableConcept)"); List gchildren = children.get(11).children(); - checkElement(gchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, true, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension"); + checkElement(gchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, true, "http://hl7.org/fhir/StructureDefinition/Extension", 2, "extension"); checkElement(gchildren.get(1), "coding", "coding", 0, Integer.MAX_VALUE, true, "http://hl7.org/fhir/StructureDefinition/Coding", 6, "coding"); checkElement(gchildren.get(2), "text", "text", 0, 1, true, "http://hl7.org/fhir/StructureDefinition/string", 2, "text"); @@ -128,17 +128,17 @@ public class PETests { checkElement(gchildren.get(3), "text", "text", 1, 1, false, "http://hl7.org/fhir/StructureDefinition/string", 2, "text"); List ggchildren = gchildren.get(3).children("http://hl7.org/fhir/StructureDefinition/string"); - checkElement(ggchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension"); + checkElement(ggchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 2, "extension"); checkElement(ggchildren.get(1), "value", "value", 1, 1, false, null, 3, "value"); gchildren = children.get(7).children("http://hl7.org/fhir/StructureDefinition/Extension"); - checkElement(gchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension.where(((url = 'slice1') or (url = 'slice2') or (url = 'slice3')).not())"); + checkElement(gchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 2, "extension.where(((url = 'slice1') or (url = 'slice2') or (url = 'slice3')).not())"); checkElement(gchildren.get(1), "extension", "slice1", 0, 2, false, "http://hl7.org/fhir/StructureDefinition/Coding", 6, "extension('slice1').value"); checkElement(gchildren.get(2), "extension", "slice2", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/string", 2, "extension('slice2').value"); checkElement(gchildren.get(3), "extension", "slice3", 1, 1, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension('slice3')"); ggchildren = gchildren.get(3).children("http://hl7.org/fhir/StructureDefinition/Extension"); - checkElement(ggchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 3, "extension"); + checkElement(ggchildren.get(0), "extension", "extension", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/Extension", 2, "extension"); checkElement(ggchildren.get(1), "extension", "slice3a", 0, 2, false, "http://hl7.org/fhir/StructureDefinition/Coding", 6, "extension('slice3a').value"); checkElement(ggchildren.get(2), "extension", "slice3b", 0, Integer.MAX_VALUE, false, "http://hl7.org/fhir/StructureDefinition/string", 2, "extension('slice3b').value"); } @@ -177,7 +177,7 @@ public class PETests { Assertions.assertEquals("\\-", pe.documentation()); List children = pe.children("Patient"); - Assertions.assertEquals(28, children.size()); + Assertions.assertEquals(26, children.size()); pe = children.get(9); Assertions.assertEquals("birthsex", pe.name()); @@ -269,7 +269,7 @@ public class PETests { Assertions.assertEquals("May be used to represent additional information that is not part of the basic definition of the resource. To make the use of extensions safe and managable, there is a strict set of governance applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension.", pe.documentation()); iChildren = pe.children("http://hl7.org/fhir/StructureDefinition/Extension"); - Assertions.assertEquals(4, iChildren.size()); + Assertions.assertEquals(3, iChildren.size()); pe = iChildren.get(1); Assertions.assertEquals("extension", pe.name()); Assertions.assertEquals("extension", pe.schemaName()); @@ -283,7 +283,7 @@ public class PETests { iChildren = pe.children("http://hl7.org/fhir/StructureDefinition/Extension"); - Assertions.assertEquals(4, iChildren.size()); + Assertions.assertEquals(3, iChildren.size()); pe = iChildren.get(1); Assertions.assertEquals("extension", pe.name()); Assertions.assertEquals("extension", pe.schemaName()); From 93c7c3da68ffb6f562f87bb3e471c46f20fd23b4 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Wed, 23 Oct 2024 23:00:13 +1030 Subject: [PATCH 4/6] fix type evaluation of .item() in FHIRPath --- .../src/main/java/org/hl7/fhir/r5/fhirpath/FHIRPathEngine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/fhirpath/FHIRPathEngine.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/fhirpath/FHIRPathEngine.java index 7a63e0c59..126ee57cc 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/fhirpath/FHIRPathEngine.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/fhirpath/FHIRPathEngine.java @@ -3430,7 +3430,7 @@ public class FHIRPathEngine { case Item : { checkOrdered(focus, "item", exp); checkParamTypes(exp, exp.getFunction().toCode(), paramTypes, new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Integer)); - return focus; + return focus.toSingleton(); } case As : { checkParamTypes(exp, exp.getFunction().toCode(), paramTypes, new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String)); From 44b6888cb85117f7515644d06900ed283a355bbb Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Wed, 23 Oct 2024 23:00:29 +1030 Subject: [PATCH 5/6] Improve rendering of coded values --- .../hl7/fhir/r5/renderers/DataRenderer.java | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java index 37b3d0a88..f0caf0e85 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java @@ -1318,18 +1318,14 @@ public class DataRenderer extends Renderer implements CodeResolver { if (Utilities.noString(s)) s = lookupCode(c.primitiveValue("system"), c.primitiveValue("version"), c.primitiveValue("code")); - CodeSystem cs = context.getWorker().fetchCodeSystem(c.primitiveValue("system")); + String sn = displaySystem(c.primitiveValue("system")); + String link = getLinkForCode(c.primitiveValue("system"), c.primitiveValue("version"), c.primitiveValue("code")); + XhtmlNode xi = link != null ? x.ah(context.prefixLocalHref(link)) : x; + xi.tx(sn); + xi.tx(" "); - String sn = cs != null ? crPresent(cs) : displaySystem(c.primitiveValue("system")); - String link = getLinkForCode(c.primitiveValue("system"), c.primitiveValue("version"), c.primitiveValue("code")); - if (link != null) { - x.ah(context.prefixLocalHref(link)).tx(sn); - } else { - x.tx(sn); - } - - x.tx(" "); - x.tx(c.primitiveValue("code")); + xi.tx(c.primitiveValue("code")); + if (!Utilities.noString(s)) { x.tx(": "); x.tx(s); From 7c075ae3474c0069d0a9539fb977acfaf4fdc751 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Wed, 23 Oct 2024 23:00:48 +1030 Subject: [PATCH 6/6] Improve warning messages about collections in SQL ViewDefinitions --- .../org/hl7/fhir/r5/utils/sql/Validator.java | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/Validator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/Validator.java index 1d9eba82f..e311be44a 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/Validator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/Validator.java @@ -338,16 +338,20 @@ public class Validator { } if (isColl) { if (td.getCollectionStatus() == CollectionStatus.SINGLETON) { - hint(path, column, "collection is true, but the path statement(s) can only return single values for the column '"+columnName+"'"); + hint(path, column, "collection is true, but the path statement(s) ('"+expr+"') can only return single values for the column '"+columnName+"'"); + } + if (supportsArrays == TrueFalseOrUnknown.UNKNOWN) { + warning(path, expression, "The column '"+columnName+"' is defined as a collection, but collections are not supported in all execution contexts"); + } else if (supportsArrays == TrueFalseOrUnknown.FALSE) { + if (td.getCollectionStatus() == CollectionStatus.SINGLETON) { + warning(path, expression, "The column '"+columnName+"' is defined as a collection, but this is not allowed in the current execution context. Note that the path '"+expr+"' can only return a single value"); + } else { + warning(path, expression, "The column '"+columnName+"' is defined as a collection, but this is not allowed in the current execution context. Note that the path '"+expr+"' can return a collection of values"); + } } } else { - if (supportsArrays == TrueFalseOrUnknown.UNKNOWN) { - warning(path, expression, "The column '"+columnName+"' appears to be a collection based on it's path. Collections are not supported in all execution contexts"); - } else if (supportsArrays == TrueFalseOrUnknown.FALSE) { - warning(path, expression, "The column '"+columnName+"' appears to be a collection based on it's path, but this is not allowed in the current execution context"); - } if (td.getCollectionStatus() != CollectionStatus.SINGLETON) { - warning(path, column, "collection is not true, but the path statement(s) might return multiple values for the column '"+columnName+"' for some inputs"); + warning(path, column, "This column is not defined as a collection, but the path statement '"+expr+"' might return multiple values for the column '"+columnName+"' for some inputs"); } } Set types = new HashSet<>(); @@ -364,7 +368,7 @@ public class Validator { if (typeJ instanceof JsonString) { String type = typeJ.asString(); if (!td.hasType(type)) { - error(path+".type", typeJ, "The path expression does not return a value of the type '"+type+"' - found "+td.describe(), IssueType.VALUE); + error(path+".type", typeJ, "The path expression ('"+expr+"') does not return a value of the type '"+type+"' - found "+td.describe(), IssueType.VALUE); } else { types.clear(); types.add(simpleType(type)); @@ -381,9 +385,9 @@ public class Validator { boolean ok = false; if (!isSimpleType(type) && !"null".equals(type)) { if (supportsComplexTypes == TrueFalseOrUnknown.UNKNOWN) { - warning(path, expression, "Column is a complex type. This is not supported in some Runners"); + warning(path, expression, "Column from path '"+expr+"' is a complex type ('"+type+"'). This is not supported in some Runners"); } else if (supportsComplexTypes == TrueFalseOrUnknown.FALSE) { - error(path, expression, "Column is a complex type but this is not allowed in this context", IssueType.BUSINESSRULE); + error(path, expression, "Column from path '"+expr+"' is a complex type ('"+type+"') but this is not allowed in this context", IssueType.BUSINESSRULE); } else { ok = true; } @@ -411,6 +415,11 @@ public class Validator { case "integer": return ColumnKind.Integer; case "decimal": return ColumnKind.Decimal; case "string": return ColumnKind.String; + case "canonical": return ColumnKind.String; + case "url": return ColumnKind.String; + case "uri": return ColumnKind.String; + case "oid": return ColumnKind.String; + case "uuid": return ColumnKind.String; case "id": return ColumnKind.String; case "code": return ColumnKind.String; case "base64Binary": return ColumnKind.Binary; @@ -420,7 +429,7 @@ public class Validator { } private boolean isSimpleType(String type) { - return Utilities.existsInList(type, "dateTime", "boolean", "integer", "decimal", "string", "base64Binary", "id", "code", "date", "time"); + return Utilities.existsInList(type, "dateTime", "boolean", "integer", "decimal", "string", "base64Binary", "id", "code", "date", "time", "canonical"); } private String simpleType(String type) {