diff --git a/.github/workflows/bidi-checker.yml b/.github/workflows/bidi-checker.yml new file mode 100644 index 000000000..cae645b5f --- /dev/null +++ b/.github/workflows/bidi-checker.yml @@ -0,0 +1,28 @@ +name: BIDI CHECK + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [ master ] + pull_request: + branches: [ master ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + bidi_checker_job: + runs-on: ubuntu-latest + name: Check for bidi unicode characters in repo + steps: + # Checkout the repo code. IMPORTANT, this step is needed to populate the directory defined by GITHUB_WORKSPACE + - name: Checkout repo + uses: actions/checkout@v1 + id: checkout + # Run the check for bidi characters. + - name: Check for bidi characters + id: bidi_check + uses: HL7/bidi-checker-action@v1.5 + - name: Get the output time + run: echo "The time was ${{ steps.bidi_check.outputs.time }}" diff --git a/org.hl7.fhir.convertors/pom.xml b/org.hl7.fhir.convertors/pom.xml index 58dac6bdf..125972da6 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 - 5.6.1-SNAPSHOT + 5.6.2-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu2/pom.xml b/org.hl7.fhir.dstu2/pom.xml index b764bf51f..467f8654d 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 - 5.6.1-SNAPSHOT + 5.6.2-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/IWorkerContext.java b/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/IWorkerContext.java index cac9c6fba..6eab85c3d 100644 --- a/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/IWorkerContext.java +++ b/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/IWorkerContext.java @@ -1,33 +1,33 @@ package org.hl7.fhir.dstu2.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 - list of conditions and the following disclaimer. - * 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 - 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. - IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - 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. - - */ +/* + 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 + list of conditions and the following disclaimer. + * 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 + 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. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + 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. + + */ @@ -46,6 +46,7 @@ import org.hl7.fhir.dstu2.model.ValueSet.ConceptDefinitionComponent; import org.hl7.fhir.dstu2.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.dstu2.model.ValueSet.ValueSetExpansionComponent; import org.hl7.fhir.dstu2.terminologies.ValueSetExpander.ValueSetExpansionOutcome; +import org.hl7.fhir.dstu2.utils.validation.IResourceValidator; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; diff --git a/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/SimpleWorkerContext.java b/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/SimpleWorkerContext.java index f64a7dbbe..70e3a39e8 100644 --- a/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/SimpleWorkerContext.java +++ b/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/SimpleWorkerContext.java @@ -1,33 +1,33 @@ package org.hl7.fhir.dstu2.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 - list of conditions and the following disclaimer. - * 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 - 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. - IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - 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. - - */ +/* + 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 + list of conditions and the following disclaimer. + * 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 + 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. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + 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. + + */ @@ -59,6 +59,7 @@ import org.hl7.fhir.dstu2.model.ValueSet; import org.hl7.fhir.dstu2.terminologies.ValueSetExpansionCache; import org.hl7.fhir.dstu2.utils.ProfileUtilities.ProfileKnowledgeProvider; import org.hl7.fhir.dstu2.utils.client.FHIRToolingClient; +import org.hl7.fhir.dstu2.utils.validation.IResourceValidator; import org.hl7.fhir.exceptions.DefinitionException; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.utilities.CSFileInputStream; diff --git a/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/IResourceValidator.java b/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/validation/IResourceValidator.java similarity index 83% rename from org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/IResourceValidator.java rename to org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/validation/IResourceValidator.java index c12ffd40c..dd6717a1f 100644 --- a/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/IResourceValidator.java +++ b/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/validation/IResourceValidator.java @@ -1,39 +1,42 @@ -package org.hl7.fhir.dstu2.utils; +package org.hl7.fhir.dstu2.utils.validation; -/* - 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 - list of conditions and the following disclaimer. - * 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 - 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. - IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - 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. - - */ +/* + 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 + list of conditions and the following disclaimer. + * 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 + 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. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + 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. + + */ import java.util.List; import org.hl7.fhir.dstu2.model.StructureDefinition; +import org.hl7.fhir.dstu2.utils.validation.constants.BestPracticeWarningLevel; +import org.hl7.fhir.dstu2.utils.validation.constants.CheckDisplayOption; +import org.hl7.fhir.dstu2.utils.validation.constants.IdStatus; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -42,29 +45,6 @@ import com.google.gson.JsonObject; public interface IResourceValidator { - /** - * whether the validator should enforce best practice guidelines - * as defined by various HL7 committees - * - * - * @author Grahame Grieve - * - */ - public enum BestPracticeWarningLevel { - Ignore, - Hint, - Warning, - Error - } - - public enum CheckDisplayOption { - Ignore, - Check, - CheckCaseAndSpace, - CheckCase, - CheckSpace - } - /** * how much to check displays for coded elements * @return @@ -77,10 +57,6 @@ public interface IResourceValidator { */ void setCheckDisplay(CheckDisplayOption checkDisplay); - enum IdStatus { - OPTIONAL, REQUIRED, PROHIBITED - } - /** * whether the resource must have an id or not (depends on context) * @@ -92,40 +68,27 @@ public interface IResourceValidator { BestPracticeWarningLevel getBasePracticeWarningLevel(); void setBestPracticeWarningLevel(BestPracticeWarningLevel value); - - + /** * Given a DOM element, return a list of errors in the resource - * - * @param errors - * @param elem * @- if the underlying infrastructure fails (not if the resource is invalid) */ void validate(List errors, Element element) throws Exception; /** * Given a JSON Object, return a list of errors in the resource - * - * @param errors - * @param elem * @- if the underlying infrastructure fails (not if the resource is invalid) */ void validate(List errors, JsonObject object) throws Exception; /** * Given a DOM element, return a list of errors in the resource - * - * @param errors - * @param elem * @- if the underlying infrastructure fails (not if the resource is invalid) */ List validate(Element element) throws Exception; /** * Given a DOM element, return a list of errors in the resource - * - * @param errors - * @param elem * @- if the underlying infrastructure fails (not if the resource is invalid) */ List validate(JsonObject object) throws Exception; @@ -133,10 +96,6 @@ public interface IResourceValidator { /** * Given a DOM element, return a list of errors in the resource * with regard to the specified profile (by logical identifier) - * - * @param errors - * @param element - * @param profile * @- if the underlying infrastructure fails, or the profile can't be found (not if the resource is invalid) */ void validate(List errors, Element element, String profile) throws Exception; @@ -144,10 +103,6 @@ public interface IResourceValidator { /** * Given a DOM element, return a list of errors in the resource * with regard to the specified profile (by logical identifier) - * - * @param errors - * @param element - * @param profile * @- if the underlying infrastructure fails, or the profile can't be found (not if the resource is invalid) */ List validate(Element element, String profile) throws Exception; @@ -155,10 +110,6 @@ public interface IResourceValidator { /** * Given a DOM element, return a list of errors in the resource * with regard to the specified profile (by logical identifier) - * - * @param errors - * @param element - * @param profile * @- if the underlying infrastructure fails, or the profile can't be found (not if the resource is invalid) */ List validate(JsonObject object, StructureDefinition profile) throws Exception; @@ -166,10 +117,6 @@ public interface IResourceValidator { /** * Given a DOM element, return a list of errors in the resource * with regard to the specified profile (by logical identifier) - * - * @param errors - * @param element - * @param profile * @- if the underlying infrastructure fails, or the profile can't be found (not if the resource is invalid) */ List validate(JsonObject object, String profile) throws Exception; @@ -177,10 +124,6 @@ public interface IResourceValidator { /** * Given a DOM element, return a list of errors in the resource * with regard to the specified profile - * - * @param errors - * @param element - * @param profile * @- if the underlying infrastructure fails (not if the resource is invalid) */ void validate(List errors, Element element, StructureDefinition profile) throws Exception; @@ -188,10 +131,6 @@ public interface IResourceValidator { /** * Given a DOM element, return a list of errors in the resource * with regard to the specified profile - * - * @param errors - * @param element - * @param profile * @- if the underlying infrastructure fails (not if the resource is invalid) */ void validate(List errors, JsonObject object, StructureDefinition profile) throws Exception; @@ -199,10 +138,6 @@ public interface IResourceValidator { /** * Given a DOM element, return a list of errors in the resource * with regard to the specified profile - * - * @param errors - * @param element - * @param profile * @- if the underlying infrastructure fails (not if the resource is invalid) */ void validate(List errors, JsonObject object, String profile) throws Exception; @@ -210,10 +145,6 @@ public interface IResourceValidator { /** * Given a DOM element, return a list of errors in the resource * with regard to the specified profile - * - * @param errors - * @param element - * @param profile * @- if the underlying infrastructure fails (not if the resource is invalid) */ List validate(Element element, StructureDefinition profile) throws Exception; @@ -221,18 +152,12 @@ public interface IResourceValidator { /** * Given a DOM document, return a list of errors in the resource - * - * @param errors - * @param elem * @- if the underlying infrastructure fails (not if the resource is invalid) */ void validate(List errors, Document document) throws Exception; /** * Given a DOM document, return a list of errors in the resource - * - * @param errors - * @param elem * @- if the underlying infrastructure fails (not if the resource is invalid) */ List validate(Document document) throws Exception; @@ -240,10 +165,6 @@ public interface IResourceValidator { /** * Given a DOM document, return a list of errors in the resource * with regard to the specified profile (by logical identifier) - * - * @param errors - * @param element - * @param profile * @- if the underlying infrastructure fails, or the profile can't be found (not if the resource is invalid) */ void validate(List errors, Document document, String profile) throws Exception; @@ -251,10 +172,6 @@ public interface IResourceValidator { /** * Given a DOM document, return a list of errors in the resource * with regard to the specified profile (by logical identifier) - * - * @param errors - * @param element - * @param profile * @- if the underlying infrastructure fails, or the profile can't be found (not if the resource is invalid) */ List validate(Document document, String profile) throws Exception; @@ -262,10 +179,6 @@ public interface IResourceValidator { /** * Given a DOM document, return a list of errors in the resource * with regard to the specified profile - * - * @param errors - * @param element - * @param profile * @- if the underlying infrastructure fails (not if the resource is invalid) */ void validate(List errors, Document document, StructureDefinition profile) throws Exception; @@ -273,10 +186,6 @@ public interface IResourceValidator { /** * Given a DOM document, return a list of errors in the resource * with regard to the specified profile - * - * @param errors - * @param element - * @param profile * @- if the underlying infrastructure fails (not if the resource is invalid) */ List validate(Document document, StructureDefinition profile) throws Exception; diff --git a/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/validation/constants/BestPracticeWarningLevel.java b/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/validation/constants/BestPracticeWarningLevel.java new file mode 100644 index 000000000..3ea64e188 --- /dev/null +++ b/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/validation/constants/BestPracticeWarningLevel.java @@ -0,0 +1,12 @@ +package org.hl7.fhir.dstu2.utils.validation.constants; + +/** + * whether the validator should enforce best practice guidelines + * as defined by various HL7 committees + */ +public enum BestPracticeWarningLevel { + Ignore, + Hint, + Warning, + Error +} diff --git a/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/validation/constants/CheckDisplayOption.java b/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/validation/constants/CheckDisplayOption.java new file mode 100644 index 000000000..ba2958efe --- /dev/null +++ b/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/validation/constants/CheckDisplayOption.java @@ -0,0 +1,9 @@ +package org.hl7.fhir.dstu2.utils.validation.constants; + +public enum CheckDisplayOption { + Ignore, + Check, + CheckCaseAndSpace, + CheckCase, + CheckSpace +} diff --git a/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/validation/constants/IdStatus.java b/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/validation/constants/IdStatus.java new file mode 100644 index 000000000..22ac0e3de --- /dev/null +++ b/org.hl7.fhir.dstu2/src/main/java/org/hl7/fhir/dstu2/utils/validation/constants/IdStatus.java @@ -0,0 +1,7 @@ +package org.hl7.fhir.dstu2.utils.validation.constants; + +public enum IdStatus { + OPTIONAL, + REQUIRED, + PROHIBITED +} diff --git a/org.hl7.fhir.dstu2016may/pom.xml b/org.hl7.fhir.dstu2016may/pom.xml index 9926f4838..626aef9ba 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 - 5.6.1-SNAPSHOT + 5.6.2-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu3/pom.xml b/org.hl7.fhir.dstu3/pom.xml index d6f9f2d55..8cf19b74b 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 - 5.6.1-SNAPSHOT + 5.6.2-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/context/IWorkerContext.java b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/context/IWorkerContext.java index a0962e269..75d922a1d 100644 --- a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/context/IWorkerContext.java +++ b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/context/IWorkerContext.java @@ -1,33 +1,33 @@ package org.hl7.fhir.dstu3.context; -/* - 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 - list of conditions and the following disclaimer. - * 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 - 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. - IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - 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. - - */ +/* + 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 + list of conditions and the following disclaimer. + * 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 + 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. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + 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. + + */ @@ -52,7 +52,7 @@ import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent; import org.hl7.fhir.dstu3.terminologies.ValueSetExpander.TerminologyServiceErrorClass; import org.hl7.fhir.dstu3.terminologies.ValueSetExpander.ValueSetExpansionOutcome; import org.hl7.fhir.dstu3.utils.INarrativeGenerator; -import org.hl7.fhir.dstu3.utils.IResourceValidator; +import org.hl7.fhir.dstu3.utils.validation.IResourceValidator; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.TerminologyServiceException; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; diff --git a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/context/SimpleWorkerContext.java b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/context/SimpleWorkerContext.java index 35bd0485f..0dd0887fe 100644 --- a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/context/SimpleWorkerContext.java +++ b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/context/SimpleWorkerContext.java @@ -1,33 +1,33 @@ package org.hl7.fhir.dstu3.context; -/* - 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 - list of conditions and the following disclaimer. - * 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 - 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. - IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - 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. - - */ +/* + 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 + list of conditions and the following disclaimer. + * 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 + 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. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + 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. + + */ @@ -80,7 +80,7 @@ import org.hl7.fhir.dstu3.model.StructureMap.StructureMapStructureComponent; import org.hl7.fhir.dstu3.model.ValueSet; import org.hl7.fhir.dstu3.terminologies.ValueSetExpansionCache; import org.hl7.fhir.dstu3.utils.INarrativeGenerator; -import org.hl7.fhir.dstu3.utils.IResourceValidator; +import org.hl7.fhir.dstu3.utils.validation.IResourceValidator; import org.hl7.fhir.dstu3.utils.NarrativeGenerator; import org.hl7.fhir.dstu3.utils.client.FHIRToolingClient; import org.hl7.fhir.exceptions.DefinitionException; diff --git a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/client/network/FhirRequestBuilder.java b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/client/network/FhirRequestBuilder.java index 3508a9adb..870957cda 100644 --- a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/client/network/FhirRequestBuilder.java +++ b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/client/network/FhirRequestBuilder.java @@ -206,14 +206,19 @@ public class FhirRequestBuilder { public ResourceRequest execute() throws IOException { formatHeaders(httpRequest, resourceFormat, headers); - Response response = getHttpClient().newCall(httpRequest.build()).execute(); + final Request request = httpRequest.build(); + log(request.method(), request.url().toString(), request.headers(), request.body() != null ? request.body().toString().getBytes() : null); + Response response = getHttpClient().newCall(request).execute(); T resource = unmarshalReference(response, resourceFormat); return new ResourceRequest(resource, response.code(), getLocationHeader(response.headers())); } public Bundle executeAsBatch() throws IOException { formatHeaders(httpRequest, resourceFormat, null); - Response response = getHttpClient().newCall(httpRequest.build()).execute(); + final Request request = httpRequest.build(); + log(request.method(), request.url().toString(), request.headers(), request.body() != null ? request.body().toString().getBytes() : null); + + Response response = getHttpClient().newCall(request).execute(); return unmarshalFeed(response, resourceFormat); } @@ -302,6 +307,26 @@ public class FhirRequestBuilder { } } + /** + * Logs the given {@link Request}, using the current {@link ToolingClientLogger}. If the current + * {@link FhirRequestBuilder#logger} is null, no action is taken. + * + * @param method HTTP request method + * @param url request URL + * @param requestHeaders {@link Headers} for request + * @param requestBody Byte array request + */ + protected void log(String method, String url, Headers requestHeaders, byte[] requestBody) { + if (logger != null) { + List headerList = new ArrayList<>(Collections.emptyList()); + Map> headerMap = requestHeaders.toMultimap(); + headerMap.keySet().forEach(key -> headerMap.get(key).forEach(value -> headerList.add(key + ":" + value))); + + logger.logRequest(method, url, headerList, requestBody); + } + + } + /** * Logs the given {@link Response}, using the current {@link ToolingClientLogger}. If the current * {@link FhirRequestBuilder#logger} is null, no action is taken. diff --git a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/IResourceValidator.java b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/IResourceValidator.java similarity index 83% rename from org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/IResourceValidator.java rename to org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/IResourceValidator.java index 2701d3f60..529f433fe 100644 --- a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/IResourceValidator.java +++ b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/IResourceValidator.java @@ -1,50 +1,49 @@ -package org.hl7.fhir.dstu3.utils; +package org.hl7.fhir.dstu3.utils.validation; -/* - 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 - list of conditions and the following disclaimer. - * 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 - 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. - IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - 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. - - */ +/* + 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 + list of conditions and the following disclaimer. + * 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 + 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. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + 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. + + */ +import com.google.gson.JsonObject; +import org.hl7.fhir.dstu3.elementmodel.Manager.FhirFormat; +import org.hl7.fhir.dstu3.model.StructureDefinition; +import org.hl7.fhir.dstu3.utils.ValidationProfileSet; +import org.hl7.fhir.dstu3.utils.validation.constants.BestPracticeWarningLevel; +import org.hl7.fhir.dstu3.utils.validation.constants.CheckDisplayOption; +import org.hl7.fhir.dstu3.utils.validation.constants.IdStatus; +import org.hl7.fhir.exceptions.FHIRException; +import org.hl7.fhir.utilities.validation.ValidationMessage; import java.io.IOException; import java.io.InputStream; import java.util.List; -import org.hl7.fhir.dstu3.elementmodel.Element; -import org.hl7.fhir.dstu3.elementmodel.Manager.FhirFormat; -import org.hl7.fhir.dstu3.model.StructureDefinition; -import org.hl7.fhir.exceptions.DefinitionException; -import org.hl7.fhir.exceptions.FHIRException; -import org.hl7.fhir.exceptions.FHIRFormatError; -import org.hl7.fhir.utilities.validation.ValidationMessage; - -import com.google.gson.JsonObject; - /** * Interface to the instance validator. This takes a resource, in one of many forms, and * checks whether it is valid @@ -54,49 +53,6 @@ import com.google.gson.JsonObject; */ public interface IResourceValidator { - public enum ReferenceValidationPolicy { - IGNORE, CHECK_TYPE_IF_EXISTS, CHECK_EXISTS, CHECK_EXISTS_AND_TYPE, CHECK_VALID; - - public boolean checkExists() { - return this == CHECK_EXISTS_AND_TYPE || this == CHECK_EXISTS || this == CHECK_VALID; - } - - public boolean checkType() { - return this == CHECK_TYPE_IF_EXISTS || this == CHECK_EXISTS_AND_TYPE || this == CHECK_VALID; - } - - public boolean checkValid() { - return this == CHECK_VALID; - } - } - - public interface IValidatorResourceFetcher { - Element fetch(Object appContext, String url) throws FHIRFormatError, DefinitionException, IOException, FHIRException; - ReferenceValidationPolicy validationPolicy(Object appContext, String path, String url); - boolean resolveURL(Object appContext, String path, String url) throws IOException, FHIRException; - } - - public enum BestPracticeWarningLevel { - Ignore, - Hint, - Warning, - Error - } - - public enum CheckDisplayOption { - Ignore, - Check, - CheckCaseAndSpace, - CheckCase, - CheckSpace - } - - enum IdStatus { - OPTIONAL, REQUIRED, PROHIBITED - } - - - /** * how much to check displays for coded elements * @return @@ -123,22 +79,25 @@ public interface IResourceValidator { IValidatorResourceFetcher getFetcher(); IResourceValidator setFetcher(IValidatorResourceFetcher value); - + + IValidationPolicyAdvisor getPolicyAdvisor(); + IResourceValidator setPolicyAdvisor(IValidationPolicyAdvisor advisor); + boolean isNoBindingMsgSuppressed(); IResourceValidator setNoBindingMsgSuppressed(boolean noBindingMsgSuppressed); - public boolean isNoInvariantChecks(); - public IResourceValidator setNoInvariantChecks(boolean value) ; + boolean isNoInvariantChecks(); + IResourceValidator setNoInvariantChecks(boolean value) ; - public boolean isNoTerminologyChecks(); - public IResourceValidator setNoTerminologyChecks(boolean noTerminologyChecks); + boolean isNoTerminologyChecks(); + IResourceValidator setNoTerminologyChecks(boolean noTerminologyChecks); /** * Whether being unable to resolve a profile in found in Resource.meta.profile or ElementDefinition.type.profile or targetProfile is an error or just a warning * @return */ - public boolean isErrorForUnknownProfiles(); - public void setErrorForUnknownProfiles(boolean errorForUnknownProfiles); + boolean isErrorForUnknownProfiles(); + void setErrorForUnknownProfiles(boolean errorForUnknownProfiles); /** * Validate suite diff --git a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/IValidationPolicyAdvisor.java b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/IValidationPolicyAdvisor.java new file mode 100644 index 000000000..3f7536bc0 --- /dev/null +++ b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/IValidationPolicyAdvisor.java @@ -0,0 +1,21 @@ +package org.hl7.fhir.dstu3.utils.validation; + +import org.hl7.fhir.dstu3.elementmodel.Element; +import org.hl7.fhir.dstu3.utils.validation.constants.ReferenceValidationPolicy; + +public interface IValidationPolicyAdvisor { + + ReferenceValidationPolicy policyForReference(IResourceValidator validator, + Object appContext, + String path, + String url); + + ReferenceValidationPolicy policyForContained(IResourceValidator validator, + Object appContext, + String containerType, + String containerId, + Element.SpecialElement containingResourceType, + String path, + String url); + +} \ No newline at end of file diff --git a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/IValidatorResourceFetcher.java b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/IValidatorResourceFetcher.java new file mode 100644 index 000000000..d2fb0ade1 --- /dev/null +++ b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/IValidatorResourceFetcher.java @@ -0,0 +1,13 @@ +package org.hl7.fhir.dstu3.utils.validation; + +import org.hl7.fhir.dstu3.elementmodel.Element; +import org.hl7.fhir.exceptions.DefinitionException; +import org.hl7.fhir.exceptions.FHIRException; +import org.hl7.fhir.exceptions.FHIRFormatError; + +import java.io.IOException; + +public interface IValidatorResourceFetcher { + Element fetch(Object appContext, String url) throws IOException, FHIRException; + boolean resolveURL(Object appContext, String path, String url) throws IOException, FHIRException; +} diff --git a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/constants/BestPracticeWarningLevel.java b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/constants/BestPracticeWarningLevel.java new file mode 100644 index 000000000..55bf800a3 --- /dev/null +++ b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/constants/BestPracticeWarningLevel.java @@ -0,0 +1,8 @@ +package org.hl7.fhir.dstu3.utils.validation.constants; + +public enum BestPracticeWarningLevel { + Ignore, + Hint, + Warning, + Error +} diff --git a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/constants/CheckDisplayOption.java b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/constants/CheckDisplayOption.java new file mode 100644 index 000000000..414371393 --- /dev/null +++ b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/constants/CheckDisplayOption.java @@ -0,0 +1,9 @@ +package org.hl7.fhir.dstu3.utils.validation.constants; + +public enum CheckDisplayOption { + Ignore, + Check, + CheckCaseAndSpace, + CheckCase, + CheckSpace +} diff --git a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/constants/IdStatus.java b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/constants/IdStatus.java new file mode 100644 index 000000000..d4bb24f70 --- /dev/null +++ b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/constants/IdStatus.java @@ -0,0 +1,7 @@ +package org.hl7.fhir.dstu3.utils.validation.constants; + +public enum IdStatus { + OPTIONAL, + REQUIRED, + PROHIBITED +} diff --git a/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/constants/ReferenceValidationPolicy.java b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/constants/ReferenceValidationPolicy.java new file mode 100644 index 000000000..efe07ec42 --- /dev/null +++ b/org.hl7.fhir.dstu3/src/main/java/org/hl7/fhir/dstu3/utils/validation/constants/ReferenceValidationPolicy.java @@ -0,0 +1,21 @@ +package org.hl7.fhir.dstu3.utils.validation.constants; + +public enum ReferenceValidationPolicy { + IGNORE, + CHECK_TYPE_IF_EXISTS, + CHECK_EXISTS, + CHECK_EXISTS_AND_TYPE, + CHECK_VALID; + + public boolean checkExists() { + return this == CHECK_EXISTS_AND_TYPE || this == CHECK_EXISTS || this == CHECK_VALID; + } + + public boolean checkType() { + return this == CHECK_TYPE_IF_EXISTS || this == CHECK_EXISTS_AND_TYPE || this == CHECK_VALID; + } + + public boolean checkValid() { + return this == CHECK_VALID; + } +} diff --git a/org.hl7.fhir.dstu3/src/test/java/org/hl7/fhir/dstu3/utils/client/network/FhirRequestBuilderTests.java b/org.hl7.fhir.dstu3/src/test/java/org/hl7/fhir/dstu3/utils/client/network/FhirRequestBuilderTests.java new file mode 100644 index 000000000..448af2a78 --- /dev/null +++ b/org.hl7.fhir.dstu3/src/test/java/org/hl7/fhir/dstu3/utils/client/network/FhirRequestBuilderTests.java @@ -0,0 +1,101 @@ +package org.hl7.fhir.dstu3.utils.client.network; + +import okhttp3.*; +import org.hl7.fhir.dstu3.formats.IParser; + +import org.hl7.fhir.utilities.ToolingClientLogger; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.AdditionalMatchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.ArgumentMatchers; + +import org.mockito.junit.jupiter.MockitoExtension; +import java.io.IOException; + +@ExtendWith(MockitoExtension.class) +public class FhirRequestBuilderTests { + + private static final String DUMMY_URL = "https://some-url.com/"; + + Request mockRequest = new Request.Builder() + .url(DUMMY_URL) + .build(); + + final String RESPONSE_BODY_STRING = "{}"; + + Response response = new Response.Builder() + .request(mockRequest) + .protocol(Protocol.HTTP_2) + .code(200) // status code + .message("") + .body(ResponseBody.create(RESPONSE_BODY_STRING, + MediaType.get("application/json; charset=utf-8") + )) + .addHeader("Content-Type", "") + .build(); + + final Request.Builder requestBuilder = new Request.Builder() + .url(DUMMY_URL); + + final FhirRequestBuilder fhirRequestBuilder = Mockito.spy(new FhirRequestBuilder(requestBuilder)); + + @Mock + OkHttpClient client; + + @Mock + Call mockCall; + + @Mock + ToolingClientLogger logger; + + @BeforeEach + public void beforeEach() { + Mockito.doReturn(client).when(fhirRequestBuilder).getHttpClient(); + fhirRequestBuilder.withLogger(logger); + } + + @Nested + class RequestLoggingTests { + + @BeforeEach + public void beforeEach() throws IOException { + Mockito.doReturn(response).when(mockCall).execute(); + Mockito.doReturn(mockCall).when(client).newCall(ArgumentMatchers.any()); + + Mockito.doReturn(null).when(fhirRequestBuilder).unmarshalReference(ArgumentMatchers.any(), ArgumentMatchers.isNull()); + } + + @Test + public void testExecuteLogging() throws IOException { + fhirRequestBuilder.execute(); + Mockito.verify(logger).logRequest(ArgumentMatchers.eq("GET"), ArgumentMatchers.eq(DUMMY_URL), ArgumentMatchers.anyList(), ArgumentMatchers.isNull()); + } + + @Test + public void testExecuteBatchLogging() throws IOException { + fhirRequestBuilder.executeAsBatch(); + Mockito.verify(logger).logRequest(ArgumentMatchers.eq("GET"), ArgumentMatchers.eq(DUMMY_URL), ArgumentMatchers.anyList(), ArgumentMatchers.isNull()); + } + + } + + @Test + public void testUnmarshallReferenceLogging() { + IParser parser = Mockito.mock(IParser.class); + Mockito.doReturn(parser).when(fhirRequestBuilder).getParser(ArgumentMatchers.eq("json")); + + fhirRequestBuilder.unmarshalReference(response, "json"); + Mockito.verify(logger).logResponse(ArgumentMatchers.eq("200"), ArgumentMatchers.anyList(), AdditionalMatchers.aryEq(RESPONSE_BODY_STRING.getBytes())); + } + + @Test + public void testUnmarshallFeedLogging() { + fhirRequestBuilder.unmarshalFeed(response, "application/json"); + Mockito.verify(logger).logResponse(ArgumentMatchers.eq("200"), ArgumentMatchers.anyList(), AdditionalMatchers.aryEq(RESPONSE_BODY_STRING.getBytes())); + } + +} diff --git a/org.hl7.fhir.r4/pom.xml b/org.hl7.fhir.r4/pom.xml index 771dc597a..3d4e87644 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 - 5.6.1-SNAPSHOT + 5.6.2-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/context/IWorkerContext.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/context/IWorkerContext.java index f6c943a58..0e420ebf6 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/context/IWorkerContext.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/context/IWorkerContext.java @@ -1,39 +1,38 @@ package org.hl7.fhir.r4.context; -/* - 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 - list of conditions and the following disclaimer. - * 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 - 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. - IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - 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. - - */ +/* + 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 + list of conditions and the following disclaimer. + * 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 + 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. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + 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. + + */ import java.util.List; import java.util.Locale; -import java.util.Map; import java.util.Set; import org.fhir.ucum.UcumService; @@ -58,8 +57,7 @@ import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.r4.terminologies.ValueSetExpander.TerminologyServiceErrorClass; import org.hl7.fhir.r4.terminologies.ValueSetExpander.ValueSetExpansionOutcome; import org.hl7.fhir.r4.utils.INarrativeGenerator; -import org.hl7.fhir.r4.utils.IResourceValidator; -import org.hl7.fhir.utilities.TerminologyServiceOptions; +import org.hl7.fhir.r4.utils.validation.IResourceValidator; import org.hl7.fhir.utilities.TranslationServices; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; import org.hl7.fhir.utilities.validation.ValidationOptions; diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/context/SimpleWorkerContext.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/context/SimpleWorkerContext.java index 72a0f050c..c2c5c332f 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/context/SimpleWorkerContext.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/context/SimpleWorkerContext.java @@ -1,33 +1,33 @@ package org.hl7.fhir.r4.context; -/* - 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 - list of conditions and the following disclaimer. - * 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 - 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. - IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - 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. - - */ +/* + 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 + list of conditions and the following disclaimer. + * 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 + 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. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + 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. + + */ @@ -75,7 +75,7 @@ import org.hl7.fhir.r4.model.StructureMap.StructureMapModelMode; import org.hl7.fhir.r4.model.StructureMap.StructureMapStructureComponent; import org.hl7.fhir.r4.terminologies.TerminologyClient; import org.hl7.fhir.r4.utils.INarrativeGenerator; -import org.hl7.fhir.r4.utils.IResourceValidator; +import org.hl7.fhir.r4.utils.validation.IResourceValidator; import org.hl7.fhir.r4.utils.NarrativeGenerator; import org.hl7.fhir.utilities.CSFileInputStream; import org.hl7.fhir.utilities.Utilities; diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/StructureMapUtilities.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/StructureMapUtilities.java index ae4524927..65286544b 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/StructureMapUtilities.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/StructureMapUtilities.java @@ -1,33 +1,33 @@ package org.hl7.fhir.r4.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 - list of conditions and the following disclaimer. - * 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 - 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. - IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - 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. - - */ +/* + 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 + list of conditions and the following disclaimer. + * 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 + 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. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + 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. + + */ @@ -115,6 +115,7 @@ import org.hl7.fhir.r4.model.ValueSet.ValueSetExpansionContainsComponent; import org.hl7.fhir.r4.terminologies.ValueSetExpander.ValueSetExpansionOutcome; import org.hl7.fhir.r4.utils.FHIRLexer.FHIRLexerException; import org.hl7.fhir.r4.utils.FHIRPathEngine.IEvaluationContext; +import org.hl7.fhir.r4.utils.validation.IResourceValidator; import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; import org.hl7.fhir.utilities.TerminologyServiceOptions; import org.hl7.fhir.utilities.Utilities; diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/IResourceValidator.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/IResourceValidator.java similarity index 79% rename from org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/IResourceValidator.java rename to org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/IResourceValidator.java index 864fe831f..e94333c3b 100644 --- a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/IResourceValidator.java +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/IResourceValidator.java @@ -1,46 +1,45 @@ -package org.hl7.fhir.r4.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 - list of conditions and the following disclaimer. - * 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 - 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. - IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - 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. - - */ - +package org.hl7.fhir.r4.utils.validation; +/* + 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 + list of conditions and the following disclaimer. + * 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 + 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. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + 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. + + */ import java.io.IOException; import java.io.InputStream; import java.util.List; -import org.hl7.fhir.exceptions.DefinitionException; import org.hl7.fhir.exceptions.FHIRException; -import org.hl7.fhir.exceptions.FHIRFormatError; -import org.hl7.fhir.r4.elementmodel.Element; import org.hl7.fhir.r4.elementmodel.Manager.FhirFormat; import org.hl7.fhir.r4.model.StructureDefinition; +import org.hl7.fhir.r4.utils.ValidationProfileSet; +import org.hl7.fhir.r4.utils.validation.constants.BestPracticeWarningLevel; +import org.hl7.fhir.r4.utils.validation.constants.CheckDisplayOption; +import org.hl7.fhir.r4.utils.validation.constants.IdStatus; import org.hl7.fhir.utilities.validation.ValidationMessage; import com.google.gson.JsonObject; @@ -54,97 +53,51 @@ import com.google.gson.JsonObject; */ public interface IResourceValidator { - public enum ReferenceValidationPolicy { - IGNORE, CHECK_TYPE_IF_EXISTS, CHECK_EXISTS, CHECK_EXISTS_AND_TYPE, CHECK_VALID; - - public boolean checkExists() { - return this == CHECK_EXISTS_AND_TYPE || this == CHECK_EXISTS || this == CHECK_VALID; - } - - public boolean checkType() { - return this == CHECK_TYPE_IF_EXISTS || this == CHECK_EXISTS_AND_TYPE || this == CHECK_VALID; - } - - public boolean checkValid() { - return this == CHECK_VALID; - } - } - - public interface IValidatorResourceFetcher { - Element fetch(Object appContext, String url) throws FHIRFormatError, DefinitionException, FHIRException, IOException; - ReferenceValidationPolicy validationPolicy(Object appContext, String path, String url); - boolean resolveURL(Object appContext, String path, String url) throws IOException, FHIRException; - } - - public enum BestPracticeWarningLevel { - Ignore, - Hint, - Warning, - Error - } - - public enum CheckDisplayOption { - Ignore, - Check, - CheckCaseAndSpace, - CheckCase, - CheckSpace - } - - enum IdStatus { - OPTIONAL, REQUIRED, PROHIBITED - } - - - /** * how much to check displays for coded elements - * @return */ CheckDisplayOption getCheckDisplay(); void setCheckDisplay(CheckDisplayOption checkDisplay); /** * whether the resource must have an id or not (depends on context) - * - * @return */ - IdStatus getResourceIdRule(); void setResourceIdRule(IdStatus resourceIdRule); /** * whether the validator should enforce best practice guidelines * as defined by various HL7 committees - * */ BestPracticeWarningLevel getBestPracticeWarningLevel(); IResourceValidator setBestPracticeWarningLevel(BestPracticeWarningLevel value); IValidatorResourceFetcher getFetcher(); IResourceValidator setFetcher(IValidatorResourceFetcher value); + + IValidationPolicyAdvisor getPolicyAdvisor(); + IResourceValidator setPolicyAdvisor(IValidationPolicyAdvisor advisor); boolean isNoBindingMsgSuppressed(); IResourceValidator setNoBindingMsgSuppressed(boolean noBindingMsgSuppressed); - public boolean isNoInvariantChecks(); - public IResourceValidator setNoInvariantChecks(boolean value) ; + boolean isNoInvariantChecks(); + IResourceValidator setNoInvariantChecks(boolean value) ; - public boolean isNoTerminologyChecks(); - public IResourceValidator setNoTerminologyChecks(boolean noTerminologyChecks); + boolean isNoTerminologyChecks(); + IResourceValidator setNoTerminologyChecks(boolean noTerminologyChecks); - public boolean isNoExtensibleWarnings(); - public IResourceValidator setNoExtensibleWarnings(boolean noExtensibleWarnings); + boolean isNoExtensibleWarnings(); + IResourceValidator setNoExtensibleWarnings(boolean noExtensibleWarnings); /** * Whether being unable to resolve a profile in found in Resource.meta.profile or ElementDefinition.type.profile or targetProfile is an error or just a warning - * @return */ - public boolean isErrorForUnknownProfiles(); - public void setErrorForUnknownProfiles(boolean errorForUnknownProfiles); + boolean isErrorForUnknownProfiles(); + void setErrorForUnknownProfiles(boolean errorForUnknownProfiles); - public String getValidationLanguage(); - public void setValidationLanguage(String value); + String getValidationLanguage(); + void setValidationLanguage(String value); /** * Validate suite @@ -194,5 +147,4 @@ public interface IResourceValidator { org.hl7.fhir.r4.elementmodel.Element validate(Object Context, List errors, JsonObject object, String profile) throws FHIRException; org.hl7.fhir.r4.elementmodel.Element validate(Object Context, List errors, JsonObject object, StructureDefinition profile) throws FHIRException; - } \ No newline at end of file diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/IValidationPolicyAdvisor.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/IValidationPolicyAdvisor.java new file mode 100644 index 000000000..700c1802e --- /dev/null +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/IValidationPolicyAdvisor.java @@ -0,0 +1,21 @@ +package org.hl7.fhir.r4.utils.validation; + +import org.hl7.fhir.r4.elementmodel.Element; +import org.hl7.fhir.r4.utils.validation.constants.ReferenceValidationPolicy; + +public interface IValidationPolicyAdvisor { + + ReferenceValidationPolicy policyForReference(IResourceValidator validator, + Object appContext, + String path, + String url); + + ReferenceValidationPolicy policyForContained(IResourceValidator validator, + Object appContext, + String containerType, + String containerId, + Element.SpecialElement containingResourceType, + String path, + String url); + +} \ No newline at end of file diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/IValidatorResourceFetcher.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/IValidatorResourceFetcher.java new file mode 100644 index 000000000..54e5cbc2d --- /dev/null +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/IValidatorResourceFetcher.java @@ -0,0 +1,11 @@ +package org.hl7.fhir.r4.utils.validation; + +import org.hl7.fhir.exceptions.FHIRException; +import org.hl7.fhir.r4.elementmodel.Element; + +import java.io.IOException; + +public interface IValidatorResourceFetcher { + Element fetch(Object appContext, String url) throws FHIRException, IOException; + boolean resolveURL(Object appContext, String path, String url) throws IOException, FHIRException; +} diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/constants/BestPracticeWarningLevel.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/constants/BestPracticeWarningLevel.java new file mode 100644 index 000000000..41755cf6d --- /dev/null +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/constants/BestPracticeWarningLevel.java @@ -0,0 +1,8 @@ +package org.hl7.fhir.r4.utils.validation.constants; + +public enum BestPracticeWarningLevel { + Ignore, + Hint, + Warning, + Error +} diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/constants/CheckDisplayOption.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/constants/CheckDisplayOption.java new file mode 100644 index 000000000..00f4608c5 --- /dev/null +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/constants/CheckDisplayOption.java @@ -0,0 +1,9 @@ +package org.hl7.fhir.r4.utils.validation.constants; + +public enum CheckDisplayOption { + Ignore, + Check, + CheckCaseAndSpace, + CheckCase, + CheckSpace +} diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/constants/IdStatus.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/constants/IdStatus.java new file mode 100644 index 000000000..a26479ba0 --- /dev/null +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/constants/IdStatus.java @@ -0,0 +1,7 @@ +package org.hl7.fhir.r4.utils.validation.constants; + +public enum IdStatus { + OPTIONAL, + REQUIRED, + PROHIBITED +} diff --git a/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/constants/ReferenceValidationPolicy.java b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/constants/ReferenceValidationPolicy.java new file mode 100644 index 000000000..cffa1de70 --- /dev/null +++ b/org.hl7.fhir.r4/src/main/java/org/hl7/fhir/r4/utils/validation/constants/ReferenceValidationPolicy.java @@ -0,0 +1,21 @@ +package org.hl7.fhir.r4.utils.validation.constants; + +public enum ReferenceValidationPolicy { + IGNORE, + CHECK_TYPE_IF_EXISTS, + CHECK_EXISTS, + CHECK_EXISTS_AND_TYPE, + CHECK_VALID; + + public boolean checkExists() { + return this == CHECK_EXISTS_AND_TYPE || this == CHECK_EXISTS || this == CHECK_VALID; + } + + public boolean checkType() { + return this == CHECK_TYPE_IF_EXISTS || this == CHECK_EXISTS_AND_TYPE || this == CHECK_VALID; + } + + public boolean checkValid() { + return this == CHECK_VALID; + } +} diff --git a/org.hl7.fhir.r4/src/test/java/org/hl7/fhir/r4/test/SnapShotGenerationTests.java b/org.hl7.fhir.r4/src/test/java/org/hl7/fhir/r4/test/SnapShotGenerationTests.java index 747c66149..2b4a32a44 100644 --- a/org.hl7.fhir.r4/src/test/java/org/hl7/fhir/r4/test/SnapShotGenerationTests.java +++ b/org.hl7.fhir.r4/src/test/java/org/hl7/fhir/r4/test/SnapShotGenerationTests.java @@ -22,7 +22,7 @@ import org.hl7.fhir.r4.model.ValueSet; import org.hl7.fhir.r4.test.utils.TestingUtilities; import org.hl7.fhir.r4.utils.FHIRPathEngine; import org.hl7.fhir.r4.utils.FHIRPathEngine.IEvaluationContext; -import org.hl7.fhir.r4.utils.IResourceValidator; +import org.hl7.fhir.r4.utils.validation.IResourceValidator; import org.hl7.fhir.r4.utils.NarrativeGenerator; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.validation.ValidationMessage; diff --git a/org.hl7.fhir.r5/pom.xml b/org.hl7.fhir.r5/pom.xml index 0a628c8ac..6fb444db2 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 - 5.6.1-SNAPSHOT + 5.6.2-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/HTMLClientLogger.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/HTMLClientLogger.java index 122dd2a3a..9d6803e15 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/HTMLClientLogger.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/HTMLClientLogger.java @@ -46,7 +46,7 @@ public class HTMLClientLogger extends BaseLogger implements ToolingClientLogger private boolean req = false; private PrintStream file; - + public HTMLClientLogger(String log) { if (log != null) { try { @@ -89,12 +89,13 @@ public class HTMLClientLogger extends BaseLogger implements ToolingClientLogger if (DEBUG) { System.out.println(" txlog resp: " +outcome+" "+present(body)); } - req = false; + if (file == null) return; if (!req) { System.out.println("Record Response without request"); } + req = false; file.println("
");
     file.println(outcome);
     for (String s : headers)  
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/IWorkerContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/IWorkerContext.java
index 0b5803bec..7f90e56c1 100644
--- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/IWorkerContext.java
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/IWorkerContext.java
@@ -4,34 +4,34 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 
-/*
-  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 
-     list of conditions and the following disclaimer.
-   * 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 
-     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. 
-  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
-  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
-  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
-  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
-  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.
-  
- */
+/*
+  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 
+     list of conditions and the following disclaimer.
+   * 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 
+     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. 
+  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+  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.
+  
+ */
 
 
 
@@ -44,7 +44,6 @@ import org.fhir.ucum.UcumService;
 import org.hl7.fhir.exceptions.DefinitionException;
 import org.hl7.fhir.exceptions.FHIRException;
 import org.hl7.fhir.exceptions.TerminologyServiceException;
-import org.hl7.fhir.r5.context.IWorkerContext.CodingValidationRequest;
 import org.hl7.fhir.r5.context.TerminologyCache.CacheToken;
 import org.hl7.fhir.r5.formats.IParser;
 import org.hl7.fhir.r5.formats.ParserType;
@@ -64,7 +63,7 @@ import org.hl7.fhir.r5.model.ValueSet;
 import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
 import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass;
 import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome;
-import org.hl7.fhir.r5.utils.IResourceValidator;
+import org.hl7.fhir.r5.utils.validation.IResourceValidator;
 import org.hl7.fhir.utilities.TimeTracker;
 import org.hl7.fhir.utilities.TranslationServices;
 import org.hl7.fhir.utilities.npm.BasePackageCacheManager;
@@ -247,10 +246,10 @@ public interface IWorkerContext {
    * Get the versions of the definitions loaded in context
    * @return
    */
-  public String getVersion();
-  
-  /**
-   * return the link to the base of the specification for the loaded version e.g. http://hl7.org/fhir/R4
+  public String getVersion();
+  
+  /**
+   * return the link to the base of the specification for the loaded version e.g. http://hl7.org/fhir/R4
    */
   public String getSpecUrl();
   
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java
index 7e132e33b..13ee2c3a1 100644
--- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/SimpleWorkerContext.java
@@ -54,9 +54,7 @@ import org.hl7.fhir.exceptions.FHIRFormatError;
 import org.hl7.fhir.r5.conformance.ProfileUtilities;
 import org.hl7.fhir.r5.conformance.ProfileUtilities.ProfileKnowledgeProvider;
 import org.hl7.fhir.r5.context.CanonicalResourceManager.CanonicalResourceProxy;
-import org.hl7.fhir.r5.context.IWorkerContext.PackageVersion;
 import org.hl7.fhir.r5.context.IWorkerContext.ILoggingService.LogCategory;
-import org.hl7.fhir.r5.context.SimpleWorkerContext.PackageResourceLoader;
 import org.hl7.fhir.r5.formats.IParser;
 import org.hl7.fhir.r5.formats.JsonParser;
 import org.hl7.fhir.r5.formats.ParserType;
@@ -76,7 +74,7 @@ import org.hl7.fhir.r5.model.StructureMap;
 import org.hl7.fhir.r5.model.StructureMap.StructureMapModelMode;
 import org.hl7.fhir.r5.model.StructureMap.StructureMapStructureComponent;
 import org.hl7.fhir.r5.terminologies.TerminologyClient;
-import org.hl7.fhir.r5.utils.IResourceValidator;
+import org.hl7.fhir.r5.utils.validation.IResourceValidator;
 import org.hl7.fhir.r5.utils.XVerExtensionManager;
 import org.hl7.fhir.utilities.CSFileInputStream;
 import org.hl7.fhir.utilities.TextFile;
@@ -85,15 +83,12 @@ import org.hl7.fhir.utilities.Utilities;
 import org.hl7.fhir.utilities.VersionUtilities;
 import org.hl7.fhir.utilities.i18n.I18nConstants;
 import org.hl7.fhir.utilities.npm.BasePackageCacheManager;
-import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager;
 import org.hl7.fhir.utilities.npm.NpmPackage;
 import org.hl7.fhir.utilities.npm.NpmPackage.PackageResourceInformation;
 import org.hl7.fhir.utilities.validation.ValidationMessage;
 import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType;
 import org.hl7.fhir.utilities.validation.ValidationMessage.Source;
 
-import com.google.gson.JsonObject;
-
 import ca.uhn.fhir.parser.DataFormatException;
 
 /*
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/structuremap/FFHIRPathHostServices.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/structuremap/FFHIRPathHostServices.java
index 3748e2235..c5024dc22 100644
--- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/structuremap/FFHIRPathHostServices.java
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/structuremap/FFHIRPathHostServices.java
@@ -9,7 +9,7 @@ import org.hl7.fhir.r5.model.Resource;
 import org.hl7.fhir.r5.model.TypeDetails;
 import org.hl7.fhir.r5.model.ValueSet;
 import org.hl7.fhir.r5.utils.FHIRPathEngine;
-import org.hl7.fhir.r5.utils.IResourceValidator;
+import org.hl7.fhir.r5.utils.validation.IResourceValidator;
 import org.hl7.fhir.utilities.validation.ValidationMessage;
 
 import java.util.ArrayList;
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/BundleValidationRule.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/BundleValidationRule.java
new file mode 100644
index 000000000..370f67c4c
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/BundleValidationRule.java
@@ -0,0 +1,29 @@
+package org.hl7.fhir.r5.utils.validation;
+
+public class BundleValidationRule {
+  private String rule;
+  private String profile;
+  private boolean checked;
+
+  public BundleValidationRule(String rule, String profile) {
+    super();
+    this.rule = rule;
+    this.profile = profile;
+  }
+
+  public String getRule() {
+    return rule;
+  }
+
+  public String getProfile() {
+    return profile;
+  }
+
+  public boolean isChecked() {
+    return checked;
+  }
+
+  public void setChecked(boolean checked) {
+    this.checked = checked;
+  }
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/IResourceValidator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/IResourceValidator.java
similarity index 60%
rename from org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/IResourceValidator.java
rename to org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/IResourceValidator.java
index e1c24bf02..2ce6aca70 100644
--- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/IResourceValidator.java
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/IResourceValidator.java
@@ -1,4 +1,4 @@
-package org.hl7.fhir.r5.utils;
+package org.hl7.fhir.r5.utils.validation;
 
 /*
   Copyright (c) 2011+, HL7, Inc.
@@ -30,26 +30,18 @@ package org.hl7.fhir.r5.utils;
  */
 
 
+import com.google.gson.JsonObject;
+import org.hl7.fhir.exceptions.FHIRException;
+import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
+import org.hl7.fhir.r5.model.StructureDefinition;
+import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel;
+import org.hl7.fhir.r5.utils.validation.constants.CheckDisplayOption;
+import org.hl7.fhir.r5.utils.validation.constants.IdStatus;
+import org.hl7.fhir.utilities.validation.ValidationMessage;
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
 import java.util.List;
-import java.util.Locale;
-
-import org.hl7.fhir.exceptions.DefinitionException;
-import org.hl7.fhir.exceptions.FHIRException;
-import org.hl7.fhir.exceptions.FHIRFormatError;
-import org.hl7.fhir.r5.elementmodel.Element;
-import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
-import org.hl7.fhir.r5.model.CanonicalResource;
-import org.hl7.fhir.r5.model.StructureDefinition;
-import org.hl7.fhir.r5.utils.IResourceValidator.BundleValidationRule;
-import org.hl7.fhir.utilities.Utilities;
-import org.hl7.fhir.utilities.validation.ValidationMessage;
-
-import com.google.gson.JsonObject;
 
 /**
  * Interface to the instance validator. This takes a resource, in one of many forms, and 
@@ -60,124 +52,21 @@ import com.google.gson.JsonObject;
    */
 public interface IResourceValidator {
 
-  public class BundleValidationRule {
-    private String rule;
-    private String profile;
-    private boolean checked;
-    
-    public BundleValidationRule(String rule, String profile) {
-      super();
-      this.rule = rule;
-      this.profile = profile;
-    }
-    public String getRule() {
-      return rule;
-    }
-    public String getProfile() {
-      return profile;
-    }
-    public boolean isChecked() {
-      return checked;
-    }
-    public void setChecked(boolean checked) {
-      this.checked = checked;
-    }    
-  }
-
-  public enum ReferenceValidationPolicy {
-    IGNORE, CHECK_TYPE_IF_EXISTS, CHECK_EXISTS, CHECK_EXISTS_AND_TYPE, CHECK_VALID;
-    
-    public boolean checkExists() {
-      return this == CHECK_EXISTS_AND_TYPE || this == CHECK_EXISTS || this == CHECK_VALID || this == CHECK_TYPE_IF_EXISTS;
-    }
-    
-    public boolean checkType() {
-      return this == CHECK_TYPE_IF_EXISTS || this == CHECK_EXISTS_AND_TYPE || this == CHECK_VALID;
-    }
-    
-    public boolean checkValid() {
-      return this == CHECK_VALID;
-    }
-  }
-  
-  public interface IValidationProfileUsageTracker {
-    void recordProfileUsage(StructureDefinition profile, Object appContext, Element element);
-  }
-  
-
-  public interface IValidatorResourceFetcher {
-
-    Element fetch(IResourceValidator validator, Object appContext, String url) throws FHIRFormatError, DefinitionException, FHIRException, IOException;
-    ReferenceValidationPolicy validationPolicy(IResourceValidator validator, Object appContext, String path, String url);
-    boolean resolveURL(IResourceValidator validator, Object appContext, String path, String url, String type) throws IOException, FHIRException;
-
-    byte[] fetchRaw(IResourceValidator validator, String url) throws MalformedURLException, IOException; // for attachment checking
-
-    IValidatorResourceFetcher setLocale(Locale locale);
-    
-    
-    /**
-     * this is used when the validator encounters a reference to a structure definition, value set or code system at some random URL reference 
-     * while validating. 
-     *
-     *  Added in v5.2.2. return null to leave functionality as it was before then.
-     *  
-     * @param primitiveValue
-     * @return an R5 version of the resource
-     * @throws URISyntaxException 
-     */
-    CanonicalResource fetchCanonicalResource(IResourceValidator validator, String url) throws URISyntaxException;
-    
-    /**
-     * Whether to try calling fetchCanonicalResource for this reference (not whether it will succeed - just throw an exception from fetchCanonicalResource if it doesn't resolve. This is a policy thing.
-     * 
-     *  Added in v5.2.2. return false to leave functionality as it was before then.
-     *  
-     * @param url
-     * @return
-     */
-    boolean fetchesCanonicalResource(IResourceValidator validator, String url);
-  }
-  
-  public enum BestPracticeWarningLevel {
-    Ignore,
-    Hint,
-    Warning,
-    Error
-  }
-
-  public enum CheckDisplayOption {
-    Ignore,
-    Check,
-    CheckCaseAndSpace,
-    CheckCase,
-    CheckSpace
-  }
-
-  enum IdStatus {
-    OPTIONAL, REQUIRED, PROHIBITED
-  }
-  
   /**
    * how much to check displays for coded elements 
-   * @return
    */
   CheckDisplayOption getCheckDisplay();
   void setCheckDisplay(CheckDisplayOption checkDisplay);
 
   /**
    * whether the resource must have an id or not (depends on context)
-   * 
-   * @return
    */
-
 	IdStatus getResourceIdRule();
 	void setResourceIdRule(IdStatus resourceIdRule);
   
   /**
    * whether the validator should enforce best practice guidelines
    * as defined by various HL7 committees 
-   *  
    */
   BestPracticeWarningLevel getBestPracticeWarningLevel();
   IResourceValidator setBestPracticeWarningLevel(BestPracticeWarningLevel value);
@@ -185,48 +74,46 @@ public interface IResourceValidator {
   IValidatorResourceFetcher getFetcher();
   IResourceValidator setFetcher(IValidatorResourceFetcher value);
 
+  IValidationPolicyAdvisor getPolicyAdvisor();
+  IResourceValidator setPolicyAdvisor(IValidationPolicyAdvisor advisor);
+
   IValidationProfileUsageTracker getTracker();
   IResourceValidator setTracker(IValidationProfileUsageTracker value);
 
   boolean isNoBindingMsgSuppressed();
   IResourceValidator setNoBindingMsgSuppressed(boolean noBindingMsgSuppressed);
   
-  public boolean isNoInvariantChecks();
-  public IResourceValidator setNoInvariantChecks(boolean value) ;
+  boolean isNoInvariantChecks();
+  IResourceValidator setNoInvariantChecks(boolean value) ;
 
-  public boolean isWantInvariantInMessage();
-  public IResourceValidator setWantInvariantInMessage(boolean wantInvariantInMessage); 
+  boolean isWantInvariantInMessage();
+  IResourceValidator setWantInvariantInMessage(boolean wantInvariantInMessage);
 
-  public boolean isNoTerminologyChecks();
-  public IResourceValidator setNoTerminologyChecks(boolean noTerminologyChecks);
+  boolean isNoTerminologyChecks();
+  IResourceValidator setNoTerminologyChecks(boolean noTerminologyChecks);
 
-  public boolean isNoExtensibleWarnings();
-  public IResourceValidator setNoExtensibleWarnings(boolean noExtensibleWarnings);
+  boolean isNoExtensibleWarnings();
+  IResourceValidator setNoExtensibleWarnings(boolean noExtensibleWarnings);
   
-  public boolean isNoUnicodeBiDiControlChars();
-  public void setNoUnicodeBiDiControlChars(boolean noUnicodeBiDiControlChars);
+  boolean isNoUnicodeBiDiControlChars();
+  void setNoUnicodeBiDiControlChars(boolean noUnicodeBiDiControlChars);
   
   /**
    * Whether being unable to resolve a profile in found in Resource.meta.profile or ElementDefinition.type.profile or targetProfile is an error or just a warning
-   * @return
    */
-  public boolean isErrorForUnknownProfiles();
-  public void setErrorForUnknownProfiles(boolean errorForUnknownProfiles);
+  boolean isErrorForUnknownProfiles();
+  void setErrorForUnknownProfiles(boolean errorForUnknownProfiles);
 
-  public boolean isShowMessagesFromReferences();
-  public void setShowMessagesFromReferences(boolean value);
+  boolean isShowMessagesFromReferences();
+  void setShowMessagesFromReferences(boolean value);
 
   /** 
    * this is used internally in the publishing stack to ensure that everything is water tight, but 
    * this check is not necessary or appropriate at run time when the validator is hosted in HAPI
    * @return
    */
-  public boolean isWantCheckSnapshotUnchanged();
-  public void setWantCheckSnapshotUnchanged(boolean wantCheckSnapshotUnchanged);
-  
-  //FIXME: don't need that, gets never used?
-//  public String getValidationLanguage();
-//  public void setValidationLanguage(String value);
+  boolean isWantCheckSnapshotUnchanged();
+  void setWantCheckSnapshotUnchanged(boolean wantCheckSnapshotUnchanged);
   
   /**
    * It's common to see references such as Patient/234234 - these usually mean a reference to a Patient resource. 
@@ -235,27 +122,28 @@ public interface IResourceValidator {
    * 
    * @return
    */
-  public boolean isAssumeValidRestReferences();
-  public void setAssumeValidRestReferences(boolean value);
+  boolean isAssumeValidRestReferences();
+  void setAssumeValidRestReferences(boolean value);
   
   /** 
    * if this is true, the validator will accept extensions and references to example.org and acme.com as 
    * valid, on the basis that they are understood to be references to content that could exist in priniple but can't in practice
    */
-  public boolean isAllowExamples();
-  public void setAllowExamples(boolean value) ;
+  boolean isAllowExamples();
+  void setAllowExamples(boolean value) ;
  
-  public boolean isNoCheckAggregation();
-  public void setNoCheckAggregation(boolean value);
+  boolean isNoCheckAggregation();
+  void setNoCheckAggregation(boolean value);
+
   /**
    * CrumbTrail - whether the validator creates hints to 
    * @return
    */
-  public boolean isCrumbTrails();
-  public void setCrumbTrails(boolean crumbTrails);
+  boolean isCrumbTrails();
+  void setCrumbTrails(boolean crumbTrails);
 
-  public boolean isValidateValueSetCodesOnTxServer();
-  public void setValidateValueSetCodesOnTxServer(boolean value);
+  boolean isValidateValueSetCodesOnTxServer();
+  void setValidateValueSetCodesOnTxServer(boolean value);
 
   /** 
    * Bundle validation rules allow for requesting particular entries in a bundle get validated against particular profiles
@@ -264,7 +152,7 @@ public interface IResourceValidator {
    *  
    * @return
    */
-  public List getBundleValidationRules();
+  List getBundleValidationRules();
   
   /**
    * Validate suite
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/IValidationPolicyAdvisor.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/IValidationPolicyAdvisor.java
new file mode 100644
index 000000000..58a7f62bf
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/IValidationPolicyAdvisor.java
@@ -0,0 +1,41 @@
+package org.hl7.fhir.r5.utils.validation;
+
+import org.hl7.fhir.r5.elementmodel.Element;
+import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPolicy;
+import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy;
+
+public interface IValidationPolicyAdvisor {
+
+  /**
+   *
+   * @param validator
+   * @param appContext What was originally provided from the app for it's context
+   * @param path Path that led us to this resource.
+   * @param url Url of the profile the container resource is being validated against.
+   * @return {@link ReferenceValidationPolicy}
+   */
+  ReferenceValidationPolicy policyForReference(IResourceValidator validator,
+                                               Object appContext,
+                                               String path,
+                                               String url);
+
+  /**
+   * //TODO pass through the actual containing Element as opposed to the type, id
+   * @param validator
+   * @param appContext What was originally provided from the app for it's context
+   * @param containerType Type of the resources that contains the resource being validated
+   * @param containerId Id of the resources that contains the resource being validated
+   * @param containingResourceType Type of the resource that will be validated (BUNDLE_ENTRY, BUNDLE_OUTCOME, CONTAINED_RESOURCE, PARAMETER)
+   * @param path Path that led us to this resource.
+   * @param url Url of the profile the container resource is being validated against.
+   * @return {@link ReferenceValidationPolicy}
+   */
+  ContainedReferenceValidationPolicy policyForContained(IResourceValidator validator,
+                                                        Object appContext,
+                                                        String containerType,
+                                                        String containerId,
+                                                        Element.SpecialElement containingResourceType,
+                                                        String path,
+                                                        String url);
+
+}
\ No newline at end of file
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/IValidationProfileUsageTracker.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/IValidationProfileUsageTracker.java
new file mode 100644
index 000000000..b0ef7bfd7
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/IValidationProfileUsageTracker.java
@@ -0,0 +1,8 @@
+package org.hl7.fhir.r5.utils.validation;
+
+import org.hl7.fhir.r5.elementmodel.Element;
+import org.hl7.fhir.r5.model.StructureDefinition;
+
+public interface IValidationProfileUsageTracker {
+  void recordProfileUsage(StructureDefinition profile, Object appContext, Element element);
+}
diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/IValidatorResourceFetcher.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/IValidatorResourceFetcher.java
new file mode 100644
index 000000000..26378c3c8
--- /dev/null
+++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/IValidatorResourceFetcher.java
@@ -0,0 +1,41 @@
+package org.hl7.fhir.r5.utils.validation;
+
+import org.hl7.fhir.exceptions.FHIRException;
+import org.hl7.fhir.r5.elementmodel.Element;
+import org.hl7.fhir.r5.model.CanonicalResource;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Locale;
+
+public interface IValidatorResourceFetcher {
+
+  Element fetch(IResourceValidator validator, Object appContext, String url) throws FHIRException, IOException;
+
+  boolean resolveURL(IResourceValidator validator, Object appContext, String path, String url, String type) throws IOException, FHIRException;
+
+  byte[] fetchRaw(IResourceValidator validator, String url) throws IOException; // for attachment checking
+
+  IValidatorResourceFetcher setLocale(Locale locale);
+
+  /**
+   * this is used when the validator encounters a reference to a structure definition, value set or code system at some random URL reference
+   * while validating.
+   * 

+ * Added in v5.2.2. return null to leave functionality as it was before then. + * + * @return an R5 version of the resource + * @throws URISyntaxException + */ + CanonicalResource fetchCanonicalResource(IResourceValidator validator, String url) throws URISyntaxException; + + /** + * Whether to try calling fetchCanonicalResource for this reference (not whether it will succeed - just throw an exception from fetchCanonicalResource if it doesn't resolve. This is a policy thing. + *

+ * Added in v5.2.2. return false to leave functionality as it was before then. + * + * @param url + * @return + */ + boolean fetchesCanonicalResource(IResourceValidator validator, String url); +} diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/constants/BestPracticeWarningLevel.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/constants/BestPracticeWarningLevel.java new file mode 100644 index 000000000..441fadea8 --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/constants/BestPracticeWarningLevel.java @@ -0,0 +1,8 @@ +package org.hl7.fhir.r5.utils.validation.constants; + +public enum BestPracticeWarningLevel { + Ignore, + Hint, + Warning, + Error +} diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/constants/CheckDisplayOption.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/constants/CheckDisplayOption.java new file mode 100644 index 000000000..9a080366a --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/constants/CheckDisplayOption.java @@ -0,0 +1,9 @@ +package org.hl7.fhir.r5.utils.validation.constants; + +public enum CheckDisplayOption { + Ignore, + Check, + CheckCaseAndSpace, + CheckCase, + CheckSpace +} diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/constants/ContainedReferenceValidationPolicy.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/constants/ContainedReferenceValidationPolicy.java new file mode 100644 index 000000000..8361ebdde --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/constants/ContainedReferenceValidationPolicy.java @@ -0,0 +1,19 @@ +package org.hl7.fhir.r5.utils.validation.constants; + +public enum ContainedReferenceValidationPolicy { + IGNORE, + CHECK_TYPE, + CHECK_VALID; + + public boolean ignore() { + return this == IGNORE; + } + + public boolean checkType() { + return this == CHECK_TYPE || this == CHECK_VALID; + } + + public boolean checkValid() { + return this == CHECK_VALID; + } +} diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/constants/IdStatus.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/constants/IdStatus.java new file mode 100644 index 000000000..84004111d --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/constants/IdStatus.java @@ -0,0 +1,7 @@ +package org.hl7.fhir.r5.utils.validation.constants; + +public enum IdStatus { + OPTIONAL, + REQUIRED, + PROHIBITED +} diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/constants/ReferenceValidationPolicy.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/constants/ReferenceValidationPolicy.java new file mode 100644 index 000000000..616fb10eb --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/validation/constants/ReferenceValidationPolicy.java @@ -0,0 +1,25 @@ +package org.hl7.fhir.r5.utils.validation.constants; + +public enum ReferenceValidationPolicy { + IGNORE, + CHECK_TYPE_IF_EXISTS, + CHECK_EXISTS, + CHECK_EXISTS_AND_TYPE, + CHECK_VALID; + + public boolean ignore() { + return this == IGNORE; + } + + public boolean checkExists() { + return this == CHECK_EXISTS_AND_TYPE || this == CHECK_EXISTS || this == CHECK_VALID || this == CHECK_TYPE_IF_EXISTS; + } + + public boolean checkType() { + return this == CHECK_TYPE_IF_EXISTS || this == CHECK_EXISTS_AND_TYPE || this == CHECK_VALID; + } + + public boolean checkValid() { + return this == CHECK_VALID; + } +} diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/ParsingTests.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/ParsingTests.java index 9e1f1c7cf..fc2f92699 100644 --- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/ParsingTests.java +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/ParsingTests.java @@ -1,61 +1,27 @@ package org.hl7.fhir.r5.test; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; import javax.xml.parsers.ParserConfigurationException; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.NotImplementedException; -import org.hl7.fhir.exceptions.DefinitionException; -import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRFormatError; -import org.hl7.fhir.exceptions.PathEngineException; -import org.hl7.fhir.r5.conformance.ProfileUtilities; -import org.hl7.fhir.r5.conformance.ProfileUtilities.ProfileKnowledgeProvider; -import org.hl7.fhir.r5.context.IWorkerContext.IContextResourceLoader; import org.hl7.fhir.r5.formats.IParser.OutputStyle; import org.hl7.fhir.r5.formats.JsonParser; import org.hl7.fhir.r5.formats.XmlParser; -import org.hl7.fhir.r5.model.Base; -import org.hl7.fhir.r5.model.Bundle; -import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent; -import org.hl7.fhir.r5.model.ExpressionNode.CollectionStatus; import org.hl7.fhir.r5.model.Resource; -import org.hl7.fhir.r5.model.StructureDefinition; -import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind; -import org.hl7.fhir.r5.model.StructureDefinition.TypeDerivationRule; -import org.hl7.fhir.r5.renderers.RendererFactory; -import org.hl7.fhir.r5.renderers.utils.RenderingContext; -import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode; -import org.hl7.fhir.r5.model.TypeDetails; -import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.test.utils.TestingUtilities; -import org.hl7.fhir.r5.utils.FHIRPathEngine; -import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext; -import org.hl7.fhir.r5.utils.IResourceValidator; -import org.hl7.fhir.r5.utils.XVerExtensionManager; import org.hl7.fhir.utilities.TextFile; -import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.npm.FilesystemPackageCacheManager; import org.hl7.fhir.utilities.npm.NpmPackage; import org.hl7.fhir.utilities.npm.ToolsVersion; -import org.hl7.fhir.utilities.validation.ValidationMessage; -import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; -import org.hl7.fhir.utilities.xml.XMLUtil; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.w3c.dom.Document; -import org.w3c.dom.Element; import org.xml.sax.SAXException; public class ParsingTests { diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/SnapShotGenerationTests.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/SnapShotGenerationTests.java index 066edc1bd..8c06c149a 100644 --- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/SnapShotGenerationTests.java +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/SnapShotGenerationTests.java @@ -39,7 +39,7 @@ import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.test.utils.TestingUtilities; import org.hl7.fhir.r5.utils.FHIRPathEngine; import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext; -import org.hl7.fhir.r5.utils.IResourceValidator; +import org.hl7.fhir.r5.utils.validation.IResourceValidator; import org.hl7.fhir.r5.utils.XVerExtensionManager; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.npm.CommonPackages; diff --git a/org.hl7.fhir.report/pom.xml b/org.hl7.fhir.report/pom.xml index 69bdb4fe3..0e535718b 100644 --- a/org.hl7.fhir.report/pom.xml +++ b/org.hl7.fhir.report/pom.xml @@ -5,7 +5,7 @@ ca.uhn.hapi.fhir org.hl7.fhir.core - 5.6.1-SNAPSHOT + 5.6.2-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.utilities/pom.xml b/org.hl7.fhir.utilities/pom.xml index 7c1fc33af..e83a15947 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 - 5.6.1-SNAPSHOT + 5.6.2-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/UtilitiesTest.java b/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/UtilitiesTest.java index 252a0d033..b2264c95f 100644 --- a/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/UtilitiesTest.java +++ b/org.hl7.fhir.utilities/src/test/java/org/hl7/fhir/utilities/UtilitiesTest.java @@ -8,6 +8,7 @@ import org.junit.jupiter.api.Test; import java.io.File; import java.io.IOException; import java.nio.file.Paths; +import java.text.MessageFormat; import java.util.Random; import static org.junit.jupiter.api.Assertions.*; @@ -126,27 +127,34 @@ class UtilitiesTest { public static final int BIG_NEG = Utilities.ONE_MB * -1; + + private static final String buildMeasureLimitMessage(int size, String contains) { + return MessageFormat.format("\"{0}\" should contain \"{1}\"", size, contains); + } + + //TODO we've witnessed at least one intermittent failure of this test. It could be refactored to run several times to + // trigger edge cases more often now that it provides better feedback. @Test @DisplayName("Test size bounds on file size utility.") void describeSizeTest() { Assertions.assertAll("GB Measure Limits", - () -> assertTrue(Utilities.describeSize(GB_MEASURE_JUST_OVER).contains(Utilities.GB)), - () -> assertTrue(Utilities.describeSize(GB_MEASURE_EXACT).contains(Utilities.MB)), - () -> assertTrue(Utilities.describeSize(GB_MEASURE_JUST_UNDER).contains(Utilities.MB)) + () -> assertTrue(Utilities.describeSize(GB_MEASURE_JUST_OVER).contains(Utilities.GB), buildMeasureLimitMessage(GB_MEASURE_JUST_OVER, Utilities.GB)), + () -> assertTrue(Utilities.describeSize(GB_MEASURE_EXACT).contains(Utilities.MB), buildMeasureLimitMessage(GB_MEASURE_EXACT, Utilities.MB)), + () -> assertTrue(Utilities.describeSize(GB_MEASURE_JUST_UNDER).contains(Utilities.MB), buildMeasureLimitMessage(GB_MEASURE_JUST_UNDER, Utilities.MB)) ); Assertions.assertAll("MB Measure Limits", - () -> assertTrue(Utilities.describeSize(MB_MEASURE_JUST_OVER).contains(Utilities.MB)), - () -> assertTrue(Utilities.describeSize(MB_MEASURE_EXACT).contains(Utilities.KB)), - () -> assertTrue(Utilities.describeSize(MB_MEASURE_JUST_UNDER).contains(Utilities.KB)) + () -> assertTrue(Utilities.describeSize(MB_MEASURE_JUST_OVER).contains(Utilities.MB), buildMeasureLimitMessage(MB_MEASURE_JUST_OVER, Utilities.MB)), + () -> assertTrue(Utilities.describeSize(MB_MEASURE_EXACT).contains(Utilities.KB), buildMeasureLimitMessage(MB_MEASURE_EXACT, Utilities.KB)), + () -> assertTrue(Utilities.describeSize(MB_MEASURE_JUST_UNDER).contains(Utilities.KB), buildMeasureLimitMessage(MB_MEASURE_JUST_UNDER, Utilities.KB)) ); Assertions.assertAll("KB Measure Limits", - () -> assertTrue(Utilities.describeSize(KB_MEASURE_JUST_OVER).contains(Utilities.KB)), - () -> assertTrue(Utilities.describeSize(KB_MEASURE_EXACT).contains(Utilities.BT)), - () -> assertTrue(Utilities.describeSize(KB_MEASURE_JUST_UNDER).contains(Utilities.BT)) + () -> assertTrue(Utilities.describeSize(KB_MEASURE_JUST_OVER).contains(Utilities.KB), buildMeasureLimitMessage(KB_MEASURE_JUST_OVER, Utilities.KB)), + () -> assertTrue(Utilities.describeSize(KB_MEASURE_EXACT).contains(Utilities.BT), buildMeasureLimitMessage(KB_MEASURE_EXACT, Utilities.BT)), + () -> assertTrue(Utilities.describeSize(KB_MEASURE_JUST_UNDER).contains(Utilities.BT), buildMeasureLimitMessage(KB_MEASURE_JUST_UNDER, Utilities.BT)) ); Assertions.assertAll("BT Measure Limits", - () -> assertTrue(Utilities.describeSize(BT_MEASURE).contains(Utilities.BT)), - () -> assertTrue(Utilities.describeSize(EMPTY).contains(Utilities.BT)) + () -> assertTrue(Utilities.describeSize(BT_MEASURE).contains(Utilities.BT), buildMeasureLimitMessage(BT_MEASURE, Utilities.BT)), + () -> assertTrue(Utilities.describeSize(EMPTY).contains(Utilities.BT), buildMeasureLimitMessage(EMPTY, Utilities.BT)) ); Assertions.assertThrows(IllegalArgumentException.class, () -> Utilities.describeSize(BIG_NEG)); } diff --git a/org.hl7.fhir.validation.cli/pom.xml b/org.hl7.fhir.validation.cli/pom.xml index 1111b260c..afc498a13 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 - 5.6.1-SNAPSHOT + 5.6.2-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.validation/pom.xml b/org.hl7.fhir.validation/pom.xml index c7f9dc9bb..d84e3480f 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 - 5.6.1-SNAPSHOT + 5.6.2-SNAPSHOT ../pom.xml diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java index d33363999..a26e280f4 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/BaseValidator.java @@ -1,84 +1,39 @@ package org.hl7.fhir.validation; -import static org.apache.commons.lang3.StringUtils.isBlank; - -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; - -/* - 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 - list of conditions and the following disclaimer. - * 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 - 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. - IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - 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. - - */ - - /* -Copyright (c) 2011+, HL7, Inc -All rights reserved. + 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: + 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 - list of conditions and the following disclaimer. - * 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 - endorse or promote products derived from this software without specific - prior written permission. + * 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, + 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 + 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. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -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. + 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. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + 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. */ -import java.util.List; -import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.r5.context.IWorkerContext; import org.hl7.fhir.r5.elementmodel.Element; -import org.hl7.fhir.r5.model.Base; -import org.hl7.fhir.r5.model.DomainResource; -import org.hl7.fhir.r5.model.Resource; -import org.hl7.fhir.r5.model.StructureDefinition; -import org.hl7.fhir.r5.model.ValueSet; +import org.hl7.fhir.r5.model.*; import org.hl7.fhir.r5.terminologies.ValueSetUtilities; import org.hl7.fhir.r5.utils.XVerExtensionManager; import org.hl7.fhir.r5.utils.XVerExtensionManager.XVerExtensionStatus; @@ -88,11 +43,16 @@ import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueType; import org.hl7.fhir.utilities.validation.ValidationMessage.Source; -import org.hl7.fhir.validation.BaseValidator.TrackedLocationRelatedMessage; import org.hl7.fhir.validation.instance.utils.IndexedElement; -public class BaseValidator { +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import static org.apache.commons.lang3.StringUtils.isBlank; + +public class BaseValidator { public class TrackedLocationRelatedMessage { private Object location; private ValidationMessage vmsg; @@ -107,8 +67,7 @@ public class BaseValidator { public ValidationMessage getVmsg() { return vmsg; } - - } + } public class ValidationControl { private boolean allowed; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/NativeHostServices.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/NativeHostServices.java index e332a9ae8..57107e01d 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/NativeHostServices.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/NativeHostServices.java @@ -34,9 +34,6 @@ package org.hl7.fhir.validation; import java.io.ByteArrayOutputStream; import java.io.IOException; -import org.hl7.fhir.convertors.conv10_50.VersionConvertor_10_50; -import org.hl7.fhir.convertors.conv14_50.VersionConvertor_14_50; -import org.hl7.fhir.convertors.conv30_50.VersionConvertor_30_50; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_14_50; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_50; @@ -69,9 +66,9 @@ import org.hl7.fhir.r5.model.FhirPublication; import org.hl7.fhir.r5.model.OperationOutcome; import org.hl7.fhir.r5.model.Resource; import org.hl7.fhir.r5.model.ValueSet; -import org.hl7.fhir.r5.utils.IResourceValidator.BestPracticeWarningLevel; -import org.hl7.fhir.r5.utils.IResourceValidator.CheckDisplayOption; -import org.hl7.fhir.r5.utils.IResourceValidator.IdStatus; +import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel; +import org.hl7.fhir.r5.utils.validation.constants.CheckDisplayOption; +import org.hl7.fhir.r5.utils.validation.constants.IdStatus; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java index 033927d7f..197460299 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidationEngine.java @@ -3,9 +3,6 @@ package org.hl7.fhir.validation; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; -import org.hl7.fhir.convertors.conv10_50.VersionConvertor_10_50; -import org.hl7.fhir.convertors.conv14_50.VersionConvertor_14_50; -import org.hl7.fhir.convertors.conv30_50.VersionConvertor_30_50; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_14_50; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_50; @@ -35,10 +32,13 @@ import org.hl7.fhir.r5.renderers.utils.RenderingContext; import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode; import org.hl7.fhir.r5.utils.EOperationOutcome; import org.hl7.fhir.r5.utils.FHIRPathEngine; -import org.hl7.fhir.r5.utils.IResourceValidator; -import org.hl7.fhir.r5.utils.IResourceValidator.*; +import org.hl7.fhir.r5.utils.validation.BundleValidationRule; +import org.hl7.fhir.r5.utils.validation.IResourceValidator; import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.r5.utils.structuremap.StructureMapUtilities; +import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor; +import org.hl7.fhir.r5.utils.validation.IValidatorResourceFetcher; +import org.hl7.fhir.r5.utils.validation.constants.*; import org.hl7.fhir.utilities.TimeTracker; import org.hl7.fhir.utilities.*; import org.hl7.fhir.utilities.SimpleHTTPClient.HTTPResult; @@ -57,7 +57,6 @@ import org.xml.sax.SAXException; import java.io.*; import java.net.URISyntaxException; -import java.net.URL; import java.util.*; /* @@ -131,7 +130,7 @@ POSSIBILITY OF SUCH DAMAGE. * @author Grahame Grieve */ @Accessors(chain = true) -public class ValidationEngine implements IValidatorResourceFetcher, IPackageInstaller { +public class ValidationEngine implements IValidatorResourceFetcher, IValidationPolicyAdvisor, IPackageInstaller { @Getter @Setter private SimpleWorkerContext context; @Getter @Setter private Map binaries = new HashMap<>(); @@ -146,6 +145,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst @Getter @Setter private PrintWriter mapLog; @Getter @Setter private boolean debug = false; @Getter @Setter private IValidatorResourceFetcher fetcher; + @Getter @Setter private IValidationPolicyAdvisor policyAdvisor; @Getter @Setter private ICanonicalResourceLocator locator; @Getter @Setter private boolean assumeValidRestReferences; @Getter @Setter private boolean noExtensibleBindingMessages; @@ -730,22 +730,43 @@ public class ValidationEngine implements IValidatorResourceFetcher, IPackageInst } @Override - public ReferenceValidationPolicy validationPolicy(IResourceValidator validator, Object appContext, String path, String url) { + public ReferenceValidationPolicy policyForReference(IResourceValidator validator, Object appContext, String path, String url) { Resource resource = context.fetchResource(StructureDefinition.class, url); if (resource != null) { return ReferenceValidationPolicy.CHECK_VALID; } if (!(url.contains("hl7.org") || url.contains("fhir.org"))) { return ReferenceValidationPolicy.IGNORE; - } else if (fetcher != null) { - return fetcher.validationPolicy(validator, appContext, path, url); + } else if (policyAdvisor != null) { + return policyAdvisor.policyForReference(validator, appContext, path, url); } else { return ReferenceValidationPolicy.CHECK_EXISTS_AND_TYPE; } } @Override - public boolean resolveURL(IResourceValidator validator, Object appContext, String path, String url, String type) throws IOException, FHIRException { + public ContainedReferenceValidationPolicy policyForContained(IResourceValidator validator, + Object appContext, + String containerType, + String containerId, + Element.SpecialElement containingResourceType, + String path, + String url) { + Resource resource = context.fetchResource(StructureDefinition.class, url); + if (resource != null) { + return ContainedReferenceValidationPolicy.CHECK_VALID; + } + if (!(url.contains("hl7.org") || url.contains("fhir.org"))) { + return ContainedReferenceValidationPolicy.IGNORE; + } else if (policyAdvisor != null) { + return policyAdvisor.policyForContained(validator, appContext, containerType, containerId, containingResourceType, path, url); + } else { + return ContainedReferenceValidationPolicy.CHECK_TYPE; + } + } + + @Override + public boolean resolveURL(IResourceValidator validator, Object appContext, String path, String url, String type) throws FHIRException { if (!url.startsWith("http://") && !url.startsWith("https://")) { // ignore these return true; } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java index f6ae3964d..1ac810f2d 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/model/CliContext.java @@ -7,7 +7,7 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; -import org.hl7.fhir.r5.utils.IResourceValidator.BundleValidationRule; +import org.hl7.fhir.r5.utils.validation.BundleValidationRule; import org.hl7.fhir.validation.cli.utils.QuestionnaireMode; import org.hl7.fhir.validation.cli.utils.EngineMode; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/StandAloneValidatorFetcher.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/StandAloneValidatorFetcher.java index 9eba19d20..7c3340fc8 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/StandAloneValidatorFetcher.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/services/StandAloneValidatorFetcher.java @@ -8,9 +8,11 @@ import org.hl7.fhir.r5.context.IWorkerContext.ICanonicalResourceLocator; import org.hl7.fhir.r5.elementmodel.Element; import org.hl7.fhir.r5.model.CanonicalResource; import org.hl7.fhir.r5.terminologies.TerminologyClient; -import org.hl7.fhir.r5.utils.IResourceValidator; -import org.hl7.fhir.r5.utils.IResourceValidator.IValidatorResourceFetcher; -import org.hl7.fhir.r5.utils.IResourceValidator.ReferenceValidationPolicy; +import org.hl7.fhir.r5.utils.validation.IResourceValidator; +import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor; +import org.hl7.fhir.r5.utils.validation.IValidatorResourceFetcher; +import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPolicy; +import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.VersionUtilities.VersionURLInfo; @@ -28,7 +30,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; -public class StandAloneValidatorFetcher implements IValidatorResourceFetcher, ICanonicalResourceLocator { +public class StandAloneValidatorFetcher implements IValidatorResourceFetcher, IValidationPolicyAdvisor, ICanonicalResourceLocator { List mappingsUris = new ArrayList<>(); private FilesystemPackageCacheManager pcm; @@ -51,10 +53,24 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher, IC } @Override - public ReferenceValidationPolicy validationPolicy(IResourceValidator validator, Object appContext, String path, String url) { + public ReferenceValidationPolicy policyForReference(IResourceValidator validator, + Object appContext, + String path, + String url) { return ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS; } + @Override + public ContainedReferenceValidationPolicy policyForContained(IResourceValidator validator, + Object appContext, + String containerType, + String containerId, + Element.SpecialElement containingResourceType, + String path, + String url) { + return ContainedReferenceValidationPolicy.CHECK_TYPE; + } + @Override public boolean resolveURL(IResourceValidator validator, Object appContext, String path, String url, String type) throws IOException, FHIRException { if (!Utilities.isAbsoluteUrl(url)) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Params.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Params.java index e17b99afa..b738a825f 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Params.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/cli/utils/Params.java @@ -1,7 +1,6 @@ package org.hl7.fhir.validation.cli.utils; -import org.apache.http.auth.AUTH; -import org.hl7.fhir.r5.utils.IResourceValidator.BundleValidationRule; +import org.hl7.fhir.r5.utils.validation.BundleValidationRule; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.validation.cli.model.CliContext; 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 0f08b395a..4c6b51d6d 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 @@ -47,8 +47,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import org.apache.commons.codec.binary.Base64InputStream; import org.apache.commons.lang3.NotImplementedException; @@ -135,9 +133,10 @@ import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorCla import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException; import org.hl7.fhir.r5.utils.FHIRPathEngine; import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext; -import org.hl7.fhir.r5.utils.IResourceValidator; +import org.hl7.fhir.r5.utils.validation.*; import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.r5.utils.XVerExtensionManager; +import org.hl7.fhir.r5.utils.validation.constants.*; import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; import org.hl7.fhir.utilities.SIDUtilities; import org.hl7.fhir.utilities.UnicodeUtilities; @@ -174,8 +173,6 @@ import org.w3c.dom.Document; import com.google.gson.Gson; import com.google.gson.JsonObject; -import javax.annotation.Nonnull; - /** * Thinking of using this in a java program? Don't! @@ -381,6 +378,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat private Map fetchCache = new HashMap<>(); private HashMap resourceTracker = new HashMap<>(); private IValidatorResourceFetcher fetcher; + private IValidationPolicyAdvisor policyAdvisor; long time = 0; private IEvaluationContext externalHostServices; private boolean noExtensibleWarnings; @@ -464,6 +462,17 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat return this; } + @Override + public IValidationPolicyAdvisor getPolicyAdvisor() { + return policyAdvisor; + } + + @Override + public IResourceValidator setPolicyAdvisor(IValidationPolicyAdvisor advisor) { + this.policyAdvisor = advisor; + return this; + } + public IValidationProfileUsageTracker getTracker() { return this.tracker; } @@ -2114,7 +2123,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } if (!found) { if (type.equals("canonical")) { - ReferenceValidationPolicy rp = fetcher.validationPolicy(this, appContext, path, url); + ReferenceValidationPolicy rp = policyAdvisor == null ? ReferenceValidationPolicy.CHECK_VALID : policyAdvisor.policyForReference(this, appContext, path, url); if (rp == ReferenceValidationPolicy.CHECK_EXISTS || rp == ReferenceValidationPolicy.CHECK_EXISTS_AND_TYPE) { rule(errors, IssueType.INVALID, e.line(), e.col(), path, found, I18nConstants.TYPE_SPECIFIC_CHECKS_DT_CANONICAL_RESOLVE, url); } else { @@ -2131,7 +2140,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } else { if (type.equals("canonical")) { - ReferenceValidationPolicy rp = fetcher.validationPolicy(this, appContext, path, url); + ReferenceValidationPolicy rp = policyAdvisor == null ? ReferenceValidationPolicy.CHECK_VALID : policyAdvisor.policyForReference(this, appContext, path, url); if (rp == ReferenceValidationPolicy.CHECK_EXISTS_AND_TYPE || rp == ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS || rp == ReferenceValidationPolicy.CHECK_VALID) { try { Resource r = fetcher.fetchCanonicalResource(this, url); @@ -2690,14 +2699,22 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat checkFixedValue(errors, path + ".denominator", focus.getNamedChild("denominator"), fixed.getDenominator(), fixedSource, "denominator", focus, pattern); } - private void checkReference(ValidatorHostContext hostContext, List errors, String path, Element element, StructureDefinition profile, ElementDefinition container, String parentType, NodeStack stack) throws FHIRException { + private void checkReference(ValidatorHostContext hostContext, + List errors, + String path, + Element element, + StructureDefinition profile, + ElementDefinition container, + String parentType, + NodeStack stack) throws FHIRException { Reference reference = ObjectConverter.readAsReference(element); String ref = reference.getReference(); if (Utilities.noString(ref)) { if (!path.contains("element.pattern")) { // this business rule doesn't apply to patterns if (Utilities.noString(reference.getIdentifier().getSystem()) && Utilities.noString(reference.getIdentifier().getValue())) { - warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, !Utilities.noString(element.getNamedChildValue("display")), I18nConstants.REFERENCE_REF_NODISPLAY); + warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, + !Utilities.noString(element.getNamedChildValue("display")), I18nConstants.REFERENCE_REF_NODISPLAY); } } return; @@ -2718,7 +2735,13 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat refType = "bundled"; } } - ReferenceValidationPolicy pol = refType.equals("contained") || refType.equals("bundled") ? ReferenceValidationPolicy.CHECK_VALID : fetcher == null ? ReferenceValidationPolicy.IGNORE : fetcher.validationPolicy(this, hostContext.getAppContext(), path, ref); + ReferenceValidationPolicy pol; + if (refType.equals("contained") || refType.equals("bundled")) { + pol = ReferenceValidationPolicy.CHECK_VALID; + } else { + if (policyAdvisor == null) pol = ReferenceValidationPolicy.IGNORE; + else pol = policyAdvisor.policyForReference(this, hostContext.getAppContext(), path, ref); + } if (pol.checkExists()) { if (we == null) { @@ -2745,7 +2768,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } } - boolean ok = (allowExamples && (ref.contains("example.org") || ref.contains("acme.com"))) || (we != null || pol == ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS); + boolean ok = (allowExamples && (ref.contains("example.org") || ref.contains("acme.com"))) + || (we != null || pol == ReferenceValidationPolicy.CHECK_TYPE_IF_EXISTS); rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, ok, I18nConstants.REFERENCE_REF_CANTRESOLVE, ref); } @@ -2767,22 +2791,26 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat boolean matchingResource = false; for (CanonicalType target : containerType.getTargetProfile()) { StructureDefinition sd = resolveProfile(profile, target.asStringValue()); - if (rule(errors, IssueType.NOTFOUND, element.line(), element.col(), path, sd != null, I18nConstants.REFERENCE_REF_CANTRESOLVEPROFILE, target.asStringValue())) { + if (rule(errors, IssueType.NOTFOUND, element.line(), element.col(), path, sd != null, + I18nConstants.REFERENCE_REF_CANTRESOLVEPROFILE, target.asStringValue())) { if (("http://hl7.org/fhir/StructureDefinition/" + sd.getType()).equals(tu)) { matchingResource = true; break; } } } - rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, matchingResource, I18nConstants.REFERENCE_REF_WRONGTARGET, reference.getType(), container.getType("Reference").getTargetProfile()); + rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, matchingResource, + I18nConstants.REFERENCE_REF_WRONGTARGET, reference.getType(), container.getType("Reference").getTargetProfile()); } // the type has to match the actual - rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, ft == null || ft.equals(reference.getType()), I18nConstants.REFERENCE_REF_BADTARGETTYPE, reference.getType(), ft); + rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, + ft == null || ft.equals(reference.getType()), I18nConstants.REFERENCE_REF_BADTARGETTYPE, reference.getType(), ft); } if (we != null && pol.checkType()) { - if (warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, ft != null, I18nConstants.REFERENCE_REF_NOTYPE)) { + if (warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, ft != null, + I18nConstants.REFERENCE_REF_NOTYPE)) { // we validate as much as we can. First, can we infer a type from the profile? boolean ok = false; TypeRefComponent type = getReferenceTypeRef(container.getType()); @@ -2791,7 +2819,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat List profiles = new ArrayList<>(); for (UriType u : type.getTargetProfile()) { StructureDefinition sd = resolveProfile(profile, u.getValue()); - if (rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, sd != null, I18nConstants.REFERENCE_REF_CANTRESOLVEPROFILE, u.getValue())) { + if (rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, sd != null, + I18nConstants.REFERENCE_REF_CANTRESOLVEPROFILE, u.getValue())) { types.add(sd.getType()); if (ft.equals(sd.getType())) { ok = true; @@ -2800,14 +2829,16 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } if (!pol.checkValid()) { - rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, profiles.size() > 0, I18nConstants.REFERENCE_REF_CANTMATCHTYPE, ref, StringUtils.join("; ", type.getTargetProfile())); + rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, profiles.size() > 0, + I18nConstants.REFERENCE_REF_CANTMATCHTYPE, ref, StringUtils.join("; ", type.getTargetProfile())); } else { - Map> badProfiles = new HashMap>(); - Map> goodProfiles = new HashMap>(); + Map> badProfiles = new HashMap<>(); + Map> goodProfiles = new HashMap<>(); int goodCount = 0; for (StructureDefinition pr : profiles) { List profileErrors = new ArrayList(); - validateResource(we.hostContext(hostContext, pr), profileErrors, we.getResource(), we.getFocus(), pr, IdStatus.OPTIONAL, we.getStack().resetIds()); + validateResource(we.hostContext(hostContext, pr), profileErrors, we.getResource(), we.getFocus(), pr, + IdStatus.OPTIONAL, we.getStack().resetIds()); if (!hasErrors(profileErrors)) { goodCount++; goodProfiles.put(pr, profileErrors); @@ -2827,14 +2858,16 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } else if (goodProfiles.size() == 0) { if (!isShowMessagesFromReferences()) { - rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, areAllBaseProfiles(profiles), I18nConstants.REFERENCE_REF_CANTMATCHCHOICE, ref, asList(type.getTargetProfile())); + rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, areAllBaseProfiles(profiles), + I18nConstants.REFERENCE_REF_CANTMATCHCHOICE, ref, asList(type.getTargetProfile())); for (StructureDefinition sd : badProfiles.keySet()) { slicingHint(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, false, context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, ref, sd.getUrl()), errorSummaryForSlicingAsHtml(badProfiles.get(sd)), errorSummaryForSlicingAsText(badProfiles.get(sd))); } } else { - rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, profiles.size() == 1, I18nConstants.REFERENCE_REF_CANTMATCHCHOICE, ref, asList(type.getTargetProfile())); + rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, profiles.size() == 1, + I18nConstants.REFERENCE_REF_CANTMATCHCHOICE, ref, asList(type.getTargetProfile())); for (List messages : badProfiles.values()) { for (ValidationMessage vm : messages) { if (!errors.contains(vm)) { @@ -2845,13 +2878,16 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } else { if (!isShowMessagesFromReferences()) { - warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, I18nConstants.REFERENCE_REF_MULTIPLEMATCHES, ref, asListByUrl(goodProfiles.keySet())); + warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, + I18nConstants.REFERENCE_REF_MULTIPLEMATCHES, ref, asListByUrl(goodProfiles.keySet())); for (StructureDefinition sd : badProfiles.keySet()) { - slicingHint(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, false, context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, ref, sd.getUrl()), + slicingHint(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, + false, context.formatMessage(I18nConstants.DETAILS_FOR__MATCHING_AGAINST_PROFILE_, ref, sd.getUrl()), errorSummaryForSlicingAsHtml(badProfiles.get(sd)), errorSummaryForSlicingAsText(badProfiles.get(sd))); } } else { - warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, I18nConstants.REFERENCE_REF_MULTIPLEMATCHES, ref, asListByUrl(goodProfiles.keySet())); + warning(errors, IssueType.STRUCTURE, element.line(), element.col(), path, false, + I18nConstants.REFERENCE_REF_MULTIPLEMATCHES, ref, asListByUrl(goodProfiles.keySet())); for (List messages : goodProfiles.values()) { for (ValidationMessage vm : messages) { if (!errors.contains(vm)) { @@ -2862,7 +2898,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } } - rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, ok, I18nConstants.REFERENCE_REF_BADTARGETTYPE, ft, types.toString()); + rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, ok, + I18nConstants.REFERENCE_REF_BADTARGETTYPE, ft, types.toString()); } if (type.hasAggregation() && !noCheckAggregation) { boolean modeOk = false; @@ -2876,7 +2913,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat else if (mode.getValue().equals(AggregationMode.REFERENCED) && (refType.equals("bundled") || refType.equals("remote"))) modeOk = true; } - rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, modeOk, I18nConstants.REFERENCE_REF_AGGREGATION, refType, b.toString()); + rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, modeOk, + I18nConstants.REFERENCE_REF_AGGREGATION, refType, b.toString()); } } } @@ -2905,7 +2943,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat sdF = sdF.hasBaseDefinition() ? context.fetchResource(StructureDefinition.class, sdF.getBaseDefinition()) : null; } } - rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, types.isEmpty() || ok, I18nConstants.REFERENCE_REF_BADTARGETTYPE2, ft, ref, types); + rule(errors, IssueType.STRUCTURE, element.line(), element.col(), path, types.isEmpty() || ok, + I18nConstants.REFERENCE_REF_BADTARGETTYPE2, ft, ref, types); } if (pol == ReferenceValidationPolicy.CHECK_VALID) { @@ -4349,84 +4388,108 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } - private void validateContains(ValidatorHostContext hostContext, List errors, String path, ElementDefinition child, ElementDefinition context, Element resource, Element element, NodeStack stack, IdStatus idstatus) throws FHIRException { + private void validateContains(ValidatorHostContext hostContext, List errors, String path, + ElementDefinition child, ElementDefinition context, Element resource, + Element element, NodeStack stack, IdStatus idstatus, StructureDefinition parentProfile) throws FHIRException { + + SpecialElement special = element.getSpecial(); + + ContainedReferenceValidationPolicy containedValidationPolicy = getPolicyAdvisor() == null ? + ContainedReferenceValidationPolicy.CHECK_VALID : getPolicyAdvisor().policyForContained(this, + hostContext, context.fhirType(), context.getId(), special, path, parentProfile.getUrl()); + + if (containedValidationPolicy.ignore()) { + return; + } + String resourceName = element.getType(); - TypeRefComponent trr = null; + TypeRefComponent typeForResource = null; CommaSeparatedStringBuilder bt = new CommaSeparatedStringBuilder(); - for (TypeRefComponent tr : child.getType()) { - bt.append(tr.getCode()); - if (tr.getCode().equals("Resource") || tr.getCode().equals(resourceName) ) { - trr = tr; + + // Iterate through all possible types + for (TypeRefComponent type : child.getType()) { + bt.append(type.getCode()); + if (type.getCode().equals("Resource") || type.getCode().equals(resourceName) ) { + typeForResource = type; break; } } + stack.qualifyPath(".ofType("+resourceName+")"); - if (trr == null) { - rule(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), false, I18nConstants.BUNDLE_BUNDLE_ENTRY_TYPE, resourceName, bt.toString()); - } else if (isValidResourceType(resourceName, trr)) { - // special case: resource wrapper is reset if we're crossing a bundle boundary, but not otherwise - ValidatorHostContext hc = null; - if (element.getSpecial() == SpecialElement.BUNDLE_ENTRY || element.getSpecial() == SpecialElement.BUNDLE_OUTCOME || element.getSpecial() == SpecialElement.PARAMETER) { - resource = element; - hc = hostContext.forEntry(element); - } else { - hc = hostContext.forContained(element); - } - stack.resetIds(); - if (element.getSpecial() != null) { - switch (element.getSpecial()) { - case BUNDLE_ENTRY: - idstatus = IdStatus.OPTIONAL; - break; - case BUNDLE_OUTCOME: - idstatus = IdStatus.OPTIONAL; - break; - case CONTAINED: - stack.setContained(true); - idstatus = IdStatus.REQUIRED; - break; - case PARAMETER: - idstatus = IdStatus.OPTIONAL; - break; - default: - break; + + if (typeForResource == null) { + rule(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), + false, I18nConstants.BUNDLE_BUNDLE_ENTRY_TYPE, resourceName, bt.toString()); + } else if (isValidResourceType(resourceName, typeForResource)) { + if (containedValidationPolicy.checkValid()) { + // special case: resource wrapper is reset if we're crossing a bundle boundary, but not otherwise + ValidatorHostContext hc = null; + if (special == SpecialElement.BUNDLE_ENTRY || special == SpecialElement.BUNDLE_OUTCOME || special == SpecialElement.PARAMETER) { + resource = element; + hc = hostContext.forEntry(element); + } else { + hc = hostContext.forContained(element); } - } - if (trr.getProfile().size() == 1) { - long t = System.nanoTime(); - StructureDefinition profile = this.context.fetchResource(StructureDefinition.class, trr.getProfile().get(0).asStringValue()); - timeTracker.sd(t); - trackUsage(profile, hostContext, element); - if (rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), profile != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOPROFILE, resourceName)) { - validateResource(hc, errors, resource, element, profile, idstatus, stack); + + stack.resetIds(); + if (special != null) { + switch (special) { + case BUNDLE_ENTRY: + case BUNDLE_OUTCOME: + case PARAMETER: + idstatus = IdStatus.OPTIONAL; + break; + case CONTAINED: + stack.setContained(true); + idstatus = IdStatus.REQUIRED; + break; + default: + break; + } } - } else if (trr.getProfile().size() == 0) { - long t = System.nanoTime(); - StructureDefinition profile = this.context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/" + resourceName); - timeTracker.sd(t); - trackUsage(profile, hostContext, element); - if (rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), profile != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOPROFILE, resourceName)) { - validateResource(hc, errors, resource, element, profile, idstatus, stack); + + if (typeForResource.getProfile().size() == 1) { + long t = System.nanoTime(); + StructureDefinition profile = this.context.fetchResource(StructureDefinition.class, typeForResource.getProfile().get(0).asStringValue()); + timeTracker.sd(t); + trackUsage(profile, hostContext, element); + if (rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), + profile != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOPROFILE, resourceName)) { + validateResource(hc, errors, resource, element, profile, idstatus, stack); + } + } else if (typeForResource.getProfile().isEmpty()) { + long t = System.nanoTime(); + StructureDefinition profile = this.context.fetchResource(StructureDefinition.class, + "http://hl7.org/fhir/StructureDefinition/" + resourceName); + timeTracker.sd(t); + trackUsage(profile, hostContext, element); + if (rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), + profile != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOPROFILE, resourceName)) { + validateResource(hc, errors, resource, element, profile, idstatus, stack); + } + } else { + CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); + for (CanonicalType u : typeForResource.getProfile()) { + b.append(u.asStringValue()); + } + rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), + false, I18nConstants.BUNDLE_BUNDLE_ENTRY_MULTIPLE_PROFILES, typeForResource.getCode(), b.toString()); } - } else { - CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); - for (CanonicalType u : trr.getProfile()) { - b.append(u.asStringValue()); - } - rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), false, I18nConstants.BUNDLE_BUNDLE_ENTRY_MULTIPLE_PROFILES, trr.getCode(), b.toString()); } } else { List types = new ArrayList<>(); - for (UriType u : trr.getProfile()) { + for (UriType u : typeForResource.getProfile()) { StructureDefinition sd = this.context.fetchResource(StructureDefinition.class, u.getValue()); if (sd != null && !types.contains(sd.getType())) { types.add(sd.getType()); } } if (types.size() == 1) { - rule(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), false, I18nConstants.BUNDLE_BUNDLE_ENTRY_TYPE2, resourceName, types.get(0)); + rule(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), + false, I18nConstants.BUNDLE_BUNDLE_ENTRY_TYPE2, resourceName, types.get(0)); } else { - rule(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), false, I18nConstants.BUNDLE_BUNDLE_ENTRY_TYPE3, resourceName, types); + rule(errors, IssueType.INFORMATIONAL, element.line(), element.col(), stack.getLiteralPath(), + false, I18nConstants.BUNDLE_BUNDLE_ENTRY_TYPE3, resourceName, types); } } } @@ -4590,7 +4653,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat rule(errors, IssueType.STRUCTURE, element.line(), element.col(), ei.getPath(), false, I18nConstants.EXTENSION_PROF_TYPE, profile.getUrl(), type, stype); } } - // + // Excluding reference is a kludge to get around versioning issues if (checkDefn.getType().get(0).hasProfile()) { for (CanonicalType p : checkDefn.getType().get(0).getProfile()) { @@ -4717,7 +4780,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } } else if (type.equals("Resource") || isResource(type)) { - validateContains(hostContext, errors, ei.getPath(), checkDefn, definition, resource, ei.getElement(), localStack, idStatusForEntry(element, ei)); // if + validateContains(hostContext, errors, ei.getPath(), checkDefn, definition, resource, ei.getElement(), + localStack, idStatusForEntry(element, ei), profile); // if elementValidated = true; // (str.matches(".*([.,/])work\\1$")) } else if (Utilities.isAbsoluteUrl(type)) { @@ -5288,18 +5352,24 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat /* * The actual base entry point for internal use (re-entrant) */ - private void validateResource(ValidatorHostContext hostContext, List errors, Element resource, Element element, StructureDefinition defn, IdStatus idstatus, NodeStack stack) throws FHIRException { + private void validateResource(ValidatorHostContext hostContext, List errors, Element resource, + Element element, StructureDefinition defn, IdStatus idstatus, NodeStack stack) throws FHIRException { + + // check here if we call validation policy here, and then change it to the new interface assert stack != null; assert resource != null; boolean ok = true; String resourceName = element.getType(); // todo: consider namespace...? + if (defn == null) { long t = System.nanoTime(); defn = element.getProperty().getStructure(); if (defn == null) defn = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/" + resourceName); timeTracker.sd(t); - ok = rule(errors, IssueType.INVALID, element.line(), element.col(), stack.addToLiteralPath(resourceName), defn != null, I18nConstants.VALIDATION_VAL_PROFILE_NODEFINITION, resourceName); + //check exists + ok = rule(errors, IssueType.INVALID, element.line(), element.col(), stack.addToLiteralPath(resourceName), + defn != null, I18nConstants.VALIDATION_VAL_PROFILE_NODEFINITION, resourceName); } // special case: we have a bundle, and the profile is not for a bundle. We'll try the first entry instead @@ -5308,19 +5378,16 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (first != null && typeMatchesDefn(first.getElement().getType(), defn)) { element = first.getElement(); stack = first; - resourceName = element.getType(); idstatus = IdStatus.OPTIONAL; // why? } // todo: validate everything in this bundle. } - ok = rule(errors, IssueType.INVALID, -1, -1, stack.getLiteralPath(), typeMatchesDefn(resourceName, defn), I18nConstants.VALIDATION_VAL_PROFILE_WRONGTYPE, defn.getType(), resourceName, defn.getName()); - if (ok) { if (idstatus == IdStatus.REQUIRED && (element.getNamedChild(ID) == null)) { rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), false, I18nConstants.RESOURCE_RES_ID_MISSING); } else if (idstatus == IdStatus.PROHIBITED && (element.getNamedChild(ID) != null)) { rule(errors, IssueType.INVALID, element.line(), element.col(), stack.getLiteralPath(), false, I18nConstants.RESOURCE_RES_ID_PROHIBITED); - } + } if (element.getNamedChild(ID) != null) { Element eid = element.getNamedChild(ID); if (eid.getProperty() != null && eid.getProperty().getDefinition() != null && eid.getProperty().getDefinition().getBase().getPath().equals("Resource.id")) { @@ -5328,6 +5395,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat rule(errors, IssueType.INVALID, eid.line(), eid.col(), ns.getLiteralPath(), FormatUtilities.isValidId(eid.primitiveValue()), I18nConstants.RESOURCE_RES_ID_MALFORMED); } } + // validate start(hostContext, errors, element, element, defn, stack); // root is both definition and type } } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidatorFactory.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidatorFactory.java index d51487f6e..cf69c05fc 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidatorFactory.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidatorFactory.java @@ -1,7 +1,7 @@ -package org.hl7.fhir.validation.instance; - -import org.hl7.fhir.exceptions.FHIRException; - +package org.hl7.fhir.validation.instance; + +import org.hl7.fhir.exceptions.FHIRException; + /* Copyright (c) 2011+, HL7, Inc. All rights reserved. @@ -30,24 +30,24 @@ import org.hl7.fhir.exceptions.FHIRException; POSSIBILITY OF SUCH DAMAGE. */ - - - -import org.hl7.fhir.r5.context.IWorkerContext; -import org.hl7.fhir.r5.context.SimpleWorkerContext.IValidatorFactory; -import org.hl7.fhir.r5.utils.IResourceValidator; -import org.hl7.fhir.r5.utils.XVerExtensionManager; - -public class InstanceValidatorFactory implements IValidatorFactory { - - @Override - public IResourceValidator makeValidator(IWorkerContext ctxt, XVerExtensionManager xverManager) throws FHIRException { - return new InstanceValidator(ctxt, null, xverManager); - } - - @Override - public IResourceValidator makeValidator(IWorkerContext ctxt) throws FHIRException { - return new InstanceValidator(ctxt, null, null); - } - + + + +import org.hl7.fhir.r5.context.IWorkerContext; +import org.hl7.fhir.r5.context.SimpleWorkerContext.IValidatorFactory; +import org.hl7.fhir.r5.utils.validation.IResourceValidator; +import org.hl7.fhir.r5.utils.XVerExtensionManager; + +public class InstanceValidatorFactory implements IValidatorFactory { + + @Override + public IResourceValidator makeValidator(IWorkerContext ctxt, XVerExtensionManager xverManager) throws FHIRException { + return new InstanceValidator(ctxt, null, xverManager); + } + + @Override + public IResourceValidator makeValidator(IWorkerContext ctxt) throws FHIRException { + return new InstanceValidator(ctxt, null, null); + } + } \ No newline at end of file diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/BundleValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/BundleValidator.java index 6f53644d1..2ab7ab597 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/BundleValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/BundleValidator.java @@ -14,7 +14,7 @@ import org.hl7.fhir.r5.model.Constants; import org.hl7.fhir.r5.model.Enumerations.FHIRVersion; import org.hl7.fhir.r5.model.StructureDefinition; import org.hl7.fhir.r5.utils.XVerExtensionManager; -import org.hl7.fhir.r5.utils.IResourceValidator.BundleValidationRule; +import org.hl7.fhir.r5.utils.validation.BundleValidationRule; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.i18n.I18nConstants; @@ -369,7 +369,8 @@ public class BundleValidator extends BaseValidator{ if (ref != null && !Utilities.noString(reference) && !reference.startsWith("#")) { Element target = resolveInBundle(entries, reference, fullUrl, type, id); - rule(errors, IssueType.INVALID, ref.line(), ref.col(), stack.addToLiteralPath("reference"), target != null, I18nConstants.BUNDLE_BUNDLE_ENTRY_NOTFOUND, reference, name); + rule(errors, IssueType.INVALID, ref.line(), ref.col(), stack.addToLiteralPath("reference"), target != null, + I18nConstants.BUNDLE_BUNDLE_ENTRY_NOTFOUND, reference, name); } } diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/R3R4ConversionTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/R3R4ConversionTests.java index 9ea700674..f0a78967b 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/R3R4ConversionTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/R3R4ConversionTests.java @@ -37,11 +37,12 @@ import org.hl7.fhir.r4.model.StructureDefinition.StructureDefinitionKind; import org.hl7.fhir.r4.model.StructureMap; import org.hl7.fhir.r4.model.UriType; import org.hl7.fhir.r4.test.utils.TestingUtilities; -import org.hl7.fhir.r4.utils.IResourceValidator; -import org.hl7.fhir.r4.utils.IResourceValidator.IValidatorResourceFetcher; -import org.hl7.fhir.r4.utils.IResourceValidator.ReferenceValidationPolicy; +import org.hl7.fhir.r4.utils.validation.IResourceValidator; +import org.hl7.fhir.r4.utils.validation.IValidatorResourceFetcher; +import org.hl7.fhir.r4.utils.validation.constants.ReferenceValidationPolicy; import org.hl7.fhir.r4.utils.StructureMapUtilities; import org.hl7.fhir.r4.utils.StructureMapUtilities.ITransformerServices; +import org.hl7.fhir.r4.utils.validation.IValidationPolicyAdvisor; import org.hl7.fhir.utilities.IniFile; import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; @@ -62,7 +63,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; @Disabled -public class R3R4ConversionTests implements ITransformerServices, IValidatorResourceFetcher { +public class R3R4ConversionTests implements ITransformerServices, IValidatorResourceFetcher, IValidationPolicyAdvisor { private static final boolean SAVING = true; private FilesystemPackageCacheManager pcm = null; @@ -454,7 +455,15 @@ public class R3R4ConversionTests implements ITransformerServices, IValidatorReso } @Override - public ReferenceValidationPolicy validationPolicy(Object appContext, String path, String url) { + public ReferenceValidationPolicy policyForReference(IResourceValidator validator, Object appContext, String path, String url) { + return ReferenceValidationPolicy.IGNORE; + } + + @Override + public ReferenceValidationPolicy policyForContained(IResourceValidator validator, Object appContext, + String containerType, String containerId, + Element.SpecialElement containingResourceType, String path, + String url) { return ReferenceValidationPolicy.IGNORE; } diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/SnapShotGenerationXTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/SnapShotGenerationXTests.java index d6a087ab5..d5896e537 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/SnapShotGenerationXTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/conversion/tests/SnapShotGenerationXTests.java @@ -4,7 +4,6 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.util.ArrayList; import java.util.List; @@ -20,7 +19,6 @@ import org.hl7.fhir.exceptions.PathEngineException; import org.hl7.fhir.r5.conformance.ProfileUtilities; import org.hl7.fhir.r5.conformance.ProfileUtilities.ProfileKnowledgeProvider; import org.hl7.fhir.r5.formats.IParser.OutputStyle; -import org.hl7.fhir.r5.formats.JsonParser; import org.hl7.fhir.r5.formats.XmlParser; import org.hl7.fhir.r5.model.Base; import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingComponent; @@ -37,7 +35,7 @@ import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode; import org.hl7.fhir.r5.test.utils.TestingUtilities; import org.hl7.fhir.r5.utils.FHIRPathEngine; import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext; -import org.hl7.fhir.r5.utils.IResourceValidator; +import org.hl7.fhir.r5.utils.validation.IResourceValidator; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity; 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 0d2ccf2c8..0d38760f4 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 @@ -5,7 +5,6 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; -import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; @@ -16,9 +15,6 @@ import java.util.Map; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.NotImplementedException; -import org.hl7.fhir.convertors.conv10_50.VersionConvertor_10_50; -import org.hl7.fhir.convertors.conv14_50.VersionConvertor_14_50; -import org.hl7.fhir.convertors.conv30_50.VersionConvertor_30_50; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_14_50; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_50; @@ -32,7 +28,6 @@ import org.hl7.fhir.r5.elementmodel.Element; import org.hl7.fhir.r5.elementmodel.Manager; import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat; import org.hl7.fhir.r5.elementmodel.ObjectConverter; -import org.hl7.fhir.r5.elementmodel.SHCParser; import org.hl7.fhir.r5.formats.JsonParser; import org.hl7.fhir.r5.formats.XmlParser; import org.hl7.fhir.r5.model.Base; @@ -48,11 +43,13 @@ import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.test.utils.TestingUtilities; import org.hl7.fhir.r5.utils.FHIRPathEngine; import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext; -import org.hl7.fhir.r5.utils.IResourceValidator; -import org.hl7.fhir.r5.utils.IResourceValidator.BestPracticeWarningLevel; -import org.hl7.fhir.r5.utils.IResourceValidator.BundleValidationRule; -import org.hl7.fhir.r5.utils.IResourceValidator.IValidatorResourceFetcher; -import org.hl7.fhir.r5.utils.IResourceValidator.ReferenceValidationPolicy; +import org.hl7.fhir.r5.utils.validation.IResourceValidator; +import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor; +import org.hl7.fhir.r5.utils.validation.constants.BestPracticeWarningLevel; +import org.hl7.fhir.r5.utils.validation.BundleValidationRule; +import org.hl7.fhir.r5.utils.validation.IValidatorResourceFetcher; +import org.hl7.fhir.r5.utils.validation.constants.ContainedReferenceValidationPolicy; +import org.hl7.fhir.r5.utils.validation.constants.ReferenceValidationPolicy; import org.hl7.fhir.utilities.SimpleHTTPClient; import org.hl7.fhir.utilities.SimpleHTTPClient.HTTPResult; import org.hl7.fhir.utilities.TextFile; @@ -80,7 +77,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; @RunWith(Parameterized.class) -public class ValidationTests implements IEvaluationContext, IValidatorResourceFetcher { +public class ValidationTests implements IEvaluationContext, IValidatorResourceFetcher, IValidationPolicyAdvisor { public final static boolean PRINT_OUTPUT_TO_CONSOLE = true; @@ -179,6 +176,9 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe } else { val.setFetcher(this); } + + val.setPolicyAdvisor(this); + if (content.has("allowed-extension-domain")) val.getExtensionDomains().add(content.get("allowed-extension-domain").getAsString()); if (content.has("allowed-extension-domains")) @@ -509,13 +509,24 @@ public class ValidationTests implements IEvaluationContext, IValidatorResourceFe } @Override - public ReferenceValidationPolicy validationPolicy(IResourceValidator validator, Object appContext, String path, String url) { - if (content.has("validate")) - return ReferenceValidationPolicy.valueOf(content.get("validate").getAsString()); + public ReferenceValidationPolicy policyForReference(IResourceValidator validator, Object appContext, String path, String url) { + if (content.has("validateReference")) + return ReferenceValidationPolicy.valueOf(content.get("validateReference").getAsString()); else return ReferenceValidationPolicy.IGNORE; } + @Override + public ContainedReferenceValidationPolicy policyForContained(IResourceValidator validator, Object appContext, + String containerType, String containerId, + Element.SpecialElement containingResourceType, + String path, String url) { + if (content.has("validateContains")) + return ContainedReferenceValidationPolicy.valueOf(content.get("validateContains").getAsString()); + else + return ContainedReferenceValidationPolicy.CHECK_VALID; + } + @Override public boolean resolveURL(IResourceValidator validator, Object appContext, String path, String url, String type) throws IOException, FHIRException { return !url.contains("example.org") && !url.startsWith("http://hl7.org/fhir/invalid"); diff --git a/pom.xml b/pom.xml index ca6fa9907..81266af93 100644 --- a/pom.xml +++ b/pom.xml @@ -14,12 +14,12 @@ HAPI FHIR --> org.hl7.fhir.core - 5.6.1-SNAPSHOT + 5.6.2-SNAPSHOT pom 5.1.0 - 1.1.77 + 1.1.79-SNAPSHOT 5.7.1 1.7.1 3.0.0-M5