From 0140fa1ad1a24f9bdabf64f2ef4e091042574923 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Fri, 6 Oct 2023 05:59:39 +0300 Subject: [PATCH 01/12] fix merge issues --- .../org/hl7/fhir/r4/utils/CmdLineApp.java | 57 +------------------ 1 file changed, 2 insertions(+), 55 deletions(-) diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/CmdLineApp.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/CmdLineApp.java index f52a3349a..ef70a11ea 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/CmdLineApp.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/CmdLineApp.java @@ -10,33 +10,24 @@ import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.r4.context.SimpleWorkerContext; import org.hl7.fhir.r4.formats.IParser.OutputStyle; import org.hl7.fhir.r4.formats.JsonParser; -<<<<<<< HEAD import org.hl7.fhir.r4.formats.XmlParser; -======= ->>>>>>> master import org.hl7.fhir.r4.model.Base; import org.hl7.fhir.r4.model.BooleanType; import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent; import org.hl7.fhir.r4.model.CapabilityStatement; -<<<<<<< HEAD import org.hl7.fhir.r4.model.CodeSystem; -======= ->>>>>>> master import org.hl7.fhir.r4.model.CodeType; import org.hl7.fhir.r4.model.CodeableConcept; import org.hl7.fhir.r4.model.Coding; import org.hl7.fhir.r4.model.Condition; -<<<<<<< HEAD import org.hl7.fhir.r4.model.DateType; import org.hl7.fhir.r4.model.HumanName; import org.hl7.fhir.r4.model.Immunization; import org.hl7.fhir.r4.model.Parameters; import org.hl7.fhir.r4.model.Parameters.ParametersParameterComponent; -======= import org.hl7.fhir.r4.model.HumanName; import org.hl7.fhir.r4.model.Immunization; ->>>>>>> master import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Period; import org.hl7.fhir.r4.model.Procedure; @@ -79,11 +70,8 @@ public class CmdLineApp { finished = true; } else if (p.length == 1 && p[0].equals("?")) { genMenu(); -<<<<<<< HEAD } else if (p.length == 1 && p[0].equals("?tx")) { genMenuTx(); -======= ->>>>>>> master } else if (p.length >= 1 && p[0].equals("c")) { if (p.length == 1) { connectToServer("http://hapi.fhir.org/baseR4"); @@ -129,15 +117,10 @@ public class CmdLineApp { select("Patient", p[1]); } else if (p.length == 3 && p[0].equals("e")) { edit(p[1], p[2]); -<<<<<<< HEAD } else if (p.length > 3 && p[0].equals("tx")) { tx(p); - } else { - tx(p); -======= } else { System.out.println("Command unknown or not understood: "+cmd); ->>>>>>> master } } catch (Exception e) { System.out.println("Error executing command "+p[0]+": "+e.getMessage()); @@ -147,7 +130,6 @@ public class CmdLineApp { System.out.println("Finished!"); } -<<<<<<< HEAD private boolean tx(String[] p) throws IOException { if (p[1].equals("l")) { if (p.length == 4) { @@ -190,10 +172,6 @@ public class CmdLineApp { } private void getImmunizations() throws IOException { -======= - private void getImmunizations() { ->>>>>>> master - Bundle bnd = client.search("Immunization", "?patient="+currentId); System.out.println(""+bnd.getTotal()+" Immunizations found. Printing "+bnd.getEntry().size()); @@ -203,11 +181,8 @@ public class CmdLineApp { } } -<<<<<<< HEAD + private void getProcedures() throws IOException { -======= - private void getProcedures() { ->>>>>>> master Bundle bnd = client.search("Procedure", "?patient="+currentId); System.out.println(""+bnd.getTotal()+" Procedures found. Printing "+bnd.getEntry().size()); @@ -218,11 +193,8 @@ public class CmdLineApp { } } -<<<<<<< HEAD + private void getConditions() throws IOException { -======= - private void getConditions() { ->>>>>>> master Bundle bnd = client.search("Condition", "?patient="+currentId); System.out.println(""+bnd.getTotal()+" Conditions found. Printing "+bnd.getEntry().size()); @@ -257,10 +229,7 @@ public class CmdLineApp { case "boolean" : return new BooleanType(value); case "code" : return new CodeType(value); case "string" : return new StringType(value); -<<<<<<< HEAD case "date" : return new DateType(value); -======= ->>>>>>> master } throw new FHIRException("Unhandled type "+p.getTypeCode()); } @@ -278,11 +247,7 @@ public class CmdLineApp { System.out.println(new JsonParser().setOutputStyle(OutputStyle.PRETTY).composeString(currentResource)); } -<<<<<<< HEAD private void select(String type, String id) throws IOException { -======= - private void select(String type, String id) { ->>>>>>> master if (type.equals("Patient")) { currentResource = client.fetchResource(Patient.class, id); } else if (type.equals("Immunization")) { @@ -298,12 +263,8 @@ public class CmdLineApp { System.out.println("Resource = "+currentId+" "+summary(currentResource)); } -<<<<<<< HEAD private String summary(Resource r) throws IOException { // return new XmlParser().composeString(r); -======= - private String summary(Resource r) { ->>>>>>> master if (r instanceof Patient) { Patient pat = (Patient) r; return pat.getIdBase()+" "+pat.getGender()+" "+pat.getBirthDateElement().asStringValue()+" "+name(pat); @@ -366,11 +327,7 @@ public class CmdLineApp { return ""; } -<<<<<<< HEAD private void search(String[] p) throws IOException { -======= - private void search(String[] p) { ->>>>>>> master if (client == null) { throw new FHIRException("Not connected to to a server"); } @@ -378,11 +335,7 @@ public class CmdLineApp { if (p.length > 2) { search = search +"&gender="+p[2]; if (p.length > 3) { -<<<<<<< HEAD search = search +"&birthdate="+p[3]; -======= - search = search +"&dob="+p[3]; ->>>>>>> master } } Bundle bnd = client.search("Patient", search); @@ -418,7 +371,6 @@ public class CmdLineApp { private void connectToServer(String url) throws URISyntaxException { client = new FHIRToolingClient(url, "FHIR-Command-Line-App"); CapabilityStatement cs = client.getCapabilitiesStatementQuick(); -<<<<<<< HEAD System.out.println("Connected to "+url+": "+cs.getSoftware().getName()+", version "+cs.getFhirVersion().toCode()); } @@ -431,11 +383,6 @@ public class CmdLineApp { System.out.println(" x - exit"); } -======= - System.out.println("Connected to "+url+": "+cs.getSoftware().getName()+"."); - } - ->>>>>>> master private void genMenu() { System.out.println("Simple Client. Commands you can run:"); System.out.println(" c {url} - connect to a server"); From f860af857db085e06a1d2ece22cd3bd12d9bd5e1 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Mon, 9 Oct 2023 17:41:26 +1100 Subject: [PATCH 02/12] Fix conversion issue associated with ConceptMap.element.target.equivalence in versions previous to R5 (use proper extension URL, and move extension so it can be a modifier. And fix for modifierExtension handling) --- .../convertors/VersionConvertorConstants.java | 2 +- .../resources10_50/ConceptMap10_50.java | 18 +- .../resources14_50/ConceptMap14_50.java | 18 +- .../resources30_50/ConceptMap30_50.java | 18 +- .../resources40_50/ConceptMap40_50.java | 18 +- .../resources43_50/ConceptMap43_50.java | 18 +- .../fhir/dstu3/utils/ToolingExtensions.java | 25 +++ .../hl7/fhir/r4/model/BackboneElement.java | 137 +++++++++++- .../org/hl7/fhir/r4/model/BackboneType.java | 76 +++++-- .../java/org/hl7/fhir/r4/model/Element.java | 75 ++++++- .../hl7/fhir/r4/utils/ToolingExtensions.java | 25 +++ .../hl7/fhir/r4b/model/BackboneElement.java | 53 +++++ .../org/hl7/fhir/r4b/model/BackboneType.java | 54 +++++ .../java/org/hl7/fhir/r4b/model/Element.java | 150 +++++++++---- .../hl7/fhir/r4b/utils/ToolingExtensions.java | 201 ++++++++++-------- .../hl7/fhir/r5/model/BackboneElement.java | 42 ++++ .../org/hl7/fhir/r5/model/BackboneType.java | 54 +++++ .../fhir/r5/renderers/ConceptMapRenderer.java | 4 +- 18 files changed, 774 insertions(+), 214 deletions(-) diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertorConstants.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertorConstants.java index 74dd8352e..8df0e5ca0 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertorConstants.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/VersionConvertorConstants.java @@ -41,7 +41,7 @@ public class VersionConvertorConstants { public final static String MODIFIER_REASON_LEGACY = "No Modifier Reason provideed in previous versions of FHIR"; public final static String PROFILE_EXTENSION = "http://hl7.org/fhir/4.0/StructureDefinition/extension-ElementDefinition.type.profile"; public final static String IG_CONFORMANCE_MESSAGE_EVENT = "http://hl7.org/fhir/1.0/StructureDefinition/extension-Conformance.messaging.event"; - public static final String EXT_OLD_CONCEPTMAP_EQUIVALENCE = "http://hl7.org/fhir/1.0/StructureDefinition/extension-ConceptMap.element.target.equivalence"; + public static final String EXT_OLD_CONCEPTMAP_EQUIVALENCE = "http://hl7.org/fhir/1.0/StructureDefinition/extension-ConceptMap.group.element.target.equivalence"; public static final String EXT_ACTUAL_RESOURCE_NAME = "http://hl7.org/fhir/tools/StructureDefinition/original-resource-name"; public static final String EXT_QUESTIONNAIRE_ITEM_TYPE_ORIGINAL = QuestionnaireRenderer.EXT_QUESTIONNAIRE_ITEM_TYPE_ORIGINAL; public static final String EXT_NAMINGSYSTEM_TITLE = "http://hl7.org/fhir/5.0/StructureDefinition/extension-NamingSystem.title"; diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv10_50/resources10_50/ConceptMap10_50.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv10_50/resources10_50/ConceptMap10_50.java index ff1c017d1..6ba73f1e1 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv10_50/resources10_50/ConceptMap10_50.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv10_50/resources10_50/ConceptMap10_50.java @@ -148,13 +148,13 @@ public class ConceptMap10_50 { return tgt; } - public static org.hl7.fhir.dstu2.model.Enumeration convertConceptMapEquivalence(Enumeration src) throws FHIRException { + public static org.hl7.fhir.dstu2.model.Enumeration convertConceptMapEquivalence(Enumeration src, org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent ccm) throws FHIRException { if (src == null || src.isEmpty()) return null; org.hl7.fhir.dstu2.model.Enumeration tgt = new org.hl7.fhir.dstu2.model.Enumeration(new org.hl7.fhir.dstu2.model.Enumerations.ConceptMapEquivalenceEnumFactory()); - ConversionContext10_50.INSTANCE.getVersionConvertor_10_50().copyElement(src, tgt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE); - if (src.hasExtension(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)) { - tgt.setValueAsString(src.getExtensionString(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)); + ConversionContext10_50.INSTANCE.getVersionConvertor_10_50().copyElement(src, tgt); + if (ccm.hasExtension(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)) { + tgt.setValueAsString(ccm.getExtensionString(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)); } else { switch (src.getValue()) { case EQUIVALENT: @@ -177,12 +177,12 @@ public class ConceptMap10_50 { return tgt; } - public static Enumeration convertConceptMapRelationship(org.hl7.fhir.dstu2.model.Enumeration src) throws FHIRException { + public static Enumeration convertConceptMapRelationship(org.hl7.fhir.dstu2.model.Enumeration src, org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent tgtCtxt) throws FHIRException { if (src == null || src.isEmpty()) return null; Enumeration tgt = new Enumeration(new Enumerations.ConceptMapRelationshipEnumFactory()); ConversionContext10_50.INSTANCE.getVersionConvertor_10_50().copyElement(src, tgt); - ToolingExtensions.setCodeExtension(tgt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE, src.getValueAsString()); + ToolingExtensions.setCodeExtensionMod(tgtCtxt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE, src.getValueAsString()); switch (src.getValue()) { case EQUIVALENT: tgt.setValue(org.hl7.fhir.r5.model.Enumerations.ConceptMapRelationship.EQUIVALENT); @@ -283,12 +283,12 @@ public class ConceptMap10_50 { if (src == null || src.isEmpty()) return null; org.hl7.fhir.dstu2.model.ConceptMap.TargetElementComponent tgt = new org.hl7.fhir.dstu2.model.ConceptMap.TargetElementComponent(); - ConversionContext10_50.INSTANCE.getVersionConvertor_10_50().copyBackboneElement(src,tgt); + ConversionContext10_50.INSTANCE.getVersionConvertor_10_50().copyBackboneElement(src,tgt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE); tgt.setCodeSystem(g.getTarget()); if (src.hasCodeElement()) tgt.setCodeElement(Code10_50.convertCode(src.getCodeElement())); if (src.hasRelationship()) - tgt.setEquivalenceElement(convertConceptMapEquivalence(src.getRelationshipElement())); + tgt.setEquivalenceElement(convertConceptMapEquivalence(src.getRelationshipElement(), src)); if (src.hasCommentElement()) tgt.setCommentsElement(String10_50.convertString(src.getCommentElement())); for (org.hl7.fhir.r5.model.ConceptMap.OtherElementComponent t : src.getDependsOn()) @@ -306,7 +306,7 @@ public class ConceptMap10_50 { if (src.hasCodeElement()) tgt.setCodeElement(Code10_50.convertCode(src.getCodeElement())); if (src.hasEquivalence()) - tgt.setRelationshipElement(convertConceptMapRelationship(src.getEquivalenceElement())); + tgt.setRelationshipElement(convertConceptMapRelationship(src.getEquivalenceElement(), tgt)); if (src.hasCommentsElement()) tgt.setCommentElement(String10_50.convertString(src.getCommentsElement())); for (org.hl7.fhir.dstu2.model.ConceptMap.OtherElementComponent t : src.getDependsOn()) diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv14_50/resources14_50/ConceptMap14_50.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv14_50/resources14_50/ConceptMap14_50.java index a80148454..6b877363c 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv14_50/resources14_50/ConceptMap14_50.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv14_50/resources14_50/ConceptMap14_50.java @@ -151,13 +151,13 @@ public class ConceptMap14_50 { return tgt; } - public static org.hl7.fhir.dstu2016may.model.Enumeration convertConceptMapEquivalence(Enumeration src) throws FHIRException { + public static org.hl7.fhir.dstu2016may.model.Enumeration convertConceptMapEquivalence(Enumeration src, org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent ccm) throws FHIRException { if (src == null || src.isEmpty()) return null; org.hl7.fhir.dstu2016may.model.Enumeration tgt = new org.hl7.fhir.dstu2016may.model.Enumeration(new org.hl7.fhir.dstu2016may.model.Enumerations.ConceptMapEquivalenceEnumFactory()); - ConversionContext14_50.INSTANCE.getVersionConvertor_14_50().copyElement(src, tgt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE); - if (src.hasExtension(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)) { - tgt.setValueAsString(src.getExtensionString(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)); + ConversionContext14_50.INSTANCE.getVersionConvertor_14_50().copyElement(src, tgt); + if (ccm.hasExtension(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)) { + tgt.setValueAsString(ccm.getExtensionString(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)); } else { switch (src.getValue()) { case EQUIVALENT: @@ -180,12 +180,12 @@ public class ConceptMap14_50 { return tgt; } - public static Enumeration convertConceptMapRelationship(org.hl7.fhir.dstu2016may.model.Enumeration src) throws FHIRException { + public static Enumeration convertConceptMapRelationship(org.hl7.fhir.dstu2016may.model.Enumeration src, org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent tgtCtxt) throws FHIRException { if (src == null || src.isEmpty()) return null; Enumeration tgt = new Enumeration(new Enumerations.ConceptMapRelationshipEnumFactory()); ConversionContext14_50.INSTANCE.getVersionConvertor_14_50().copyElement(src, tgt); - ToolingExtensions.setCodeExtension(tgt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE, src.getValueAsString()); + ToolingExtensions.setCodeExtensionMod(tgtCtxt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE, src.getValueAsString()); switch (src.getValue()) { case EQUIVALENT: tgt.setValue(org.hl7.fhir.r5.model.Enumerations.ConceptMapRelationship.EQUIVALENT); @@ -293,13 +293,13 @@ public class ConceptMap14_50 { if (src == null || src.isEmpty()) return null; org.hl7.fhir.dstu2016may.model.ConceptMap.TargetElementComponent tgt = new org.hl7.fhir.dstu2016may.model.ConceptMap.TargetElementComponent(); - ConversionContext14_50.INSTANCE.getVersionConvertor_14_50().copyBackboneElement(src,tgt); + ConversionContext14_50.INSTANCE.getVersionConvertor_14_50().copyBackboneElement(src,tgt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE); if (g.hasTarget()) tgt.setSystem(g.getTarget()); if (src.hasCode()) tgt.setCodeElement(Code14_50.convertCode(src.getCodeElement())); if (src.hasRelationship()) - tgt.setEquivalenceElement(convertConceptMapEquivalence(src.getRelationshipElement())); + tgt.setEquivalenceElement(convertConceptMapEquivalence(src.getRelationshipElement(), src)); if (src.hasComment()) tgt.setCommentsElement(String14_50.convertString(src.getCommentElement())); for (org.hl7.fhir.r5.model.ConceptMap.OtherElementComponent t : src.getDependsOn()) @@ -317,7 +317,7 @@ public class ConceptMap14_50 { if (src.hasCode()) tgt.setCodeElement(Code14_50.convertCode(src.getCodeElement())); if (src.hasEquivalence()) - tgt.setRelationshipElement(convertConceptMapRelationship(src.getEquivalenceElement())); + tgt.setRelationshipElement(convertConceptMapRelationship(src.getEquivalenceElement(), tgt)); if (src.hasComments()) tgt.setCommentElement(String14_50.convertString(src.getCommentsElement())); for (org.hl7.fhir.dstu2016may.model.ConceptMap.OtherElementComponent t : src.getDependsOn()) diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv30_50/resources30_50/ConceptMap30_50.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv30_50/resources30_50/ConceptMap30_50.java index 626c0a948..f1d14a317 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv30_50/resources30_50/ConceptMap30_50.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv30_50/resources30_50/ConceptMap30_50.java @@ -247,13 +247,13 @@ public class ConceptMap30_50 { return tgt; } - public static org.hl7.fhir.dstu3.model.Enumeration convertConceptMapEquivalence(Enumeration src) throws FHIRException { + public static org.hl7.fhir.dstu3.model.Enumeration convertConceptMapEquivalence(Enumeration src, org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent ccm) throws FHIRException { if (src == null || src.isEmpty()) return null; org.hl7.fhir.dstu3.model.Enumeration tgt = new org.hl7.fhir.dstu3.model.Enumeration(new org.hl7.fhir.dstu3.model.Enumerations.ConceptMapEquivalenceEnumFactory()); - ConversionContext30_50.INSTANCE.getVersionConvertor_30_50().copyElement(src, tgt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE); - if (src.hasExtension(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)) { - tgt.setValueAsString(src.getExtensionString(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)); + ConversionContext30_50.INSTANCE.getVersionConvertor_30_50().copyElement(src, tgt); + if (ccm.hasExtension(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)) { + tgt.setValueAsString(ccm.getExtensionString(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)); } else { switch (src.getValue()) { case EQUIVALENT: @@ -279,12 +279,12 @@ public class ConceptMap30_50 { return tgt; } - public static Enumeration convertConceptMapRelationship(org.hl7.fhir.dstu3.model.Enumeration src) throws FHIRException { + public static Enumeration convertConceptMapRelationship(org.hl7.fhir.dstu3.model.Enumeration src, org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent tgtCtxt) throws FHIRException { if (src == null || src.isEmpty()) return null; Enumeration tgt = new Enumeration(new Enumerations.ConceptMapRelationshipEnumFactory()); ConversionContext30_50.INSTANCE.getVersionConvertor_30_50().copyElement(src, tgt); - ToolingExtensions.setCodeExtension(tgt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE, src.getValueAsString()); + ToolingExtensions.setCodeExtensionMod(tgtCtxt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE, src.getValueAsString()); switch (src.getValue()) { case EQUIVALENT: tgt.setValue(org.hl7.fhir.r5.model.Enumerations.ConceptMapRelationship.EQUIVALENT); @@ -402,7 +402,7 @@ public class ConceptMap30_50 { if (src.hasDisplay()) tgt.setDisplayElement(String30_50.convertString(src.getDisplayElement())); if (src.hasEquivalence()) - tgt.setRelationshipElement(convertConceptMapRelationship(src.getEquivalenceElement())); + tgt.setRelationshipElement(convertConceptMapRelationship(src.getEquivalenceElement(), tgt)); if (src.hasComment()) tgt.setCommentElement(String30_50.convertString(src.getCommentElement())); for (org.hl7.fhir.dstu3.model.ConceptMap.OtherElementComponent t : src.getDependsOn()) @@ -416,13 +416,13 @@ public class ConceptMap30_50 { if (src == null) return null; org.hl7.fhir.dstu3.model.ConceptMap.TargetElementComponent tgt = new org.hl7.fhir.dstu3.model.ConceptMap.TargetElementComponent(); - ConversionContext30_50.INSTANCE.getVersionConvertor_30_50().copyBackboneElement(src,tgt); + ConversionContext30_50.INSTANCE.getVersionConvertor_30_50().copyBackboneElement(src,tgt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE); if (src.hasCode()) tgt.setCodeElement(Code30_50.convertCode(src.getCodeElement())); if (src.hasDisplay()) tgt.setDisplayElement(String30_50.convertString(src.getDisplayElement())); if (src.hasRelationship()) - tgt.setEquivalenceElement(convertConceptMapEquivalence(src.getRelationshipElement())); + tgt.setEquivalenceElement(convertConceptMapEquivalence(src.getRelationshipElement(), src)); if (src.hasComment()) tgt.setCommentElement(String30_50.convertString(src.getCommentElement())); for (org.hl7.fhir.r5.model.ConceptMap.OtherElementComponent t : src.getDependsOn()) diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/resources40_50/ConceptMap40_50.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/resources40_50/ConceptMap40_50.java index cbfa9afd3..9b2ffc4cd 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/resources40_50/ConceptMap40_50.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv40_50/resources40_50/ConceptMap40_50.java @@ -242,7 +242,7 @@ public class ConceptMap40_50 { if (src.hasDisplay()) tgt.setDisplayElement(String40_50.convertString(src.getDisplayElement())); if (src.hasEquivalence()) - tgt.setRelationshipElement(convertConceptMapRelationship(src.getEquivalenceElement())); + tgt.setRelationshipElement(convertConceptMapRelationship(src.getEquivalenceElement(), tgt)); if (src.hasComment()) tgt.setCommentElement(String40_50.convertString(src.getCommentElement())); for (org.hl7.fhir.r4.model.ConceptMap.OtherElementComponent t : src.getDependsOn()) @@ -256,13 +256,13 @@ public class ConceptMap40_50 { if (src == null) return null; org.hl7.fhir.r4.model.ConceptMap.TargetElementComponent tgt = new org.hl7.fhir.r4.model.ConceptMap.TargetElementComponent(); - ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().copyBackboneElement(src, tgt); + ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().copyBackboneElement(src, tgt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE); if (src.hasCode()) tgt.setCodeElement(Code40_50.convertCode(src.getCodeElement())); if (src.hasDisplay()) tgt.setDisplayElement(String40_50.convertString(src.getDisplayElement())); if (src.hasRelationship()) - tgt.setEquivalenceElement(convertConceptMapEquivalence(src.getRelationshipElement())); + tgt.setEquivalenceElement(convertConceptMapEquivalence(src.getRelationshipElement(), src)); else tgt.setEquivalence(ConceptMapEquivalence.RELATEDTO); if (src.hasComment()) @@ -274,13 +274,13 @@ public class ConceptMap40_50 { return tgt; } - public static org.hl7.fhir.r4.model.Enumeration convertConceptMapEquivalence(Enumeration src) throws FHIRException { + public static org.hl7.fhir.r4.model.Enumeration convertConceptMapEquivalence(Enumeration src, org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent ccm) throws FHIRException { if (src == null || src.isEmpty()) return null; org.hl7.fhir.r4.model.Enumeration tgt = new org.hl7.fhir.r4.model.Enumeration(new org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalenceEnumFactory()); - ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().copyElement(src, tgt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE); - if (src.hasExtension(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)) { - tgt.setValueAsString(src.getExtensionString(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)); + ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().copyElement(src, tgt); + if (ccm.hasExtension(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)) { + tgt.setValueAsString(ccm.getExtensionString(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)); } else { switch (src.getValue()) { case RELATEDTO: @@ -306,12 +306,12 @@ public class ConceptMap40_50 { return tgt; } - public static Enumeration convertConceptMapRelationship(org.hl7.fhir.r4.model.Enumeration src) throws FHIRException { + public static Enumeration convertConceptMapRelationship(org.hl7.fhir.r4.model.Enumeration src, org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent tgtCtxt) throws FHIRException { if (src == null || src.isEmpty()) return null; Enumeration tgt = new Enumeration(new Enumerations.ConceptMapRelationshipEnumFactory()); ConversionContext40_50.INSTANCE.getVersionConvertor_40_50().copyElement(src, tgt); - ToolingExtensions.setCodeExtension(tgt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE, src.getValueAsString()); + ToolingExtensions.setCodeExtensionMod(tgtCtxt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE, src.getValueAsString()); switch (src.getValue()) { case EQUIVALENT: tgt.setValue(org.hl7.fhir.r5.model.Enumerations.ConceptMapRelationship.EQUIVALENT); diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv43_50/resources43_50/ConceptMap43_50.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv43_50/resources43_50/ConceptMap43_50.java index aca58d330..86e6e2596 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv43_50/resources43_50/ConceptMap43_50.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv43_50/resources43_50/ConceptMap43_50.java @@ -241,7 +241,7 @@ public class ConceptMap43_50 { if (src.hasDisplay()) tgt.setDisplayElement(String43_50.convertString(src.getDisplayElement())); if (src.hasEquivalence()) - tgt.setRelationshipElement(convertConceptMapRelationship(src.getEquivalenceElement())); + tgt.setRelationshipElement(convertConceptMapRelationship(src.getEquivalenceElement(), tgt)); if (src.hasComment()) tgt.setCommentElement(String43_50.convertString(src.getCommentElement())); for (org.hl7.fhir.r4b.model.ConceptMap.OtherElementComponent t : src.getDependsOn()) @@ -255,13 +255,13 @@ public class ConceptMap43_50 { if (src == null) return null; org.hl7.fhir.r4b.model.ConceptMap.TargetElementComponent tgt = new org.hl7.fhir.r4b.model.ConceptMap.TargetElementComponent(); - ConversionContext43_50.INSTANCE.getVersionConvertor_43_50().copyBackboneElement(src, tgt); + ConversionContext43_50.INSTANCE.getVersionConvertor_43_50().copyBackboneElement(src, tgt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE); if (src.hasCode()) tgt.setCodeElement(Code43_50.convertCode(src.getCodeElement())); if (src.hasDisplay()) tgt.setDisplayElement(String43_50.convertString(src.getDisplayElement())); if (src.hasRelationship()) - tgt.setEquivalenceElement(convertConceptMapEquivalence(src.getRelationshipElement())); + tgt.setEquivalenceElement(convertConceptMapEquivalence(src.getRelationshipElement(), src)); else tgt.setEquivalence(org.hl7.fhir.r4b.model.ConceptMap.ConceptMapEquivalence.RELATEDTO); if (src.hasComment()) @@ -273,13 +273,13 @@ public class ConceptMap43_50 { return tgt; } - public static org.hl7.fhir.r4b.model.Enumeration convertConceptMapEquivalence(Enumeration src) throws FHIRException { + public static org.hl7.fhir.r4b.model.Enumeration convertConceptMapEquivalence(Enumeration src, org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent ccm) throws FHIRException { if (src == null || src.isEmpty()) return null; org.hl7.fhir.r4b.model.Enumeration tgt = new org.hl7.fhir.r4b.model.Enumeration(new org.hl7.fhir.r4b.model.ConceptMap.ConceptMapEquivalenceEnumFactory()); - ConversionContext43_50.INSTANCE.getVersionConvertor_43_50().copyElement(src, tgt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE); - if (src.hasExtension(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)) { - tgt.setValueAsString(src.getExtensionString(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)); + ConversionContext43_50.INSTANCE.getVersionConvertor_43_50().copyElement(src, tgt); + if (ccm.hasExtension(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)) { + tgt.setValueAsString(ccm.getExtensionString(VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE)); } else { switch (src.getValue()) { case RELATEDTO: @@ -305,12 +305,12 @@ public class ConceptMap43_50 { return tgt; } - public static Enumeration convertConceptMapRelationship(org.hl7.fhir.r4b.model.Enumeration src) throws FHIRException { + public static Enumeration convertConceptMapRelationship(org.hl7.fhir.r4b.model.Enumeration src, org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent tgtCtxt) throws FHIRException { if (src == null || src.isEmpty()) return null; Enumeration tgt = new Enumeration(new Enumerations.ConceptMapRelationshipEnumFactory()); ConversionContext43_50.INSTANCE.getVersionConvertor_43_50().copyElement(src, tgt); - ToolingExtensions.setCodeExtension(tgt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE, src.getValueAsString()); + ToolingExtensions.setCodeExtensionMod(tgtCtxt, VersionConvertorConstants.EXT_OLD_CONCEPTMAP_EQUIVALENCE, src.getValueAsString()); switch (src.getValue()) { case EQUIVALENT: tgt.setValue(org.hl7.fhir.r5.model.Enumerations.ConceptMapRelationship.EQUIVALENT); diff --git a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/ToolingExtensions.java b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/ToolingExtensions.java index 9a1dcb969..b0cda3fdc 100644 --- a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/ToolingExtensions.java +++ b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/ToolingExtensions.java @@ -88,6 +88,8 @@ import org.hl7.fhir.dstu3.model.Type; import org.hl7.fhir.dstu3.model.UriType; import org.hl7.fhir.dstu3.model.ValueSet.ConceptReferenceComponent; import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent; +import org.hl7.fhir.dstu3.model.BackboneElement; +import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.validation.ValidationMessage.Source; @@ -433,6 +435,29 @@ public class ToolingExtensions { else resource.getExtension().add(new Extension(new UriType(uri)).setValue(new IntegerType(value))); } + + + public static void setCodeExtensionMod(DomainResource resource, String uri, String value) { + if (Utilities.noString(value)) + return; + + Extension ext = getExtension(resource, uri); + if (ext != null) + ext.setValue(new CodeType(value)); + else + resource.getModifierExtension().add(new Extension(uri).setValue(new CodeType(value))); + } + + public static void setCodeExtensionMod(BackboneElement resource, String uri, String value) { + if (Utilities.noString(value)) + return; + + Extension ext = getExtension(resource, uri); + if (ext != null) + ext.setValue(new CodeType(value)); + else + resource.getModifierExtension().add(new Extension(uri).setValue(new CodeType(value))); + } // public static String getOID(CodeSystem define) { // return readStringExtension(define, EXT_OID); diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/BackboneElement.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/BackboneElement.java index 03cfa787e..48ab63124 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/BackboneElement.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/BackboneElement.java @@ -3,19 +3,19 @@ package org.hl7.fhir.r4.model; /* Copyright (c) 2011+, HL7, Inc. All rights reserved. - + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of HL7 nor the names of its contributors may be used to + * Neither the name of HL7 nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. @@ -26,8 +26,8 @@ package org.hl7.fhir.r4.model; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ + + */ // Generated on Tue, May 12, 2020 07:26+1000 for FHIR v4.0.1 import java.util.ArrayList; @@ -35,6 +35,7 @@ import java.util.List; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.instance.model.api.IBaseBackboneElement; +import org.hl7.fhir.utilities.Utilities; import ca.uhn.fhir.model.api.annotation.Child; import ca.uhn.fhir.model.api.annotation.DatatypeDef; @@ -203,7 +204,7 @@ public abstract class BackboneElement extends Element implements IBaseBackboneEl this.getModifierExtension().remove(castToExtension(value)); } else super.removeChild(name, value); - + } @Override @@ -277,7 +278,7 @@ public abstract class BackboneElement extends Element implements IBaseBackboneEl return super.isEmpty() && ca.uhn.fhir.util.ElementUtil.isEmpty(modifierExtension); } -// added from java-adornments.txt: + // added from java-adornments.txt: public void checkNoModifiers(String noun, String verb) throws FHIRException { if (hasModifierExtension()) { @@ -286,6 +287,120 @@ public abstract class BackboneElement extends Element implements IBaseBackboneEl } -// end addition + public void addModifierExtension(String url, Type value) { + if (isDisallowExtensions()) + throw new Error("Extensions are not allowed in this context"); + Extension ex = new Extension(); + ex.setUrl(url); + ex.setValue(value); + getModifierExtension().add(ex); + } + + + @Override + public Extension getExtensionByUrl(String theUrl) { + org.apache.commons.lang3.Validate.notBlank(theUrl, "theUrl must not be blank or null"); + ArrayList retVal = new ArrayList(); + Extension res = super.getExtensionByUrl(theUrl); + if (res != null) { + retVal.add(res); + } + for (Extension next : getModifierExtension()) { + if (theUrl.equals(next.getUrl())) { + retVal.add(next); + } + } + if (retVal.size() == 0) + return null; + else { + org.apache.commons.lang3.Validate.isTrue(retVal.size() == 1, "Url "+theUrl+" must have only one match"); + return retVal.get(0); + } + } + + @Override + public void removeExtension(String theUrl) { + for (int i = getModifierExtension().size()-1; i >= 0; i--) { + if (theUrl.equals(getExtension().get(i).getUrl())) + getExtension().remove(i); + } + super.removeExtension(theUrl); + } + + + /** + * Returns an unmodifiable list containing all extensions on this element which + * match the given URL. + * + * @param theUrl The URL. Must not be blank or null. + * @return an unmodifiable list containing all extensions on this element which + * match the given URL + */ + @Override + public List getExtensionsByUrl(String theUrl) { + org.apache.commons.lang3.Validate.notBlank(theUrl, "theUrl must not be blank or null"); + ArrayList retVal = new ArrayList(); + retVal.addAll(super.getExtensionsByUrl(theUrl)); + for (Extension next : getModifierExtension()) { + if (theUrl.equals(next.getUrl())) { + retVal.add(next); + } + } + return java.util.Collections.unmodifiableList(retVal); + } + + public void copyExtensions(org.hl7.fhir.r4.model.BackboneElement src, String... urls) { + super.copyExtensions(src,urls); + for (Extension e : src.getModifierExtension()) { + if (Utilities.existsInList(e.getUrl(), urls)) { + addModifierExtension(e.copy()); + } + } + } + + public List getExtensionsByUrl(String... theUrls) { + + ArrayList retVal = new ArrayList<>(); + for (Extension next : getModifierExtension()) { + if (Utilities.existsInList(next.getUrl(), theUrls)) { + retVal.add(next); + } + } + List sv = super.getExtensionsByUrl(theUrls); + sv.addAll(retVal); + return sv; + } + + + public boolean hasExtension(String... theUrls) { + for (Extension next : getModifierExtension()) { + if (Utilities.existsInList(next.getUrl(), theUrls)) { + return true; + } + } + return super.hasExtension(theUrls); + } + + + public boolean hasExtension(String theUrl) { + for (Extension ext : getModifierExtension()) { + if (theUrl.equals(ext.getUrl())) { + return true; + } + } + + return super.hasExtension(theUrl); + } + + + public void copyNewExtensions(org.hl7.fhir.r4.model.BackboneElement src, String... urls) { + for (Extension e : src.getModifierExtension()) { + if (Utilities.existsInList(e.getUrl(), urls) && !!hasExtension(e.getUrl())) { + addExtension(e.copy()); + } + } + super.copyNewExtensions(src, urls); + } + // end addition } \ No newline at end of file diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/BackboneType.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/BackboneType.java index 6fdcb1526..1b329308e 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/BackboneType.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/BackboneType.java @@ -3,19 +3,19 @@ package org.hl7.fhir.r4.model; /* Copyright (c) 2011+, HL7, Inc. All rights reserved. - + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of HL7 nor the names of its contributors may be used to + * Neither the name of HL7 nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. @@ -26,8 +26,8 @@ package org.hl7.fhir.r4.model; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ + + */ // Generated on Mon, Mar 5, 2018 18:26+1100 for FHIR v3.2.0 import java.util.ArrayList; @@ -35,6 +35,7 @@ import java.util.List; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.instance.model.api.IBaseBackboneElement; +import org.hl7.fhir.utilities.Utilities; import ca.uhn.fhir.model.api.annotation.Child; import ca.uhn.fhir.model.api.annotation.DatatypeDef; @@ -193,7 +194,7 @@ public abstract class BackboneType extends Type implements IBaseBackboneElement this.getModifierExtension().remove(castToExtension(value)); } else super.removeChild(name, value); - + } @Override @@ -267,15 +268,66 @@ public abstract class BackboneType extends Type implements IBaseBackboneElement return super.isEmpty() && ca.uhn.fhir.util.ElementUtil.isEmpty(modifierExtension); } -// added from java-adornments.txt: + // added from java-adornments.txt: public void checkNoModifiers(String noun, String verb) throws FHIRException { if (hasModifierExtension()) { throw new FHIRException("Found unknown Modifier Exceptions on " + noun + " doing " + verb); } - } -// end addition + public void copyExtensions(org.hl7.fhir.r4.model.BackboneElement src, String... urls) { + super.copyExtensions(src,urls); + for (Extension e : src.getModifierExtension()) { + if (Utilities.existsInList(e.getUrl(), urls)) { + addModifierExtension(e.copy()); + } + } + } + + public List getExtensionsByUrl(String... theUrls) { + + ArrayList retVal = new ArrayList<>(); + for (Extension next : getModifierExtension()) { + if (Utilities.existsInList(next.getUrl(), theUrls)) { + retVal.add(next); + } + } + List sv = super.getExtensionsByUrl(theUrls); + sv.addAll(retVal); + return sv; + } + + + public boolean hasExtension(String... theUrls) { + for (Extension next : getModifierExtension()) { + if (Utilities.existsInList(next.getUrl(), theUrls)) { + return true; + } + } + return super.hasExtension(theUrls); + } + + + public boolean hasExtension(String theUrl) { + for (Extension ext : getModifierExtension()) { + if (theUrl.equals(ext.getUrl())) { + return true; + } + } + + return super.hasExtension(theUrl); + } + + + public void copyNewExtensions(org.hl7.fhir.r4.model.BackboneElement src, String... urls) { + for (Extension e : src.getModifierExtension()) { + if (Utilities.existsInList(e.getUrl(), urls) && !!hasExtension(e.getUrl())) { + addExtension(e.copy()); + } + } + super.copyNewExtensions(src, urls); + } + // end addition } \ No newline at end of file diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/Element.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/Element.java index c89bfcd3c..e0646c9c3 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/Element.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/Element.java @@ -3,19 +3,19 @@ package org.hl7.fhir.r4.model; /* Copyright (c) 2011+, HL7, Inc. All rights reserved. - + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of HL7 nor the names of its contributors may be used to + * Neither the name of HL7 nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. @@ -26,8 +26,8 @@ package org.hl7.fhir.r4.model; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ + + */ // Generated on Tue, May 12, 2020 07:26+1000 for FHIR v4.0.1 import java.util.ArrayList; @@ -36,6 +36,7 @@ import java.util.List; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.instance.model.api.IBaseElement; import org.hl7.fhir.instance.model.api.IBaseHasExtensions; +import org.hl7.fhir.utilities.StandardsStatus; import org.hl7.fhir.utilities.Utilities; import ca.uhn.fhir.model.api.annotation.Child; @@ -303,7 +304,7 @@ public abstract class Element extends Base implements IBaseHasExtensions, IBaseE this.getExtension().remove(castToExtension(value)); } else super.removeChild(name, value); - + } @Override @@ -393,7 +394,7 @@ public abstract class Element extends Base implements IBaseHasExtensions, IBaseE setId(value); } -// added from java-adornments.txt: + // added from java-adornments.txt: public void addExtension(String url, Type value) { if (disallowExtensions) throw new Error("Extensions are not allowed in this context"); @@ -446,6 +447,58 @@ public abstract class Element extends Base implements IBaseHasExtensions, IBaseE return this; } -// end addition + + public List getExtensionsByUrl(String... theUrls) { + + ArrayList retVal = new ArrayList<>(); + for (Extension next : getExtension()) { + if (Utilities.existsInList(next.getUrl(), theUrls)) { + retVal.add(next); + } + } + return java.util.Collections.unmodifiableList(retVal); + } + + + public boolean hasExtension(String... theUrls) { + for (Extension next : getExtension()) { + if (Utilities.existsInList(next.getUrl(), theUrls)) { + return true; + } + } + return false; + } + + + + + public boolean hasExtension(Extension ext) { + if (hasExtension()) { + for (Extension t : getExtension()) { + if (Base.compareDeep(t, ext, false)) { + return true; + } + } + } + return false; + } + + public void copyExtensions(org.hl7.fhir.r4.model.Element src, String... urls) { + for (Extension e : src.getExtension()) { + if (Utilities.existsInList(e.getUrl(), urls)) { + addExtension(e.copy()); + } + } + } + + public void copyNewExtensions(org.hl7.fhir.r4.model.Element src, String... urls) { + for (Extension e : src.getExtension()) { + if (Utilities.existsInList(e.getUrl(), urls) && !!hasExtension(e.getUrl())) { + addExtension(e.copy()); + } + } + } + + // end addition } \ No newline at end of file diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/ToolingExtensions.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/ToolingExtensions.java index 913d3003d..73238d879 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/ToolingExtensions.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/ToolingExtensions.java @@ -92,6 +92,7 @@ import org.hl7.fhir.r4.model.UriType; import org.hl7.fhir.r4.model.UrlType; import org.hl7.fhir.r4.model.ValueSet.ConceptReferenceComponent; import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent; +import org.hl7.fhir.r4.model.BackboneElement; import org.hl7.fhir.utilities.StandardsStatus; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; @@ -550,6 +551,30 @@ public class ToolingExtensions { else element.getExtension().add(new Extension(new UriType(uri)).setValue(new CodeType(value))); } + + + public static void setCodeExtensionMod(DomainResource resource, String uri, String value) { + if (Utilities.noString(value)) + return; + + Extension ext = getExtension(resource, uri); + if (ext != null) + ext.setValue(new CodeType(value)); + else + resource.getModifierExtension().add(new Extension(uri).setValue(new CodeType(value))); + } + + public static void setCodeExtensionMod(BackboneElement resource, String uri, String value) { + if (Utilities.noString(value)) + return; + + Extension ext = getExtension(resource, uri); + if (ext != null) + ext.setValue(new CodeType(value)); + else + resource.getModifierExtension().add(new Extension(uri).setValue(new CodeType(value))); + } + public static void setIntegerExtension(DomainResource resource, String uri, int value) { Extension ext = getExtension(resource, uri); diff --git a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/BackboneElement.java b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/BackboneElement.java index 87ba3dc25..220724330 100644 --- a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/BackboneElement.java +++ b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/BackboneElement.java @@ -34,6 +34,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import org.hl7.fhir.r4b.model.Enumerations.*; +import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.instance.model.api.IBaseDatatypeElement; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.instance.model.api.ICompositeType; @@ -348,7 +349,59 @@ public abstract class BackboneElement extends DataType implements IBaseBackboneE } return java.util.Collections.unmodifiableList(retVal); } + + public void copyExtensions(org.hl7.fhir.r4b.model.BackboneElement src, String... urls) { + super.copyExtensions(src,urls); + for (Extension e : src.getModifierExtension()) { + if (Utilities.existsInList(e.getUrl(), urls)) { + addModifierExtension(e.copy()); + } + } + } + public List getExtensionsByUrl(String... theUrls) { + + ArrayList retVal = new ArrayList<>(); + for (Extension next : getModifierExtension()) { + if (Utilities.existsInList(next.getUrl(), theUrls)) { + retVal.add(next); + } + } + List sv = super.getExtensionsByUrl(theUrls); + sv.addAll(retVal); + return sv; + } + + + public boolean hasExtension(String... theUrls) { + for (Extension next : getModifierExtension()) { + if (Utilities.existsInList(next.getUrl(), theUrls)) { + return true; + } + } + return super.hasExtension(theUrls); + } + + + public boolean hasExtension(String theUrl) { + for (Extension ext : getModifierExtension()) { + if (theUrl.equals(ext.getUrl())) { + return true; + } + } + + return super.hasExtension(theUrl); + } + + + public void copyNewExtensions(org.hl7.fhir.r4b.model.BackboneElement src, String... urls) { + for (Extension e : src.getModifierExtension()) { + if (Utilities.existsInList(e.getUrl(), urls) && !!hasExtension(e.getUrl())) { + addExtension(e.copy()); + } + } + super.copyNewExtensions(src, urls); + } // end addition } diff --git a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/BackboneType.java b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/BackboneType.java index 3994ee7bf..ee77c7b2b 100644 --- a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/BackboneType.java +++ b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/BackboneType.java @@ -34,6 +34,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import org.hl7.fhir.r4b.model.Enumerations.*; +import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.instance.model.api.IBaseDatatypeElement; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.instance.model.api.ICompositeType; @@ -288,6 +289,59 @@ public abstract class BackboneType extends DataType implements IBaseBackboneElem } } + + public void copyExtensions(org.hl7.fhir.r4b.model.BackboneElement src, String... urls) { + super.copyExtensions(src,urls); + for (Extension e : src.getModifierExtension()) { + if (Utilities.existsInList(e.getUrl(), urls)) { + addModifierExtension(e.copy()); + } + } + } + + public List getExtensionsByUrl(String... theUrls) { + + ArrayList retVal = new ArrayList<>(); + for (Extension next : getModifierExtension()) { + if (Utilities.existsInList(next.getUrl(), theUrls)) { + retVal.add(next); + } + } + List sv = super.getExtensionsByUrl(theUrls); + sv.addAll(retVal); + return sv; + } + + + public boolean hasExtension(String... theUrls) { + for (Extension next : getModifierExtension()) { + if (Utilities.existsInList(next.getUrl(), theUrls)) { + return true; + } + } + return super.hasExtension(theUrls); + } + + + public boolean hasExtension(String theUrl) { + for (Extension ext : getModifierExtension()) { + if (theUrl.equals(ext.getUrl())) { + return true; + } + } + + return super.hasExtension(theUrl); + } + + + public void copyNewExtensions(org.hl7.fhir.r4b.model.BackboneElement src, String... urls) { + for (Extension e : src.getModifierExtension()) { + if (Utilities.existsInList(e.getUrl(), urls) && !!hasExtension(e.getUrl())) { + addExtension(e.copy()); + } + } + super.copyNewExtensions(src, urls); + } // end addition } diff --git a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/Element.java b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/Element.java index 2c406fb48..1a796a0dc 100644 --- a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/Element.java +++ b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/Element.java @@ -438,57 +438,121 @@ public abstract class Element extends Base implements IBaseHasExtensions, IBaseE return this; } - /** - * Returns an unmodifiable list containing all extensions on this element which - * match the given URL. - * - * Note: BackbdoneElements override this to add matching Modifier Extensions too - * - * @param theUrl The URL. Must not be blank or null. - * @return an unmodifiable list containing all extensions on this element which - * match the given URL - */ - public List getExtensionsByUrl(String theUrl) { - org.apache.commons.lang3.Validate.notBlank(theUrl, "theUrl must not be blank or null"); - ArrayList retVal = new ArrayList(); - for (Extension next : getExtension()) { - if (theUrl.equals(next.getUrl())) { - retVal.add(next); - } - } - return java.util.Collections.unmodifiableList(retVal); - } + /** + * Returns an unmodifiable list containing all extensions on this element which + * match the given URL. + * + * Note: BackbdoneElements override this to add matching Modifier Extensions too + * + * @param theUrl The URL. Must not be blank or null. + * @return an unmodifiable list containing all extensions on this element which match the given URL + */ + public List getExtensionsByUrl(String theUrl) { + if (theUrl == null) { + throw new NullPointerException("theUrl must not be null"); + } else if (theUrl.length() == 0) { + throw new IllegalArgumentException("theUrl must not be empty"); + } + ArrayList retVal = new ArrayList<>(); + for (Extension next : getExtension()) { + if (theUrl.equals(next.getUrl())) { + retVal.add(next); + } + } + return java.util.Collections.unmodifiableList(retVal); + } + + public List getExtensionsByUrl(String... theUrls) { + + ArrayList retVal = new ArrayList<>(); + for (Extension next : getExtension()) { + if (Utilities.existsInList(next.getUrl(), theUrls)) { + retVal.add(next); + } + } + return java.util.Collections.unmodifiableList(retVal); + } + - /** - * Returns an true if this element has an extension that matchs the given URL. - * - * Note: BackbdoneElements override this to check Modifier Extensions too - * - * @param theUrl The URL. Must not be blank or null. - */ - public boolean hasExtension(String theUrl) { - return !getExtensionsByUrl(theUrl).isEmpty(); - } + public boolean hasExtension(String... theUrls) { + for (Extension next : getExtension()) { + if (Utilities.existsInList(next.getUrl(), theUrls)) { + return true; + } + } + return false; + } - /** - * Returns the value as a string if this element has only one extension that - * matches the given URL, and that can be converted to a string. - * - * Note: BackbdoneElements override this to check Modifier Extensions too - * - * @param theUrl The URL. Must not be blank or null. - */ + + /** + * Returns an true if this element has an extension that matchs the given URL. + * + * Note: BackbdoneElements override this to check Modifier Extensions too + * + * @param theUrl The URL. Must not be blank or null. + */ + public boolean hasExtension(String theUrl) { + if (extension == null || extension.size() == 0) { + return false; + } + + for (Extension ext : extension) { + if (theUrl.equals(ext.getUrl())) { + return true; + } + } + + return false; + } + + /** + * Returns the value as a string if this element has only one extension that matches the given URL, and that can be converted to a string. + * + * Note: BackbdoneElements override this to check Modifier Extensions too + * + * @param theUrl The URL. Must not be blank or null. + */ public String getExtensionString(String theUrl) throws FHIRException { - List ext = getExtensionsByUrl(theUrl); - if (ext.isEmpty()) + List ext = getExtensionsByUrl(theUrl); + if (ext.isEmpty()) + return null; + if (ext.size() > 1) + throw new FHIRException("Multiple matching extensions found for extension '"+theUrl+"'"); + if (!ext.get(0).hasValue()) return null; - if (ext.size() > 1) - throw new FHIRException("Multiple matching extensions found"); if (!ext.get(0).getValue().isPrimitive()) - throw new FHIRException("Extension could not be converted to a string"); + throw new FHIRException("Extension '"+theUrl+"' could not be converted to a string"); return ext.get(0).getValue().primitiveValue(); } + + public boolean hasExtension(Extension ext) { + if (hasExtension()) { + for (Extension t : getExtension()) { + if (Base.compareDeep(t, ext, false)) { + return true; + } + } + } + return false; + } + + public void copyExtensions(org.hl7.fhir.r4b.model.Element src, String... urls) { + for (Extension e : src.getExtension()) { + if (Utilities.existsInList(e.getUrl(), urls)) { + addExtension(e.copy()); + } + } + } + + public void copyNewExtensions(org.hl7.fhir.r4b.model.Element src, String... urls) { + for (Extension e : src.getExtension()) { + if (Utilities.existsInList(e.getUrl(), urls) && !!hasExtension(e.getUrl())) { + addExtension(e.copy()); + } + } + } + // end addition } diff --git a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/ToolingExtensions.java b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/ToolingExtensions.java index bcaa9c6f7..2cd04caf7 100644 --- a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/ToolingExtensions.java +++ b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/utils/ToolingExtensions.java @@ -3,19 +3,19 @@ package org.hl7.fhir.r4b.utils; /* Copyright (c) 2011+, HL7, Inc. All rights reserved. - + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of HL7 nor the names of its contributors may be used to + * Neither the name of HL7 nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. @@ -26,7 +26,7 @@ package org.hl7.fhir.r4b.utils; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - + */ /* @@ -97,6 +97,7 @@ import org.hl7.fhir.r4b.model.UriType; import org.hl7.fhir.r4b.model.UrlType; import org.hl7.fhir.r4b.model.ValueSet.ConceptReferenceComponent; import org.hl7.fhir.r4b.model.ValueSet.ConceptSetComponent; +import org.hl7.fhir.r4b.model.BackboneElement; import org.hl7.fhir.utilities.StandardsStatus; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; @@ -106,8 +107,8 @@ import org.hl7.fhir.utilities.validation.ValidationMessage.Source; public class ToolingExtensions { // validated -// private static final String EXT_OID = "http://hl7.org/fhir/StructureDefinition/valueset-oid"; -// public static final String EXT_DEPRECATED = "http://hl7.org/fhir/StructureDefinition/codesystem-deprecated"; + // private static final String EXT_OID = "http://hl7.org/fhir/StructureDefinition/valueset-oid"; + // public static final String EXT_DEPRECATED = "http://hl7.org/fhir/StructureDefinition/codesystem-deprecated"; public static final String EXT_DEFINITION = "http://hl7.org/fhir/StructureDefinition/valueset-concept-definition"; public static final String EXT_CS_COMMENT = "http://hl7.org/fhir/StructureDefinition/codesystem-concept-comments"; public static final String EXT_VS_COMMENT = "http://hl7.org/fhir/StructureDefinition/valueset-concept-comments"; @@ -134,12 +135,12 @@ public class ToolingExtensions { public static final String EXT_MAPPING_PREFIX = "http://hl7.org/fhir/tools/StructureDefinition/logical-mapping-prefix"; public static final String EXT_MAPPING_SUFFIX = "http://hl7.org/fhir/tools/StructureDefinition/logical-mapping-suffix"; -// public static final String EXT_FLYOVER = "http://hl7.org/fhir/Profile/questionnaire-extensions#flyover"; + // public static final String EXT_FLYOVER = "http://hl7.org/fhir/Profile/questionnaire-extensions#flyover"; public static final String EXT_QTYPE = "http://hl7.org/fhir/StructureDefinition/questionnnaire-baseType"; -// private static final String EXT_QREF = "http://www.healthintersections.com.au/fhir/Profile/metadata#reference"; -// private static final String EXTENSION_FILTER_ONLY = "http://www.healthintersections.com.au/fhir/Profile/metadata#expandNeedsFilter"; -// private static final String EXT_TYPE = "http://www.healthintersections.com.au/fhir/Profile/metadata#type"; -// private static final String EXT_REFERENCE = "http://www.healthintersections.com.au/fhir/Profile/metadata#reference"; + // private static final String EXT_QREF = "http://www.healthintersections.com.au/fhir/Profile/metadata#reference"; + // private static final String EXTENSION_FILTER_ONLY = "http://www.healthintersections.com.au/fhir/Profile/metadata#expandNeedsFilter"; + // private static final String EXT_TYPE = "http://www.healthintersections.com.au/fhir/Profile/metadata#type"; + // private static final String EXT_REFERENCE = "http://www.healthintersections.com.au/fhir/Profile/metadata#reference"; private static final String EXT_FHIRTYPE = "http://hl7.org/fhir/StructureDefinition/questionnaire-fhirType"; private static final String EXT_ALLOWABLE_UNITS = "http://hl7.org/fhir/StructureDefinition/elementdefinition-allowedUnits"; public static final String EXT_CIMI_REFERENCE = "http://hl7.org/fhir/StructureDefinition/cimi-reference"; @@ -166,8 +167,8 @@ public class ToolingExtensions { public static final String EXT_IGP_MAPPING_CSV = "http://hl7.org/fhir/StructureDefinition/igpublisher-mapping-csv"; public static final String EXT_IGP_BUNDLE = "http://hl7.org/fhir/StructureDefinition/igpublisher-bundle"; public static final String EXT_IGP_RESOURCE_INFO = "http://hl7.org/fhir/tools/StructureDefinition/resource-information"; -// public static final String EXT_IGP_CONTAINED_RESOURCE_INFO = "http://hl7.org/fhir/tools/StructureDefinition/contained-resource-information"; -// public static final String EXT_IGP_LOADVERSION = "http://hl7.org/fhir/StructureDefinition/igpublisher-loadversion"; + // public static final String EXT_IGP_CONTAINED_RESOURCE_INFO = "http://hl7.org/fhir/tools/StructureDefinition/contained-resource-information"; + // public static final String EXT_IGP_LOADVERSION = "http://hl7.org/fhir/StructureDefinition/igpublisher-loadversion"; public static final String EXT_MAX_VALUESET = "http://hl7.org/fhir/StructureDefinition/elementdefinition-maxValueSet"; public static final String EXT_MIN_VALUESET = "http://hl7.org/fhir/StructureDefinition/elementdefinition-minValueSet"; public static final String EXT_PROFILE_ELEMENT = "http://hl7.org/fhir/StructureDefinition/elementdefinition-profile-element"; @@ -182,7 +183,7 @@ public class ToolingExtensions { public static final String EXT_FHIR_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type"; public static final String EXT_XML_TYPE = "http://hl7.org/fhir/StructureDefinition/structuredefinition-xml-type"; public static final String EXT_RENDERED_VALUE = "http://hl7.org/fhir/StructureDefinition/rendered-value"; - public static final String EXT_OLD_CONCEPTMAP_EQUIVALENCE = "http://hl7.org/fhir/1.0/StructureDefinition/extension-ConceptMap.element.target.equivalence"; + public static final String EXT_OLD_CONCEPTMAP_EQUIVALENCE = "http://hl7.org/fhir/1.0/StructureDefinition/extension-ConceptMap.group.element.target.equivalence"; public static final String EXT_EXP_TOOCOSTLY = "http://hl7.org/fhir/StructureDefinition/valueset-toocostly"; public static final String EXT_MUST_SUPPORT = "http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support"; public static final String EXT_TRANSLATABLE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-translatable"; @@ -223,15 +224,15 @@ public class ToolingExtensions { return getExtension(e, url) != null; } -// public static void addStringExtension(DomainResource dr, String url, String content) { -// if (!StringUtils.isBlank(content)) { -// Extension ex = getExtension(dr, url); -// if (ex != null) -// ex.setValue(new StringType(content)); -// else -// dr.getExtension().add(Factory.newExtension(url, new StringType(content), true)); -// } -// } + // public static void addStringExtension(DomainResource dr, String url, String content) { + // if (!StringUtils.isBlank(content)) { + // Extension ex = getExtension(dr, url); + // if (ex != null) + // ex.setValue(new StringType(content)); + // else + // dr.getExtension().add(Factory.newExtension(url, new StringType(content), true)); + // } + // } public static void addMarkdownExtension(DomainResource dr, String url, String content) { if (!StringUtils.isBlank(content)) { @@ -320,10 +321,10 @@ public class ToolingExtensions { nc.getExtension().add(Factory.newExtension(EXT_CS_COMMENT, Factory.newString_(comment), true)); } -// public static void markDeprecated(Element nc) { -// setDeprecated(nc); -// } -// + // public static void markDeprecated(Element nc) { + // setDeprecated(nc); + // } + // public static void addDefinition(Element nc, String definition) { if (!StringUtils.isBlank(definition)) @@ -459,18 +460,18 @@ public class ToolingExtensions { public static String getCSComment(ConceptDefinitionComponent c) { return readStringExtension(c, EXT_CS_COMMENT); } -// -// public static Boolean getDeprecated(Element c) { -// return readBooleanExtension(c, EXT_DEPRECATED); -// } + // + // public static Boolean getDeprecated(Element c) { + // return readBooleanExtension(c, EXT_DEPRECATED); + // } public static boolean hasCSComment(ConceptDefinitionComponent c) { return findStringExtension(c, EXT_CS_COMMENT); } -// public static boolean hasDeprecated(Element c) { -// return findBooleanExtension(c, EXT_DEPRECATED); -// } + // public static boolean hasDeprecated(Element c) { + // return findBooleanExtension(c, EXT_DEPRECATED); + // } public static void addFlyOver(QuestionnaireItemComponent item, String text, String linkId) { if (!StringUtils.isBlank(text)) { @@ -582,6 +583,28 @@ public class ToolingExtensions { element.getExtension().add(new Extension(uri).setValue(new CodeType(value))); } + public static void setCodeExtensionMod(DomainResource resource, String uri, String value) { + if (Utilities.noString(value)) + return; + + Extension ext = getExtension(resource, uri); + if (ext != null) + ext.setValue(new CodeType(value)); + else + resource.getModifierExtension().add(new Extension(uri).setValue(new CodeType(value))); + } + + public static void setCodeExtensionMod(BackboneElement resource, String uri, String value) { + if (Utilities.noString(value)) + return; + + Extension ext = getExtension(resource, uri); + if (ext != null) + ext.setValue(new CodeType(value)); + else + resource.getModifierExtension().add(new Extension(uri).setValue(new CodeType(value))); + } + public static void setIntegerExtension(DomainResource resource, String uri, int value) { Extension ext = getExtension(resource, uri); if (ext != null) @@ -590,34 +613,34 @@ public class ToolingExtensions { resource.getExtension().add(new Extension(uri).setValue(new IntegerType(value))); } -// public static String getOID(CodeSystem define) { -// return readStringExtension(define, EXT_OID); -// } -// -// public static String getOID(ValueSet vs) { -// return readStringExtension(vs, EXT_OID); -// } -// -// public static void setOID(CodeSystem define, String oid) throws FHIRFormatError, URISyntaxException { -// if (!oid.startsWith("urn:oid:")) -// throw new FHIRFormatError("Error in OID format"); -// if (oid.startsWith("urn:oid:urn:oid:")) -// throw new FHIRFormatError("Error in OID format"); -// if (!hasExtension(define, EXT_OID)) -// define.getExtension().add(Factory.newExtension(EXT_OID, Factory.newUri(oid), false)); -// else if (!oid.equals(readStringExtension(define, EXT_OID))) -// throw new Error("Attempt to assign multiple OIDs to a code system"); -// } -// public static void setOID(ValueSet vs, String oid) throws FHIRFormatError, URISyntaxException { -// if (!oid.startsWith("urn:oid:")) -// throw new FHIRFormatError("Error in OID format"); -// if (oid.startsWith("urn:oid:urn:oid:")) -// throw new FHIRFormatError("Error in OID format"); -// if (!hasExtension(vs, EXT_OID)) -// vs.getExtension().add(Factory.newExtension(EXT_OID, Factory.newUri(oid), false)); -// else if (!oid.equals(readStringExtension(vs, EXT_OID))) -// throw new Error("Attempt to assign multiple OIDs to value set "+vs.getName()+" ("+vs.getUrl()+"). Has "+readStringExtension(vs, EXT_OID)+", trying to add "+oid); -// } + // public static String getOID(CodeSystem define) { + // return readStringExtension(define, EXT_OID); + // } + // + // public static String getOID(ValueSet vs) { + // return readStringExtension(vs, EXT_OID); + // } + // + // public static void setOID(CodeSystem define, String oid) throws FHIRFormatError, URISyntaxException { + // if (!oid.startsWith("urn:oid:")) + // throw new FHIRFormatError("Error in OID format"); + // if (oid.startsWith("urn:oid:urn:oid:")) + // throw new FHIRFormatError("Error in OID format"); + // if (!hasExtension(define, EXT_OID)) + // define.getExtension().add(Factory.newExtension(EXT_OID, Factory.newUri(oid), false)); + // else if (!oid.equals(readStringExtension(define, EXT_OID))) + // throw new Error("Attempt to assign multiple OIDs to a code system"); + // } + // public static void setOID(ValueSet vs, String oid) throws FHIRFormatError, URISyntaxException { + // if (!oid.startsWith("urn:oid:")) + // throw new FHIRFormatError("Error in OID format"); + // if (oid.startsWith("urn:oid:urn:oid:")) + // throw new FHIRFormatError("Error in OID format"); + // if (!hasExtension(vs, EXT_OID)) + // vs.getExtension().add(Factory.newExtension(EXT_OID, Factory.newUri(oid), false)); + // else if (!oid.equals(readStringExtension(vs, EXT_OID))) + // throw new Error("Attempt to assign multiple OIDs to value set "+vs.getName()+" ("+vs.getUrl()+"). Has "+readStringExtension(vs, EXT_OID)+", trying to add "+oid); + // } public static boolean hasLanguageTranslation(Element element, String lang) { for (Extension e : element.getExtension()) { @@ -687,23 +710,23 @@ public class ToolingExtensions { return results; } -// public static void addDEReference(DataElement de, String value) { -// for (Extension e : de.getExtension()) -// if (e.getUrl().equals(EXT_CIMI_REFERENCE)) { -// e.setValue(new UriType(value)); -// return; -// } -// de.getExtension().add(new Extension().setUrl(EXT_CIMI_REFERENCE).setValue(new UriType(value))); -// } + // public static void addDEReference(DataElement de, String value) { + // for (Extension e : de.getExtension()) + // if (e.getUrl().equals(EXT_CIMI_REFERENCE)) { + // e.setValue(new UriType(value)); + // return; + // } + // de.getExtension().add(new Extension().setUrl(EXT_CIMI_REFERENCE).setValue(new UriType(value))); + // } -// public static void setDeprecated(Element nc) { -// for (Extension e : nc.getExtension()) -// if (e.getUrl().equals(EXT_DEPRECATED)) { -// e.setValue(new BooleanType(true)); -// return; -// } -// nc.getExtension().add(new Extension().setUrl(EXT_DEPRECATED).setValue(new BooleanType(true))); -// } + // public static void setDeprecated(Element nc) { + // for (Extension e : nc.getExtension()) + // if (e.getUrl().equals(EXT_DEPRECATED)) { + // e.setValue(new BooleanType(true)); + // return; + // } + // nc.getExtension().add(new Extension().setUrl(EXT_DEPRECATED).setValue(new BooleanType(true))); + // } public static void setExtension(Element focus, String url, Coding c) { for (Extension e : focus.getExtension()) @@ -908,14 +931,14 @@ public class ToolingExtensions { return type.primitiveValue(); } -// public static boolean hasOID(ValueSet vs) { -// return hasExtension(vs, EXT_OID); -// } -// -// public static boolean hasOID(CodeSystem cs) { -// return hasExtension(cs, EXT_OID); -// } -// + // public static boolean hasOID(ValueSet vs) { + // return hasExtension(vs, EXT_OID); + // } + // + // public static boolean hasOID(CodeSystem cs) { + // return hasExtension(cs, EXT_OID); + // } + // public static void addUrlExtension(Element e, String url, String content) { if (!StringUtils.isBlank(content)) { Extension ex = getExtension(e, url); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneElement.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneElement.java index b462680b9..e25bf74ce 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneElement.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneElement.java @@ -323,8 +323,50 @@ Modifier extensions SHALL NOT change the meaning of any elements on Resource or } } + public List getExtensionsByUrl(String... theUrls) { + ArrayList retVal = new ArrayList<>(); + for (Extension next : getModifierExtension()) { + if (Utilities.existsInList(next.getUrl(), theUrls)) { + retVal.add(next); + } + } + List sv = super.getExtensionsByUrl(theUrls); + sv.addAll(retVal); + return sv; + } + + public boolean hasExtension(String... theUrls) { + for (Extension next : getModifierExtension()) { + if (Utilities.existsInList(next.getUrl(), theUrls)) { + return true; + } + } + return super.hasExtension(theUrls); + } + + + public boolean hasExtension(String theUrl) { + for (Extension ext : getModifierExtension()) { + if (theUrl.equals(ext.getUrl())) { + return true; + } + } + + return super.hasExtension(theUrl); + } + + + public void copyNewExtensions(org.hl7.fhir.r5.model.BackboneElement src, String... urls) { + for (Extension e : src.getModifierExtension()) { + if (Utilities.existsInList(e.getUrl(), urls) && !!hasExtension(e.getUrl())) { + addExtension(e.copy()); + } + } + super.copyNewExtensions(src, urls); + } + // end addition } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneType.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneType.java index d7127c091..970e86700 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneType.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneType.java @@ -250,6 +250,60 @@ public void checkNoModifiers(String noun, String verb) throws FHIRException { } } + + + public void copyExtensions(org.hl7.fhir.r5.model.BackboneElement src, String... urls) { + super.copyExtensions(src,urls); + for (Extension e : src.getModifierExtension()) { + if (Utilities.existsInList(e.getUrl(), urls)) { + addModifierExtension(e.copy()); + } + } + } + + public List getExtensionsByUrl(String... theUrls) { + + ArrayList retVal = new ArrayList<>(); + for (Extension next : getModifierExtension()) { + if (Utilities.existsInList(next.getUrl(), theUrls)) { + retVal.add(next); + } + } + List sv = super.getExtensionsByUrl(theUrls); + sv.addAll(retVal); + return sv; + } + + + public boolean hasExtension(String... theUrls) { + for (Extension next : getModifierExtension()) { + if (Utilities.existsInList(next.getUrl(), theUrls)) { + return true; + } + } + return super.hasExtension(theUrls); + } + + + public boolean hasExtension(String theUrl) { + for (Extension ext : getModifierExtension()) { + if (theUrl.equals(ext.getUrl())) { + return true; + } + } + + return super.hasExtension(theUrl); + } + + + public void copyNewExtensions(org.hl7.fhir.r5.model.BackboneElement src, String... urls) { + for (Extension e : src.getModifierExtension()) { + if (Utilities.existsInList(e.getUrl(), urls) && !!hasExtension(e.getUrl())) { + addExtension(e.copy()); + } + } + super.copyNewExtensions(src, urls); + } // end addition } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ConceptMapRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ConceptMapRenderer.java index 90a3b072c..c6ab07684 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ConceptMapRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ConceptMapRenderer.java @@ -169,8 +169,8 @@ public class ConceptMapRenderer extends TerminologyRenderer { if (!ccm.hasRelationship()) tr.td().tx(":"+"("+ConceptMapRelationship.EQUIVALENT.toCode()+")"); else { - if (ccm.getRelationshipElement().hasExtension(ToolingExtensions.EXT_OLD_CONCEPTMAP_EQUIVALENCE)) { - String code = ToolingExtensions.readStringExtension(ccm.getRelationshipElement(), ToolingExtensions.EXT_OLD_CONCEPTMAP_EQUIVALENCE); + if (ccm.hasExtension(ToolingExtensions.EXT_OLD_CONCEPTMAP_EQUIVALENCE)) { + String code = ToolingExtensions.readStringExtension(ccm, ToolingExtensions.EXT_OLD_CONCEPTMAP_EQUIVALENCE); tr.td().ah(eqpath+"#"+code, code).tx(presentEquivalenceCode(code)); } else { tr.td().ah(eqpath+"#"+ccm.getRelationship().toCode(), ccm.getRelationship().toCode()).tx(presentRelationshipCode(ccm.getRelationship().toCode())); From f598ade02ca80283b22935e537cea15eec1c254a Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Mon, 9 Oct 2023 17:41:59 +1100 Subject: [PATCH 03/12] Workaround issue where R5 build wrongly adds ele-1 to base --- .../hl7/fhir/convertors/loaders/loaderR5/R5ToR5Loader.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/loaders/loaderR5/R5ToR5Loader.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/loaders/loaderR5/R5ToR5Loader.java index 5310742b1..c008b30fe 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/loaders/loaderR5/R5ToR5Loader.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/loaders/loaderR5/R5ToR5Loader.java @@ -107,6 +107,13 @@ public class R5ToR5Loader extends BaseLoaderR5 { if (patchUrls) { doPatchUrls(r5); } + if (r5 instanceof StructureDefinition) { + StructureDefinition sd = (StructureDefinition) r5; + if ("http://hl7.org/fhir/StructureDefinition/Base".equals(sd.getUrl())) { + sd.getSnapshot().getElementFirstRep().getConstraint().clear(); + + } + } return r5; } From 33776523aee47bb108f39c4acea767a9a226890d Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Mon, 9 Oct 2023 17:44:03 +1100 Subject: [PATCH 04/12] make sure snapshots are generated when fetching types --- .../StructureDefinitionHacker.java | 4 +-- .../fhir/r5/context/BaseWorkerContext.java | 25 ++++++++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/StructureDefinitionHacker.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/StructureDefinitionHacker.java index 69e231200..8e4c92e26 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/StructureDefinitionHacker.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/StructureDefinitionHacker.java @@ -8,7 +8,7 @@ import org.hl7.fhir.r5.model.StructureDefinition; import org.hl7.fhir.utilities.VersionUtilities; /** - * This doesn't do anythign at this time + * This works around known issues in struture definitions * * @author graha * @@ -48,7 +48,7 @@ public class StructureDefinitionHacker { ed.setComment("e.g. The patient is a pregnant, has congestive heart failure, has an Adenocarcinoma, and is allergic to penicillin."); } } - } + } return sd; } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java index dd2ec8995..49a2e9f26 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java @@ -2472,7 +2472,30 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte return res; } } - return typeManager.fetchTypeDefinition(typeName); + StructureDefinition p = typeManager.fetchTypeDefinition(typeName); + if (p != null && !p.isGeneratedSnapshot()) { + if (p.isGeneratingSnapshot()) { + throw new FHIRException("Attempt to fetch the profile "+p.getVersionedUrl()+" while generating the snapshot for it"); + } + try { + if (logger.isDebugLogging()) { + System.out.println("Generating snapshot for "+p.getVersionedUrl()); + } + p.setGeneratingSnapshot(true); + try { + new ContextUtilities(this).generateSnapshot(p); + } finally { + p.setGeneratingSnapshot(false); + } + } catch (Exception e) { + // not sure what to do in this case? + System.out.println("Unable to generate snapshot @4 for "+p.getVersionedUrl()+": "+e.getMessage()); + if (logger.isDebugLogging()) { + e.printStackTrace(); + } + } + } + return p; } @Override From af0f9bc765fa6d403ed0ad8a5684159ff1887e31 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Mon, 9 Oct 2023 17:45:38 +1100 Subject: [PATCH 05/12] Add support for hosts to manage certificate resolution using ISignatureServices + fix issue matching type names when validating logical models --- .../java/org/hl7/fhir/r5/elementmodel/Manager.java | 3 +++ .../org/hl7/fhir/r5/elementmodel/ParserBase.java | 10 ++++++++++ .../org/hl7/fhir/r5/elementmodel/SHCParser.java | 2 +- .../org/hl7/fhir/r5/elementmodel/XmlParser.java | 3 +-- .../hl7/fhir/validation/tests/ValidationTests.java | 14 +++++++++++++- 5 files changed, 28 insertions(+), 4 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Manager.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Manager.java index 16a59718b..9893582bf 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Manager.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Manager.java @@ -95,6 +95,9 @@ public class Manager { return null; } public static FhirFormat readFromMimeType(String mt) { + if (mt == null) { + return null; + } if (mt.contains("/xml") || mt.contains("+xml")) { return FhirFormat.XML; } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ParserBase.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ParserBase.java index 5471e9468..feef0008a 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ParserBase.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/ParserBase.java @@ -49,6 +49,7 @@ import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule; import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.i18n.I18nConstants; +import org.hl7.fhir.utilities.validation.IDigitalSignatureServices; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; @@ -86,6 +87,7 @@ public abstract class ParserBase { protected boolean showDecorations; protected IdRenderingPolicy idPolicy = IdRenderingPolicy.All; protected StructureDefinition logical; + protected IDigitalSignatureServices signatureServices; public ParserBase(IWorkerContext context) { super(); @@ -281,4 +283,12 @@ public abstract class ParserBase { return this; } + public IDigitalSignatureServices getSignatureServices() { + return signatureServices; + } + + public void setSignatureServices(IDigitalSignatureServices signatureServices) { + this.signatureServices = signatureServices; + } + } \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHCParser.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHCParser.java index 1e3d56895..3d9aa170e 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHCParser.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/SHCParser.java @@ -329,7 +329,7 @@ public class SHCParser extends ParserBase { String url = Utilities.pathURL(iss, "/.well-known/jwks.json"); JsonObject jwks = null; try { - jwks = org.hl7.fhir.utilities.json.parser.JsonParser.parseObjectFromUrl(url); + jwks = signatureServices != null ? signatureServices.fetchJWKS(url) : org.hl7.fhir.utilities.json.parser.JsonParser.parseObjectFromUrl(url); } catch (Exception e) { logError(errors, "2023-09-08", 1, 1, name, IssueType.NOTFOUND, "Unable to verify the signature, because unable to retrieve JWKS from "+url+": "+ e.getMessage().replace("Connection refused (Connection refused)", "Connection refused"), IssueSeverity.ERROR); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/XmlParser.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/XmlParser.java index da6868bb6..a79da099c 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/XmlParser.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/XmlParser.java @@ -326,8 +326,7 @@ public class XmlParser extends ParserBase { n.setPath(element.getPath()+"."+property.getName()); element.getChildren().add(n); } - } - else { + } else { Node n = node.getFirstChild(); while (n != null) { if (n.getNodeType() == Node.TEXT_NODE && !Utilities.noString(n.getTextContent().trim())) { 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 ed08bad1a..4f3e022e5 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 @@ -70,11 +70,13 @@ import org.hl7.fhir.utilities.SimpleHTTPClient.HTTPResult; import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; +import org.hl7.fhir.utilities.json.JsonException; import org.hl7.fhir.utilities.json.JsonTrackingParser; import org.hl7.fhir.utilities.json.JsonUtilities; import org.hl7.fhir.utilities.npm.NpmPackage; import org.hl7.fhir.utilities.settings.FhirSettings; import org.hl7.fhir.utilities.tests.CacheVerificationLogger; +import org.hl7.fhir.utilities.validation.IDigitalSignatureServices; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.validation.IgLoader; import org.hl7.fhir.validation.ValidationEngine; @@ -98,7 +100,7 @@ import com.google.gson.JsonObject; @RunWith(Parameterized.class) -public class ValidationTests implements IEvaluationContext, IValidatorResourceFetcher, IValidationPolicyAdvisor { +public class ValidationTests implements IEvaluationContext, IValidatorResourceFetcher, IValidationPolicyAdvisor, IDigitalSignatureServices { public class TestSorter implements Comparator { @@ -319,6 +321,7 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe if (content.has("noHtmlInMarkdown")) { val.setHtmlInMarkdownCheck(HtmlInMarkdownCheck.ERROR); } + val.setSignatureServices(this); if (content.has("logical")==false) { val.setAssumeValidRestReferences(content.has("assumeValidRestReferences") ? content.get("assumeValidRestReferences").getAsBoolean() : false); logOutput(String.format("Start Validating (%d to set up)", (System.nanoTime() - setup) / 1000000)); @@ -792,4 +795,13 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe return false; } + @Override + public org.hl7.fhir.utilities.json.model.JsonObject fetchJWKS(String address) throws JsonException, IOException { + if ("https://test.fhir.org/icao/.well-known/jwks.json".equals(address)) { + return org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(TestingUtilities.loadTestResourceBytes("validator", "test.fhir.org-jwks.json")); + } else { + return org.hl7.fhir.utilities.json.parser.JsonParser.parseObjectFromUrl(address); + } + } + } \ No newline at end of file From 9da31ae8ad4670c384c6db068d3e6f03342c730c Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Mon, 9 Oct 2023 17:46:33 +1100 Subject: [PATCH 06/12] improve language on constraint error message + add expression checking for SQL on FHIR project --- .../fhir/utilities/i18n/I18nConstants.java | 3 ++ .../validation/IDigitalSignatureServices.java | 11 +++++ .../src/main/resources/Messages.properties | 8 +++- .../instance/InstanceValidator.java | 46 +++++++++++++++---- 4 files changed, 58 insertions(+), 10 deletions(-) create mode 100644 org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/validation/IDigitalSignatureServices.java 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 616ff8f71..5a92d704a 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 @@ -1003,6 +1003,9 @@ public class I18nConstants { public static final String CONCEPTMAP_VS_CONCEPT_CODE_UNKNOWN_SYSTEM = "CONCEPTMAP_VS_CONCEPT_CODE_UNKNOWN_SYSTEM"; public static final String LOGICAL_MODEL_NAME_MISMATCH = "LOGICAL_MODEL_NAME_MISMATCH"; public static final String LOGICAL_MODEL_QNAME_MISMATCH = "LOGICAL_MODEL_QNAME_MISMATCH"; + public static final String FHIRPATH_CHOICE_NO_TYPE_SPECIFIER = "FHIRPATH_CHOICE_NO_TYPE_SPECIFIER"; + public static final String FHIRPATH_CHOICE_SPURIOUS_TYPE_SPECIFIER = "FHIRPATH_CHOICE_SPURIOUS_TYPE_SPECIFIER"; + public static final String FHIRPATH_NOT_A_COLLECTION = "FHIRPATH_NOT_A_COLLECTION"; } diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/validation/IDigitalSignatureServices.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/validation/IDigitalSignatureServices.java new file mode 100644 index 000000000..d8ea77890 --- /dev/null +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/validation/IDigitalSignatureServices.java @@ -0,0 +1,11 @@ +package org.hl7.fhir.utilities.validation; + +import java.io.IOException; + +import org.hl7.fhir.utilities.json.JsonException; +import org.hl7.fhir.utilities.json.model.JsonObject; + +public interface IDigitalSignatureServices { + + JsonObject fetchJWKS(String address) throws JsonException, IOException; +} diff --git a/org.hl7.fhir.utilities/src/main/resources/Messages.properties b/org.hl7.fhir.utilities/src/main/resources/Messages.properties index 0e2abdeda..0492e4f39 100644 --- a/org.hl7.fhir.utilities/src/main/resources/Messages.properties +++ b/org.hl7.fhir.utilities/src/main/resources/Messages.properties @@ -736,8 +736,8 @@ BUNDLE_SEARCH_ENTRY_WRONG_RESOURCE_TYPE_MODE = This is not a matching resource t BUNDLE_SEARCH_ENTRY_WRONG_RESOURCE_TYPE_OUTCOME = This is not an OperationOutcome ({0}) BUNDLE_SEARCH_ENTRY_WRONG_RESOURCE_TYPE_NO_MODE = This is not a matching resource type for the specified search (is a search mode needed?) ({0} expecting {1}) BUNDLE_SEARCH_NO_MODE = SearchSet bundles should have search modes on the entries -INV_FAILED = Rule {0} Failed -INV_FAILED_SOURCE = Rule {0} Failed (defined in {1}) +INV_FAILED = Constraint failed: {0} +INV_FAILED_SOURCE = Constraint failed: {0} (defined in {1}) PATTERN_CHECK_STRING = The pattern [{0}] defined in the profile {1} not found. Issues: {2} TYPE_SPECIFIC_CHECKS_DT_URL_EXAMPLE = Example URLs are not allowed in this context ({0}) UNICODE_BIDI_CONTROLS_CHARS_DISALLOWED = The Unicode sequence has bi-di control characters which are not allowed in this context: {0} @@ -1060,3 +1060,7 @@ TYPE_SPECIFIC_CHECKS_DT_QTY_UCUM_ANNOTATIONS_NOT_IN_UNIT = UCUM Codes that conta TYPE_SPECIFIC_CHECKS_DT_QTY_UCUM_ANNOTATIONS = UCUM Codes that contain human readable annotations like {0} can be misleading (e.g. they are ignored when comparing units). Best Practice is not to depend on annotations in the UCUM code, so this usage should be checked LOGICAL_MODEL_NAME_MISMATCH = The name ''{0}'' does not match the expected name ''{1}'' LOGICAL_MODEL_QNAME_MISMATCH = The QName ''{0}'' does not match the expected QName ''{1}'' +FHIRPATH_CHOICE_NO_TYPE_SPECIFIER = The expression ''{0}'' refers to an element that is a choice, but doesn''t have an .ofType() so that SQL view runners can pre-determine the full element name +FHIRPATH_CHOICE_SPURIOUS_TYPE_SPECIFIER = The expression ''{0}'' refers to an element that is not a choice, but has an .ofType(). SQL view runners are likely to pre-determine an incorrect full element name +FHIRPATH_NOT_A_COLLECTION = Found a use of a collection operator on something that is not a collection at ''{0}'' - check that there's no mistakes in the expression syntax + 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 900410dec..b9c1ff12e 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 @@ -185,6 +185,7 @@ import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.VersionUtilities.VersionURLInfo; import org.hl7.fhir.utilities.i18n.I18nConstants; import org.hl7.fhir.utilities.json.model.JsonObject; +import org.hl7.fhir.utilities.validation.IDigitalSignatureServices; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; @@ -493,6 +494,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat public List validatedContent; public boolean testMode; private boolean example ; + private IDigitalSignatureServices signatureServices; public InstanceValidator(@Nonnull IWorkerContext theContext, @Nonnull IEvaluationContext hostServices, @Nonnull XVerExtensionManager xverManager) { super(theContext, xverManager, false); @@ -710,6 +712,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (parser instanceof JsonParser) { ((JsonParser) parser).setAllowComments(allowComments); } + parser.setSignatureServices(signatureServices); + long t = System.nanoTime(); validatedContent = null; try { @@ -5586,9 +5590,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat long t = System.nanoTime(); StructureDefinition profile = this.context.fetchResource(StructureDefinition.class, typeForResource.getProfile().get(0).asStringValue(), parentProfile); timeTracker.sd(t); - trackUsage(profile, valContext, element); if (rule(errors, NO_RULE_DATE, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), - profile != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOPROFILE_EXPL, special.toHuman(), resourceName, typeForResource.getProfile().get(0).asStringValue())) { + profile != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOPROFILE_EXPL, special == null ? "??" : special.toHuman(), resourceName, typeForResource.getProfile().get(0).asStringValue())) { + trackUsage(profile, valContext, element); ok = validateResource(hc, errors, resource, element, profile, idstatus, stack, pct, mode) && ok; } else { ok = false; @@ -5841,6 +5845,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat boolean ok = true; List profiles = new ArrayList(); String type = null; + String typeName = null; ElementDefinition typeDefn = null; checkMustSupport(profile, ei); long s = System.currentTimeMillis(); @@ -5848,21 +5853,29 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (checkDefn.getType().size() == 1 && !"*".equals(checkDefn.getType().get(0).getWorkingCode()) && !"Element".equals(checkDefn.getType().get(0).getWorkingCode()) && !"BackboneElement".equals(checkDefn.getType().get(0).getWorkingCode())) { type = checkDefn.getType().get(0).getWorkingCode(); + typeName = type; + if (Utilities.isAbsoluteUrl(type)) { + StructureDefinition sdt = context.fetchTypeDefinition(type); + if (sdt != null) { + typeName = sdt.getTypeName(); + } + } String stype = ei.getElement().fhirType(); if (!stype.equals(type)) { if (checkDefn.isChoice()) { if (extensionUrl != null && !isAbsolute(extensionUrl)) { ok = rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), ei.getPath(), false, I18nConstants.EXTENSION_PROF_TYPE, profile.getVersionedUrl(), type, stype) && ok; } else if (!isAbstractType(type) && !"Extension".equals(profile.getType())) { - ok = rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), ei.getPath(), stype.equals(type), I18nConstants.EXTENSION_PROF_TYPE, profile.getVersionedUrl(), type, stype) && ok; + ok = rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), ei.getPath(), stype.equals(typeName), I18nConstants.EXTENSION_PROF_TYPE, profile.getVersionedUrl(), type, stype) && ok; } } else if (!isAbstractType(type)) { - ok = rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), ei.getPath(), stype.equals(type) || + ok = rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), ei.getPath(), stype.equals(typeName) || (Utilities.existsInList(type, "string", "id") && Utilities.existsInList(stype, "string", "id")), // work around a r4 problem with id/string I18nConstants.EXTENSION_PROF_TYPE, profile.getVersionedUrl(), type, stype) && ok; } else if (!isResource(type)) { // System.out.println("update type "+type+" to "+stype+"?"); type = stype; + typeName = type; } else { // this will be sorted out in contains ... System.out.println("update type "+type+" to "+stype+"?"); } @@ -5878,8 +5891,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat String prefix = tail(checkDefn.getPath()); assert prefix.endsWith("[x]"); type = ei.getName().substring(prefix.length() - 3); - if (isPrimitiveType(type)) + typeName = type; + if (isPrimitiveType(type)) { type = Utilities.uncapitalize(type); + typeName = type; + } if (checkDefn.getType().get(0).hasProfile()) { for (CanonicalType p : checkDefn.getType().get(0).getProfile()) { profiles.add(p.getValue()); @@ -5892,13 +5908,16 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (checkDefn.hasRepresentation(PropertyRepresentation.TYPEATTR)) { type = ei.getElement().getType(); + typeName = type; } else if (ei.getElement().isResource()) { - type = ei.getElement().fhirType(); + type = ei.getElement().fhirType(); + typeName = type; } else { prefix = prefix.substring(0, prefix.length() - 3); for (TypeRefComponent t : checkDefn.getType()) if ((prefix + Utilities.capitalize(t.getWorkingCode())).equals(ei.getName())) { type = t.getWorkingCode(); + typeName = type; // Excluding reference is a kludge to get around versioning issues if (t.hasProfile() && !type.equals("Reference")) profiles.add(t.getProfile().get(0).getValue()); @@ -5906,9 +5925,10 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } if (type == null) { TypeRefComponent trc = checkDefn.getType().get(0); - if (trc.getWorkingCode().equals("Reference")) + if (trc.getWorkingCode().equals("Reference")) { type = "Reference"; - else + typeName = type; + } else ok = rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, ei.line(), ei.col(), stack.getLiteralPath(), false, I18nConstants.VALIDATION_VAL_PROFILE_NOTYPE, ei.getName(), describeTypes(checkDefn.getType())) && ok; } } else if (checkDefn.getContentReference() != null) { @@ -5933,6 +5953,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat ei.definition = ei.definition; } type = null; + typeName = type; } } NodeStack localStack = stack.push(ei.getElement(), "*".equals(ei.getDefinition().getBase().getMax()) && ei.count == -1 ? 0 : ei.count, checkDefn, type == null ? typeDefn : resolveType(type, checkDefn.getType())); @@ -7115,4 +7136,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat this.example = example; return this; } + + public IDigitalSignatureServices getSignatureServices() { + return signatureServices; + } + + public void setSignatureServices(IDigitalSignatureServices signatureServices) { + this.signatureServices = signatureServices; + } + } \ No newline at end of file From 737c51f2a536c85bae71e3da32d07870b1c0833d Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Mon, 9 Oct 2023 17:46:49 +1100 Subject: [PATCH 07/12] Fix rendering of XML Attributes in profiles --- .../r5/renderers/StructureDefinitionRenderer.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/StructureDefinitionRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/StructureDefinitionRenderer.java index 7c21255ff..845dc8314 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/StructureDefinitionRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/StructureDefinitionRenderer.java @@ -848,8 +848,16 @@ public class StructureDefinitionRenderer extends ResourceRenderer { if (element.hasSliceName()) sName = sName +":"+element.getSliceName(); used.used = true; - if (logicalModel && element.hasRepresentation(PropertyRepresentation.XMLATTR)) - sName = "@"+sName; + if (logicalModel) { + if (element.hasRepresentation(PropertyRepresentation.XMLATTR)) { + sName = "@"+sName; + } else if (element.hasUserData("derived.pointer")) { + ElementDefinition drv = (ElementDefinition) element.getUserData("derived.pointer"); + if (drv.hasRepresentation(PropertyRepresentation.XMLATTR)) { + sName = "@"+sName; + } + } + } Cell nc = genElementNameCell(gen, element, profileBaseFileName, snapshot, corePath, imagePath, root, logicalModel, allInvariants, profile, typesRow, row, hasDef, ext, used, ref, sName, all); switch (context.getStructureMode()) { case BINDINGS: From 7b7484e08ebc5a7c4cce03b8c6f46c6f86397a77 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Mon, 9 Oct 2023 17:47:15 +1100 Subject: [PATCH 08/12] Add support for test folder in NPM packages --- .../org/hl7/fhir/r5/utils/FHIRPathEngine.java | 77 +++++++++++++++---- .../fhir/r5/utils/NPMPackageGenerator.java | 3 +- 2 files changed, 63 insertions(+), 17 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java index dc6f9021e..9bfde3080 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java @@ -135,6 +135,7 @@ public class FHIRPathEngine { private boolean doNotEnforceAsCaseSensitive; private boolean allowDoubleQuotes; private List typeWarnings = new ArrayList<>(); + private boolean emitSQLonFHIRWarning; // if the fhir path expressions are allowed to use constants beyond those defined in the specification // the application can implement them by providing a constant resolver @@ -474,7 +475,7 @@ public class FHIRPathEngine { } } - return executeType(new ExecutionTypeContext(appContext, resourceType, types, types), types, expr, elementDependencies, true, false); + return executeType(new ExecutionTypeContext(appContext, resourceType, types, types), types, expr, elementDependencies, true, false, expr); } /** @@ -531,14 +532,14 @@ public class FHIRPathEngine { } } } - TypeDetails res = executeType(new ExecutionTypeContext(appContext, resourceType, types, types), types, expr, null, true, false); + TypeDetails res = executeType(new ExecutionTypeContext(appContext, resourceType, types, types), types, expr, null, true, false, expr); warnings.addAll(typeWarnings); return res; } public TypeDetails checkOnTypes(Object appContext, String resourceType, TypeDetails types, ExpressionNode expr, List warnings) throws FHIRLexerException, PathEngineException, DefinitionException { typeWarnings.clear(); - TypeDetails res = executeType(new ExecutionTypeContext(appContext, resourceType, types, types), types, expr, null, true, false); + TypeDetails res = executeType(new ExecutionTypeContext(appContext, resourceType, types, types), types, expr, null, true, false, expr); warnings.addAll(typeWarnings); return res; } @@ -566,7 +567,7 @@ public class FHIRPathEngine { } } - return executeType(new ExecutionTypeContext(appContext, resourceType, types, types), types, expr, elementDependencies, true, false); + return executeType(new ExecutionTypeContext(appContext, resourceType, types, types), types, expr, elementDependencies, true, false, expr); } private FHIRException makeExceptionPlural(Integer num, ExpressionNode holder, String constName, Object... args) { @@ -615,13 +616,13 @@ public class FHIRPathEngine { } } - return executeType(new ExecutionTypeContext(appContext, sd.getUrl(), types, types), types, expr, null, true, false); + return executeType(new ExecutionTypeContext(appContext, sd.getUrl(), types, types), types, expr, null, true, false, expr); } public TypeDetails check(Object appContext, StructureDefinition sd, ExpressionNode expr) throws FHIRLexerException, PathEngineException, DefinitionException { // if context is a path that refers to a type, do that conversion now TypeDetails types = null; // this is a special case; the first path reference will have to resolve to something in the context - return executeType(new ExecutionTypeContext(appContext, sd == null ? null : sd.getUrl(), null, types), types, expr, null, true, false); + return executeType(new ExecutionTypeContext(appContext, sd == null ? null : sd.getUrl(), null, types), types, expr, null, true, false, expr); } public TypeDetails check(Object appContext, String resourceType, String context, String expr) throws FHIRLexerException, PathEngineException, DefinitionException { @@ -1515,7 +1516,8 @@ public class FHIRPathEngine { return new TypeDetails(CollectionStatus.SINGLETON, exp.getName()); } - private TypeDetails executeType(ExecutionTypeContext context, TypeDetails focus, ExpressionNode exp, Set elementDependencies, boolean atEntry, boolean canBeNone) throws PathEngineException, DefinitionException { + private TypeDetails executeType(ExecutionTypeContext context, TypeDetails focus, ExpressionNode exp, Set elementDependencies, boolean atEntry, boolean canBeNone, ExpressionNode container) throws PathEngineException, DefinitionException { + TypeDetails result = new TypeDetails(null); switch (exp.getKind()) { case Name: @@ -1539,9 +1541,10 @@ public class FHIRPathEngine { } } } + doSQLOnFHIRCheck(result, exp); break; case Function: - result.update(evaluateFunctionType(context, focus, exp, elementDependencies)); + result.update(evaluateFunctionType(context, focus, exp, elementDependencies, container)); break; case Unary: result.addType(TypeDetails.FP_Integer); @@ -1552,12 +1555,12 @@ public class FHIRPathEngine { result.update(resolveConstantType(context, exp.getConstant(), exp)); break; case Group: - result.update(executeType(context, focus, exp.getGroup(), elementDependencies, atEntry, canBeNone)); + result.update(executeType(context, focus, exp.getGroup(), elementDependencies, atEntry, canBeNone, exp)); } exp.setTypes(result); if (exp.getInner() != null) { - result = executeType(context, result, exp.getInner(), elementDependencies, false, false); + result = executeType(context, result, exp.getInner(), elementDependencies, false, false, exp); } if (exp.isProximal() && exp.getOperation() != null) { @@ -1568,7 +1571,7 @@ public class FHIRPathEngine { if (last.getOperation() == Operation.Is || last.getOperation() == Operation.As) { work = executeTypeName(context, focus, next, atEntry); } else { - work = executeType(context, focus, next, elementDependencies, atEntry, canBeNone); + work = executeType(context, focus, next, elementDependencies, atEntry, canBeNone, exp); } result = operateTypes(result, last.getOperation(), work, last); last = next; @@ -1579,6 +1582,19 @@ public class FHIRPathEngine { return result; } + private void doSQLOnFHIRCheck(TypeDetails focus, ExpressionNode expr) { + if (emitSQLonFHIRWarning) { + // special Logic for SQL-on-FHIR: + if (focus.isChoice()) { + if (expr.getInner() == null || expr.getInner().getFunction() != Function.OfType) { + typeWarnings.add(worker.formatMessage(I18nConstants.FHIRPATH_CHOICE_NO_TYPE_SPECIFIER, expr.toString())); + } + } else if (expr.getInner() != null && expr.getInner().getFunction() == Function.OfType) { + typeWarnings.add(worker.formatMessage(I18nConstants.FHIRPATH_CHOICE_SPURIOUS_TYPE_SPECIFIER, expr.toString())); + } + } + } + private List resolveConstant(ExecutionContext context, Base constant, boolean beforeContext, ExpressionNode expr) throws PathEngineException { if (constant == null) { return new ArrayList(); @@ -3129,16 +3145,16 @@ public class FHIRPathEngine { int i = 0; for (ExpressionNode expr : exp.getParameters()) { if (isExpressionParameter(exp, i)) { - paramTypes.add(executeType(changeThis(context, focus), focus, expr, elementDependencies, true, canBeNone)); + paramTypes.add(executeType(changeThis(context, focus), focus, expr, elementDependencies, true, canBeNone, expr)); } else { - paramTypes.add(executeType(context, context.thisItem, expr, elementDependencies, true, canBeNone)); + paramTypes.add(executeType(context, context.thisItem, expr, elementDependencies, true, canBeNone, expr)); } i++; } } @SuppressWarnings("unchecked") - private TypeDetails evaluateFunctionType(ExecutionTypeContext context, TypeDetails focus, ExpressionNode exp, Set elementDependencies) throws PathEngineException, DefinitionException { + private TypeDetails evaluateFunctionType(ExecutionTypeContext context, TypeDetails focus, ExpressionNode exp, Set elementDependencies, ExpressionNode container) throws PathEngineException, DefinitionException { List paramTypes = new ArrayList(); if (exp.getFunction() == Function.Is || exp.getFunction() == Function.As || exp.getFunction() == Function.OfType) { paramTypes.add(new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String)); @@ -3164,6 +3180,12 @@ public class FHIRPathEngine { } else { evaluateParameters(context, focus, exp, elementDependencies, paramTypes, false); } + if (exp.getFunction() == Function.First || exp.getFunction() == Function.Last || exp.getFunction() == Function.Tail || exp.getFunction() == Function.Skip || exp.getFunction() == Function.Take) { + if (focus.getCollectionStatus() == CollectionStatus.SINGLETON) { + typeWarnings.add(worker.formatMessage(I18nConstants.FHIRPATH_NOT_A_COLLECTION, container.toString())); + + } + } switch (exp.getFunction()) { case Empty : return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean); @@ -5926,6 +5948,9 @@ public class FHIRPathEngine { ElementDefinitionMatch ed = getElementDefinition(sdi, path, isAllowPolymorphicNames(), expr); if (ed != null) { + if (ed.getDefinition().isChoice()) { + result.setChoice(true); + } if (!Utilities.noString(ed.getFixedType())) { if (elementDependencies != null) { elementDependencies.add(ed.definition); @@ -6024,7 +6049,11 @@ public class FHIRPathEngine { if (ed.getPath().equals(path)) { if (ed.hasContentReference()) { ElementDefinitionMatch res = getElementDefinitionById(sd, ed.getContentReference()); - res.sourceDefinition = ed; + if (res == null) { + throw new Error("Unable to find "+ed.getContentReference()); + } else { + res.sourceDefinition = ed; + } return res; } else { return new ElementDefinitionMatch(ed, null); @@ -6055,7 +6084,11 @@ public class FHIRPathEngine { if (ed.hasContentReference() && path.startsWith(ed.getPath()+".")) { ElementDefinitionMatch m = getElementDefinitionById(sd, ed.getContentReference()); ElementDefinitionMatch res = getElementDefinition(sd, m.definition.getPath()+path.substring(ed.getPath().length()), allowTypedName, expr); - res.sourceDefinition = ed; + if (res == null) { + throw new Error("Unable to find "+ed.getContentReference()); + } else { + res.sourceDefinition = ed; + } return res; } } @@ -6090,6 +6123,9 @@ public class FHIRPathEngine { } private ElementDefinitionMatch getElementDefinitionById(StructureDefinition sd, String ref) { + if (ref.startsWith(sd.getUrl()+"#")) { + ref = ref.replace(sd.getUrl()+"#", "#"); + } for (ElementDefinition ed : sd.getSnapshot().getElement()) { if (ref.equals("#"+ed.getId())) { return new ElementDefinitionMatch(ed, null); @@ -6411,4 +6447,13 @@ public class FHIRPathEngine { public void setAllowDoubleQuotes(boolean allowDoubleQuotes) { this.allowDoubleQuotes = allowDoubleQuotes; } + + public boolean isEmitSQLonFHIRWarning() { + return emitSQLonFHIRWarning; + } + + public void setEmitSQLonFHIRWarning(boolean emitSQLonFHIRWarning) { + this.emitSQLonFHIRWarning = emitSQLonFHIRWarning; + } + } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/NPMPackageGenerator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/NPMPackageGenerator.java index e7cef5ab5..fb8bbd49b 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/NPMPackageGenerator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/NPMPackageGenerator.java @@ -73,7 +73,7 @@ import org.hl7.fhir.utilities.npm.ToolsVersion; public class NPMPackageGenerator { public enum Category { - RESOURCE, EXAMPLE, OPENAPI, SCHEMATRON, RDF, OTHER, TOOL, TEMPLATE, JEKYLL; + RESOURCE, EXAMPLE, OPENAPI, SCHEMATRON, RDF, OTHER, TOOL, TEMPLATE, JEKYLL, TEST; private String getDirectory() { switch (this) { @@ -85,6 +85,7 @@ public class NPMPackageGenerator { case OTHER: return "package/other/"; case TEMPLATE: return "package/other/"; case JEKYLL: return "package/jekyll/"; + case TEST: return "package/tests/"; case TOOL: return "package/bin/"; } return "/"; From 97914518fa2a4dea7ef498fdd8571d665450a71f Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Mon, 9 Oct 2023 17:47:49 +1100 Subject: [PATCH 09/12] update test case dependency --- .../org/hl7/fhir/r5/model/TypeDetails.java | 12 +++++++++ .../hl7/fhir/r5/utils/ToolingExtensions.java | 25 ++++++++++++++++++- .../org/hl7/fhir/r5/utils/sql/Runner.java | 1 + pom.xml | 2 +- 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/TypeDetails.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/TypeDetails.java index cde80a5cf..5b6609c19 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/TypeDetails.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/TypeDetails.java @@ -132,6 +132,7 @@ public class TypeDetails { private List types = new ArrayList(); private CollectionStatus collectionStatus; private Set targets; // or, not and, canonical urls + private boolean choice; public TypeDetails(CollectionStatus collectionStatus, String... names) { super(); @@ -308,6 +309,9 @@ public class TypeDetails { } targets.addAll(source.targets); } + if (source.isChoice()) { + choice = true; + } } public TypeDetails union(TypeDetails right) { @@ -537,4 +541,12 @@ public class TypeDetails { return collectionStatus != null && collectionStatus.isList(); } + // for SQL-on-FHIR: warnings when .ofType() is not paired with a choice element + public void setChoice(boolean b) { + choice = true; + } + public boolean isChoice() { + return choice; + } + } \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java index 460677e69..d592d856b 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java @@ -74,6 +74,7 @@ import java.util.HashSet; import org.apache.commons.lang3.StringUtils; import org.fhir.ucum.Utilities; import org.hl7.fhir.exceptions.FHIRException; +import org.hl7.fhir.r5.model.BackboneElement; import org.hl7.fhir.r5.model.Base; import org.hl7.fhir.r5.model.BooleanType; import org.hl7.fhir.r5.model.CanonicalType; @@ -205,7 +206,7 @@ public class ToolingExtensions { public static final String EXT_VS_KEYWORD = "http://hl7.org/fhir/StructureDefinition/valueset-keyWord"; public static final String EXT_WORKGROUP = "http://hl7.org/fhir/StructureDefinition/structuredefinition-wg"; public static final String EXT_XML_NAMESPACE = "http://hl7.org/fhir/StructureDefinition/elementdefinition-namespace"; - public static final String EXT_OLD_CONCEPTMAP_EQUIVALENCE = "http://hl7.org/fhir/1.0/StructureDefinition/extension-ConceptMap.element.target.equivalence"; + public static final String EXT_OLD_CONCEPTMAP_EQUIVALENCE = "http://hl7.org/fhir/1.0/StructureDefinition/extension-ConceptMap.group.element.target.equivalence"; public static final String EXT_Q_IS_SUBJ = "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-isSubject"; public static final String EXT_Q_HIDDEN = "http://hl7.org/fhir/StructureDefinition/questionnaire-hidden"; public static final String EXT_Q_OTP_DISP = "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-optionalDisplay"; @@ -674,6 +675,28 @@ public class ToolingExtensions { resource.getExtension().add(new Extension(uri).setValue(new CodeType(value))); } + public static void setCodeExtensionMod(DomainResource resource, String uri, String value) { + if (Utilities.noString(value)) + return; + + Extension ext = getExtension(resource, uri); + if (ext != null) + ext.setValue(new CodeType(value)); + else + resource.getModifierExtension().add(new Extension(uri).setValue(new CodeType(value))); + } + + public static void setCodeExtensionMod(BackboneElement resource, String uri, String value) { + if (Utilities.noString(value)) + return; + + Extension ext = getExtension(resource, uri); + if (ext != null) + ext.setValue(new CodeType(value)); + else + resource.getModifierExtension().add(new Extension(uri).setValue(new CodeType(value))); + } + public static void setCodeExtension(Element element, String uri, String value) { if (Utilities.noString(value)) return; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/Runner.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/Runner.java index ad34b998f..3ca7c9be9 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/Runner.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/sql/Runner.java @@ -74,6 +74,7 @@ public class Runner implements IEvaluationContext { } fpe = new FHIRPathEngine(context); fpe.setHostServices(this); + fpe.setEmitSQLonFHIRWarning(true); if (viewDefinition == null) { throw new FHIRException("No viewDefinition provided"); } diff --git a/pom.xml b/pom.xml index 89751d330..71a3be9c1 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 32.0.1-jre 6.4.1 - 1.4.8 + 1.4.9-SNAPSHOT 2.15.2 5.9.2 1.8.2 From 423e50c797b1b25f693077f849faa1210d427732 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Mon, 9 Oct 2023 17:57:25 +1100 Subject: [PATCH 10/12] fix missed code --- .../src/main/java/org/hl7/fhir/r5/model/BackboneType.java | 1 + 1 file changed, 1 insertion(+) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneType.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneType.java index 970e86700..e7c34de62 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneType.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneType.java @@ -35,6 +35,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import org.hl7.fhir.r5.model.Enumerations.*; +import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.instance.model.api.IBaseDatatypeElement; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.instance.model.api.ICompositeType; From d08039a3a7d1a97453c996055a6c00a6b335766c Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Mon, 9 Oct 2023 21:09:39 +1100 Subject: [PATCH 11/12] fix issue in extension processing --- .../hl7/fhir/r4/model/BackboneElement.java | 5 +- .../org/hl7/fhir/r4/model/BackboneType.java | 5 +- .../hl7/fhir/r4b/model/BackboneElement.java | 5 +- .../org/hl7/fhir/r4b/model/BackboneType.java | 5 +- .../hl7/fhir/r5/model/BackboneElement.java | 5 +- .../org/hl7/fhir/r5/model/BackboneType.java | 421 +++++++++--------- 6 files changed, 220 insertions(+), 226 deletions(-) diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/BackboneElement.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/BackboneElement.java index 48ab63124..3cacc103a 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/BackboneElement.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/BackboneElement.java @@ -366,9 +366,8 @@ public abstract class BackboneElement extends Element implements IBaseBackboneEl retVal.add(next); } } - List sv = super.getExtensionsByUrl(theUrls); - sv.addAll(retVal); - return sv; + retVal.addAll(super.getExtensionsByUrl(theUrls)); + return java.util.Collections.unmodifiableList(retVal); } diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/BackboneType.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/BackboneType.java index 1b329308e..1fa03307d 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/BackboneType.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/model/BackboneType.java @@ -293,9 +293,8 @@ public abstract class BackboneType extends Type implements IBaseBackboneElement retVal.add(next); } } - List sv = super.getExtensionsByUrl(theUrls); - sv.addAll(retVal); - return sv; + retVal.addAll(super.getExtensionsByUrl(theUrls)); + return java.util.Collections.unmodifiableList(retVal); } diff --git a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/BackboneElement.java b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/BackboneElement.java index 220724330..6e18228db 100644 --- a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/BackboneElement.java +++ b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/BackboneElement.java @@ -367,9 +367,8 @@ public abstract class BackboneElement extends DataType implements IBaseBackboneE retVal.add(next); } } - List sv = super.getExtensionsByUrl(theUrls); - sv.addAll(retVal); - return sv; + retVal.addAll(super.getExtensionsByUrl(theUrls)); + return java.util.Collections.unmodifiableList(retVal); } diff --git a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/BackboneType.java b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/BackboneType.java index ee77c7b2b..92f8f7dcd 100644 --- a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/BackboneType.java +++ b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/model/BackboneType.java @@ -307,9 +307,8 @@ public abstract class BackboneType extends DataType implements IBaseBackboneElem retVal.add(next); } } - List sv = super.getExtensionsByUrl(theUrls); - sv.addAll(retVal); - return sv; + retVal.addAll(super.getExtensionsByUrl(theUrls)); + return java.util.Collections.unmodifiableList(retVal); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneElement.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneElement.java index e25bf74ce..aaac1bb30 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneElement.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneElement.java @@ -331,9 +331,8 @@ Modifier extensions SHALL NOT change the meaning of any elements on Resource or retVal.add(next); } } - List sv = super.getExtensionsByUrl(theUrls); - sv.addAll(retVal); - return sv; + retVal.addAll(super.getExtensionsByUrl(theUrls)); + return java.util.Collections.unmodifiableList(retVal); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneType.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneType.java index e7c34de62..cef6549e6 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneType.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/BackboneType.java @@ -4,19 +4,19 @@ package org.hl7.fhir.r5.model; /* Copyright (c) 2011+, HL7, Inc. All rights reserved. - + Redistribution and use in source and binary forms, with or without modification, \ are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this \ + + * Redistributions of source code must retain the above copyright notice, this \ list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, \ + * Redistributions in binary form must reproduce the above copyright notice, \ this list of conditions and the following disclaimer in the documentation \ and/or other materials provided with the distribution. - * Neither the name of HL7 nor the names of its contributors may be used to + * Neither the name of HL7 nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND \ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \ @@ -27,7 +27,7 @@ package org.hl7.fhir.r5.model; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) \ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \ POSSIBILITY OF SUCH DAMAGE. - */ + */ // Generated on Thu, Mar 23, 2023 19:59+1100 for FHIR v5.0.0 @@ -52,260 +52,259 @@ import ca.uhn.fhir.model.api.annotation.Block; @DatatypeDef(name="BackboneType") public abstract class BackboneType extends DataType implements IBaseBackboneElement { - /** - * May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. 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. Applications processing a resource are required to check for modifier extensions. + /** + * May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. 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. Applications processing a resource are required to check for modifier extensions. Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself). - */ - @Child(name = "modifierExtension", type = {Extension.class}, order=0, min=0, max=Child.MAX_UNLIMITED, modifier=true, summary=true) - @Description(shortDefinition="Extensions that cannot be ignored even if unrecognized", formalDefinition="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. 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. Applications processing a resource are required to check for modifier extensions.\n\nModifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)." ) - protected List modifierExtension; + */ + @Child(name = "modifierExtension", type = {Extension.class}, order=0, min=0, max=Child.MAX_UNLIMITED, modifier=true, summary=true) + @Description(shortDefinition="Extensions that cannot be ignored even if unrecognized", formalDefinition="May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. 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. Applications processing a resource are required to check for modifier extensions.\n\nModifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself)." ) + protected List modifierExtension; - private static final long serialVersionUID = -1431673179L; + private static final long serialVersionUID = -1431673179L; /** * Constructor */ - public BackboneType() { - super(); - } + public BackboneType() { + super(); + } - /** - * @return {@link #modifierExtension} (May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. 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. Applications processing a resource are required to check for modifier extensions. + /** + * @return {@link #modifierExtension} (May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. 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. Applications processing a resource are required to check for modifier extensions. Modifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself).) - */ - public List getModifierExtension() { - if (this.modifierExtension == null) - this.modifierExtension = new ArrayList(); - return this.modifierExtension; - } + */ + public List getModifierExtension() { + if (this.modifierExtension == null) + this.modifierExtension = new ArrayList(); + return this.modifierExtension; + } - /** - * @return Returns a reference to this for easy method chaining - */ - public BackboneType setModifierExtension(List theModifierExtension) { - this.modifierExtension = theModifierExtension; - return this; - } + /** + * @return Returns a reference to this for easy method chaining + */ + public BackboneType setModifierExtension(List theModifierExtension) { + this.modifierExtension = theModifierExtension; + return this; + } - public boolean hasModifierExtension() { - if (this.modifierExtension == null) - return false; - for (Extension item : this.modifierExtension) - if (!item.isEmpty()) - return true; + public boolean hasModifierExtension() { + if (this.modifierExtension == null) return false; - } + for (Extension item : this.modifierExtension) + if (!item.isEmpty()) + return true; + return false; + } - public Extension addModifierExtension() { //3 - Extension t = new Extension(); - if (this.modifierExtension == null) - this.modifierExtension = new ArrayList(); - this.modifierExtension.add(t); - return t; - } + public Extension addModifierExtension() { //3 + Extension t = new Extension(); + if (this.modifierExtension == null) + this.modifierExtension = new ArrayList(); + this.modifierExtension.add(t); + return t; + } - public BackboneType addModifierExtension(Extension t) { //3 - if (t == null) - return this; - if (this.modifierExtension == null) - this.modifierExtension = new ArrayList(); - this.modifierExtension.add(t); + public BackboneType addModifierExtension(Extension t) { //3 + if (t == null) return this; + if (this.modifierExtension == null) + this.modifierExtension = new ArrayList(); + this.modifierExtension.add(t); + return this; + } + + /** + * @return The first repetition of repeating field {@link #modifierExtension}, creating it if it does not already exist {3} + */ + public Extension getModifierExtensionFirstRep() { + if (getModifierExtension().isEmpty()) { + addModifierExtension(); + } + return getModifierExtension().get(0); + } + + protected void listChildren(List children) { + super.listChildren(children); + children.add(new Property("modifierExtension", "Extension", "May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. 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. Applications processing a resource are required to check for modifier extensions.\n\nModifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself).", 0, java.lang.Integer.MAX_VALUE, modifierExtension)); + } + + @Override + public Property getNamedProperty(int _hash, String _name, boolean _checkValid) throws FHIRException { + switch (_hash) { + case -298878168: /*modifierExtension*/ return new Property("modifierExtension", "Extension", "May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. 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. Applications processing a resource are required to check for modifier extensions.\n\nModifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself).", 0, java.lang.Integer.MAX_VALUE, modifierExtension); + default: return super.getNamedProperty(_hash, _name, _checkValid); } - /** - * @return The first repetition of repeating field {@link #modifierExtension}, creating it if it does not already exist {3} - */ - public Extension getModifierExtensionFirstRep() { - if (getModifierExtension().isEmpty()) { - addModifierExtension(); - } - return getModifierExtension().get(0); + } + + @Override + public Base[] getProperty(int hash, String name, boolean checkValid) throws FHIRException { + switch (hash) { + case -298878168: /*modifierExtension*/ return this.modifierExtension == null ? new Base[0] : this.modifierExtension.toArray(new Base[this.modifierExtension.size()]); // Extension + default: return super.getProperty(hash, name, checkValid); } - protected void listChildren(List children) { - super.listChildren(children); - children.add(new Property("modifierExtension", "Extension", "May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. 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. Applications processing a resource are required to check for modifier extensions.\n\nModifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself).", 0, java.lang.Integer.MAX_VALUE, modifierExtension)); - } + } - @Override - public Property getNamedProperty(int _hash, String _name, boolean _checkValid) throws FHIRException { - switch (_hash) { - case -298878168: /*modifierExtension*/ return new Property("modifierExtension", "Extension", "May be used to represent additional information that is not part of the basic definition of the element and that modifies the understanding of the element in which it is contained and/or the understanding of the containing element's descendants. Usually modifier elements provide negation or qualification. 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. Applications processing a resource are required to check for modifier extensions.\n\nModifier extensions SHALL NOT change the meaning of any elements on Resource or DomainResource (including cannot change the meaning of modifierExtension itself).", 0, java.lang.Integer.MAX_VALUE, modifierExtension); - default: return super.getNamedProperty(_hash, _name, _checkValid); - } + @Override + public Base setProperty(int hash, String name, Base value) throws FHIRException { + switch (hash) { + case -298878168: // modifierExtension + this.getModifierExtension().add(TypeConvertor.castToExtension(value)); // Extension + return value; + default: return super.setProperty(hash, name, value); + } - } + } - @Override - public Base[] getProperty(int hash, String name, boolean checkValid) throws FHIRException { - switch (hash) { - case -298878168: /*modifierExtension*/ return this.modifierExtension == null ? new Base[0] : this.modifierExtension.toArray(new Base[this.modifierExtension.size()]); // Extension - default: return super.getProperty(hash, name, checkValid); - } - - } - - @Override - public Base setProperty(int hash, String name, Base value) throws FHIRException { - switch (hash) { - case -298878168: // modifierExtension - this.getModifierExtension().add(TypeConvertor.castToExtension(value)); // Extension - return value; - default: return super.setProperty(hash, name, value); - } - - } - - @Override - public Base setProperty(String name, Base value) throws FHIRException { - if (name.equals("modifierExtension")) { - this.getModifierExtension().add(TypeConvertor.castToExtension(value)); - } else - return super.setProperty(name, value); - return value; - } + @Override + public Base setProperty(String name, Base value) throws FHIRException { + if (name.equals("modifierExtension")) { + this.getModifierExtension().add(TypeConvertor.castToExtension(value)); + } else + return super.setProperty(name, value); + return value; + } @Override public void removeChild(String name, Base value) throws FHIRException { - if (name.equals("modifierExtension")) { - this.getModifierExtension().remove(value); - } else - super.removeChild(name, value); - - } + if (name.equals("modifierExtension")) { + this.getModifierExtension().remove(value); + } else + super.removeChild(name, value); - @Override - public Base makeProperty(int hash, String name) throws FHIRException { - switch (hash) { - case -298878168: return addModifierExtension(); - default: return super.makeProperty(hash, name); - } + } - } + @Override + public Base makeProperty(int hash, String name) throws FHIRException { + switch (hash) { + case -298878168: return addModifierExtension(); + default: return super.makeProperty(hash, name); + } - @Override - public String[] getTypesForProperty(int hash, String name) throws FHIRException { - switch (hash) { - case -298878168: /*modifierExtension*/ return new String[] {"Extension"}; - default: return super.getTypesForProperty(hash, name); - } + } - } + @Override + public String[] getTypesForProperty(int hash, String name) throws FHIRException { + switch (hash) { + case -298878168: /*modifierExtension*/ return new String[] {"Extension"}; + default: return super.getTypesForProperty(hash, name); + } - @Override - public Base addChild(String name) throws FHIRException { - if (name.equals("modifierExtension")) { - return addModifierExtension(); - } - else - return super.addChild(name); - } + } + + @Override + public Base addChild(String name) throws FHIRException { + if (name.equals("modifierExtension")) { + return addModifierExtension(); + } + else + return super.addChild(name); + } public String fhirType() { return "BackboneType"; } - public abstract BackboneType copy(); + public abstract BackboneType copy(); - public void copyValues(BackboneType dst) { - super.copyValues(dst); - if (modifierExtension != null) { - dst.modifierExtension = new ArrayList(); - for (Extension i : modifierExtension) - dst.modifierExtension.add(i.copy()); - }; + public void copyValues(BackboneType dst) { + super.copyValues(dst); + if (modifierExtension != null) { + dst.modifierExtension = new ArrayList(); + for (Extension i : modifierExtension) + dst.modifierExtension.add(i.copy()); + }; + } + + @Override + public boolean equalsDeep(Base other_) { + if (!super.equalsDeep(other_)) + return false; + if (!(other_ instanceof BackboneType)) + return false; + BackboneType o = (BackboneType) other_; + return compareDeep(modifierExtension, o.modifierExtension, true); + } + + @Override + public boolean equalsShallow(Base other_) { + if (!super.equalsShallow(other_)) + return false; + if (!(other_ instanceof BackboneType)) + return false; + BackboneType o = (BackboneType) other_; + return true; + } + + public boolean isEmpty() { + return super.isEmpty() && ca.uhn.fhir.util.ElementUtil.isEmpty(modifierExtension); + } + + // Manual code (from Configuration.txt): + public void checkNoModifiers(String noun, String verb) throws FHIRException { + if (hasModifierExtension()) { + throw new FHIRException("Found unknown Modifier Exceptions on "+noun+" doing "+verb); + } + + } + + + public void copyExtensions(org.hl7.fhir.r5.model.BackboneElement src, String... urls) { + super.copyExtensions(src,urls); + for (Extension e : src.getModifierExtension()) { + if (Utilities.existsInList(e.getUrl(), urls)) { + addModifierExtension(e.copy()); } + } + } - @Override - public boolean equalsDeep(Base other_) { - if (!super.equalsDeep(other_)) - return false; - if (!(other_ instanceof BackboneType)) - return false; - BackboneType o = (BackboneType) other_; - return compareDeep(modifierExtension, o.modifierExtension, true); + public List getExtensionsByUrl(String... theUrls) { + + ArrayList retVal = new ArrayList<>(); + for (Extension next : getModifierExtension()) { + if (Utilities.existsInList(next.getUrl(), theUrls)) { + retVal.add(next); } + } + retVal.addAll(super.getExtensionsByUrl(theUrls)); + return java.util.Collections.unmodifiableList(retVal); + } - @Override - public boolean equalsShallow(Base other_) { - if (!super.equalsShallow(other_)) - return false; - if (!(other_ instanceof BackboneType)) - return false; - BackboneType o = (BackboneType) other_; + + public boolean hasExtension(String... theUrls) { + for (Extension next : getModifierExtension()) { + if (Utilities.existsInList(next.getUrl(), theUrls)) { return true; } - - public boolean isEmpty() { - return super.isEmpty() && ca.uhn.fhir.util.ElementUtil.isEmpty(modifierExtension); - } - -// Manual code (from Configuration.txt): -public void checkNoModifiers(String noun, String verb) throws FHIRException { - if (hasModifierExtension()) { - throw new FHIRException("Found unknown Modifier Exceptions on "+noun+" doing "+verb); - } - + } + return super.hasExtension(theUrls); } - - - public void copyExtensions(org.hl7.fhir.r5.model.BackboneElement src, String... urls) { - super.copyExtensions(src,urls); - for (Extension e : src.getModifierExtension()) { - if (Utilities.existsInList(e.getUrl(), urls)) { - addModifierExtension(e.copy()); - } - } - } - - public List getExtensionsByUrl(String... theUrls) { - - ArrayList retVal = new ArrayList<>(); - for (Extension next : getModifierExtension()) { - if (Utilities.existsInList(next.getUrl(), theUrls)) { - retVal.add(next); - } - } - List sv = super.getExtensionsByUrl(theUrls); - sv.addAll(retVal); - return sv; - } - - - public boolean hasExtension(String... theUrls) { - for (Extension next : getModifierExtension()) { - if (Utilities.existsInList(next.getUrl(), theUrls)) { - return true; - } - } - return super.hasExtension(theUrls); - } - public boolean hasExtension(String theUrl) { - for (Extension ext : getModifierExtension()) { - if (theUrl.equals(ext.getUrl())) { - return true; - } - } + public boolean hasExtension(String theUrl) { + for (Extension ext : getModifierExtension()) { + if (theUrl.equals(ext.getUrl())) { + return true; + } + } - return super.hasExtension(theUrl); - } + return super.hasExtension(theUrl); + } - public void copyNewExtensions(org.hl7.fhir.r5.model.BackboneElement src, String... urls) { - for (Extension e : src.getModifierExtension()) { - if (Utilities.existsInList(e.getUrl(), urls) && !!hasExtension(e.getUrl())) { - addExtension(e.copy()); - } - } - super.copyNewExtensions(src, urls); - } -// end addition + public void copyNewExtensions(org.hl7.fhir.r5.model.BackboneElement src, String... urls) { + for (Extension e : src.getModifierExtension()) { + if (Utilities.existsInList(e.getUrl(), urls) && !!hasExtension(e.getUrl())) { + addExtension(e.copy()); + } + } + super.copyNewExtensions(src, urls); + } + // end addition } From d2a8c91214489f1ec501fe60a5394d2d75587fef Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Mon, 9 Oct 2023 21:09:56 +1100 Subject: [PATCH 12/12] fix UUID() and don't throw errors processing StructureMaps --- .../structuremap/StructureMapUtilities.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/structuremap/StructureMapUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/structuremap/StructureMapUtilities.java index 563ae47de..afd641e8d 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/structuremap/StructureMapUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/structuremap/StructureMapUtilities.java @@ -1256,7 +1256,7 @@ public class StructureMapUtilities { vars.add(VariableMode.OUTPUT, getInputName(g, StructureMapInputMode.TARGET, "target"), target); else if (getInputName(g, StructureMapInputMode.TARGET, null) != null) { String type = getInputType(g, StructureMapInputMode.TARGET); - throw new Error("not handled yet: creating a type of " + type); + throw new FHIRException("not handled yet: creating a type of " + type); } executeGroup("", context, map, vars, g, true); @@ -1424,7 +1424,7 @@ public class StructureMapUtilities { Set check = new HashSet(); for (StructureMap sm : res) { if (check.contains(sm.getUrl())) - throw new Error("duplicate"); + throw new FHIRException("duplicate"); else check.add(sm.getUrl()); } @@ -1753,7 +1753,7 @@ public class StructureMapUtilities { else if (srcVar != null) { tn = determineTypeFromSourceType(map, group, vars.get(VariableMode.INPUT, srcVar), types); } else - throw new Error("Cannot determine type implicitly because there is no single input variable"); + throw new FHIRException("Cannot determine type implicitly because there is no single input variable"); } else { tn = getParamStringNoNull(vars, tgt.getParameter().get(0), tgt.toString()); // ok, now we resolve the type name against the import statements @@ -1799,7 +1799,7 @@ public class StructureMapUtilities { } return new StringType(src); case ESCAPE: - throw new Error("Rule \"" + rulePath + "\": Transform " + tgt.getTransform().toCode() + " not supported yet"); + throw new FHIRException("Rule \"" + rulePath + "\": Transform " + tgt.getTransform().toCode() + " not supported yet"); case CAST: src = getParamString(vars, tgt.getParameter().get(0)); if (tgt.getParameter().size() == 1) @@ -1870,7 +1870,7 @@ public class StructureMapUtilities { return new StringType(b.fhirType() + "/" + id); } case DATEOP: - throw new Error("Rule \"" + rulePath + "\": Transform " + tgt.getTransform().toCode() + " not supported yet"); + throw new FHIRException("Rule \"" + rulePath + "\": Transform " + tgt.getTransform().toCode() + " not supported yet"); case UUID: return new IdType(UUID.randomUUID().toString()); case POINTER: @@ -1887,7 +1887,7 @@ public class StructureMapUtilities { Coding c = buildCoding(getParamStringNoNull(vars, tgt.getParameter().get(0), tgt.toString()), getParamStringNoNull(vars, tgt.getParameter().get(1), tgt.toString())); return c; default: - throw new Error("Rule \"" + rulePath + "\": Transform Unknown: " + tgt.getTransform().toCode()); + throw new FHIRException("Rule \"" + rulePath + "\": Transform Unknown: " + tgt.getTransform().toCode()); } } catch (Exception e) { throw new FHIRException("Exception executing transform " + tgt.toString() + " on Rule \"" + rulePath + "\": " + e.getMessage(), e); @@ -2214,7 +2214,7 @@ public class StructureMapUtilities { TypeDetails type = new TypeDetails(CollectionStatus.SINGLETON); for (TypeRefComponent tr : element.getDefinition().getType()) { if (!tr.hasCode()) - throw new Error("Rule \"" + ruleId + "\": Element has no type"); + throw new FHIRException("Rule \"" + ruleId + "\": Element has no type"); ProfiledType pt = new ProfiledType(tr.getWorkingCode()); if (tr.hasProfile()) pt.addProfiles(tr.getProfile()); @@ -2268,7 +2268,7 @@ public class StructureMapUtilities { } if (mapsSrc) { if (var == null) - throw new Error("Rule \"" + ruleId + "\": Attempt to assign with no context"); + throw new FHIRException("Rule \"" + ruleId + "\": Attempt to assign with no context"); tw.valueAssignment(tgt.getContext(), var.getProperty().getPath() + "." + tgt.getElement() + getTransformSuffix(tgt.getTransform())); } else if (tgt.hasContext()) { if (isSignificantElement(var.getProperty(), tgt.getElement())) { @@ -2531,8 +2531,10 @@ public class StructureMapUtilities { TypeDetails td = new TypeDetails(CollectionStatus.SINGLETON); td.addType("Reference", profile); return td; + case UUID: + return new TypeDetails(CollectionStatus.SINGLETON, "id"); default: - throw new Error("Transform Unknown or not handled yet: " + tgt.getTransform().toCode()); + throw new FHIRException("Transform Unknown or not handled yet: " + tgt.getTransform().toCode()); } }