From 29f253bf2c020ffe47440322b3898a87ef9c7d00 Mon Sep 17 00:00:00 2001 From: Michael Lawley Date: Tue, 21 May 2019 15:46:27 +1000 Subject: [PATCH 1/5] relax validation rules for implicit valusets --- .../hl7/fhir/r4/validation/InstanceValidator.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r4/validation/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r4/validation/InstanceValidator.java index dc38f363d..25ca31df7 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r4/validation/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r4/validation/InstanceValidator.java @@ -2759,12 +2759,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat vs = null; } if (vs != null) { - if (rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs.hasCompose() && !vs.hasExpansion(), "CodeSystem "+url+" has a 'all system' value set of "+vsu+", but it is an expansion")) - if (rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs.getCompose().getInclude().size() == 1, "CodeSystem "+url+" has a 'all system' value set of "+vsu+", but doesn't have a single include")) - if (rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs.getCompose().getInclude().get(0).getSystem().equals(url), "CodeSystem "+url+" has a 'all system' value set of "+vsu+", but doesn't have a matching system ("+vs.getCompose().getInclude().get(0).getSystem()+")")) { - rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), !vs.getCompose().getInclude().get(0).hasValueSet() - && !vs.getCompose().getInclude().get(0).hasConcept() && !vs.getCompose().getInclude().get(0).hasFilter(), "CodeSystem "+url+" has a 'all system' value set of "+vsu+", but the include has extra details"); - } + warning(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs.hasCompose() && !vs.hasExpansion(), "CodeSystem "+url+" has a 'all system' value set of "+vsu+", and contains an expansion"); + if (rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs.getCompose().getInclude().size() == 0, "CodeSystem "+url+" has a 'all system' value set of "+vsu+", but doesn't have an include")) + if (rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), vs.getCompose().getInclude().get(0).getSystem().equals(url), "CodeSystem "+url+" has a 'all system' value set of "+vsu+", but doesn't have a matching system ("+vs.getCompose().getInclude().get(0).getSystem()+")")) { + if (rule(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), !vs.getCompose().getInclude().get(0).hasValueSet() && !vs.getCompose().getInclude().get(0).hasConcept(), "CodeSystem "+url+" has a 'all system' value set of "+vsu+", but the include has extra details")) + warning(errors, IssueType.BUSINESSRULE, stack.getLiteralPath(), !vs.getCompose().getInclude().get(0).hasFilter(), "CodeSystem "+url+" has a 'all system' value set of "+vsu+", but the include involves filters"); + } } } // todo... try getting the value set the other way... } From 88f3924ba7ce6e15915bb3c2a02ef7a2405b03fc Mon Sep 17 00:00:00 2001 From: Lloyd McKenzie Date: Thu, 23 May 2019 14:19:15 -0600 Subject: [PATCH 2/5] New test case - contained profiles not supported by validator and validator doesn't check profiles asserted on references to contained resources. --- .../validation-examples/manifest.json | 8 +++- .../patient-contained-org-profile.xml | 48 +++++++++++++++++++ .../patient-contained-org.xml | 20 ++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 org.hl7.fhir.validation/src/test/resources/validation-examples/patient-contained-org-profile.xml create mode 100644 org.hl7.fhir.validation/src/test/resources/validation-examples/patient-contained-org.xml diff --git a/org.hl7.fhir.validation/src/test/resources/validation-examples/manifest.json b/org.hl7.fhir.validation/src/test/resources/validation-examples/manifest.json index 774d3611f..f6c44462e 100644 --- a/org.hl7.fhir.validation/src/test/resources/validation-examples/manifest.json +++ b/org.hl7.fhir.validation/src/test/resources/validation-examples/manifest.json @@ -560,8 +560,14 @@ "source" : "slicing-example-uk.profile.xml", "errorCount": 16 } + }, + "patient-contained-org.xml" : { + "errorCount": 0, + "profile" : { + "source" : "patient-contained-org-profile.xml", + "errorCount": 1 + } } - } } } \ No newline at end of file diff --git a/org.hl7.fhir.validation/src/test/resources/validation-examples/patient-contained-org-profile.xml b/org.hl7.fhir.validation/src/test/resources/validation-examples/patient-contained-org-profile.xml new file mode 100644 index 000000000..805a06c70 --- /dev/null +++ b/org.hl7.fhir.validation/src/test/resources/validation-examples/patient-contained-org-profile.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.hl7.fhir.validation/src/test/resources/validation-examples/patient-contained-org.xml b/org.hl7.fhir.validation/src/test/resources/validation-examples/patient-contained-org.xml new file mode 100644 index 000000000..5a6fb5faf --- /dev/null +++ b/org.hl7.fhir.validation/src/test/resources/validation-examples/patient-contained-org.xml @@ -0,0 +1,20 @@ + + + + +
+ Check that profile validation checks contained resources - should fail because Organization is missing 'name' which is required by profile +
+
+ + + + + + + + + + + +
From 1aa26aee72fbac52fae4721ee9f51b978bb9dfc3 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Fri, 24 May 2019 22:42:05 +1000 Subject: [PATCH 3/5] rendering improvemnets for code system --- .../org/hl7/fhir/r5/context/BaseWorkerContext.java | 8 ++++++-- .../main/java/org/hl7/fhir/r5/model/Constants.java | 1 + .../org/hl7/fhir/r5/utils/NarrativeGenerator.java | 11 +++++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) 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 0035756d9..e348514f3 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 @@ -800,8 +800,12 @@ public abstract class BaseWorkerContext implements IWorkerContext { public Resource fetchResourceById(String type, String uri) { synchronized (lock) { String[] parts = uri.split("\\/"); - if (!Utilities.noString(type) && parts.length == 1) - return allResourcesById.get(type).get(parts[0]); + if (!Utilities.noString(type) && parts.length == 1) { + if (allResourcesById.containsKey(type)) + return allResourcesById.get(type).get(parts[0]); + else + return null; + } if (parts.length >= 2) { if (!Utilities.noString(type)) if (!type.equals(parts[parts.length-2])) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Constants.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Constants.java index e572af7fc..1c4185fd3 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Constants.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Constants.java @@ -59,4 +59,5 @@ public class Constants { public final static String BUILD_ID = "e0e3caf9ba"; public final static String DATE = "Thu Dec 13 14:07:26 AEDT 2018"; public final static String URI_REGEX = "((http|https)://([A-Za-z0-9\\\\\\.\\:\\%\\$]*\\/)*)?(Account|ActivityDefinition|AdverseEvent|AllergyIntolerance|Appointment|AppointmentResponse|AuditEvent|Basic|Binary|BiologicallyDerivedProduct|BodyStructure|Bundle|CapabilityStatement|CarePlan|CareTeam|CatalogEntry|ChargeItem|ChargeItemDefinition|Claim|ClaimResponse|ClinicalImpression|CodeSystem|Communication|CommunicationRequest|CompartmentDefinition|Composition|ConceptMap|Condition|Consent|Contract|Coverage|CoverageEligibilityRequest|CoverageEligibilityResponse|DetectedIssue|Device|DeviceDefinition|DeviceMetric|DeviceRequest|DeviceUseStatement|DiagnosticReport|DocumentManifest|DocumentReference|EffectEvidenceSynthesis|Encounter|Endpoint|EnrollmentRequest|EnrollmentResponse|EpisodeOfCare|EventDefinition|Evidence|EvidenceVariable|ExampleScenario|ExplanationOfBenefit|FamilyMemberHistory|Flag|Goal|GraphDefinition|Group|GuidanceResponse|HealthcareService|ImagingStudy|Immunization|ImmunizationEvaluation|ImmunizationRecommendation|ImplementationGuide|InsurancePlan|Invoice|Library|Linkage|List|Location|Measure|MeasureReport|Media|Medication|MedicationAdministration|MedicationDispense|MedicationKnowledge|MedicationRequest|MedicationStatement|MedicinalProduct|MedicinalProductAuthorization|MedicinalProductContraindication|MedicinalProductIndication|MedicinalProductIngredient|MedicinalProductInteraction|MedicinalProductManufactured|MedicinalProductPackaged|MedicinalProductPharmaceutical|MedicinalProductUndesirableEffect|MessageDefinition|MessageHeader|MolecularSequence|NamingSystem|NutritionOrder|Observation|ObservationDefinition|OperationDefinition|OperationOutcome|Organization|OrganizationAffiliation|Patient|PaymentNotice|PaymentReconciliation|Person|PlanDefinition|Practitioner|PractitionerRole|Procedure|Provenance|Questionnaire|QuestionnaireResponse|RelatedPerson|RequestGroup|ResearchDefinition|ResearchElementDefinition|ResearchStudy|ResearchSubject|RiskAssessment|RiskEvidenceSynthesis|Schedule|SearchParameter|ServiceRequest|Slot|Specimen|SpecimenDefinition|StructureDefinition|StructureMap|Subscription|Substance|SubstanceNucleicAcid|SubstancePolymer|SubstanceProtein|SubstanceReferenceInformation|SubstanceSourceMaterial|SubstanceSpecification|SupplyDelivery|SupplyRequest|Task|TerminologyCapabilities|TestReport|TestScript|ValueSet|VerificationResult|VisionPrescription)\\/[A-Za-z0-9\\-\\.]{1,64}(\\/_history\\/[A-Za-z0-9\\-\\.]{1,64})?"; + public final static String LOCAL_REF_REGEX = "(Account|ActivityDefinition|AdverseEvent|AllergyIntolerance|Appointment|AppointmentResponse|AuditEvent|Basic|Binary|BiologicallyDerivedProduct|BodyStructure|Bundle|CapabilityStatement|CarePlan|CareTeam|CatalogEntry|ChargeItem|ChargeItemDefinition|Claim|ClaimResponse|ClinicalImpression|CodeSystem|Communication|CommunicationRequest|CompartmentDefinition|Composition|ConceptMap|Condition|Consent|Contract|Coverage|CoverageEligibilityRequest|CoverageEligibilityResponse|DetectedIssue|Device|DeviceDefinition|DeviceMetric|DeviceRequest|DeviceUseStatement|DiagnosticReport|DocumentManifest|DocumentReference|EffectEvidenceSynthesis|Encounter|Endpoint|EnrollmentRequest|EnrollmentResponse|EpisodeOfCare|EventDefinition|Evidence|EvidenceVariable|ExampleScenario|ExplanationOfBenefit|FamilyMemberHistory|Flag|Goal|GraphDefinition|Group|GuidanceResponse|HealthcareService|ImagingStudy|Immunization|ImmunizationEvaluation|ImmunizationRecommendation|ImplementationGuide|InsurancePlan|Invoice|Library|Linkage|List|Location|Measure|MeasureReport|Media|Medication|MedicationAdministration|MedicationDispense|MedicationKnowledge|MedicationRequest|MedicationStatement|MedicinalProduct|MedicinalProductAuthorization|MedicinalProductContraindication|MedicinalProductIndication|MedicinalProductIngredient|MedicinalProductInteraction|MedicinalProductManufactured|MedicinalProductPackaged|MedicinalProductPharmaceutical|MedicinalProductUndesirableEffect|MessageDefinition|MessageHeader|MolecularSequence|NamingSystem|NutritionOrder|Observation|ObservationDefinition|OperationDefinition|OperationOutcome|Organization|OrganizationAffiliation|Patient|PaymentNotice|PaymentReconciliation|Person|PlanDefinition|Practitioner|PractitionerRole|Procedure|Provenance|Questionnaire|QuestionnaireResponse|RelatedPerson|RequestGroup|ResearchDefinition|ResearchElementDefinition|ResearchStudy|ResearchSubject|RiskAssessment|RiskEvidenceSynthesis|Schedule|SearchParameter|ServiceRequest|Slot|Specimen|SpecimenDefinition|StructureDefinition|StructureMap|Subscription|Substance|SubstanceNucleicAcid|SubstancePolymer|SubstanceProtein|SubstanceReferenceInformation|SubstanceSourceMaterial|SubstanceSpecification|SupplyDelivery|SupplyRequest|Task|TerminologyCapabilities|TestReport|TestScript|ValueSet|VerificationResult|VisionPrescription)\\/[A-Za-z0-9\\-\\.]{1,64}"; } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/NarrativeGenerator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/NarrativeGenerator.java index 2a7758af5..e0e325150 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/NarrativeGenerator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/NarrativeGenerator.java @@ -3369,7 +3369,7 @@ public class NarrativeGenerator implements INarrativeGenerator { return "??Lang"; } - private boolean addDefineRowToTable(XhtmlNode t, ConceptDefinitionComponent c, int i, boolean hasHierarchy, boolean hasDisplay, boolean comment, boolean version, boolean deprecated, List maps, String system, CodeSystem cs, String lang) { + private boolean addDefineRowToTable(XhtmlNode t, ConceptDefinitionComponent c, int i, boolean hasHierarchy, boolean hasDisplay, boolean comment, boolean version, boolean deprecated, List maps, String system, CodeSystem cs, String lang) throws FHIRFormatError, DefinitionException, IOException { boolean hasExtensions = false; XhtmlNode tr = t.tr(); XhtmlNode td = tr.td(); @@ -3417,7 +3417,10 @@ public class NarrativeGenerator implements INarrativeGenerator { if (c != null && c.hasDefinitionElement()) { if (lang == null) { - td.addText(c.getDefinition()); + if (hasMarkdownInDefinitions(cs)) + addMarkdown(td, c.getDefinition()); + else + td.addText(c.getDefinition()); } else if (lang.equals("*")) { boolean sl = false; for (ConceptDefinitionDesignationComponent cd : c.getDesignation()) @@ -3534,6 +3537,10 @@ public class NarrativeGenerator implements INarrativeGenerator { } + private boolean hasMarkdownInDefinitions(CodeSystem cs) { + return ToolingExtensions.readBoolExtension(cs, "http://hl7.org/fhir/StructureDefinition/codesystem-use-markdown"); + } + private String makeAnchor(String codeSystem, String code) { String s = codeSystem+'-'+code; StringBuilder b = new StringBuilder(); From 6af05d5762a0506162fd0fe1d83c99e96106705a Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Fri, 24 May 2019 22:42:41 +1000 Subject: [PATCH 4/5] Release new version --- org.hl7.fhir.convertors/pom.xml | 2 +- org.hl7.fhir.dstu2/pom.xml | 2 +- org.hl7.fhir.dstu2016may/pom.xml | 2 +- org.hl7.fhir.dstu3/pom.xml | 2 +- org.hl7.fhir.r4/pom.xml | 2 +- org.hl7.fhir.r5/pom.xml | 2 +- org.hl7.fhir.utilities/pom.xml | 2 +- org.hl7.fhir.validation.cli/pom.xml | 2 +- org.hl7.fhir.validation/pom.xml | 2 +- pom.xml | 2 +- release.bat | 16 ++++++++-------- 11 files changed, 18 insertions(+), 18 deletions(-) diff --git a/org.hl7.fhir.convertors/pom.xml b/org.hl7.fhir.convertors/pom.xml index 6f2a5d019..b082643de 100644 --- a/org.hl7.fhir.convertors/pom.xml +++ b/org.hl7.fhir.convertors/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 3.7.37-SNAPSHOT + 3.7.38-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu2/pom.xml b/org.hl7.fhir.dstu2/pom.xml index 296317077..6be59ddb6 100644 --- a/org.hl7.fhir.dstu2/pom.xml +++ b/org.hl7.fhir.dstu2/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 3.7.37-SNAPSHOT + 3.7.38-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu2016may/pom.xml b/org.hl7.fhir.dstu2016may/pom.xml index a5b276a02..3922fe3e1 100644 --- a/org.hl7.fhir.dstu2016may/pom.xml +++ b/org.hl7.fhir.dstu2016may/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 3.7.37-SNAPSHOT + 3.7.38-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu3/pom.xml b/org.hl7.fhir.dstu3/pom.xml index 6e83abc5a..e0dc273cf 100644 --- a/org.hl7.fhir.dstu3/pom.xml +++ b/org.hl7.fhir.dstu3/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 3.7.37-SNAPSHOT + 3.7.38-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.r4/pom.xml b/org.hl7.fhir.r4/pom.xml index 526e7629b..0136dffde 100644 --- a/org.hl7.fhir.r4/pom.xml +++ b/org.hl7.fhir.r4/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 3.7.37-SNAPSHOT + 3.7.38-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.r5/pom.xml b/org.hl7.fhir.r5/pom.xml index 406283533..446bd909f 100644 --- a/org.hl7.fhir.r5/pom.xml +++ b/org.hl7.fhir.r5/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 3.7.37-SNAPSHOT + 3.7.38-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.utilities/pom.xml b/org.hl7.fhir.utilities/pom.xml index f320fd4bd..5c6a0c59c 100644 --- a/org.hl7.fhir.utilities/pom.xml +++ b/org.hl7.fhir.utilities/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 3.7.37-SNAPSHOT + 3.7.38-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.validation.cli/pom.xml b/org.hl7.fhir.validation.cli/pom.xml index ae49a27c1..9fafa2790 100644 --- a/org.hl7.fhir.validation.cli/pom.xml +++ b/org.hl7.fhir.validation.cli/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 3.7.37-SNAPSHOT + 3.7.38-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.validation/pom.xml b/org.hl7.fhir.validation/pom.xml index cdd4be000..7566662ac 100644 --- a/org.hl7.fhir.validation/pom.xml +++ b/org.hl7.fhir.validation/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 3.7.37-SNAPSHOT + 3.7.38-SNAPSHOT ../pom.xml diff --git a/pom.xml b/pom.xml index a02fce849..bec831e65 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ each other. It is fine to bump the point version of this POM without affecting HAPI FHIR. --> - 3.7.37-SNAPSHOT + 3.7.38-SNAPSHOT 3.7.0-SNAPSHOT diff --git a/release.bat b/release.bat index 9215e95da..697c16d6c 100644 --- a/release.bat +++ b/release.bat @@ -4,25 +4,25 @@ REM make sure you are committed @echo off echo .. echo ===================================================================== -echo upgrade and release fhir.core from 3.7.36-SNAPSHOT to 3.7.37-SNAPSHOT +echo upgrade and release fhir.core from 3.7.37-SNAPSHOT to 3.7.38-SNAPSHOT echo ===================================================================== echo .. echo check versions and make sure committed... pause -call mvn versions:set -DnewVersion=3.7.37-SNAPSHOT +call mvn versions:set -DnewVersion=3.7.38-SNAPSHOT call git commit -a -m "Release new version" call git push origin master -call "C:\tools\fnr.exe" --cl --dir "C:\work\org.hl7.fhir\build" --fileMask "*.java" --includeSubDirectories --find "3.7.36-SNAPSHOT" --replace "3.7.37-SNAPSHOT" -call "C:\tools\fnr.exe" --cl --dir "C:\work\org.hl7.fhir\fhir-ig-publisher" --fileMask "*.xml" --includeSubDirectories --find "3.7.36-SNAPSHOT" --replace "3.7.37-SNAPSHOT" -call "C:\tools\fnr.exe" --cl --dir "C:\work\org.hl7.fhir\build" --fileMask "*.xml" --find "3.7.36-SNAPSHOT" --replace "3.7.37-SNAPSHOT" +call "C:\tools\fnr.exe" --cl --dir "C:\work\org.hl7.fhir\build" --fileMask "*.java" --includeSubDirectories --find "3.7.37-SNAPSHOT" --replace "3.7.38-SNAPSHOT" +call "C:\tools\fnr.exe" --cl --dir "C:\work\org.hl7.fhir\fhir-ig-publisher" --fileMask "*.xml" --includeSubDirectories --find "3.7.37-SNAPSHOT" --replace "3.7.38-SNAPSHOT" +call "C:\tools\fnr.exe" --cl --dir "C:\work\org.hl7.fhir\build" --fileMask "*.xml" --find "3.7.37-SNAPSHOT" --replace "3.7.38-SNAPSHOT" call mvn deploy -copy org.hl7.fhir.validation.cli\target\org.hl7.fhir.validation.cli-3.7.37-SNAPSHOT.jar ..\latest-ig-publisher\org.hl7.fhir.validator.jar +copy org.hl7.fhir.validation.cli\target\org.hl7.fhir.validation.cli-3.7.38-SNAPSHOT.jar ..\latest-ig-publisher\org.hl7.fhir.validator.jar cd ..\latest-ig-publisher -call git commit -a -m "Release new version 3.7.37-SNAPSHOT" +call git commit -a -m "Release new version 3.7.38-SNAPSHOT" call git push origin master cd ..\org.hl7.fhir.core -call python c:\tools\zulip-api\zulip\zulip\send.py --stream committers/notification --subject "java core" -m "New Java Core v3.7.37-SNAPSHOT released. New Validator at https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=ca.uhn.hapi.fhir&a=org.hl7.fhir.validation.cli&v=3.7.37-SNAPSHOT&e=jar, and also deployed at https://fhir.github.io/latest-ig-publisher/org.hl7.fhir.validator.jar" --config-file zuliprc +call python c:\tools\zulip-api\zulip\zulip\send.py --stream committers/notification --subject "java core" -m "New Java Core v3.7.38-SNAPSHOT released. New Validator at https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=ca.uhn.hapi.fhir&a=org.hl7.fhir.validation.cli&v=3.7.38-SNAPSHOT&e=jar, and also deployed at https://fhir.github.io/latest-ig-publisher/org.hl7.fhir.validator.jar" --config-file zuliprc echo =============================================================== echo all done From 2cc62df9158f5b537da23d2a84a727a4f34df055 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Sat, 25 May 2019 07:23:20 +1000 Subject: [PATCH 5/5] extend validator to handle contained profiles --- .../org/hl7/fhir/r5/model/DomainResource.java | 86 +++++++++++-------- .../fhir/r5/model/StructureDefinition.java | 1 - .../fhir/r5/validation/InstanceValidator.java | 36 +++++--- 3 files changed, 73 insertions(+), 50 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/DomainResource.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/DomainResource.java index 7bd5a248a..dd1d73ae4 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/DomainResource.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/DomainResource.java @@ -447,47 +447,59 @@ Modifier extensions SHALL NOT change the meaning of any elements on Resource or // added from java-adornments.txt: - public void checkNoModifiers(String noun, String verb) throws FHIRException { + public void checkNoModifiers(String noun, String verb) throws FHIRException { if (hasModifierExtension()) { throw new FHIRException("Found unknown Modifier Exceptions on "+noun+" doing "+verb); } + + } + + public void addExtension(String url, Type value) { + Extension ex = new Extension(); + ex.setUrl(url); + ex.setValue(value); + getExtension().add(ex); + } + + + + + public boolean hasExtension(String url) { + for (Extension e : getExtension()) + if (url.equals(e.getUrl())) + return true; + return false; + } + + public Extension getExtensionByUrl(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); + } + } + 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); + } + } + + + public Resource getContained(String ref) { + if (ref == null) + return null; - } - - public void addExtension(String url, Type value) { - Extension ex = new Extension(); - ex.setUrl(url); - ex.setValue(value); - getExtension().add(ex); - } - - - - - public boolean hasExtension(String url) { - for (Extension e : getExtension()) - if (url.equals(e.getUrl())) - return true; - return false; - } - - public Extension getExtensionByUrl(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); - } - } - 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); - } - } - - + if (ref.startsWith("#")) + ref = ref.substring(1); + for (Resource r : getContained()) { + if (r.getId().equals(ref)) + return r; + } + return null; + } // end addition diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java index 951cf2449..956297c82 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java @@ -3885,6 +3885,5 @@ public class StructureDefinition extends MetadataResource { */ public static final ca.uhn.fhir.model.api.Include INCLUDE_BASE = new ca.uhn.fhir.model.api.Include("StructureDefinition:base").toLocked(); - } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java index 6c8ec00a9..0596b76fa 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/r5/validation/InstanceValidator.java @@ -392,11 +392,11 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (!ok) errors.add(new ValidationMessage(Source.InstanceValidator, IssueType.UNKNOWN, path, "Profile mismatch on type for "+profile.getProfile()+": the profile constrains "+sd.getType()+" but the element is "+element.fhirType(), IssueSeverity.ERROR)); } else - addProfile(errors, profile.getProfile(), profile.isError(), path, element); + addProfile(errors, profile.getProfile(), profile.isError(), path, element, sd); } } - public boolean addProfile(List errors, String profile, boolean error, String path, Element element) { + public boolean addProfile(List errors, String profile, boolean error, String path, Element element, StructureDefinition containingProfile) { String effectiveProfile = profile; String version = null; if (profile.contains("|")) { @@ -404,10 +404,22 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat version = profile.substring(profile.indexOf('|')+1); } StructureDefinition sd = null; - if (providedProfiles != null) - sd = providedProfiles.fetch(effectiveProfile); - if (sd == null) - sd = context.fetchResource(StructureDefinition.class, effectiveProfile); + if (profile.startsWith("#")) { + if (!rule(errors, IssueType.INVALID, element.line(), element.col(), path, sd != null, "StructureDefinition reference \"{0}\" is local, but there is not local context", profile)) { + return false; + } + + if (containingProfile.hasUserData("container")) + containingProfile = (StructureDefinition) containingProfile.getUserData("container"); + sd = (StructureDefinition) containingProfile.getContained(profile); + if (sd != null) + sd.setUserData("container", containingProfile); + } else { + if (providedProfiles != null) + sd = providedProfiles.fetch(effectiveProfile); + if (sd == null) + sd = context.fetchResource(StructureDefinition.class, effectiveProfile); + } if (warningOrError(error, errors, IssueType.INVALID, element.line(), element.col(), path, sd != null, "StructureDefinition reference \"{0}\" could not be resolved", profile)) { if (rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, version==null || (sd.getVersion()!=null && sd.getVersion().equals(version)), @@ -1180,7 +1192,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat String p = stack.addToLiteralPath("meta", "profile", ":" + Integer.toString(i)); if (rule(errors, IssueType.INVALID, element.line(), element.col(), p, !Utilities.noString(ref), "StructureDefinition reference invalid")) { long t = System.nanoTime(); - resourceProfiles.addProfile(errors, ref, errorForUnknownProfiles, p, element); + resourceProfiles.addProfile(errors, ref, errorForUnknownProfiles, p, element, null); i++; } } @@ -1859,7 +1871,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat b.append(bt); ok = bt.equals(ft); if (ok && we!=null && pol.checkValid()) { - doResourceProfile(hostContext, we, pr, errors, stack.push(we, -1, null, null), path, element); + doResourceProfile(hostContext, we, pr, errors, stack.push(we, -1, null, null), path, element, profile); } } else ok = true; // suppress following check @@ -1909,8 +1921,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } - private void doResourceProfile(ValidatorHostContext hostContext, Element resource, String profile, List errors, NodeStack stack, String path, Element element) throws FHIRException, IOException { - ResourceProfiles resourceProfiles = addResourceProfile(errors, resource, profile, path, element, stack); + private void doResourceProfile(ValidatorHostContext hostContext, Element resource, String profile, List errors, NodeStack stack, String path, Element element, StructureDefinition containingProfile) throws FHIRException, IOException { + ResourceProfiles resourceProfiles = addResourceProfile(errors, resource, profile, path, element, stack, containingProfile); if (resourceProfiles.isProcessed()) { start(hostContext, errors, resource, resource, null, stack); } @@ -1925,9 +1937,9 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat return resourceProfiles; } - private ResourceProfiles addResourceProfile(List errors, Element resource, String profile, String path, Element element, NodeStack stack) { + private ResourceProfiles addResourceProfile(List errors, Element resource, String profile, String path, Element element, NodeStack stack, StructureDefinition containingProfile) { ResourceProfiles resourceProfiles = getResourceProfiles(resource, stack); - resourceProfiles.addProfile(errors, profile, errorForUnknownProfiles, path, element); + resourceProfiles.addProfile(errors, profile, errorForUnknownProfiles, path, element, containingProfile); return resourceProfiles; }