From b402fd1c4529be0546954db2fade74f28c6cf805 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Fri, 5 May 2023 13:55:23 -0500 Subject: [PATCH 1/8] Fix bug handling filter, and refactor terminology code --- .../convertors/misc}/LoincToDEConvertor.java | 2 +- .../txClient/TerminologyClientFactory.java | 6 +- .../txClient/TerminologyClientR2.java | 14 +- .../txClient/TerminologyClientR3.java | 14 +- .../txClient/TerminologyClientR4.java | 14 +- .../txClient/TerminologyClientR5.java | 14 +- .../TerminologyClientFactoryTest.java | 8 +- .../fhir/r5/comparison/ValueSetComparer.java | 2 +- .../fhir/r5/conformance/ShExGenerator.java | 4 +- .../conformance/profile/ProfileUtilities.java | 2 +- .../fhir/r5/context/BaseWorkerContext.java | 133 +++---- .../hl7/fhir/r5/context/IWorkerContext.java | 4 +- .../fhir/r5/context/SimpleWorkerContext.java | 14 +- .../hl7/fhir/r5/context/TerminologyCache.java | 4 +- .../org/hl7/fhir/r5/elementmodel/Element.java | 2 +- .../r5/renderers/QuestionnaireRenderer.java | 2 +- .../fhir/r5/renderers/ValueSetRenderer.java | 2 +- .../r5/terminologies/CodeSystemUtilities.java | 15 + .../terminologies/ITerminologyServices.java | 112 ------ .../TerminologyServerDetails.java | 55 +++ .../TerminologyServiceCache.java | 37 -- .../r5/terminologies/ValueSetChecker.java | 82 ---- .../r5/terminologies/ValueSetExpander.java | 145 ------- .../ValueSetExpanderFactory.java | 65 --- .../terminologies/ValueSetExpansionCache.java | 210 ---------- .../r5/terminologies/ValueSetUtilities.java | 5 + .../fhir/r5/terminologies/ValueSetWorker.java | 12 - .../ITerminologyClient.java} | 14 +- .../client/TerminologyClientContext.java | 81 ++++ .../expansion/AllConceptsFilter.java | 18 + .../expansion/ConceptFilter.java | 28 ++ .../r5/terminologies/expansion/EFinished.java | 7 + .../terminologies/expansion/ETooCostly.java | 9 + .../expansion/PropertyFilter.java | 59 +++ .../terminologies/expansion/RegexFilter.java | 21 + .../ValueSetExpander.java} | 373 ++++++++---------- .../expansion/ValueSetExpansionOutcome.java | 77 ++++ .../expansion/WorkingContext.java | 81 ++++ .../{ => providers}/CodeSystemProvider.java | 6 +- .../providers/ColorRGBProvider.java | 3 +- .../{ => providers}/SpecialCodeSystem.java | 2 +- .../{ => providers}/URICodeSystem.java | 13 +- .../TerminologyServiceErrorClass.java | 9 + .../validation/ConceptReferencePair.java | 24 ++ .../validation/VSCheckerException.java | 23 ++ .../validation/ValidationProcessInfo.java | 43 ++ .../ValueSetValidator.java} | 172 +++----- .../terminologies/validation/VersionInfo.java | 79 ++++ .../fhir/r5/utils/QuestionnaireBuilder.java | 2 +- .../structuremap/StructureMapUtilities.java | 2 +- .../r5/context/SimpleWorkerContextTests.java | 28 +- .../r5/context/TerminologyCacheTests.java | 6 +- .../JurisdictionUtilitiesTests.java | 2 +- .../java/org/hl7/fhir/r5/test/VocabTests.java | 2 +- .../context/codableConceptEmptyValueSet.json | 21 - .../codableConceptEmptyValueSetSystem.json | 23 -- .../context/codingEmptyValueSet.json | 17 - .../context/codingEmptyValueSetSystem.json | 19 - .../src/test/resources/context/expansion.json | 28 -- .../context/expansionHierarchical.json | 28 -- .../fhir/utilities/i18n/I18nConstants.java | 1 + .../utilities/settings/FhirSettingsPOJO.java | 3 +- .../src/main/resources/Messages.properties | 1 + .../hl7/fhir/validation/ValidationEngine.java | 14 +- .../org/hl7/fhir/validation/ValidatorCli.java | 2 +- .../fhir/validation/cli/model/CliContext.java | 2 +- .../services/StandAloneValidatorFetcher.java | 4 +- .../instance/InstanceValidator.java | 2 +- .../instance/type/QuestionnaireValidator.java | 2 +- .../instance/type/StructureMapValidator.java | 2 +- .../instance/type/ValueSetValidator.java | 2 +- .../utils/FHIRPathExpressionFixer.java | 7 +- .../hl7/fhir/validation/special/TxTester.java | 34 +- .../ExternalTerminologyServiceTests.java | 10 +- .../tests/TerminologyServiceTests.java | 3 +- .../tests/utilities/TestUtilities.java | 2 +- pom.xml | 2 +- 77 files changed, 1045 insertions(+), 1347 deletions(-) rename {org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies => org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/misc}/LoincToDEConvertor.java (99%) delete mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ITerminologyServices.java create mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/TerminologyServerDetails.java delete mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/TerminologyServiceCache.java delete mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetChecker.java delete mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetExpander.java delete mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetExpanderFactory.java delete mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetExpansionCache.java delete mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetWorker.java rename org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/{TerminologyClient.java => client/ITerminologyClient.java} (86%) create mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/client/TerminologyClientContext.java create mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/AllConceptsFilter.java create mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/ConceptFilter.java create mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/EFinished.java create mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/ETooCostly.java create mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/PropertyFilter.java create mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/RegexFilter.java rename org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/{ValueSetExpanderSimple.java => expansion/ValueSetExpander.java} (73%) create mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/ValueSetExpansionOutcome.java create mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/WorkingContext.java rename org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/{ => providers}/CodeSystemProvider.java (82%) rename org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/{ => providers}/SpecialCodeSystem.java (81%) rename org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/{ => providers}/URICodeSystem.java (53%) create mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/utilities/TerminologyServiceErrorClass.java create mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ConceptReferencePair.java create mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/VSCheckerException.java create mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValidationProcessInfo.java rename org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/{ValueSetCheckerSimple.java => validation/ValueSetValidator.java} (91%) create mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/VersionInfo.java rename org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/{terminology => terminologies}/JurisdictionUtilitiesTests.java (94%) delete mode 100644 org.hl7.fhir.r5/src/test/resources/context/codableConceptEmptyValueSet.json delete mode 100644 org.hl7.fhir.r5/src/test/resources/context/codableConceptEmptyValueSetSystem.json delete mode 100644 org.hl7.fhir.r5/src/test/resources/context/codingEmptyValueSet.json delete mode 100644 org.hl7.fhir.r5/src/test/resources/context/codingEmptyValueSetSystem.json delete mode 100644 org.hl7.fhir.r5/src/test/resources/context/expansion.json delete mode 100644 org.hl7.fhir.r5/src/test/resources/context/expansionHierarchical.json diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/LoincToDEConvertor.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/misc/LoincToDEConvertor.java similarity index 99% rename from org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/LoincToDEConvertor.java rename to org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/misc/LoincToDEConvertor.java index 43dac7cb3..b498ee329 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/LoincToDEConvertor.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/misc/LoincToDEConvertor.java @@ -1,4 +1,4 @@ -package org.hl7.fhir.r5.terminologies; +package org.hl7.fhir.convertors.misc; /* Copyright (c) 2011+, HL7, Inc. diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientFactory.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientFactory.java index 56cc4ae74..48a768d44 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientFactory.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientFactory.java @@ -2,7 +2,7 @@ package org.hl7.fhir.convertors.txClient; import java.net.URISyntaxException; -import org.hl7.fhir.r5.terminologies.TerminologyClient; +import org.hl7.fhir.r5.terminologies.client.ITerminologyClient; import org.hl7.fhir.utilities.FhirPublication; import org.hl7.fhir.utilities.Utilities; @@ -10,7 +10,7 @@ import org.hl7.fhir.utilities.VersionUtilities; public class TerminologyClientFactory { - public static TerminologyClient makeClient(String id, String url, String userAgent, FhirPublication v) throws URISyntaxException { + public static ITerminologyClient makeClient(String id, String url, String userAgent, FhirPublication v) throws URISyntaxException { if (v == null) return new TerminologyClientR5(id, checkEndsWith("/r4", url), userAgent); switch (v) { @@ -33,7 +33,7 @@ public class TerminologyClientFactory { } } - public static TerminologyClient makeClient(String id, String url, String userAgent, String v) throws URISyntaxException { + public static ITerminologyClient makeClient(String id, String url, String userAgent, String v) throws URISyntaxException { if (v == null) return new TerminologyClientR5(id, checkEndsWith("/r4", url), userAgent); v = VersionUtilities.getMajMin(v); diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientR2.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientR2.java index 7dc2667a2..86c11ff1c 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientR2.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientR2.java @@ -45,13 +45,13 @@ import org.hl7.fhir.r5.model.CapabilityStatement; import org.hl7.fhir.r5.model.Parameters; import org.hl7.fhir.r5.model.TerminologyCapabilities; import org.hl7.fhir.r5.model.ValueSet; -import org.hl7.fhir.r5.terminologies.TerminologyClient; +import org.hl7.fhir.r5.terminologies.client.ITerminologyClient; import org.hl7.fhir.r5.utils.client.network.ClientHeaders; import org.hl7.fhir.utilities.FhirPublication; import org.hl7.fhir.utilities.ToolingClientLogger; import org.hl7.fhir.utilities.Utilities; -public class TerminologyClientR2 implements TerminologyClient { +public class TerminologyClientR2 implements ITerminologyClient { private final FHIRToolingClient client; // todo: use the R2 client private String id; @@ -125,19 +125,19 @@ public class TerminologyClientR2 implements TerminologyClient { } @Override - public TerminologyClient setTimeout(int i) { + public ITerminologyClient setTimeout(int i) { client.setTimeout(i); return this; } @Override - public TerminologyClient setLogger(ToolingClientLogger txLog) { + public ITerminologyClient setLogger(ToolingClientLogger txLog) { client.setLogger(txLog); return this; } @Override - public TerminologyClient setRetryCount(int retryCount) throws FHIRException { + public ITerminologyClient setRetryCount(int retryCount) throws FHIRException { client.setRetryCount(retryCount); return this; } @@ -190,12 +190,12 @@ public class TerminologyClientR2 implements TerminologyClient { } @Override - public TerminologyClient setClientHeaders(ClientHeaders clientHeaders) { + public ITerminologyClient setClientHeaders(ClientHeaders clientHeaders) { return null; } @Override - public TerminologyClient setUserAgent(String userAgent) { + public ITerminologyClient setUserAgent(String userAgent) { client.setUserAgent(userAgent); return this; } diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientR3.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientR3.java index 71c4080b4..5f15fa54f 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientR3.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientR3.java @@ -45,13 +45,13 @@ import org.hl7.fhir.r5.model.CapabilityStatement; import org.hl7.fhir.r5.model.Parameters; import org.hl7.fhir.r5.model.TerminologyCapabilities; import org.hl7.fhir.r5.model.ValueSet; -import org.hl7.fhir.r5.terminologies.TerminologyClient; +import org.hl7.fhir.r5.terminologies.client.ITerminologyClient; import org.hl7.fhir.r5.utils.client.network.ClientHeaders; import org.hl7.fhir.utilities.FhirPublication; import org.hl7.fhir.utilities.ToolingClientLogger; import org.hl7.fhir.utilities.Utilities; -public class TerminologyClientR3 implements TerminologyClient { +public class TerminologyClientR3 implements ITerminologyClient { private final FHIRToolingClient client; // todo: use the R2 client private ClientHeaders clientHeaders; @@ -123,19 +123,19 @@ public class TerminologyClientR3 implements TerminologyClient { } @Override - public TerminologyClient setTimeout(int i) { + public ITerminologyClient setTimeout(int i) { client.setTimeout(i); return this; } @Override - public TerminologyClient setLogger(ToolingClientLogger txLog) { + public ITerminologyClient setLogger(ToolingClientLogger txLog) { client.setLogger(txLog); return this; } @Override - public TerminologyClient setRetryCount(int retryCount) throws FHIRException { + public ITerminologyClient setRetryCount(int retryCount) throws FHIRException { client.setRetryCount(retryCount); return this; } @@ -188,14 +188,14 @@ public class TerminologyClientR3 implements TerminologyClient { } @Override - public TerminologyClient setClientHeaders(ClientHeaders clientHeaders) { + public ITerminologyClient setClientHeaders(ClientHeaders clientHeaders) { this.clientHeaders = clientHeaders; this.client.setClientHeaders(this.clientHeaders.headers()); return this; } @Override - public TerminologyClient setUserAgent(String userAgent) { + public ITerminologyClient setUserAgent(String userAgent) { client.setUserAgent(userAgent); return this; } diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientR4.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientR4.java index 3b14b9d27..957d35b11 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientR4.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientR4.java @@ -48,13 +48,13 @@ import org.hl7.fhir.r5.model.CapabilityStatement; import org.hl7.fhir.r5.model.Parameters; import org.hl7.fhir.r5.model.TerminologyCapabilities; import org.hl7.fhir.r5.model.ValueSet; -import org.hl7.fhir.r5.terminologies.TerminologyClient; +import org.hl7.fhir.r5.terminologies.client.ITerminologyClient; import org.hl7.fhir.r5.utils.client.network.ClientHeaders; import org.hl7.fhir.utilities.FhirPublication; import org.hl7.fhir.utilities.ToolingClientLogger; import org.hl7.fhir.utilities.Utilities; -public class TerminologyClientR4 implements TerminologyClient { +public class TerminologyClientR4 implements ITerminologyClient { private final FHIRToolingClient client; // todo: use the R2 client private ClientHeaders clientHeaders; @@ -139,19 +139,19 @@ public class TerminologyClientR4 implements TerminologyClient { } @Override - public TerminologyClient setTimeout(int i) { + public ITerminologyClient setTimeout(int i) { client.setTimeout(i); return this; } @Override - public TerminologyClient setLogger(ToolingClientLogger txLog) { + public ITerminologyClient setLogger(ToolingClientLogger txLog) { client.setLogger(txLog); return this; } @Override - public TerminologyClient setRetryCount(int retryCount) throws FHIRException { + public ITerminologyClient setRetryCount(int retryCount) throws FHIRException { client.setRetryCount(retryCount); return this; } @@ -204,14 +204,14 @@ public class TerminologyClientR4 implements TerminologyClient { } @Override - public TerminologyClient setClientHeaders(ClientHeaders clientHeaders) { + public ITerminologyClient setClientHeaders(ClientHeaders clientHeaders) { this.clientHeaders = clientHeaders; this.client.setClientHeaders(this.clientHeaders.headers()); return this; } @Override - public TerminologyClient setUserAgent(String userAgent) { + public ITerminologyClient setUserAgent(String userAgent) { client.setUserAgent(userAgent); return this; } diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientR5.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientR5.java index 9a3ae0342..fd68e352e 100644 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientR5.java +++ b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/txClient/TerminologyClientR5.java @@ -43,14 +43,14 @@ import org.hl7.fhir.r5.model.Parameters; import org.hl7.fhir.r5.model.Resource; import org.hl7.fhir.r5.model.TerminologyCapabilities; import org.hl7.fhir.r5.model.ValueSet; -import org.hl7.fhir.r5.terminologies.TerminologyClient; +import org.hl7.fhir.r5.terminologies.client.ITerminologyClient; import org.hl7.fhir.r5.utils.client.FHIRToolingClient; import org.hl7.fhir.r5.utils.client.network.ClientHeaders; import org.hl7.fhir.utilities.FhirPublication; import org.hl7.fhir.utilities.ToolingClientLogger; import org.hl7.fhir.utilities.Utilities; -public class TerminologyClientR5 implements TerminologyClient { +public class TerminologyClientR5 implements ITerminologyClient { private final FHIRToolingClient client; private ClientHeaders clientHeaders; @@ -117,13 +117,13 @@ public class TerminologyClientR5 implements TerminologyClient { } @Override - public TerminologyClient setTimeout(int i) { + public ITerminologyClient setTimeout(int i) { client.setTimeout(i); return this; } @Override - public TerminologyClient setLogger(ToolingClientLogger txLog) { + public ITerminologyClient setLogger(ToolingClientLogger txLog) { client.setLogger(txLog); return this; } @@ -139,7 +139,7 @@ public class TerminologyClientR5 implements TerminologyClient { } @Override - public TerminologyClient setRetryCount(int retryCount) throws FHIRException { + public ITerminologyClient setRetryCount(int retryCount) throws FHIRException { client.setRetryCount(retryCount); return this; } @@ -178,14 +178,14 @@ public class TerminologyClientR5 implements TerminologyClient { } @Override - public TerminologyClient setClientHeaders(ClientHeaders clientHeaders) { + public ITerminologyClient setClientHeaders(ClientHeaders clientHeaders) { this.clientHeaders = clientHeaders; this.client.setClientHeaders(this.clientHeaders.headers()); return this; } @Override - public TerminologyClient setUserAgent(String userAgent) { + public ITerminologyClient setUserAgent(String userAgent) { client.setUserAgent(userAgent); return this; } diff --git a/org.hl7.fhir.convertors/src/test/java/org/hl7/fhir/convertors/txClient/TerminologyClientFactoryTest.java b/org.hl7.fhir.convertors/src/test/java/org/hl7/fhir/convertors/txClient/TerminologyClientFactoryTest.java index aaf9a9b26..6b475bcf8 100644 --- a/org.hl7.fhir.convertors/src/test/java/org/hl7/fhir/convertors/txClient/TerminologyClientFactoryTest.java +++ b/org.hl7.fhir.convertors/src/test/java/org/hl7/fhir/convertors/txClient/TerminologyClientFactoryTest.java @@ -1,6 +1,6 @@ package org.hl7.fhir.convertors.txClient; -import org.hl7.fhir.r5.terminologies.TerminologyClient; +import org.hl7.fhir.r5.terminologies.client.ITerminologyClient; import org.hl7.fhir.utilities.FhirPublication; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -52,14 +52,14 @@ public class TerminologyClientFactoryTest { @ParameterizedTest @MethodSource("data") public void testMakeClient(String url, FhirPublication fhirPublication, String expectedAddress) throws URISyntaxException { - TerminologyClient terminologyClient = TerminologyClientFactory.makeClient("id", url, "dummyUserAgent", fhirPublication); + ITerminologyClient terminologyClient = TerminologyClientFactory.makeClient("id", url, "dummyUserAgent", fhirPublication); assertEquals(expectedAddress, terminologyClient.getAddress()); } @Test public void testMakeClientDstu1Fails() throws URISyntaxException { assertThrows(Error.class, () -> { - TerminologyClient terminologyClient = TerminologyClientFactory.makeClient("id", "urldoesnotmatter", "dummyUserAgent", FhirPublication.DSTU1); + ITerminologyClient terminologyClient = TerminologyClientFactory.makeClient("id", "urldoesnotmatter", "dummyUserAgent", FhirPublication.DSTU1); } ); } @@ -67,7 +67,7 @@ public class TerminologyClientFactoryTest { @Test public void testMakeClientNullFails() throws URISyntaxException { assertThrows(Error.class, () -> { - TerminologyClient terminologyClient = TerminologyClientFactory.makeClient("id", "urldoesnotmatter", "dummyUserAgent", FhirPublication.NULL); + ITerminologyClient terminologyClient = TerminologyClientFactory.makeClient("id", "urldoesnotmatter", "dummyUserAgent", FhirPublication.NULL); } ); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/comparison/ValueSetComparer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/comparison/ValueSetComparer.java index d4e6b33d4..c0261c3f2 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/comparison/ValueSetComparer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/comparison/ValueSetComparer.java @@ -17,7 +17,7 @@ import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetComposeComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome; +import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; 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.r5/src/main/java/org/hl7/fhir/r5/conformance/ShExGenerator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ShExGenerator.java index a663aa3f8..8ffacac6b 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ShExGenerator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/ShExGenerator.java @@ -41,7 +41,7 @@ import org.apache.commons.lang3.tuple.Pair; import org.hl7.fhir.r5.conformance.profile.ProfileUtilities; import org.hl7.fhir.r5.context.IWorkerContext; import org.hl7.fhir.r5.model.*; -import org.hl7.fhir.r5.terminologies.ValueSetExpander; +import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; import org.hl7.fhir.r5.utils.FHIRPathEngine; import org.stringtemplate.v4.ST; @@ -1848,7 +1848,7 @@ public class ShExGenerator { */ private String genValueSet(ValueSet vs) { ST vsd = tmplt(VALUE_SET_DEFINITION).add("vsuri", vsprefix(vs.getUrl())).add("comment", vs.getDescription()); - ValueSetExpander.ValueSetExpansionOutcome vse = context.expandVS(vs, true, false); + ValueSetExpansionOutcome vse = context.expandVS(vs, true, false); List valid_codes = new ArrayList(); if(vse != null && vse.getValueset() != null && diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java index 2ea201427..b3e384870 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java @@ -89,7 +89,7 @@ import org.hl7.fhir.r5.model.UriType; import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome; +import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; import org.hl7.fhir.r5.utils.FHIRPathEngine; import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.r5.utils.TranslatingUtilities; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java index 5d6da6394..ef16503bf 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/BaseWorkerContext.java @@ -110,12 +110,14 @@ import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy; import org.hl7.fhir.r5.profilemodel.PEBuilder; import org.hl7.fhir.r5.renderers.OperationOutcomeRenderer; import org.hl7.fhir.r5.terminologies.CodeSystemUtilities; -import org.hl7.fhir.r5.terminologies.TerminologyClient; -import org.hl7.fhir.r5.terminologies.ValueSetCheckerSimple; -import org.hl7.fhir.r5.terminologies.ValueSetCheckerSimple.VSCheckerException; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome; -import org.hl7.fhir.r5.terminologies.ValueSetExpanderSimple; +import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpander; +import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; +import org.hl7.fhir.r5.terminologies.utilities.TerminologyServiceErrorClass; +import org.hl7.fhir.r5.terminologies.validation.VSCheckerException; +import org.hl7.fhir.r5.terminologies.validation.ValueSetValidator; +import org.hl7.fhir.r5.terminologies.ValueSetUtilities; +import org.hl7.fhir.r5.terminologies.client.ITerminologyClient; +import org.hl7.fhir.r5.terminologies.client.TerminologyClientContext; import org.hl7.fhir.r5.utils.PackageHackerR5; import org.hl7.fhir.r5.utils.ResourceUtilities; import org.hl7.fhir.r5.utils.ToolingExtensions; @@ -205,12 +207,9 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte private Object lock = new Object(); // used as a lock for the data that follows protected String version; // although the internal resources are all R5, the version of FHIR they describe may not be - private String cacheId; - private boolean isTxCaching; - @Getter - private int serverQueryCount = 0; - private final Set cached = new HashSet<>(); - + + protected TerminologyClientContext tcc = new TerminologyClientContext(); + private Map> allResourcesById = new HashMap>(); // all maps are to the full URI private CanonicalResourceManager codeSystems = new CanonicalResourceManager(false); @@ -239,14 +238,11 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte protected Map oidCache = new HashMap<>(); protected Map> validationCache = new HashMap>(); - protected String tsServer; protected String name; private boolean allowLoadingDuplicates; - protected TerminologyClient txClient; private final Set codeSystemsUsed = new HashSet<>(); protected ToolingClientLogger txLog; - private TerminologyCapabilities txcaps; private boolean canRunWithoutTerminology; protected boolean noTerminologyServer; private int expandCodesLimit = 1000; @@ -288,7 +284,6 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte allResourcesById.putAll(other.allResourcesById); translator = other.translator; codeSystems.copy(other.codeSystems); - txcaps = other.txcaps; valueSets.copy(other.valueSets); maps.copy(other.maps); transforms.copy(other.transforms); @@ -305,11 +300,8 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte libraries.copy(libraries); allowLoadingDuplicates = other.allowLoadingDuplicates; - tsServer = other.tsServer; name = other.name; - txClient = other.txClient; txLog = other.txLog; - txcaps = other.txcaps; canRunWithoutTerminology = other.canRunWithoutTerminology; noTerminologyServer = other.noTerminologyServer; if (other.txCache != null) @@ -318,9 +310,6 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte logger = other.logger; expParameters = other.expParameters; version = other.version; - cacheId = other.cacheId; - isTxCaching = other.isTxCaching; - cached.addAll(other.cached); supportedCodeSystems.addAll(other.supportedCodeSystems); unsupportedCodeSystems.addAll(other.unsupportedCodeSystems); codeSystemsUsed.addAll(other.codeSystemsUsed); @@ -331,6 +320,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte tlogging = other.tlogging; locator = other.locator; userAgent = other.userAgent; + tcc.copy(other.tcc); } } @@ -697,18 +687,18 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte if (noTerminologyServer) { return false; } - if (txcaps == null) { + if (tcc.getTxcaps() == null) { try { logger.logMessage("Terminology server: Check for supported code systems for "+system); - final TerminologyCapabilities capabilityStatement = txCache.hasTerminologyCapabilities() ? txCache.getTerminologyCapabilities() : txClient.getTerminologyCapabilities(); + final TerminologyCapabilities capabilityStatement = txCache.hasTerminologyCapabilities() ? txCache.getTerminologyCapabilities() : tcc.getClient().getTerminologyCapabilities(); txCache.cacheTerminologyCapabilities(capabilityStatement); setTxCaps(capabilityStatement); } catch (Exception e) { if (canRunWithoutTerminology) { noTerminologyServer = true; logger.logMessage("==============!! Running without terminology server !! =============="); - if (txClient!=null) { - logger.logMessage("txServer = "+txClient.getId()); + if (tcc.getClient() != null) { + logger.logMessage("txServer = "+tcc.getClient().getId()); logger.logMessage("Error = "+e.getMessage()+""); } logger.logMessage("====================================================================="); @@ -787,7 +777,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte params.put("_incomplete", "true"); txLog("$expand on "+txCache.summary(vs)); try { - ValueSet result = txClient.expandValueset(vs, p, params); + ValueSet result = tcc.getClient().expandValueset(vs, p, params); res = new ValueSetExpansionOutcome(result).setTxLink(txLog.getLastId()); } catch (Exception e) { res = new ValueSetExpansionOutcome(e.getMessage() == null ? e.getClass().getName() : e.getMessage(), TerminologyServiceErrorClass.UNKNOWN); @@ -855,7 +845,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte List allErrors = new ArrayList<>(); // ok, first we try to expand locally - ValueSetExpanderSimple vse = constructValueSetExpanderSimple(); + ValueSetExpander vse = constructValueSetExpanderSimple(); res = null; try { res = vse.expand(vs, p); @@ -878,7 +868,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte // if that failed, we try to expand on the server if (addDependentResources(p, vs)) { - p.addParameter().setName("cache-id").setValue(new StringType(cacheId)); + p.addParameter().setName("cache-id").setValue(new StringType(tcc.getCacheId())); } if (noTerminologyServer) { @@ -889,7 +879,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte params.put("_incomplete", "true"); txLog("$expand on "+txCache.summary(vs)); try { - ValueSet result = txClient.expandValueset(vs, p, params); + ValueSet result = tcc.getClient().expandValueset(vs, p, params); if (!result.hasUrl()) { result.setUrl(vs.getUrl()); } @@ -952,7 +942,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte for (CodingValidationRequest t : codes) { if (!t.hasResult()) { try { - ValueSetCheckerSimple vsc = constructValueSetCheckerSimple(options, vs); + ValueSetValidator vsc = constructValueSetCheckerSimple(options, vs); ValidationResult res = vsc.validateCode("Coding", t.getCoding()); if (txCache != null) { txCache.cacheValidation(t.getCacheToken(), res, TerminologyCache.TRANSIENT); @@ -997,13 +987,13 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte } if (batch.getEntry().size() > 0) { txLog("$batch validate for "+batch.getEntry().size()+" codes on systems "+systems.toString()); - if (txClient == null) { + if (tcc.getClient() == null) { throw new FHIRException(formatMessage(I18nConstants.ATTEMPT_TO_USE_TERMINOLOGY_SERVER_WHEN_NO_TERMINOLOGY_SERVER_IS_AVAILABLE)); } if (txLog != null) { txLog.clearLastId(); } - Bundle resp = txClient.validateBatch(batch); + Bundle resp = tcc.getClient().validateBatch(batch); if (resp == null) { throw new FHIRException(formatMessage(I18nConstants.TX_SERVER_NO_BATCH_RESPONSE)); } @@ -1074,8 +1064,8 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte if (options.isUseClient()) { // ok, first we try to validate locally try { - ValueSetCheckerSimple vsc = constructValueSetCheckerSimple(options, vs, ctxt); - if (!vsc.isServerSide(code.getSystem())) { + ValueSetValidator vsc = constructValueSetCheckerSimple(options, vs, ctxt); + if (!ValueSetUtilities.isServerSide(code.getSystem())) { res = vsc.validateCode(path, code); if (txCache != null) { txCache.cacheValidation(cacheToken, res, TerminologyCache.TRANSIENT); @@ -1093,7 +1083,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte } } - if (localError != null && txClient == null) { + if (localError != null && tcc.getClient() == null) { return new ValidationResult(IssueSeverity.ERROR, localError, TerminologyServiceErrorClass.UNKNOWN, issues); } if (!options.isUseServer()) { @@ -1130,16 +1120,16 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte return res; } - protected ValueSetExpanderSimple constructValueSetExpanderSimple() { - return new ValueSetExpanderSimple(this); + protected ValueSetExpander constructValueSetExpanderSimple() { + return new ValueSetExpander(this); } - protected ValueSetCheckerSimple constructValueSetCheckerSimple( ValidationOptions options, ValueSet vs, ValidationContextCarrier ctxt) { - return new ValueSetCheckerSimple(options, vs, this, ctxt, expParameters, txcaps); + protected ValueSetValidator constructValueSetCheckerSimple( ValidationOptions options, ValueSet vs, ValidationContextCarrier ctxt) { + return new ValueSetValidator(options, vs, this, ctxt, expParameters, tcc.getTxcaps()); } - protected ValueSetCheckerSimple constructValueSetCheckerSimple( ValidationOptions options, ValueSet vs) { - return new ValueSetCheckerSimple(options, vs, this, expParameters, txcaps); + protected ValueSetValidator constructValueSetCheckerSimple( ValidationOptions options, ValueSet vs) { + return new ValueSetValidator(options, vs, this, expParameters, tcc.getTxcaps()); } protected Parameters constructParameters(ValueSet vs, boolean hierarchical) { @@ -1149,7 +1139,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte boolean cached = addDependentResources(p, vs); if (cached) { - p.addParameter().setName("cache-id").setValue(new StringType(cacheId)); + p.addParameter().setName("cache-id").setValue(new StringType(tcc.getCacheId())); } return p; } @@ -1218,7 +1208,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte if (options.isUseClient()) { // ok, first we try to validate locally try { - ValueSetCheckerSimple vsc = constructValueSetCheckerSimple(options, vs); + ValueSetValidator vsc = constructValueSetCheckerSimple(options, vs); res = vsc.validateCode("CodeableConcept", code); txCache.cacheValidation(cacheToken, res, TerminologyCache.TRANSIENT); return res; @@ -1259,22 +1249,23 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte codeSystemsUsed.add(inc.getSystem()); } } + if (vs != null) { - if (isTxCaching && cacheId != null && vs.getUrl() != null && cached.contains(vs.getUrl()+"|"+vs.getVersion())) { + if (tcc.isTxCaching() && tcc.getCacheId() != null && vs.getUrl() != null && tcc.getCached().contains(vs.getUrl()+"|"+vs.getVersion())) { pin.addParameter().setName("url").setValue(new UriType(vs.getUrl()+(vs.hasVersion() ? "|"+vs.getVersion() : ""))); } else if (options.getVsAsUrl()){ pin.addParameter().setName("url").setValue(new UriType(vs.getUrl())); } else { pin.addParameter().setName("valueSet").setResource(vs); if (vs.getUrl() != null) { - cached.add(vs.getUrl()+"|"+vs.getVersion()); + tcc.getCached().add(vs.getUrl()+"|"+vs.getVersion()); } } cache = true; addDependentResources(pin, vs); } if (cache) { - pin.addParameter().setName("cache-id").setValue(new StringType(cacheId)); + pin.addParameter().setName("cache-id").setValue(new StringType(tcc.getCacheId())); } for (ParametersParameterComponent pp : pin.getParameter()) { if (pp.getName().equals("profile")) { @@ -1288,14 +1279,14 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte if (txLog != null) { txLog.clearLastId(); } - if (txClient == null) { + if (tcc.getClient() == null) { throw new FHIRException(formatMessage(I18nConstants.ATTEMPT_TO_USE_TERMINOLOGY_SERVER_WHEN_NO_TERMINOLOGY_SERVER_IS_AVAILABLE)); } Parameters pOut; if (vs == null) { - pOut = txClient.validateCS(pin); + pOut = tcc.getClient().validateCS(pin); } else { - pOut = txClient.validateVS(pin); + pOut = tcc.getClient().validateVS(pin); } return processValidationResult(pOut); } @@ -1317,8 +1308,8 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte ValueSet vs = fetchResource(ValueSet.class, c.getValue(), src); if (vs != null) { pin.addParameter().setName("tx-resource").setResource(vs); - if (isTxCaching && cacheId == null || !cached.contains(vs.getVUrl())) { - cached.add(vs.getVUrl()); + if (tcc.isTxCaching() && tcc.getCacheId() == null || !tcc.getCached().contains(vs.getVUrl())) { + tcc.getCached().add(vs.getVUrl()); cache = true; } addDependentResources(pin, vs); @@ -1327,8 +1318,8 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte CodeSystem cs = fetchResource(CodeSystem.class, inc.getSystem(), src); if (cs != null && (cs.getContent() == CodeSystemContentMode.COMPLETE || cs.getContent() == CodeSystemContentMode.FRAGMENT)) { pin.addParameter().setName("tx-resource").setResource(cs); - if (isTxCaching && cacheId == null || !cached.contains(cs.getVUrl())) { - cached.add(cs.getVUrl()); + if (tcc.isTxCaching() && tcc.getCacheId() == null || !tcc.getCached().contains(cs.getVUrl())) { + tcc.getCached().add(cs.getVUrl()); cache = true; } // todo: supplements @@ -1376,9 +1367,9 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte } } if (!ok) { - return new ValidationResult(IssueSeverity.ERROR, message+" (from "+txClient.getId()+")", err, null).setTxLink(txLog.getLastId()); + return new ValidationResult(IssueSeverity.ERROR, message+" (from "+tcc.getClient().getId()+")", err, null).setTxLink(txLog.getLastId()); } else if (message != null && !message.equals("No Message returned")) { - return new ValidationResult(IssueSeverity.WARNING, message+" (from "+txClient.getId()+")", system, version, new ConceptDefinitionComponent().setDisplay(display).setCode(code), display, null).setTxLink(txLog.getLastId()); + return new ValidationResult(IssueSeverity.WARNING, message+" (from "+tcc.getClient().getId()+")", system, version, new ConceptDefinitionComponent().setDisplay(display).setCode(code), display, null).setTxLink(txLog.getLastId()); } else if (display != null) { return new ValidationResult(system, version, new ConceptDefinitionComponent().setDisplay(display).setCode(code), display).setTxLink(txLog.getLastId()); } else { @@ -1425,7 +1416,7 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte @Override public boolean isNoTerminologyServer() { - return noTerminologyServer || txClient == null; + return noTerminologyServer || tcc.getClient() == null; } public void setNoTerminologyServer(boolean noTerminologyServer) { @@ -2376,41 +2367,41 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte } public int getClientRetryCount() { - return txClient == null ? 0 : txClient.getRetryCount(); + return tcc.getClient() == null ? 0 : tcc.getClient().getRetryCount(); } public IWorkerContext setClientRetryCount(int value) { - if (txClient != null) { - txClient.setRetryCount(value); + if (tcc.getClient() != null) { + tcc.getClient().setRetryCount(value); } return this; } - public TerminologyClient getTxClient() { - return txClient; + public ITerminologyClient getTxClient() { + return tcc.getClient(); } public String getCacheId() { - return cacheId; + return tcc.getCacheId(); } public void setCacheId(String cacheId) { - this.cacheId = cacheId; + tcc.setCacheId(cacheId); } public TerminologyCapabilities getTxCaps() { - return txcaps; + return tcc.getTxcaps(); } public void setTxCaps(TerminologyCapabilities txCaps) { - this.txcaps = txCaps; + this.tcc.setTxcaps(txCaps); if (txCaps != null) { - for (TerminologyCapabilitiesExpansionParameterComponent t : txcaps.getExpansion().getParameter()) { + for (TerminologyCapabilitiesExpansionParameterComponent t : tcc.getTxcaps().getExpansion().getParameter()) { if ("cache-id".equals(t.getName())) { - isTxCaching = true; + tcc.setTxCaching(true); } } - for (TerminologyCapabilitiesCodeSystemComponent tccs : txcaps.getCodeSystem()) { + for (TerminologyCapabilitiesCodeSystemComponent tccs : tcc.getTxcaps().getCodeSystem()) { supportedCodeSystems.add(tccs.getUri()); } } @@ -2445,8 +2436,8 @@ public abstract class BaseWorkerContext extends I18nBase implements IWorkerConte protected void setUserAgent(String userAgent) { this.userAgent = userAgent; - if (txClient != null) - txClient.setUserAgent(userAgent); + if (tcc.getClient() != null) + tcc.getClient().setUserAgent(userAgent); } 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 4910acdd2..56db42573 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 @@ -71,8 +71,8 @@ import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.r5.profilemodel.PEDefinition; import org.hl7.fhir.r5.profilemodel.PEBuilder.PEElementPropertiesPolicy; import org.hl7.fhir.r5.profilemodel.PEBuilder; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome; +import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; +import org.hl7.fhir.r5.terminologies.utilities.TerminologyServiceErrorClass; import org.hl7.fhir.r5.utils.validation.IResourceValidator; import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier; import org.hl7.fhir.utilities.TimeTracker; 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 698325000..2aa6360dc 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 @@ -67,7 +67,7 @@ import org.hl7.fhir.r5.profilemodel.PEDefinition; import org.hl7.fhir.r5.profilemodel.PEBuilder; import org.hl7.fhir.r5.terminologies.CodeSystemUtilities; import org.hl7.fhir.r5.terminologies.JurisdictionUtilities; -import org.hl7.fhir.r5.terminologies.TerminologyClient; +import org.hl7.fhir.r5.terminologies.client.ITerminologyClient; import org.hl7.fhir.r5.utils.validation.IResourceValidator; import org.hl7.fhir.r5.utils.R5Hacker; import org.hl7.fhir.r5.utils.XVerExtensionManager; @@ -316,22 +316,22 @@ public class SimpleWorkerContext extends BaseWorkerContext implements IWorkerCon loadBytes(name, stream); } - public String connectToTSServer(TerminologyClient client, String log) { + public String connectToTSServer(ITerminologyClient client, String log) { try { txLog("Connect to "+client.getAddress()); - txClient = client; + tcc.setClient(client); if (log != null && (log.endsWith(".htm") || log.endsWith(".html"))) { txLog = new HTMLClientLogger(log); } else { txLog = new TextClientLogger(log); } - txClient.setLogger(txLog); - txClient.setUserAgent(userAgent); + tcc.getClient().setLogger(txLog); + tcc.getClient().setUserAgent(userAgent); - final CapabilityStatement capabilitiesStatementQuick = txCache.hasCapabilityStatement() ? txCache.getCapabilityStatement() : txClient.getCapabilitiesStatementQuick(); + final CapabilityStatement capabilitiesStatementQuick = txCache.hasCapabilityStatement() ? txCache.getCapabilityStatement() : tcc.getClient().getCapabilitiesStatementQuick(); txCache.cacheCapabilityStatement(capabilitiesStatementQuick); - final TerminologyCapabilities capabilityStatement = txCache.hasTerminologyCapabilities() ? txCache.getTerminologyCapabilities() : txClient.getTerminologyCapabilities(); + final TerminologyCapabilities capabilityStatement = txCache.hasTerminologyCapabilities() ? txCache.getTerminologyCapabilities() : tcc.getClient().getTerminologyCapabilities(); txCache.cacheTerminologyCapabilities(capabilityStatement); setTxCaps(capabilityStatement); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/TerminologyCache.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/TerminologyCache.java index b9cae5243..f9338044e 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/TerminologyCache.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/context/TerminologyCache.java @@ -51,8 +51,8 @@ import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome; +import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; +import org.hl7.fhir.r5.terminologies.utilities.TerminologyServiceErrorClass; import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.Utilities; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java index 94eb96616..3937253a3 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java @@ -57,7 +57,7 @@ import org.hl7.fhir.r5.model.StructureDefinition; import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionKind; import org.hl7.fhir.r5.model.TypeConvertor; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome; +import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.utilities.ElementDecoration; import org.hl7.fhir.utilities.ElementDecoration.DecorationType; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/QuestionnaireRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/QuestionnaireRenderer.java index 3a8ae541d..08ac4dbd1 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/QuestionnaireRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/QuestionnaireRenderer.java @@ -26,7 +26,7 @@ import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent; import org.hl7.fhir.r5.renderers.utils.RenderingContext; import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules; import org.hl7.fhir.r5.renderers.utils.RenderingContext.KnownLinkType; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome; +import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java index ffe542bc6..308b7410c 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java @@ -43,8 +43,8 @@ import org.hl7.fhir.r5.renderers.utils.RenderingContext; import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules; import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext; import org.hl7.fhir.r5.terminologies.CodeSystemUtilities; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome; import org.hl7.fhir.r5.terminologies.ValueSetUtilities; +import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.utilities.LoincLinker; import org.hl7.fhir.utilities.Utilities; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/CodeSystemUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/CodeSystemUtilities.java index 9bde1540e..429d678d8 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/CodeSystemUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/CodeSystemUtilities.java @@ -844,5 +844,20 @@ public class CodeSystemUtilities { } return false; } + + public static boolean hasPropertyDef(CodeSystem cs, String property) { + for (PropertyComponent pd : cs.getProperty()) { + if (pd.getCode().equals(property)) { + return true; + } + } + return false; + } + + public static DataType getProperty(CodeSystem cs, String code, String property) { + ConceptDefinitionComponent def = getCode(cs, code); + ConceptPropertyComponent cp = getProperty(def, property); + return cp == null ? null : cp.getValue(); + } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ITerminologyServices.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ITerminologyServices.java deleted file mode 100644 index 6b85a0910..000000000 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ITerminologyServices.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.hl7.fhir.r5.terminologies; - -/* - 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 org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; -import org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity; -import org.hl7.fhir.r5.model.ValueSet; -import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent; -import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome; - - -/** - * The value set system has a collection of value sets - * that define code systems, and construct value sets from - * them - * - * Large external terminologies - LOINC, Snomed, etc - are too big, and - * trying to represent their definition as a native value set is too - * large. (e.g. LOINC + properties ~ 500MB). So we don't try. Instead. - * we assume that there's some external server that provides these - * services, using this interface - * - * The FHIR build tool uses http://fhir.healthintersections.com.au for - * these services - * - * @author Grahame - * - */ -public interface ITerminologyServices { - /** - * return true if the service handles code or value set resolution on the system - */ - public boolean supportsSystem(String system); - - /** - * given a system|code, return a definition for it. Nil means not valid - */ - public ConceptDefinitionComponent getCodeDefinition(String system, String code); - - public class ValidationResult { - private IssueSeverity severity; - private String message; - public ValidationResult(IssueSeverity severity, String message) { - super(); - this.severity = severity; - this.message = message; - } - public IssueSeverity getSeverity() { - return severity; - } - public String getMessage() { - return message; - } - - - } - - /** - * for this system|code and display, validate the triple against the rules of - * the underlying code system - */ - public ValidationResult validateCode(String system, String code, String display); - - /** - * Expand the value set fragment (system | codes | filters). Note that this - * might fail if the expansion is very large. If the expansion fails, then the - * checkVS will be called instead - */ - public ValueSetExpansionComponent expandVS(ConceptSetComponent inc) throws Exception; -// public ValueSet expandVS(ValueSet vs) throws Exception; - public ValueSetExpansionOutcome expand(ValueSet vs); - - /** - * Test the value set fragment (system | codes | filters). - */ - public boolean checkVS(ConceptSetComponent vsi, String system, String code); - - public boolean verifiesSystem(String system); - - - -} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/TerminologyServerDetails.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/TerminologyServerDetails.java new file mode 100644 index 000000000..97b067230 --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/TerminologyServerDetails.java @@ -0,0 +1,55 @@ +package org.hl7.fhir.r5.terminologies; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.hl7.fhir.r5.model.Enumerations.FHIRVersion; + +public class TerminologyServerDetails { + public enum ServerAuthorizationMethod { + OPEN, + TOKEN, + SMART_ON_FHIR + } + private String name; + private ServerAuthorizationMethod auth; + private Map endpoints = new HashMap<>(); + private List codeSystems = new ArrayList<>(); + + public boolean handlesSystem(String uri, String version) { + for (String s : codeSystems) { + if (s.contains("|")) { + String u = s.substring(0, s.lastIndexOf("|")); + String v = s.substring(s.lastIndexOf("|")+1); + if (v.equals(version) && (s.equals(uri) || uri.matches(s))) { + return true; + } + } else { + if (s.equals(uri) || uri.matches(s)) { + return true; + } + } + } + return false; + } + + public String getName() { + return name; + } + + public ServerAuthorizationMethod getAuth() { + return auth; + } + + public Map getEndpoints() { + return endpoints; + } + + public List getCodeSystems() { + return codeSystems; + } + + +} diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/TerminologyServiceCache.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/TerminologyServiceCache.java deleted file mode 100644 index 65b20fe43..000000000 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/TerminologyServiceCache.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.hl7.fhir.r5.terminologies; - -/* - 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. - - */ - - - -public class TerminologyServiceCache { - - -} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetChecker.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetChecker.java deleted file mode 100644 index 705b5ec1a..000000000 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetChecker.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.hl7.fhir.r5.terminologies; - -import java.util.ArrayList; -import java.util.List; - -import org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity; -import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent; - -/* - 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 org.hl7.fhir.r5.terminologies.ValueSetExpander.ETooCostly; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass; -import org.hl7.fhir.r5.utils.EOperationOutcome; -import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; - -public interface ValueSetChecker { - - public static class ValidationProcessInfo { - private TerminologyServiceErrorClass err; - private List issues = new ArrayList<>(); - public TerminologyServiceErrorClass getErr() { - return err; - } - public void setErr(TerminologyServiceErrorClass err) { - this.err = err; - } - - public List getIssues() { - return issues; - } - public void addIssue(List issues) { - issues.addAll(issues); - - } - public boolean hasErrors() { - for (OperationOutcomeIssueComponent issue : issues) { - if (issue.getSeverity() == IssueSeverity.FATAL || issue.getSeverity() == IssueSeverity.ERROR) { - return true; - } - } - return false; - } - public String summary() { - CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder("; "); - for (OperationOutcomeIssueComponent issue : issues) { - b.append(issue.getDetails().getText()); - } - return b.toString(); - } - } - Boolean codeInValueSet(String system, String version, String code, ValidationProcessInfo info) throws ETooCostly, EOperationOutcome, Exception; - -} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetExpander.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetExpander.java deleted file mode 100644 index 0e76d39e8..000000000 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetExpander.java +++ /dev/null @@ -1,145 +0,0 @@ -package org.hl7.fhir.r5.terminologies; - -/* - 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.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import org.hl7.fhir.r5.model.Parameters; -import org.hl7.fhir.r5.model.ValueSet; - -public interface ValueSetExpander { - public enum TerminologyServiceErrorClass { - UNKNOWN, NOSERVICE, SERVER_ERROR, VALUESET_UNSUPPORTED, CODESYSTEM_UNSUPPORTED, BLOCKED_BY_OPTIONS, INTERNAL_ERROR, BUSINESS_RULE, TOO_COSTLY; - - public boolean isInfrastructure() { - return this == NOSERVICE || this == SERVER_ERROR || this == VALUESET_UNSUPPORTED; - } - } - - public class ETooCostly extends Exception { - - public ETooCostly(String msg) { - super(msg); - } - - } - - /** - * Some value sets are just too big to expand. Instead of an expanded value set, - * you get back an interface that can test membership - usually on a server somewhere - * - * @author Grahame - */ - public class ValueSetExpansionOutcome { - private ValueSet valueset; - private String error; - private TerminologyServiceErrorClass errorClass; - private String txLink; - private List allErrors = new ArrayList<>(); - - public ValueSetExpansionOutcome(ValueSet valueset) { - super(); - this.valueset = valueset; - this.error = null; - } - public ValueSetExpansionOutcome(ValueSet valueset, String error, TerminologyServiceErrorClass errorClass) { - super(); - this.valueset = valueset; - this.error = error; - this.errorClass = errorClass; - allErrors.add(error); - } - public ValueSetExpansionOutcome(ValueSetChecker service, String error, TerminologyServiceErrorClass errorClass) { - super(); - this.valueset = null; - this.error = error; - this.errorClass = errorClass; - allErrors.add(error); - } - public ValueSetExpansionOutcome(String error, TerminologyServiceErrorClass errorClass) { - this.valueset = null; - this.error = error; - this.errorClass = errorClass; - allErrors.add(error); - } - public ValueSetExpansionOutcome(String error, TerminologyServiceErrorClass errorClass, List errList) { - this.valueset = null; - this.error = error; - this.errorClass = errorClass; - this.allErrors.addAll(errList); - if (!allErrors.contains(error)) { - allErrors.add(error); - } - if (!errList.contains(error)) { - errList.add(error); - } - } - - public ValueSet getValueset() { - return valueset; - } - public String getError() { - return error; - } - public TerminologyServiceErrorClass getErrorClass() { - return errorClass; - } - public String getTxLink() { - return txLink; - } - public ValueSetExpansionOutcome setTxLink(String txLink) { - this.txLink = txLink; - return this; - } - public List getAllErrors() { - return allErrors; - } - - public boolean isOk() { - return (allErrors.isEmpty() || (allErrors.size() == 1 && allErrors.get(0) == null)) && error == null; - } - } -/** - * - * @param source the value set definition to expand - * @param profile a set of parameters affecting the outcome. If you don't supply parameters, the default internal parameters will be used. - * - * @return - * @throws ETooCostly - * @throws FileNotFoundException - * @throws IOException - */ - public ValueSetExpansionOutcome expand(ValueSet source, Parameters parameters) throws ETooCostly, FileNotFoundException, IOException; -} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetExpanderFactory.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetExpanderFactory.java deleted file mode 100644 index eb7cd846b..000000000 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetExpanderFactory.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.hl7.fhir.r5.terminologies; - -/* - 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. - -*/ - -public interface ValueSetExpanderFactory { - public ValueSetExpander getExpander(); -} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetExpansionCache.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetExpansionCache.java deleted file mode 100644 index 8d3e47f89..000000000 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetExpansionCache.java +++ /dev/null @@ -1,210 +0,0 @@ -package org.hl7.fhir.r5.terminologies; - -/* - 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.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.io.IOUtils; -import org.hl7.fhir.exceptions.FHIRFormatError; -import org.hl7.fhir.r5.context.IWorkerContext; -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.CanonicalResource; -import org.hl7.fhir.r5.model.OperationOutcome; -import org.hl7.fhir.r5.model.Parameters; -import org.hl7.fhir.r5.model.Resource; -import org.hl7.fhir.r5.model.ValueSet; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome; -import org.hl7.fhir.r5.utils.ToolingExtensions; -import org.hl7.fhir.utilities.Utilities; -import org.hl7.fhir.utilities.xhtml.XhtmlComposer; - -public class ValueSetExpansionCache implements ValueSetExpanderFactory { - - public class CacheAwareExpander implements ValueSetExpander { - - @Override - public ValueSetExpansionOutcome expand(ValueSet source, Parameters expParams) throws ETooCostly, IOException { - String cacheKey = makeCacheKey(source, expParams); - if (expansions.containsKey(cacheKey)) - return expansions.get(cacheKey); - ValueSetExpander vse = new ValueSetExpanderSimple(context); - ValueSetExpansionOutcome vso = vse.expand(source, expParams); - if (vso.getError() != null) { - // well, we'll see if the designated server can expand it, and if it can, we'll cache it locally - vso = context.expandVS(source, false, expParams == null || !expParams.getParameterBool("excludeNested")); - if (cacheFolder != null) { - FileOutputStream s = new FileOutputStream(Utilities.path(cacheFolder, makeFileName(source.getUrl()))); - new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(s, vso.getValueset()); - s.close(); - } - } - if (vso.getValueset() != null) - expansions.put(cacheKey, vso); - return vso; - } - - private String makeCacheKey(ValueSet source, Parameters expParams) throws IOException { - if (expParams == null) - return source.getUrl(); - JsonParser p = new JsonParser(); - String r = p.composeString(expParams); - return source.getUrl() + " " + r.hashCode(); - } - - } - - private static final String VS_ID_EXT = "http://tools/cache"; - - private final Map expansions = new HashMap(); - private final Map canonicals = new HashMap(); - private final IWorkerContext context; - private final String cacheFolder; - - private Object lock; - - public ValueSetExpansionCache(IWorkerContext context, Object lock) { - super(); - cacheFolder = null; - this.lock = lock; - this.context = context; - } - - public ValueSetExpansionCache(IWorkerContext context, String cacheFolder, Object lock) throws FHIRFormatError, IOException { - super(); - this.context = context; - this.cacheFolder = cacheFolder; - this.lock = lock; - if (this.cacheFolder != null) - loadCache(); - } - - private String makeFileName(String url) { - return url.replace("$", "").replace(":", "").replace("|", ".").replace("//", "/").replace("/", "_")+".xml"; - } - - private void loadCache() throws FHIRFormatError, IOException { - File[] files = new File(cacheFolder).listFiles(); - for (File f : files) { - if (f.getName().endsWith(".xml")) { - final FileInputStream is = new FileInputStream(f); - try { - Resource r = new XmlParser().setOutputStyle(OutputStyle.PRETTY).parse(is); - if (r instanceof OperationOutcome) { - OperationOutcome oo = (OperationOutcome) r; - expansions.put(ToolingExtensions.getExtension(oo,VS_ID_EXT).getValue().toString(), - new ValueSetExpansionOutcome(new XhtmlComposer(XhtmlComposer.XML, false).composePlainText(oo.getText().getDiv()), TerminologyServiceErrorClass.UNKNOWN)); - } else if (r instanceof ValueSet) { - ValueSet vs = (ValueSet) r; - if (vs.hasExpansion()) - expansions.put(vs.getUrl(), new ValueSetExpansionOutcome(vs)); - else { - canonicals.put(vs.getUrl(), vs); - if (vs.hasVersion()) - canonicals.put(vs.getUrl()+"|"+vs.getVersion(), vs); - } - } else if (r instanceof CanonicalResource) { - CanonicalResource md = (CanonicalResource) r; - canonicals.put(md.getUrl(), md); - if (md.hasVersion()) - canonicals.put(md.getUrl()+"|"+md.getVersion(), md); - } - } finally { - IOUtils.closeQuietly(is); - } - } - } - } - - @Override - public ValueSetExpander getExpander() { - return new CacheAwareExpander(); - // return new ValueSetExpander(valuesets, codesystems); - } - - public CanonicalResource getStoredResource(String canonicalUri) { - synchronized (lock) { - return canonicals.get(canonicalUri); - } - } - - public void storeResource(CanonicalResource md) throws IOException { - synchronized (lock) { - canonicals.put(md.getUrl(), md); - if (md.hasVersion()) - canonicals.put(md.getUrl()+"|"+md.getVersion(), md); - } - if (cacheFolder != null) { - FileOutputStream s = new FileOutputStream(Utilities.path(cacheFolder, makeFileName(md.getUrl()+"|"+md.getVersion()))); - new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(s, md); - s.close(); - } - } - - -} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetUtilities.java index cf9b950b8..c6e1f23e6 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetUtilities.java @@ -68,6 +68,11 @@ import org.hl7.fhir.utilities.Utilities; public class ValueSetUtilities { + + public static boolean isServerSide(String url) { + return Utilities.existsInList(url, "http://hl7.org/fhir/sid/cvx"); + } + public static ValueSet makeShareable(ValueSet vs) { if (!vs.hasExperimental()) { vs.setExperimental(false); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetWorker.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetWorker.java deleted file mode 100644 index 1b5ed5cde..000000000 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetWorker.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.hl7.fhir.r5.terminologies; - -import org.hl7.fhir.utilities.Utilities; - -public class ValueSetWorker { - - public boolean isServerSide(String url) { - return Utilities.existsInList(url, "http://hl7.org/fhir/sid/cvx"); - } - - -} diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/TerminologyClient.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/client/ITerminologyClient.java similarity index 86% rename from org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/TerminologyClient.java rename to org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/client/ITerminologyClient.java index e683c6308..0112746e6 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/TerminologyClient.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/client/ITerminologyClient.java @@ -1,4 +1,4 @@ -package org.hl7.fhir.r5.terminologies; +package org.hl7.fhir.r5.terminologies.client; /* Copyright (c) 2011+, HL7, Inc. @@ -40,7 +40,7 @@ import org.hl7.fhir.utilities.ToolingClientLogger; import java.util.EnumSet; import java.util.Map; -public interface TerminologyClient { +public interface ITerminologyClient { EnumSet supportableVersions(); void setAllowedVersions(EnumSet versions); @@ -54,15 +54,15 @@ public interface TerminologyClient { ValueSet expandValueset(ValueSet vs, Parameters p, Map params) throws FHIRException; Parameters validateCS(Parameters pin) throws FHIRException; Parameters validateVS(Parameters pin) throws FHIRException; - TerminologyClient setTimeout(int i) throws FHIRException; - TerminologyClient setLogger(ToolingClientLogger txLog) throws FHIRException; + ITerminologyClient setTimeout(int i) throws FHIRException; + ITerminologyClient setLogger(ToolingClientLogger txLog) throws FHIRException; int getRetryCount() throws FHIRException; - TerminologyClient setRetryCount(int retryCount) throws FHIRException; + ITerminologyClient setRetryCount(int retryCount) throws FHIRException; CapabilityStatement getCapabilitiesStatementQuick() throws FHIRException; Parameters lookupCode(Map params) throws FHIRException; Bundle validateBatch(Bundle batch); CanonicalResource read(String type, String id); ClientHeaders getClientHeaders(); - TerminologyClient setClientHeaders(ClientHeaders clientHeaders); - TerminologyClient setUserAgent(String userAgent); + ITerminologyClient setClientHeaders(ClientHeaders clientHeaders); + ITerminologyClient setUserAgent(String userAgent); } \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/client/TerminologyClientContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/client/TerminologyClientContext.java new file mode 100644 index 000000000..0e20b83fd --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/client/TerminologyClientContext.java @@ -0,0 +1,81 @@ +package org.hl7.fhir.r5.terminologies.client; + +import java.util.HashSet; +import java.util.Set; + +import org.hl7.fhir.r5.model.TerminologyCapabilities; + +public class TerminologyClientContext { + private String cacheId; + private boolean isTxCaching; + private int serverQueryCount = 0; + private final Set cached = new HashSet<>(); +// protected String tsServer; + private ITerminologyClient client; + private TerminologyCapabilities txcaps; + + public String getCacheId() { + return cacheId; + } + + public void setCacheId(String cacheId) { + this.cacheId = cacheId; + } + + public boolean isTxCaching() { + return isTxCaching; + } + + public void setTxCaching(boolean isTxCaching) { + this.isTxCaching = isTxCaching; + } + + public int getServerQueryCount() { + return serverQueryCount; + } + + public void setServerQueryCount(int serverQueryCount) { + this.serverQueryCount = serverQueryCount; + } + + public Set getCached() { + return cached; + } + +// public String getTsServer() { +// return tsServer; +// } +// +// public void setTsServer(String tsServer) { +// this.tsServer = tsServer; +// } + + public ITerminologyClient getClient() { + return client; + } + + public void setClient(ITerminologyClient client) { + this.client = client; + } + + public TerminologyCapabilities getTxcaps() { + return txcaps; + } + + public void setTxcaps(TerminologyCapabilities txcaps) { + this.txcaps = txcaps; + } + + public void copy(TerminologyClientContext other) { + cacheId = other.cacheId; + isTxCaching = other.isTxCaching; + cached.addAll(other.cached); +// tsServer = other.tsServer; + client = other.client; + txcaps = other.txcaps; + + } + + + +} diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/AllConceptsFilter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/AllConceptsFilter.java new file mode 100644 index 000000000..5ceb37cbd --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/AllConceptsFilter.java @@ -0,0 +1,18 @@ +package org.hl7.fhir.r5.terminologies.expansion; + +import java.util.List; + +import org.hl7.fhir.r5.model.CodeSystem; +import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; + +public class AllConceptsFilter extends ConceptFilter { + + public AllConceptsFilter(List allErrors) { + super(allErrors); + } + + @Override + public boolean includeConcept(CodeSystem cs, ConceptDefinitionComponent def) { + return true; + } +} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/ConceptFilter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/ConceptFilter.java new file mode 100644 index 000000000..05aaf98fc --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/ConceptFilter.java @@ -0,0 +1,28 @@ +package org.hl7.fhir.r5.terminologies.expansion; + +import java.util.ArrayList; +import java.util.List; + +import org.hl7.fhir.exceptions.FHIRException; +import org.hl7.fhir.r5.model.CodeSystem; +import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; + +public abstract class ConceptFilter { + + private List allErrors; + + + protected FHIRException fail(String msg) { + allErrors.add(msg); + return new FHIRException(msg); + } + + public ConceptFilter(List allErrors) { + super(); + this.allErrors = allErrors; + } + + + public abstract boolean includeConcept(CodeSystem cs, ConceptDefinitionComponent def); + +} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/EFinished.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/EFinished.java new file mode 100644 index 000000000..52bf0f646 --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/EFinished.java @@ -0,0 +1,7 @@ +package org.hl7.fhir.r5.terminologies.expansion; + +import org.hl7.fhir.exceptions.FHIRException; + +public class EFinished extends FHIRException { + +} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/ETooCostly.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/ETooCostly.java new file mode 100644 index 000000000..fd46f8f9c --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/ETooCostly.java @@ -0,0 +1,9 @@ +package org.hl7.fhir.r5.terminologies.expansion; + +public class ETooCostly extends Exception { + + public ETooCostly(String msg) { + super(msg); + } + +} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/PropertyFilter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/PropertyFilter.java new file mode 100644 index 000000000..3af987e8f --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/PropertyFilter.java @@ -0,0 +1,59 @@ +package org.hl7.fhir.r5.terminologies.expansion; + +import java.util.List; + +import org.hl7.fhir.r5.model.CodeSystem; +import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; +import org.hl7.fhir.r5.model.CodeSystem.ConceptPropertyComponent; +import org.hl7.fhir.r5.model.CodeSystem.PropertyComponent; +import org.hl7.fhir.r5.model.CodeSystem.PropertyType; +import org.hl7.fhir.r5.model.Enumerations.FilterOperator; +import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent; + +public class PropertyFilter extends ConceptFilter { + + private ConceptSetFilterComponent filter; + private PropertyComponent property; + + public PropertyFilter(List allErrors, ConceptSetFilterComponent fc, PropertyComponent propertyDefinition) { + super (allErrors); + this.filter = fc; + this.property = propertyDefinition; + } + + @Override + public boolean includeConcept(CodeSystem cs, ConceptDefinitionComponent def) { + ConceptPropertyComponent pc = getPropertyForConcept(def); + if (pc != null) { + String v = pc.getValue().isPrimitive() ? pc.getValue().primitiveValue() : null; + switch (filter.getOp()) { + case DESCENDENTOF: throw fail("not supported yet: "+filter.getOp().toCode()); + case EQUAL: return filter.getValue().equals(v); + case EXISTS: throw fail("not supported yet: "+filter.getOp().toCode()); + case GENERALIZES: throw fail("not supported yet: "+filter.getOp().toCode()); + case IN: throw fail("not supported yet: "+filter.getOp().toCode()); + case ISA: throw fail("not supported yet: "+filter.getOp().toCode()); + case ISNOTA: throw fail("not supported yet: "+filter.getOp().toCode()); + case NOTIN: throw fail("not supported yet: "+filter.getOp().toCode()); + case NULL: throw fail("not supported yet: "+filter.getOp().toCode()); + case REGEX: throw fail("not supported yet: "+filter.getOp().toCode()); + default: + throw fail("Shouldn't get here"); + } + } else if (property.getType() == PropertyType.BOOLEAN && filter.getOp() == FilterOperator.EQUAL) { + return "false".equals(filter.getValue()); + } else { + return false; + } + } + + private ConceptPropertyComponent getPropertyForConcept(ConceptDefinitionComponent def) { + for (ConceptPropertyComponent pc : def.getProperty()) { + if (pc.getCode().equals(property.getCode())) { + return pc; + } + } + return null; + } + +} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/RegexFilter.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/RegexFilter.java new file mode 100644 index 000000000..81242a1a1 --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/RegexFilter.java @@ -0,0 +1,21 @@ +package org.hl7.fhir.r5.terminologies.expansion; + +import java.util.List; + +import org.hl7.fhir.r5.model.CodeSystem; +import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; + +public class RegexFilter extends ConceptFilter { + + private String regex; + + protected RegexFilter(List allErrors, String regex) { + super(allErrors); + this.regex = regex; + } + + @Override + public boolean includeConcept(CodeSystem cs, ConceptDefinitionComponent def) { + return def.getCode().matches(regex); + } +} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetExpanderSimple.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/ValueSetExpander.java similarity index 73% rename from org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetExpanderSimple.java rename to org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/ValueSetExpander.java index 3bd5bdadd..12ca9e746 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetExpanderSimple.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/ValueSetExpander.java @@ -1,4 +1,4 @@ -package org.hl7.fhir.r5.terminologies; +package org.hl7.fhir.r5.terminologies.expansion; /* Copyright (c) 2011+, HL7, Inc. @@ -69,11 +69,7 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.GregorianCalendar; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.Set; import org.apache.commons.lang3.NotImplementedException; import org.hl7.fhir.exceptions.FHIRException; @@ -92,7 +88,6 @@ import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionDesignationComponent; import org.hl7.fhir.r5.model.CodeSystem.ConceptPropertyComponent; import org.hl7.fhir.r5.model.CodeSystem.PropertyComponent; -import org.hl7.fhir.r5.model.CodeSystem.PropertyType; import org.hl7.fhir.r5.model.DataType; import org.hl7.fhir.r5.model.DateTimeType; import org.hl7.fhir.r5.model.Enumerations.FilterOperator; @@ -115,121 +110,40 @@ import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionPropertyComponent; -import org.hl7.fhir.r5.terminologies.ValueSetExpanderSimple.EFinished; +import org.hl7.fhir.r5.terminologies.CodeSystemUtilities; +import org.hl7.fhir.r5.terminologies.ValueSetUtilities; +import org.hl7.fhir.r5.terminologies.providers.CodeSystemProvider; import org.hl7.fhir.r5.terminologies.providers.CodeSystemProviderExtension; +import org.hl7.fhir.r5.terminologies.utilities.TerminologyServiceErrorClass; import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.i18n.I18nConstants; import com.google.errorprone.annotations.NoAllocation; -public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetExpander { +import alleycats.std.all; - public class EFinished extends FHIRException { +public class ValueSetExpander { - } - public interface IConceptFilter { - - boolean includeConcept(CodeSystem cs, ConceptDefinitionComponent def); - - } - - public class PropertyFilter implements IConceptFilter { - - private ConceptSetFilterComponent filter; - private PropertyComponent property; - - public PropertyFilter(ConceptSetFilterComponent fc, PropertyComponent propertyDefinition) { - this.filter = fc; - this.property = propertyDefinition; - } - - @Override - public boolean includeConcept(CodeSystem cs, ConceptDefinitionComponent def) { - ConceptPropertyComponent pc = getPropertyForConcept(def); - if (pc != null) { - String v = pc.getValue().isPrimitive() ? pc.getValue().primitiveValue() : null; - switch (filter.getOp()) { - case DESCENDENTOF: throw fail("not supported yet: "+filter.getOp().toCode()); - case EQUAL: return filter.getValue().equals(v); - case EXISTS: throw fail("not supported yet: "+filter.getOp().toCode()); - case GENERALIZES: throw fail("not supported yet: "+filter.getOp().toCode()); - case IN: throw fail("not supported yet: "+filter.getOp().toCode()); - case ISA: throw fail("not supported yet: "+filter.getOp().toCode()); - case ISNOTA: throw fail("not supported yet: "+filter.getOp().toCode()); - case NOTIN: throw fail("not supported yet: "+filter.getOp().toCode()); - case NULL: throw fail("not supported yet: "+filter.getOp().toCode()); - case REGEX: throw fail("not supported yet: "+filter.getOp().toCode()); - default: - throw fail("Shouldn't get here"); - } - } else if (property.getType() == PropertyType.BOOLEAN && filter.getOp() == FilterOperator.EQUAL) { - return "false".equals(filter.getValue()); - } else { - return false; - } - } - - private ConceptPropertyComponent getPropertyForConcept(ConceptDefinitionComponent def) { - for (ConceptPropertyComponent pc : def.getProperty()) { - if (pc.getCode().equals(property.getCode())) { - return pc; - } - } - return null; - } - - } - - public class AllConceptsFilter implements IConceptFilter { - - @Override - public boolean includeConcept(CodeSystem cs, ConceptDefinitionComponent def) { - return true; - } - } - - public class RegexFilter implements IConceptFilter { - - private String regex; - - protected RegexFilter(String regex) { - super(); - this.regex = regex; - } - - @Override - public boolean includeConcept(CodeSystem cs, ConceptDefinitionComponent def) { - return def.getCode().matches(regex); - } - } private static final boolean REPORT_VERSION_ANYWAY = false; - private List codes = new ArrayList(); - private List roots = new ArrayList(); - private Map map = new HashMap(); private IWorkerContext context; - private boolean canBeHeirarchy = true; - private boolean includeAbstract = true; - private Set excludeKeys = new HashSet(); - private Set excludeSystems = new HashSet(); private ValueSet focus; - private int maxExpansionSize = 1000; - private int offset; - private int count; private List allErrors = new ArrayList<>(); private List requiredSupplements = new ArrayList<>(); - - private int total; + private int maxExpansionSize = 1000; + private WorkingContext dwc = new WorkingContext(); + private boolean checkCodesWhenExpanding; + private boolean includeAbstract = true; - public ValueSetExpanderSimple(IWorkerContext context) { + public ValueSetExpander(IWorkerContext context) { super(); this.context = context; } - public ValueSetExpanderSimple(IWorkerContext context, List allErrors) { + public ValueSetExpander(IWorkerContext context, List allErrors) { super(); this.context = context; this.allErrors = allErrors; @@ -239,7 +153,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx maxExpansionSize = theMaxExpansionSize; } - private ValueSetExpansionContainsComponent addCode(String system, String code, String display, String dispLang, ValueSetExpansionContainsComponent parent, List designations, Parameters expParams, + private ValueSetExpansionContainsComponent addCode(WorkingContext wc, String system, String code, String display, String dispLang, ValueSetExpansionContainsComponent parent, List designations, Parameters expParams, boolean isAbstract, boolean inactive, String definition, List filters, boolean noInactive, boolean deprecated, List vsProp, List csProps, List expProps, List csExtList, List vsExtList) throws ETooCostly { @@ -352,27 +266,25 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx } } - - String s = key(n); - if (map.containsKey(s) || excludeKeys.contains(s)) { - canBeHeirarchy = false; + if (wc.getMap().containsKey(s) || wc.getExcludeKeys().contains(s)) { + wc.setCanBeHeirarchy(false); } else { - codes.add(n); - map.put(s, n); - total++; - if (total > maxExpansionSize) { - if (offset+count > 0 && total > offset+count) { - total = -1; + wc.getCodes().add(n); + wc.getMap().put(s, n); + wc.incTotal(); + if (wc == dwc && wc.getTotal() > maxExpansionSize) { + if (wc.getOffset()+wc.getCount() > 0 && wc.getTotal() > wc.getOffset()+wc.getCount()) { + wc.setTotal(-1); throw new EFinished(); } throw failCostly(context.formatMessage(I18nConstants.VALUESET_TOO_COSTLY, focus.getUrl(), ">" + Integer.toString(maxExpansionSize))); } } - if (canBeHeirarchy && parent != null) { + if (wc.isCanBeHeirarchy() && parent != null) { parent.getContains().add(n); } else { - roots.add(n); + wc.getRoots().add(n); } return n; } @@ -404,12 +316,12 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx return null; } - private void addCodeAndDescendents(ValueSetExpansionContainsComponent focus, ValueSetExpansionContainsComponent parent, Parameters expParams, List filters, boolean noInactive, List vsProps, ValueSet vsSrc) throws FHIRException, ETooCostly { + private void addCodeAndDescendents(WorkingContext wc, ValueSetExpansionContainsComponent focus, ValueSetExpansionContainsComponent parent, Parameters expParams, List filters, boolean noInactive, List vsProps, ValueSet vsSrc) throws FHIRException, ETooCostly { focus.checkNoModifiers("Expansion.contains", "expanding"); - ValueSetExpansionContainsComponent np = addCode(focus.getSystem(), focus.getCode(), focus.getDisplay(), vsSrc.getLanguage(), parent, + ValueSetExpansionContainsComponent np = addCode(wc, focus.getSystem(), focus.getCode(), focus.getDisplay(), vsSrc.getLanguage(), parent, convert(focus.getDesignation()), expParams, focus.getAbstract(), focus.getInactive(), focus.getExtensionString(ToolingExtensions.EXT_DEFINITION), filters, noInactive, false, vsProps, null, focus.getProperty(), null, focus.getExtension()); for (ValueSetExpansionContainsComponent c : focus.getContains()) - addCodeAndDescendents(c, np, expParams, filters, noInactive, vsProps, vsSrc); + addCodeAndDescendents(wc, c, np, expParams, filters, noInactive, vsProps, vsSrc); } private List convert(List designations) { @@ -424,8 +336,8 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx return list; } - private void addCodeAndDescendents(CodeSystem cs, String system, ConceptDefinitionComponent def, ValueSetExpansionContainsComponent parent, Parameters expParams, List filters, - ConceptDefinitionComponent exclusion, IConceptFilter filterFunc, boolean noInactive, List vsProps) throws FHIRException, ETooCostly { + private void addCodeAndDescendents(WorkingContext wc,CodeSystem cs, String system, ConceptDefinitionComponent def, ValueSetExpansionContainsComponent parent, Parameters expParams, List filters, + ConceptDefinitionComponent exclusion, ConceptFilter filterFunc, boolean noInactive, List vsProps, List otherFilters) throws FHIRException, ETooCostly { def.checkNoModifiers("Code in Code System", "expanding"); if (exclusion != null) { if (exclusion.getCode().equals(def.getCode())) @@ -435,20 +347,21 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx boolean abs = CodeSystemUtilities.isNotSelectable(cs, def); boolean inc = CodeSystemUtilities.isInactive(cs, def); boolean dep = CodeSystemUtilities.isDeprecated(cs, def, false); - if ((includeAbstract || !abs) && filterFunc.includeConcept(cs, def)) { - np = addCode(system, def.getCode(), def.getDisplay(), cs.getLanguage(), parent, def.getDesignation(), expParams, abs, inc, def.getDefinition(), filters, noInactive, dep, vsProps, def.getProperty(), null, def.getExtension(), null); + if ((includeAbstract || !abs) && filterFunc.includeConcept(cs, def) && passesOtherFilters(otherFilters, cs, def.getCode())) { + np = addCode(wc, system, def.getCode(), def.getDisplay(), cs.getLanguage(), parent, def.getDesignation(), expParams, abs, inc, def.getDefinition(), filters, noInactive, dep, vsProps, def.getProperty(), null, def.getExtension(), null); } for (ConceptDefinitionComponent c : def.getConcept()) { - addCodeAndDescendents(cs, system, c, np, expParams, filters, exclusion, filterFunc, noInactive, vsProps); + addCodeAndDescendents(wc, cs, system, c, np, expParams, filters, exclusion, filterFunc, noInactive, vsProps, otherFilters); } if (def.hasUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK)) { List children = (List) def.getUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK); for (ConceptDefinitionComponent c : children) - addCodeAndDescendents(cs, system, c, np, expParams, filters, exclusion, filterFunc, noInactive, vsProps); + addCodeAndDescendents(wc, cs, system, c, np, expParams, filters, exclusion, filterFunc, noInactive, vsProps, otherFilters); } } + private void addCodes(ValueSetExpansionComponent expand, List params, Parameters expParams, List filters, boolean noInactive, List vsProps, ValueSet vsSrc) throws ETooCostly, FHIRException { if (expand != null) { if (expand.getContains().size() > maxExpansionSize) @@ -462,18 +375,18 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx } } - private void excludeCode(String theSystem, String theCode) { + private void excludeCode(WorkingContext wc, String theSystem, String theCode) { ValueSetExpansionContainsComponent n = new ValueSet.ValueSetExpansionContainsComponent(); n.setSystem(theSystem); n.setCode(theCode); String s = key(n); - excludeKeys.add(s); + wc.getExcludeKeys().add(s); } - private void excludeCodes(ConceptSetComponent exc, List params, String ctxt) throws FHIRException { + private void excludeCodes(WorkingContext wc, ConceptSetComponent exc, List params, String ctxt) throws FHIRException { exc.checkNoModifiers("Compose.exclude", "expanding"); if (exc.hasSystem() && exc.getConcept().size() == 0 && exc.getFilter().size() == 0) { - excludeSystems.add(exc.getSystem()); + wc.getExcludeSystems().add(exc.getSystem()); } if (exc.hasValueSet()) @@ -486,12 +399,12 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx ValueSet valueset = vse.getValueset(); if (valueset == null) throw failTSE("Error Expanding ValueSet: "+vse.getError()); - excludeCodes(valueset.getExpansion(), params); + excludeCodes(wc, valueset.getExpansion(), params); return; } for (ConceptReferenceComponent c : exc.getConcept()) { - excludeCode(exc.getSystem(), c.getCode()); + excludeCode(wc, exc.getSystem(), c.getCode()); } if (exc.getFilter().size() > 0) @@ -500,9 +413,9 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx - private void excludeCodes(ValueSetExpansionComponent expand, List params) { + private void excludeCodes(WorkingContext wc, ValueSetExpansionComponent expand, List params) { for (ValueSetExpansionContainsComponent c : expand.getContains()) { - excludeCode(c.getSystem(), c.getCode()); + excludeCode(wc, c.getSystem(), c.getCode()); } } @@ -514,7 +427,6 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx return false; } - @Override public ValueSetExpansionOutcome expand(ValueSet source, Parameters expParams) { allErrors.clear(); try { @@ -557,15 +469,15 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx focus.getExpansion().addParameter().setName(p.getName()).setValue(p.getValue()); } if ("offset".equals(p.getName()) && p.hasValueIntegerType()) { - offset = p.getValueIntegerType().getValue(); - if (offset < 0) { - offset = 0; + dwc.setOffset(p.getValueIntegerType().getValue()); + if (dwc.getOffset() < 0) { + dwc.setOffset(0); } } if ("count".equals(p.getName()) && p.hasValueIntegerType()) { - count = p.getValueIntegerType().getValue(); - if (count < 0) { - count = 0; + dwc.setCount(p.getValueIntegerType().getValue()); + if (dwc.getCount() < 0) { + dwc.setCount(0); } } } @@ -586,20 +498,20 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx // nothing - we intended to trap this here } - if (canBeHeirarchy) { - for (ValueSetExpansionContainsComponent c : roots) { + if (dwc.isCanBeHeirarchy()) { + for (ValueSetExpansionContainsComponent c : dwc.getRoots()) { focus.getExpansion().getContains().add(c); } } else { int i = 0; int cc = 0; - for (ValueSetExpansionContainsComponent c : codes) { - if (map.containsKey(key(c)) && (includeAbstract || !c.getAbstract())) { // we may have added abstract codes earlier while we still thought it might be heirarchical, but later we gave up, so now ignore them - if (offset == 0 || i >= offset) { + for (ValueSetExpansionContainsComponent c : dwc.getCodes()) { + if (dwc.getMap().containsKey(key(c)) && (includeAbstract || !c.getAbstract())) { // we may have added abstract codes earlier while we still thought it might be heirarchical, but later we gave up, so now ignore them + if (dwc.getOffset() == 0 || i >= dwc.getOffset()) { focus.getExpansion().getContains().add(c); c.getContains().clear(); // make sure any heirarchy is wiped cc++; - if (cc == count) { + if (cc == dwc.getCount()) { break; } } @@ -608,8 +520,8 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx } } - if (total >= 0) { - focus.getExpansion().setTotal(total); + if (dwc.getTotal() >= 0) { + focus.getExpansion().setTotal(dwc.getTotal()); } if (!requiredSupplements.isEmpty()) { return new ValueSetExpansionOutcome("Required supplements not found: "+requiredSupplements.toString(), TerminologyServiceErrorClass.BUSINESS_RULE, allErrors); @@ -618,6 +530,11 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx focus.setCompose(null); focus.getExtension().clear(); focus.setPublisher(null); + focus.setDescription(null); + focus.setPurpose(null); + focus.getContact().clear(); + focus.setCopyright(null); + focus.setText(null); } return new ValueSetExpansionOutcome(focus); } @@ -645,16 +562,16 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx compose.checkNoModifiers("ValueSet.compose", "expanding"); // Exclude comes first because we build up a map of things to exclude for (ConceptSetComponent inc : compose.getExclude()) - excludeCodes(inc, exp.getParameter(), ctxt); - canBeHeirarchy = !expParams.getParameterBool("excludeNested") && excludeKeys.isEmpty() && excludeSystems.isEmpty() && offset+count == 0; + excludeCodes(dwc, inc, exp.getParameter(), ctxt); + dwc.setCanBeHeirarchy(!expParams.getParameterBool("excludeNested") && dwc.getExcludeKeys().isEmpty() && dwc.getExcludeSystems().isEmpty() && dwc.getOffset()+dwc.getCount() == 0); includeAbstract = !expParams.getParameterBool("excludeNotForUI"); boolean first = true; for (ConceptSetComponent inc : compose.getInclude()) { if (first == true) first = false; else - canBeHeirarchy = false; - includeCodes(inc, exp, expParams, canBeHeirarchy, compose.hasInactive() ? !compose.getInactive() : checkNoInActiveFromParam(expParams), extensions, valueSet); + dwc.setCanBeHeirarchy(false); + includeCodes(inc, exp, expParams, dwc.isCanBeHeirarchy(), compose.hasInactive() ? !compose.getInactive() : checkNoInActiveFromParam(expParams), extensions, valueSet); } } @@ -672,7 +589,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx return false; } - private ValueSet importValueSet(String value, ValueSetExpansionComponent exp, Parameters expParams, boolean noInactive, ValueSet valueSet) throws ETooCostly, TerminologyServiceException, FileNotFoundException, IOException, FHIRFormatError { + private ValueSet importValueSet(WorkingContext wc, String value, ValueSetExpansionComponent exp, Parameters expParams, boolean noInactive, ValueSet valueSet) throws ETooCostly, TerminologyServiceException, FileNotFoundException, IOException, FHIRFormatError { if (value == null) throw fail("unable to find value set with no identity"); ValueSet vs = context.fetchResource(ValueSet.class, value, valueSet); @@ -687,7 +604,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx expParams = expParams.copy(); expParams.addParameter("activeOnly", true); } - ValueSetExpansionOutcome vso = new ValueSetExpanderSimple(context, allErrors).expand(vs, expParams); + ValueSetExpansionOutcome vso = new ValueSetExpander(context, allErrors).expand(vs, expParams); if (vso.getError() != null) { addErrors(vso.getAllErrors()); throw fail("Unable to expand imported value set "+vs.getUrl()+": " + vso.getError()); @@ -711,9 +628,9 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx exp.getParameter().add(p); } if (isValueSetUnionImports(valueSet)) { - copyExpansion(vso.getValueset().getExpansion().getContains()); + copyExpansion(wc, vso.getValueset().getExpansion().getContains()); } - canBeHeirarchy = false; // if we're importing a value set, we have to be combining, so we won't try for a heirarchy + wc.setCanBeHeirarchy(false); // if we're importing a value set, we have to be combining, so we won't try for a heirarchy return vso.getValueset(); } @@ -727,7 +644,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx } } - public void copyExpansion(List list) { + public void copyExpansion(WorkingContext wc,List list) { for (ValueSetExpansionContainsComponent cc : list) { ValueSetExpansionContainsComponent n = new ValueSet.ValueSetExpansionContainsComponent(); n.setSystem(cc.getSystem()); @@ -738,12 +655,12 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx n.getDesignation().addAll(cc.getDesignation()); String s = key(n); - if (!map.containsKey(s) && !excludeKeys.contains(s)) { - codes.add(n); - map.put(s, n); - total++; + if (!wc.getMap().containsKey(s) && !wc.getExcludeKeys().contains(s)) { + wc.getCodes().add(n); + wc.getMap().put(s, n); + wc.incTotal(); } - copyExpansion(cc.getContains()); + copyExpansion(wc, cc.getContains()); } } @@ -758,7 +675,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx private void copyImportContains(List list, ValueSetExpansionContainsComponent parent, Parameters expParams, List filter, boolean noInactive, List vsProps, ValueSet vsSrc) throws FHIRException, ETooCostly { for (ValueSetExpansionContainsComponent c : list) { c.checkNoModifiers("Imported Expansion in Code System", "expanding"); - ValueSetExpansionContainsComponent np = addCode(c.getSystem(), c.getCode(), c.getDisplay(), vsSrc.getLanguage(), parent, null, expParams, c.getAbstract(), c.getInactive(), c.getExtensionString(ToolingExtensions.EXT_DEFINITION), + ValueSetExpansionContainsComponent np = addCode(dwc, c.getSystem(), c.getCode(), c.getDisplay(), vsSrc.getLanguage(), parent, null, expParams, c.getAbstract(), c.getInactive(), c.getExtensionString(ToolingExtensions.EXT_DEFINITION), filter, noInactive, false, vsProps, null, c.getProperty(), null, c.getExtension()); copyImportContains(c.getContains(), np, expParams, filter, noInactive, vsProps, vsSrc); } @@ -768,7 +685,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx inc.checkNoModifiers("Compose.include", "expanding"); List imports = new ArrayList(); for (CanonicalType imp : inc.getValueSet()) { - imports.add(importValueSet(imp.getValue(), exp, expParams, noInactive, valueSet)); + imports.add(importValueSet(dwc, imp.getValue(), exp, expParams, noInactive, valueSet)); } if (!inc.hasSystem()) { @@ -780,7 +697,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx copyImportContains(base.getExpansion().getContains(), null, expParams, imports, noInactive, base.getExpansion().getProperty(), base); } else { CodeSystem cs = context.fetchSupplementedCodeSystem(inc.getSystem()); - if (isServerSide(inc.getSystem()) || (cs == null || (cs.getContent() != CodeSystemContentMode.COMPLETE && cs.getContent() != CodeSystemContentMode.FRAGMENT))) { + if (ValueSetUtilities.isServerSide(inc.getSystem()) || (cs == null || (cs.getContent() != CodeSystemContentMode.COMPLETE && cs.getContent() != CodeSystemContentMode.FRAGMENT))) { doServerIncludeCodes(inc, heirarchical, exp, imports, expParams, extensions, noInactive, valueSet.getExpansion().getProperty()); } else { if (cs.hasUserData("supplements.installed")) { @@ -824,7 +741,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx } } for (ValueSetExpansionContainsComponent cc : vs.getExpansion().getContains()) { - addCodeAndDescendents(cc, null, expParams, imports, noInactive, vsProps, vs); + addCodeAndDescendents(dwc, cc, null, expParams, imports, noInactive, vsProps, vs); } } @@ -847,7 +764,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx if (inc.getConcept().size() == 0 && inc.getFilter().size() == 0) { // special case - add all the code system for (ConceptDefinitionComponent def : cs.getConcept()) { - addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new AllConceptsFilter(), noInactive, exp.getProperty()); + addCodeAndDescendents(dwc, cs, inc.getSystem(), def, null, expParams, imports, null, new AllConceptsFilter(allErrors), noInactive, exp.getProperty(), null); } if (cs.getContent() == CodeSystemContentMode.FRAGMENT) { addFragmentWarning(exp, cs); @@ -858,7 +775,7 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx } if (!inc.getConcept().isEmpty()) { - canBeHeirarchy = false; + dwc.setCanBeHeirarchy(false); for (ConceptReferenceComponent c : inc.getConcept()) { c.checkNoModifiers("Code in Value Set", "expanding"); ConceptDefinitionComponent def = CodeSystemUtilities.findCode(cs.getConcept(), c.getCode()); @@ -879,69 +796,81 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx inactive = CodeSystemUtilities.isInactive(cs, def); isAbstract = CodeSystemUtilities.isNotSelectable(cs, def); } - addCode(inc.getSystem(), c.getCode(), !Utilities.noString(c.getDisplay()) ? c.getDisplay() : def == null ? null : def.getDisplay(), c.hasDisplay() ? vsSrc.getLanguage() : cs.getLanguage(), null, mergeDesignations(def, convertDesignations(c.getDesignation())), + addCode(dwc, inc.getSystem(), c.getCode(), !Utilities.noString(c.getDisplay()) ? c.getDisplay() : def == null ? null : def.getDisplay(), c.hasDisplay() ? vsSrc.getLanguage() : cs.getLanguage(), null, mergeDesignations(def, convertDesignations(c.getDesignation())), expParams, isAbstract, inactive, def == null ? null : def.getDefinition(), imports, noInactive, false, exp.getProperty(), def != null ? def.getProperty() : null, null, def == null ? null : def.getExtension(), c.getExtension()); } } - if (inc.getFilter().size() > 1) { - canBeHeirarchy = false; // which will bt the case if we get around to supporting this - throw failTSE("Multiple filters not handled yet"); // need to and them, and this isn't done yet. But this shouldn't arise in non loinc and snomed value sets - } - if (inc.getFilter().size() == 1) { + if (inc.getFilter().size() > 0) { + if (inc.getFilter().size() > 1) { + dwc.setCanBeHeirarchy(false); // which will be the case if we get around to supporting this + } if (cs.getContent() == CodeSystemContentMode.FRAGMENT) { addFragmentWarning(exp, cs); } + List filters = new ArrayList<>(); + for (int i = 1; i < inc.getFilter().size(); i++) { + WorkingContext wc = new WorkingContext(); + filters.add(wc); + processFilter(inc, exp, expParams, imports, cs, noInactive, inc.getFilter().get(i), wc, null); + } ConceptSetFilterComponent fc = inc.getFilter().get(0); - if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.ISA) { - // special: all codes in the target code system under the value - ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue()); - if (def == null) - throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'"); - addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new AllConceptsFilter(), noInactive, exp.getProperty()); - } else if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.ISNOTA) { - // special: all codes in the target code system that are not under the value - ConceptDefinitionComponent defEx = getConceptForCode(cs.getConcept(), fc.getValue()); - if (defEx == null) - throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'"); - for (ConceptDefinitionComponent def : cs.getConcept()) { - addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, defEx, new AllConceptsFilter(), noInactive, exp.getProperty()); - } - } else if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.DESCENDENTOF) { - // special: all codes in the target code system under the value - ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue()); - if (def == null) - throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'"); - for (ConceptDefinitionComponent c : def.getConcept()) - addCodeAndDescendents(cs, inc.getSystem(), c, null, expParams, imports, null, new AllConceptsFilter(), noInactive, exp.getProperty()); - if (def.hasUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK)) { - List children = (List) def.getUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK); - for (ConceptDefinitionComponent c : children) - addCodeAndDescendents(cs, inc.getSystem(), c, null, expParams, imports, null, new AllConceptsFilter(), noInactive, exp.getProperty()); - } + WorkingContext wc = dwc; + processFilter(inc, exp, expParams, imports, cs, noInactive, fc, wc, filters); + } + } - } else if ("display".equals(fc.getProperty()) && fc.getOp() == FilterOperator.EQUAL) { - // gg; note: wtf is this: if the filter is display=v, look up the code 'v', and see if it's diplsay is 'v'? - canBeHeirarchy = false; - ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue()); - if (def != null) { - if (isNotBlank(def.getDisplay()) && isNotBlank(fc.getValue())) { - if (def.getDisplay().contains(fc.getValue())) { - addCode(inc.getSystem(), def.getCode(), def.getDisplay(), cs.getLanguage(), null, def.getDesignation(), expParams, CodeSystemUtilities.isNotSelectable(cs, def), CodeSystemUtilities.isInactive(cs, def), - def.getDefinition(), imports, noInactive, false, exp.getProperty(), def.getProperty(), null, def.getExtension(), null); - } + private void processFilter(ConceptSetComponent inc, ValueSetExpansionComponent exp, Parameters expParams, + List imports, CodeSystem cs, boolean noInactive, ConceptSetFilterComponent fc, WorkingContext wc, List filters) + throws ETooCostly { + if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.ISA) { + // special: all codes in the target code system under the value + ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue()); + if (def == null) + throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'"); + addCodeAndDescendents(wc, cs, inc.getSystem(), def, null, expParams, imports, null, new AllConceptsFilter(allErrors), noInactive, exp.getProperty(), filters); + } else if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.ISNOTA) { + // special: all codes in the target code system that are not under the value + ConceptDefinitionComponent defEx = getConceptForCode(cs.getConcept(), fc.getValue()); + if (defEx == null) + throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'"); + for (ConceptDefinitionComponent def : cs.getConcept()) { + addCodeAndDescendents(wc, cs, inc.getSystem(), def, null, expParams, imports, defEx, new AllConceptsFilter(allErrors), noInactive, exp.getProperty(), filters); + } + } else if ("concept".equals(fc.getProperty()) && fc.getOp() == FilterOperator.DESCENDENTOF) { + // special: all codes in the target code system under the value + ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue()); + if (def == null) + throw failTSE("Code '" + fc.getValue() + "' not found in system '" + inc.getSystem() + "'"); + for (ConceptDefinitionComponent c : def.getConcept()) + addCodeAndDescendents(wc, cs, inc.getSystem(), c, null, expParams, imports, null, new AllConceptsFilter(allErrors), noInactive, exp.getProperty(), filters); + if (def.hasUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK)) { + List children = (List) def.getUserData(CodeSystemUtilities.USER_DATA_CROSS_LINK); + for (ConceptDefinitionComponent c : children) + addCodeAndDescendents(wc, cs, inc.getSystem(), c, null, expParams, imports, null, new AllConceptsFilter(allErrors), noInactive, exp.getProperty(), filters); + } + + } else if ("display".equals(fc.getProperty()) && fc.getOp() == FilterOperator.EQUAL) { + // gg; note: wtf is this: if the filter is display=v, look up the code 'v', and see if it's diplsay is 'v'? + dwc.setCanBeHeirarchy(false); + ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue()); + if (def != null) { + if (isNotBlank(def.getDisplay()) && isNotBlank(fc.getValue())) { + if (def.getDisplay().contains(fc.getValue()) && passesOtherFilters(filters, cs, def.getCode())) { + addCode(wc, inc.getSystem(), def.getCode(), def.getDisplay(), cs.getLanguage(), null, def.getDesignation(), expParams, CodeSystemUtilities.isNotSelectable(cs, def), CodeSystemUtilities.isInactive(cs, def), + def.getDefinition(), imports, noInactive, false, exp.getProperty(), def.getProperty(), null, def.getExtension(), null); } } - } else if (isDefinedProperty(cs, fc.getProperty())) { - for (ConceptDefinitionComponent def : cs.getConcept()) { - addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new PropertyFilter(fc, getPropertyDefinition(cs, fc.getProperty())), noInactive, exp.getProperty()); - } - } else if ("code".equals(fc.getProperty()) && fc.getOp() == FilterOperator.REGEX) { - for (ConceptDefinitionComponent def : cs.getConcept()) { - addCodeAndDescendents(cs, inc.getSystem(), def, null, expParams, imports, null, new RegexFilter(fc.getValue()), noInactive, exp.getProperty()); - } - } else { - throw fail("Search by property[" + fc.getProperty() + "] and op[" + fc.getOp() + "] is not supported yet"); } + } else if (isDefinedProperty(cs, fc.getProperty())) { + for (ConceptDefinitionComponent def : cs.getConcept()) { + addCodeAndDescendents(wc, cs, inc.getSystem(), def, null, expParams, imports, null, new PropertyFilter(allErrors, fc, getPropertyDefinition(cs, fc.getProperty())), noInactive, exp.getProperty(), filters); + } + } else if ("code".equals(fc.getProperty()) && fc.getOp() == FilterOperator.REGEX) { + for (ConceptDefinitionComponent def : cs.getConcept()) { + addCodeAndDescendents(wc, cs, inc.getSystem(), def, null, expParams, imports, null, new RegexFilter(allErrors, fc.getValue()), noInactive, exp.getProperty(), filters); + } + } else { + throw fail("Filter by property[" + fc.getProperty() + "] and op[" + fc.getOp() + "] is not supported yet"); } } @@ -1039,4 +968,16 @@ public class ValueSetExpanderSimple extends ValueSetWorker implements ValueSetEx this.checkCodesWhenExpanding = checkCodesWhenExpanding; } + private boolean passesOtherFilters(List otherFilters, CodeSystem cs, String code) { + if (otherFilters == null) { + return true; + } + String key = key(cs.getUrl(), code); + for (WorkingContext wc : otherFilters) { + if (!wc.getMap().containsKey(key)) { + return false; + } + } + return true; + } } \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/ValueSetExpansionOutcome.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/ValueSetExpansionOutcome.java new file mode 100644 index 000000000..79a5cd50d --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/ValueSetExpansionOutcome.java @@ -0,0 +1,77 @@ +package org.hl7.fhir.r5.terminologies.expansion; + +import java.util.ArrayList; +import java.util.List; + +import org.hl7.fhir.r5.model.ValueSet; +import org.hl7.fhir.r5.terminologies.utilities.TerminologyServiceErrorClass; + +/** + * Some value sets are just too big to expand. Instead of an expanded value set, + * you get back an interface that can test membership - usually on a server somewhere + * + * @author Grahame + */ +public class ValueSetExpansionOutcome { + private ValueSet valueset; + private String error; + private TerminologyServiceErrorClass errorClass; + private String txLink; + private List allErrors = new ArrayList<>(); + + public ValueSetExpansionOutcome(ValueSet valueset) { + super(); + this.valueset = valueset; + this.error = null; + } + public ValueSetExpansionOutcome(ValueSet valueset, String error, TerminologyServiceErrorClass errorClass) { + super(); + this.valueset = valueset; + this.error = error; + this.errorClass = errorClass; + allErrors.add(error); + } + + public ValueSetExpansionOutcome(String error, TerminologyServiceErrorClass errorClass) { + this.valueset = null; + this.error = error; + this.errorClass = errorClass; + allErrors.add(error); + } + public ValueSetExpansionOutcome(String error, TerminologyServiceErrorClass errorClass, List errList) { + this.valueset = null; + this.error = error; + this.errorClass = errorClass; + this.allErrors.addAll(errList); + if (!allErrors.contains(error)) { + allErrors.add(error); + } + if (!errList.contains(error)) { + errList.add(error); + } + } + + public ValueSet getValueset() { + return valueset; + } + public String getError() { + return error; + } + public TerminologyServiceErrorClass getErrorClass() { + return errorClass; + } + public String getTxLink() { + return txLink; + } + public ValueSetExpansionOutcome setTxLink(String txLink) { + this.txLink = txLink; + return this; + } + public List getAllErrors() { + return allErrors; + } + + public boolean isOk() { + return (allErrors.isEmpty() || (allErrors.size() == 1 && allErrors.get(0) == null)) && error == null; + } +} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/WorkingContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/WorkingContext.java new file mode 100644 index 000000000..aafc57306 --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/expansion/WorkingContext.java @@ -0,0 +1,81 @@ +package org.hl7.fhir.r5.terminologies.expansion; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.hl7.fhir.r5.model.ValueSet; +import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent; + +class WorkingContext { + private List codes = new ArrayList(); + private List roots = new ArrayList(); + private Map map = new HashMap(); + private Set excludeKeys = new HashSet(); + private Set excludeSystems = new HashSet(); + + private boolean canBeHeirarchy = true; + private int offset; + private int count; + private int total; + + public List getCodes() { + return codes; + } + + public List getRoots() { + return roots; + } + + public Map getMap() { + return map; + } + + public Set getExcludeKeys() { + return excludeKeys; + } + + public Set getExcludeSystems() { + return excludeSystems; + } + + public boolean isCanBeHeirarchy() { + return canBeHeirarchy; + } + + public void setCanBeHeirarchy(boolean canBeHeirarchy) { + this.canBeHeirarchy = canBeHeirarchy; + } + + public int getOffset() { + return offset; + } + + public void setOffset(int offset) { + this.offset = offset; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public void incTotal() { + total++; + } + +} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/CodeSystemProvider.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/providers/CodeSystemProvider.java similarity index 82% rename from org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/CodeSystemProvider.java rename to org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/providers/CodeSystemProvider.java index 4c7b7fcca..b2788d35d 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/CodeSystemProvider.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/providers/CodeSystemProvider.java @@ -1,4 +1,4 @@ -package org.hl7.fhir.r5.terminologies; +package org.hl7.fhir.r5.terminologies.providers; import java.util.List; @@ -8,8 +8,6 @@ import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionPropertyComponent; -import org.hl7.fhir.r5.terminologies.providers.CodeSystemProviderExtension; -import org.hl7.fhir.r5.terminologies.providers.ColorRGBProvider; /** * For special code systems where the code system resource isn't enough, but we can support them internall @@ -32,6 +30,6 @@ public abstract class CodeSystemProvider { List imports, Parameters expParams, List extensions, boolean noInactive, List vsProps) throws CodeSystemProviderExtension; - protected abstract Boolean checkCode(String code); + public abstract Boolean checkCode(String code); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/providers/ColorRGBProvider.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/providers/ColorRGBProvider.java index add98c894..c058fa759 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/providers/ColorRGBProvider.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/providers/ColorRGBProvider.java @@ -9,7 +9,6 @@ import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionPropertyComponent; -import org.hl7.fhir.r5.terminologies.CodeSystemProvider; public class ColorRGBProvider extends CodeSystemProvider { @@ -21,7 +20,7 @@ public class ColorRGBProvider extends CodeSystemProvider { } @Override - protected Boolean checkCode(String code) { + public Boolean checkCode(String code) { return code.matches("^\\#[0-9a-fA-F]{6}$"); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/SpecialCodeSystem.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/providers/SpecialCodeSystem.java similarity index 81% rename from org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/SpecialCodeSystem.java rename to org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/providers/SpecialCodeSystem.java index 4550478e7..bc0890d36 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/SpecialCodeSystem.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/providers/SpecialCodeSystem.java @@ -1,4 +1,4 @@ -package org.hl7.fhir.r5.terminologies; +package org.hl7.fhir.r5.terminologies.providers; import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; import org.hl7.fhir.r5.model.Coding; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/URICodeSystem.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/providers/URICodeSystem.java similarity index 53% rename from org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/URICodeSystem.java rename to org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/providers/URICodeSystem.java index e13cff49d..fe073698e 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/URICodeSystem.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/providers/URICodeSystem.java @@ -1,4 +1,4 @@ -package org.hl7.fhir.r5.terminologies; +package org.hl7.fhir.r5.terminologies.providers; import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; import org.hl7.fhir.r5.model.Coding; @@ -8,11 +8,12 @@ public class URICodeSystem extends SpecialCodeSystem { @Override public ConceptDefinitionComponent findConcept(Coding code) { - if (Utilities.isAbsoluteUrl(code.getCode())) { - return new ConceptDefinitionComponent(code.getCode()); - } else { - return null; - } + throw new Error("This is used"); +// if (Utilities.isAbsoluteUrl(code.getCode())) { +// return new ConceptDefinitionComponent(code.getCode()); +// } else { +// return null; +// } } } \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/utilities/TerminologyServiceErrorClass.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/utilities/TerminologyServiceErrorClass.java new file mode 100644 index 000000000..aa15bb12d --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/utilities/TerminologyServiceErrorClass.java @@ -0,0 +1,9 @@ +package org.hl7.fhir.r5.terminologies.utilities; + +public enum TerminologyServiceErrorClass { + UNKNOWN, NOSERVICE, SERVER_ERROR, VALUESET_UNSUPPORTED, CODESYSTEM_UNSUPPORTED, BLOCKED_BY_OPTIONS, INTERNAL_ERROR, BUSINESS_RULE, TOO_COSTLY; + + public boolean isInfrastructure() { + return this == NOSERVICE || this == SERVER_ERROR || this == VALUESET_UNSUPPORTED; + } +} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ConceptReferencePair.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ConceptReferencePair.java new file mode 100644 index 000000000..907779eba --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ConceptReferencePair.java @@ -0,0 +1,24 @@ +package org.hl7.fhir.r5.terminologies.validation; + +import org.hl7.fhir.r5.model.ValueSet; +import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent; + +public class ConceptReferencePair { + + private ValueSet valueset; + private ConceptReferenceComponent cc; + + public ConceptReferencePair(ValueSet valueset, ConceptReferenceComponent cc) { + this.valueset = valueset; + this.cc = cc; + } + + public ValueSet getValueset() { + return valueset; + } + + public ConceptReferenceComponent getCc() { + return cc; + } + +} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/VSCheckerException.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/VSCheckerException.java new file mode 100644 index 000000000..a701f8bed --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/VSCheckerException.java @@ -0,0 +1,23 @@ +package org.hl7.fhir.r5.terminologies.validation; + +import java.util.List; + +import org.hl7.fhir.exceptions.FHIRException; +import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent; + +public class VSCheckerException extends FHIRException { + + private List issues; + + public VSCheckerException(String message, List issues) { + super(message); + this.issues = issues; + } + + public List getIssues() { + return issues; + } + + private static final long serialVersionUID = -5889505119633054187L; + +} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValidationProcessInfo.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValidationProcessInfo.java new file mode 100644 index 000000000..84d406112 --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValidationProcessInfo.java @@ -0,0 +1,43 @@ +package org.hl7.fhir.r5.terminologies.validation; + +import java.util.ArrayList; +import java.util.List; + +import org.hl7.fhir.r5.model.OperationOutcome.IssueSeverity; +import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent; +import org.hl7.fhir.r5.terminologies.utilities.TerminologyServiceErrorClass; +import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; + +public class ValidationProcessInfo { + private TerminologyServiceErrorClass err; + private List issues = new ArrayList<>(); + public TerminologyServiceErrorClass getErr() { + return err; + } + public void setErr(TerminologyServiceErrorClass err) { + this.err = err; + } + + public List getIssues() { + return issues; + } + public void addIssue(List issues) { + issues.addAll(issues); + + } + public boolean hasErrors() { + for (OperationOutcomeIssueComponent issue : issues) { + if (issue.getSeverity() == IssueSeverity.FATAL || issue.getSeverity() == IssueSeverity.ERROR) { + return true; + } + } + return false; + } + public String summary() { + CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder("; "); + for (OperationOutcomeIssueComponent issue : issues) { + b.append(issue.getDetails().getText()); + } + return b.toString(); + } +} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetCheckerSimple.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValueSetValidator.java similarity index 91% rename from org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetCheckerSimple.java rename to org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValueSetValidator.java index 4da39cdcb..047d7809a 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/ValueSetCheckerSimple.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValueSetValidator.java @@ -1,4 +1,4 @@ -package org.hl7.fhir.r5.terminologies; +package org.hl7.fhir.r5.terminologies.validation; /* Copyright (c) 2011+, HL7, Inc. @@ -54,12 +54,12 @@ import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionDesignationComponent; import org.hl7.fhir.r5.model.CodeableConcept; import org.hl7.fhir.r5.model.Coding; +import org.hl7.fhir.r5.model.DataType; import org.hl7.fhir.r5.model.Enumerations.PublicationStatus; import org.hl7.fhir.r5.model.OperationOutcome.IssueType; import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent; import org.hl7.fhir.r5.model.PackageInformation; import org.hl7.fhir.r5.model.Parameters; -import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent; import org.hl7.fhir.r5.model.TerminologyCapabilities.TerminologyCapabilitiesCodeSystemComponent; import org.hl7.fhir.r5.model.TerminologyCapabilities; import org.hl7.fhir.r5.model.Transport.ParameterComponent; @@ -70,10 +70,12 @@ import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceDesignationComponent; import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent; -import org.hl7.fhir.r5.terminologies.ValueSetCheckerSimple.ConceptReferencePair; -import org.hl7.fhir.r5.terminologies.ValueSetCheckerSimple.VersionInfo; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome; +import org.hl7.fhir.r5.terminologies.CodeSystemUtilities; +import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; +import org.hl7.fhir.r5.terminologies.providers.CodeSystemProvider; +import org.hl7.fhir.r5.terminologies.providers.SpecialCodeSystem; +import org.hl7.fhir.r5.terminologies.providers.URICodeSystem; +import org.hl7.fhir.r5.terminologies.utilities.TerminologyServiceErrorClass; import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier; import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier.ValidationContextResourceProxy; @@ -87,117 +89,18 @@ import org.hl7.fhir.utilities.validation.ValidationOptions.ValueSetMode; import com.google.j2objc.annotations.ReflectionSupport.Level; -public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChecker { - - public class VersionInfo { - private String expansionVersion; - private String composeVersion; - - public String getExpansionVersion() { - return expansionVersion; - } - - public void setExpansionVersion(String expansionVersion) { - this.expansionVersion = expansionVersion; - } - - public String getComposeVersion() { - return composeVersion; - } - - public void setComposeVersion(String composeVersion) { - this.composeVersion = composeVersion; - } - - public String getVersion(String system, String version) { - String fixedVersion = getVersionParameter("force-system-version", system); - if (fixedVersion != null) { - return fixedVersion; - } - String checkVersion = getVersionParameter("check-system-version", system); - if (version != null) { - if (checkVersion != null && !version.equals(checkVersion)) { - throw new FHIRException("Attempt to use version "+version+" of "+system+", when the expansion parameters limit the use to "+checkVersion); - } - return version; - } - if (expansionVersion != null) { - if (checkVersion != null && !expansionVersion.equals(checkVersion)) { - throw new FHIRException("Attempt to use version "+expansionVersion+" of "+system+", when the expansion parameters limit the use to "+checkVersion); - } - return expansionVersion; - } - if (composeVersion != null) { - if (checkVersion != null && !composeVersion.equals(checkVersion)) { - throw new FHIRException("Attempt to use version "+composeVersion+" of "+system+", when the expansion parameters limit the use to "+checkVersion); - } - return composeVersion; - } - return getVersionParameter("system-version", system); - } - - private String getVersionParameter(String name, String system) { - if (expansionProfile != null) { - for (ParametersParameterComponent pc : expansionProfile.getParameter()) { - if (name.equals(pc.getName()) && pc.hasValue()) { - String v = pc.getValue().primitiveValue(); - if (v != null && v.startsWith(system+"|")) { - return v.substring(system.length()+1); - } - } - } - } - return null; - } - - } - public static class VSCheckerException extends FHIRException { - - private List issues; - - public VSCheckerException(String message, List issues) { - super(message); - this.issues = issues; - } - - public List getIssues() { - return issues; - } - - private static final long serialVersionUID = -5889505119633054187L; - - } - public class ConceptReferencePair { - - private ValueSet valueset; - private ConceptReferenceComponent cc; - - public ConceptReferencePair(ValueSet valueset, ConceptReferenceComponent cc) { - this.valueset = valueset; - this.cc = cc; - } - - public ValueSet getValueset() { - return valueset; - } - - public ConceptReferenceComponent getCc() { - return cc; - } - - } - +public class ValueSetValidator { private ValueSet valueset; private IWorkerContext context; - private Map inner = new HashMap<>(); + private Map inner = new HashMap<>(); private ValidationOptions options; private ValidationContextCarrier localContext; private List localSystems = new ArrayList<>(); - private Parameters expansionProfile; + Parameters expansionProfile; private TerminologyCapabilities txCaps; - public ValueSetCheckerSimple(ValidationOptions options, ValueSet source, IWorkerContext context, Parameters expansionProfile, TerminologyCapabilities txCaps) { + public ValueSetValidator(ValidationOptions options, ValueSet source, IWorkerContext context, Parameters expansionProfile, TerminologyCapabilities txCaps) { this.valueset = source; this.context = context; this.options = options; @@ -205,7 +108,7 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe this.txCaps = txCaps; } - public ValueSetCheckerSimple(ValidationOptions options, ValueSet source, IWorkerContext context, ValidationContextCarrier ctxt, Parameters expansionProfile, TerminologyCapabilities txCaps) { + public ValueSetValidator(ValidationOptions options, ValueSet source, IWorkerContext context, ValidationContextCarrier ctxt, Parameters expansionProfile, TerminologyCapabilities txCaps) { this.valueset = source; this.context = context; this.options = options.copy(); @@ -260,7 +163,7 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe if (!c.hasSystem()) { info.addIssue(makeIssue(IssueSeverity.WARNING, IssueType.UNKNOWN, path, context.formatMessage(I18nConstants.CODING_HAS_NO_SYSTEM__CANNOT_VALIDATE))); } - VersionInfo vi = new VersionInfo(); + VersionInfo vi = new VersionInfo(this); checkExpansion(c, vi); checkInclude(c, vi); CodeSystem cs = resolveCodeSystem(c.getSystem(), vi.getVersion(c.getSystem(), c.getVersion())); @@ -417,7 +320,7 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe ValidationResult res = null; boolean inExpansion = false; boolean inInclude = false; - VersionInfo vi = new VersionInfo(); + VersionInfo vi = new VersionInfo(this); String system = code.hasSystem() ? code.getSystem() : getValueSetSystemOrNull(); if (options.getValueSetMode() != ValueSetMode.CHECK_MEMERSHIP_ONLY) { @@ -966,7 +869,7 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe } private boolean checkForCodeInValueSet(String code, String uri, Set sys, List problems) { - ValueSetCheckerSimple vs = getVs(uri); + ValueSetValidator vs = getVs(uri); return vs.scanForCodeInValueSet(code, sys, problems); } @@ -985,7 +888,6 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe return true; } - @Override public Boolean codeInValueSet(String system, String version, String code, ValidationProcessInfo info) throws FHIRException { return codeInValueSet("code", system, version, code, info); } @@ -994,7 +896,7 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe return false; } Boolean result = false; - VersionInfo vi = new VersionInfo(); + VersionInfo vi = new VersionInfo(this); if (valueset.hasExpansion()) { return checkExpansion(new Coding(system, code, null), vi); @@ -1126,12 +1028,36 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe return codeInConceptFilter(cs, f, code); else if ("code".equals(f.getProperty()) && f.getOp() == FilterOperator.REGEX) return codeInRegexFilter(cs, f, code); - else { + else if (CodeSystemUtilities.hasPropertyDef(cs, f.getProperty())) { + return codeInPropertyFilter(cs, f, code); + } else { System.out.println("todo: handle filters with property = "+f.getProperty()+" "+f.getOp().toCode()); throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_HANDLE_SYSTEM__FILTER_WITH_PROPERTY__, cs.getUrl(), f.getProperty(), f.getOp().toCode())); } } + private boolean codeInPropertyFilter(CodeSystem cs, ConceptSetFilterComponent f, String code) { + switch (f.getOp()) { + case EQUAL: + if (f.getValue() == null) { + return false; + } + DataType d = CodeSystemUtilities.getProperty(cs, code, f.getProperty()); + return d != null && f.getValue().equals(d.primitiveValue()); + case EXISTS: + return CodeSystemUtilities.getProperty(cs, code, f.getProperty()) != null; + case REGEX: + if (f.getValue() == null) { + return false; + } + d = CodeSystemUtilities.getProperty(cs, code, f.getProperty()); + return d != null && d.primitiveValue() != null && d.primitiveValue().matches(f.getValue()); + default: + System.out.println("todo: handle property filters with op = "+f.getOp()); + throw new FHIRException(context.formatMessage(I18nConstants.UNABLE_TO_HANDLE_SYSTEM__PROPERTY_FILTER_WITH_OP__, cs.getUrl(), f.getOp())); + } + } + private boolean codeInRegexFilter(CodeSystem cs, ConceptSetFilterComponent f, String code) { return code.matches(f.getValue()); } @@ -1147,16 +1073,16 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe } } - private boolean codeInConceptIsAFilter(CodeSystem cs, ConceptSetFilterComponent f, String code, boolean rootOnly) { - if (!rootOnly && code.equals(f.getProperty())) { + private boolean codeInConceptIsAFilter(CodeSystem cs, ConceptSetFilterComponent f, String code, boolean excludeRoot) { + if (!excludeRoot && code.equals(f.getProperty())) { return true; } ConceptDefinitionComponent cc = findCodeInConcept(cs.getConcept(), f.getValue()); if (cc == null) { return false; } - cc = findCodeInConcept(cc, code); - return cc != null; + ConceptDefinitionComponent cc2 = findCodeInConcept(cc, code); + return cc2 != null && cc2 != cc; } public boolean validateCodeInConceptList(String code, CodeSystem def, List list) { @@ -1182,18 +1108,18 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe return false; } - private ValueSetCheckerSimple getVs(String url) { + private ValueSetValidator getVs(String url) { if (inner.containsKey(url)) { return inner.get(url); } ValueSet vs = context.fetchResource(ValueSet.class, url, valueset); - ValueSetCheckerSimple vsc = new ValueSetCheckerSimple(options, vs, context, localContext, expansionProfile, txCaps); + ValueSetValidator vsc = new ValueSetValidator(options, vs, context, localContext, expansionProfile, txCaps); inner.put(url, vsc); return vsc; } private boolean inImport(String uri, String system, String version, String code) throws FHIRException { - ValueSetCheckerSimple vs = getVs(uri); + ValueSetValidator vs = getVs(uri); if (vs == null) { return false; } else { diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/VersionInfo.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/VersionInfo.java new file mode 100644 index 000000000..87eba6ce6 --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/VersionInfo.java @@ -0,0 +1,79 @@ +package org.hl7.fhir.r5.terminologies.validation; + +import org.hl7.fhir.exceptions.FHIRException; +import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent; + +public class VersionInfo { + /** + * + */ + private final ValueSetValidator valueSetCheckerSimple; + + /** + * @param valueSetCheckerSimple + */ + VersionInfo(ValueSetValidator valueSetCheckerSimple) { + this.valueSetCheckerSimple = valueSetCheckerSimple; + } + + private String expansionVersion; + private String composeVersion; + + public String getExpansionVersion() { + return expansionVersion; + } + + public void setExpansionVersion(String expansionVersion) { + this.expansionVersion = expansionVersion; + } + + public String getComposeVersion() { + return composeVersion; + } + + public void setComposeVersion(String composeVersion) { + this.composeVersion = composeVersion; + } + + public String getVersion(String system, String version) { + String fixedVersion = getVersionParameter("force-system-version", system); + if (fixedVersion != null) { + return fixedVersion; + } + String checkVersion = getVersionParameter("check-system-version", system); + if (version != null) { + if (checkVersion != null && !version.equals(checkVersion)) { + throw new FHIRException("Attempt to use version "+version+" of "+system+", when the expansion parameters limit the use to "+checkVersion); + } + return version; + } + if (expansionVersion != null) { + if (checkVersion != null && !expansionVersion.equals(checkVersion)) { + throw new FHIRException("Attempt to use version "+expansionVersion+" of "+system+", when the expansion parameters limit the use to "+checkVersion); + } + return expansionVersion; + } + if (composeVersion != null) { + if (checkVersion != null && !composeVersion.equals(checkVersion)) { + throw new FHIRException("Attempt to use version "+composeVersion+" of "+system+", when the expansion parameters limit the use to "+checkVersion); + } + return composeVersion; + } + return getVersionParameter("system-version", system); + } + + private String getVersionParameter(String name, String system) { + if (this.valueSetCheckerSimple.expansionProfile != null) { + for (ParametersParameterComponent pc : this.valueSetCheckerSimple.expansionProfile.getParameter()) { + if (name.equals(pc.getName()) && pc.hasValue()) { + String v = pc.getValue().primitiveValue(); + if (v != null && v.startsWith(system+"|")) { + return v.substring(system.length()+1); + } + } + } + } + return null; + } + +} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/QuestionnaireBuilder.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/QuestionnaireBuilder.java index 289f03852..29ecaf4f3 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/QuestionnaireBuilder.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/QuestionnaireBuilder.java @@ -51,7 +51,7 @@ import org.hl7.fhir.r5.model.UriType; import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent; -import org.hl7.fhir.r5.terminologies.ValueSetExpander; +import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpander; import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; import org.hl7.fhir.utilities.Utilities; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/structuremap/StructureMapUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/structuremap/StructureMapUtilities.java index c1dbae9bf..5e91f5438 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/structuremap/StructureMapUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/structuremap/StructureMapUtilities.java @@ -63,7 +63,7 @@ import org.hl7.fhir.r5.model.StructureMap.*; import org.hl7.fhir.r5.model.TypeDetails.ProfiledType; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent; import org.hl7.fhir.r5.renderers.TerminologyRenderer; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome; +import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; import org.hl7.fhir.r5.utils.FHIRLexer; import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException; import org.hl7.fhir.r5.utils.FHIRPathEngine; diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/context/SimpleWorkerContextTests.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/context/SimpleWorkerContextTests.java index e54d2b186..83098feed 100644 --- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/context/SimpleWorkerContextTests.java +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/context/SimpleWorkerContextTests.java @@ -20,10 +20,10 @@ import org.hl7.fhir.r5.model.Enumerations; import org.hl7.fhir.r5.model.Parameters; import org.hl7.fhir.r5.model.TerminologyCapabilities; import org.hl7.fhir.r5.model.ValueSet; -import org.hl7.fhir.r5.terminologies.TerminologyClient; -import org.hl7.fhir.r5.terminologies.ValueSetCheckerSimple; -import org.hl7.fhir.r5.terminologies.ValueSetExpander; -import org.hl7.fhir.r5.terminologies.ValueSetExpanderSimple; +import org.hl7.fhir.r5.terminologies.client.ITerminologyClient; +import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpander; +import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; +import org.hl7.fhir.r5.terminologies.validation.ValueSetValidator; import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier; import org.hl7.fhir.utilities.ToolingClientLogger; import org.hl7.fhir.utilities.validation.ValidationOptions; @@ -54,7 +54,7 @@ public class SimpleWorkerContextTests { ToolingClientLogger txLog; @Mock - TerminologyClient terminologyClient; + ITerminologyClient terminologyClient; @Mock TerminologyCache.CacheToken cacheToken; @@ -63,13 +63,13 @@ public class SimpleWorkerContextTests { IWorkerContext.ValidationResult expectedValidationResult; @Mock - ValueSetExpander.ValueSetExpansionOutcome expectedExpansionResult; + ValueSetExpansionOutcome expectedExpansionResult; @Mock - ValueSetCheckerSimple valueSetCheckerSimple; + ValueSetValidator valueSetCheckerSimple; @Mock - ValueSetExpanderSimple valueSetExpanderSimple; + ValueSetExpander valueSetExpanderSimple; @Mock Parameters pIn; @@ -90,7 +90,7 @@ public class SimpleWorkerContextTests { public void beforeEach() { context.txCache = terminologyCache; context.expParameters = expParameters; - context.txClient = terminologyClient; + context.tcc.setClient(terminologyClient); context.txLog = txLog; } @@ -270,7 +270,7 @@ public class SimpleWorkerContextTests { Mockito.doReturn(cacheToken).when(terminologyCache).generateExpandToken(argThat(new ValueSetMatcher(vs)),eq(true)); Mockito.doReturn(expectedExpansionResult).when(terminologyCache).getExpansion(cacheToken); - ValueSetExpander.ValueSetExpansionOutcome actualExpansionResult = context.expandVS(inc, true, false); + ValueSetExpansionOutcome actualExpansionResult = context.expandVS(inc, true, false); assertEquals(expectedExpansionResult, actualExpansionResult); @@ -300,7 +300,7 @@ public class SimpleWorkerContextTests { Mockito.doReturn(expectedValueSet).when(terminologyClient).expandValueset(argThat(new ValueSetMatcher(vs)), argThat(new ParametersMatcher(pInWithDependentResources)), eq(params)); - ValueSetExpander.ValueSetExpansionOutcome actualExpansionResult = context.expandVS(inc, true, false); + ValueSetExpansionOutcome actualExpansionResult = context.expandVS(inc, true, false); assertEquals(expectedValueSet, actualExpansionResult.getValueset()); @@ -319,7 +319,7 @@ public class SimpleWorkerContextTests { Parameters pIn = new Parameters(); - ValueSetExpander.ValueSetExpansionOutcome actualExpansionResult = context.expandVS(vs, true, true, true, pIn); + ValueSetExpansionOutcome actualExpansionResult = context.expandVS(vs, true, true, true, pIn); assertEquals(expectedExpansionResult, actualExpansionResult); @@ -345,7 +345,7 @@ public class SimpleWorkerContextTests { Mockito.doReturn(valueSetExpanderSimple).when(context).constructValueSetExpanderSimple(); - ValueSetExpander.ValueSetExpansionOutcome actualExpansionResult = context.expandVS(vs, true, true, true, pIn); + ValueSetExpansionOutcome actualExpansionResult = context.expandVS(vs, true, true, true, pIn); assertEquals(expectedExpansionResult, actualExpansionResult); @@ -374,7 +374,7 @@ public class SimpleWorkerContextTests { Mockito.doReturn(expectedValueSet).when(terminologyClient).expandValueset(eq(vs), argThat(new ParametersMatcher(pInWithDependentResources)), eq(params)); - ValueSetExpander.ValueSetExpansionOutcome actualExpansionResult = context.expandVS(vs, true, true, true, pIn); + ValueSetExpansionOutcome actualExpansionResult = context.expandVS(vs, true, true, true, pIn); assertEquals(expectedValueSet, actualExpansionResult.getValueset()); diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/context/TerminologyCacheTests.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/context/TerminologyCacheTests.java index 329d7fd8f..3ce6eaadf 100644 --- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/context/TerminologyCacheTests.java +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/context/TerminologyCacheTests.java @@ -28,7 +28,7 @@ import org.hl7.fhir.r5.model.Coding; import org.hl7.fhir.r5.model.Parameters; import org.hl7.fhir.r5.model.TerminologyCapabilities; import org.hl7.fhir.r5.model.ValueSet; -import org.hl7.fhir.r5.terminologies.ValueSetExpander; +import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; import org.hl7.fhir.utilities.tests.ResourceLoaderTests; import org.hl7.fhir.utilities.validation.ValidationMessage; import org.junit.jupiter.api.Test; @@ -129,7 +129,7 @@ public class TerminologyCacheTests implements ResourceLoaderTests { terminologyCacheA.cacheValidation(codeableConceptTokenA, codeableConceptResultA, true); TerminologyCache.CacheToken expansionTokenA = terminologyCacheA.generateExpandToken(valueSet, true); - ValueSetExpander.ValueSetExpansionOutcome expansionOutcomeA = new ValueSetExpander.ValueSetExpansionOutcome(valueSet); + ValueSetExpansionOutcome expansionOutcomeA = new ValueSetExpansionOutcome(valueSet); terminologyCacheA.cacheExpansion(expansionTokenA, expansionOutcomeA, true); // Check that the in-memory cache is returning what we put in @@ -165,7 +165,7 @@ public class TerminologyCacheTests implements ResourceLoaderTests { assertEquals(a.getMessage(), b.getMessage()); } - private void assertExpansionOutcomeEquals(ValueSetExpander.ValueSetExpansionOutcome a, ValueSetExpander.ValueSetExpansionOutcome b) { + private void assertExpansionOutcomeEquals(ValueSetExpansionOutcome a, ValueSetExpansionOutcome b) { assertEquals(a.getValueset().getUrl(), b.getValueset().getUrl()); } diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/terminology/JurisdictionUtilitiesTests.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/terminologies/JurisdictionUtilitiesTests.java similarity index 94% rename from org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/terminology/JurisdictionUtilitiesTests.java rename to org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/terminologies/JurisdictionUtilitiesTests.java index ba56053ec..56d2e4283 100644 --- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/terminology/JurisdictionUtilitiesTests.java +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/terminologies/JurisdictionUtilitiesTests.java @@ -1,4 +1,4 @@ -package org.hl7.fhir.r5.terminology; +package org.hl7.fhir.r5.terminologies; import org.hl7.fhir.r5.terminologies.JurisdictionUtilities; import org.junit.jupiter.params.ParameterizedTest; diff --git a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/VocabTests.java b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/VocabTests.java index 73089fcff..74e24ab41 100644 --- a/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/VocabTests.java +++ b/org.hl7.fhir.r5/src/test/java/org/hl7/fhir/r5/test/VocabTests.java @@ -22,7 +22,7 @@ import org.hl7.fhir.r5.model.Base; import org.hl7.fhir.r5.model.Resource; import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.renderers.utils.RenderingContext.ITypeParser; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome; +import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; import org.hl7.fhir.r5.test.utils.TestingUtilities; import org.hl7.fhir.utilities.TextFile; import org.hl7.fhir.utilities.VersionUtilities; diff --git a/org.hl7.fhir.r5/src/test/resources/context/codableConceptEmptyValueSet.json b/org.hl7.fhir.r5/src/test/resources/context/codableConceptEmptyValueSet.json deleted file mode 100644 index fcb955cc0..000000000 --- a/org.hl7.fhir.r5/src/test/resources/context/codableConceptEmptyValueSet.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "code": { - "coding": [ - { - "code": "dummyCode" - } - ] - }, - "valueSet": { - "resourceType": "ValueSet" - }, - "langs": "[]", - "useServer": "true", - "useClient": "true", - "guessSystem": "true", - "valueSetMode": "ALL_CHECKS", - "versionFlexible": "false", - "profile":{ - "resourceType":"Parameters" - } -} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/test/resources/context/codableConceptEmptyValueSetSystem.json b/org.hl7.fhir.r5/src/test/resources/context/codableConceptEmptyValueSetSystem.json deleted file mode 100644 index a4d0b9e0b..000000000 --- a/org.hl7.fhir.r5/src/test/resources/context/codableConceptEmptyValueSetSystem.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "code": { - "coding": [ - { - "system": "dummySystem", - "version": "dummyVersion", - "code": "dummyCode" - } - ] - }, - "valueSet": { - "resourceType": "ValueSet" - }, - "langs": "[]", - "useServer": "true", - "useClient": "true", - "guessSystem": "true", - "valueSetMode": "ALL_CHECKS", - "versionFlexible": "false", - "profile":{ - "resourceType":"Parameters" - } -} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/test/resources/context/codingEmptyValueSet.json b/org.hl7.fhir.r5/src/test/resources/context/codingEmptyValueSet.json deleted file mode 100644 index 681af64eb..000000000 --- a/org.hl7.fhir.r5/src/test/resources/context/codingEmptyValueSet.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "code": { - "code": "dummyCode" - }, - "valueSet": { - "resourceType": "ValueSet" - }, - "langs": "[]", - "useServer": "true", - "useClient": "true", - "guessSystem": "true", - "valueSetMode": "ALL_CHECKS", - "versionFlexible": "false", - "profile":{ - "resourceType":"Parameters" - } -} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/test/resources/context/codingEmptyValueSetSystem.json b/org.hl7.fhir.r5/src/test/resources/context/codingEmptyValueSetSystem.json deleted file mode 100644 index 49f251f4b..000000000 --- a/org.hl7.fhir.r5/src/test/resources/context/codingEmptyValueSetSystem.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "code": { - "system": "dummySystem", - "version": "dummyVersion", - "code": "dummyCode" - }, - "valueSet": { - "resourceType": "ValueSet" - }, - "langs": "[]", - "useServer": "true", - "useClient": "true", - "guessSystem": "true", - "valueSetMode": "ALL_CHECKS", - "versionFlexible": "false", - "profile":{ - "resourceType":"Parameters" - } -} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/test/resources/context/expansion.json b/org.hl7.fhir.r5/src/test/resources/context/expansion.json deleted file mode 100644 index a386a9847..000000000 --- a/org.hl7.fhir.r5/src/test/resources/context/expansion.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "hierarchical": false, - "valueSet": { - "resourceType": "ValueSet", - "compose": { - "include": [ - { - "system": "dummyIncludeSystem", - "version": "dummyIncludeVersion" - } - ], - "exclude": [ - { - "system": "dummyExcludeSystem", - "version": "dummyExcludeVersion" - } - ] - }, - "expansion": { - "contains": [ - { - "system": "dummyContainsSystem", - "version": "dummyContainsVersion" - } - ] - } - } -} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/test/resources/context/expansionHierarchical.json b/org.hl7.fhir.r5/src/test/resources/context/expansionHierarchical.json deleted file mode 100644 index eb201490e..000000000 --- a/org.hl7.fhir.r5/src/test/resources/context/expansionHierarchical.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "hierarchical": true, - "valueSet": { - "resourceType": "ValueSet", - "compose": { - "include": [ - { - "system": "dummyIncludeSystem", - "version": "dummyIncludeVersion" - } - ], - "exclude": [ - { - "system": "dummyExcludeSystem", - "version": "dummyExcludeVersion" - } - ] - }, - "expansion": { - "contains": [ - { - "system": "dummyContainsSystem", - "version": "dummyContainsVersion" - } - ] - } - } -} \ No newline at end of file diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java index 5d4ec8b84..1c3d65423 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java @@ -560,6 +560,7 @@ public class I18nConstants { public static final String UNABLE_TO_FIND_RESOURCE__AT__RESOLVING_DISCRIMINATOR__FROM_ = "Unable_to_find_resource__at__resolving_discriminator__from_"; public static final String UNABLE_TO_FIND__RESOLVING_DISCRIMINATOR__FROM_ = "Unable_to_find__resolving_discriminator__from_"; public static final String UNABLE_TO_HANDLE_SYSTEM__CONCEPT_FILTER_WITH_OP__ = "Unable_to_handle_system__concept_filter_with_op__"; + public static final String UNABLE_TO_HANDLE_SYSTEM__PROPERTY_FILTER_WITH_OP__ = "UNABLE_TO_HANDLE_SYSTEM__PROPERTY_FILTER_WITH_OP__"; public static final String UNABLE_TO_HANDLE_SYSTEM__FILTER_WITH_PROPERTY__ = "Unable_to_handle_system__filter_with_property__"; public static final String UNABLE_TO_LOCATE_THE_PROFILE__IN_ORDER_TO_VALIDATE_AGAINST_IT = "Unable_to_locate_the_profile__in_order_to_validate_against_it"; public static final String UNABLE_TO_PROCESS_REQUEST_FOR_RESOURCE_FOR___ = "Unable_to_process_request_for_resource_for___"; diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/settings/FhirSettingsPOJO.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/settings/FhirSettingsPOJO.java index 170a2724e..39b3b55de 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/settings/FhirSettingsPOJO.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/settings/FhirSettingsPOJO.java @@ -16,7 +16,8 @@ public class FhirSettingsPOJO { protected static final String TX_SERVER_PROD = "http://tx.fhir.org"; protected static final String TX_SERVER_DEV = "http://tx-dev.fhir.org"; - protected static final String TX_SERVER_LOCAL = "http://local.fhir.org"; +// protected static final String TX_SERVER_LOCAL = "http://local.fhir.org"; + protected static final String TX_SERVER_LOCAL = "http://localhost"; private String fhirDirectory; private Map apiKeys; diff --git a/org.hl7.fhir.utilities/src/main/resources/Messages.properties b/org.hl7.fhir.utilities/src/main/resources/Messages.properties index 284db76b2..bd0fa1c6b 100644 --- a/org.hl7.fhir.utilities/src/main/resources/Messages.properties +++ b/org.hl7.fhir.utilities/src/main/resources/Messages.properties @@ -471,6 +471,7 @@ None_of_the_provided_codes_are_in_the_value_set_one = The provided code {2} is n None_of_the_provided_codes_are_in_the_value_set_other = None of the provided codes [{2}] are in the value set ''{1}'' Coding_has_no_system__cannot_validate = Coding has no system - cannot validate Unable_to_handle_system__concept_filter_with_op__ = Unable to handle system {0} concept filter with op = {1} +UNABLE_TO_HANDLE_SYSTEM__PROPERTY_FILTER_WITH_OP__ = Unable to handle system {0} property filter with op = {1} Unable_to_handle_system__filter_with_property__ = Unable to handle system {0} filter with property = {1}, op = {2} Unable_to_resolve_system__value_set_has_include_with_no_system = Unable to resolve system - value set {0} include #{1} has no system UNABLE_TO_RESOLVE_SYSTEM_SYSTEM_IS_INDETERMINATE = The code system {1} referred to from value set {0} has a grammar, and the code might be valid in it 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 90235c7c0..3eee4151e 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 @@ -369,12 +369,12 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP } engine.setVersion(version); engine.setIgLoader(new IgLoader(engine.getPcm(), engine.getContext(), engine.getVersion(), engine.isDebug())); - if (THO) { - loadTx(engine); - } - if (VersionUtilities.isR5Plus(version)) { - engine.loadPackage("hl7.fhir.uv.extensions", null); - } +// if (THO) { +// loadTx(engine); +// } +// if (VersionUtilities.isR5Plus(version)) { +// engine.loadPackage("hl7.fhir.uv.extensions", "1.0.0"); +// } return engine; } @@ -393,7 +393,7 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP pid = "hl7.terminology.r5"; } if (pid != null) { - engine.loadPackage(pid, null); + engine.loadPackage(pid, "5.0.0"); } } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidatorCli.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidatorCli.java index d6dd2d9bd..76d019efc 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidatorCli.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/ValidatorCli.java @@ -224,7 +224,7 @@ public class ValidatorCli { final String version = Params.getParam(args, Params.VERSION); final String tx = Params.getParam(args, Params.TERMINOLOGY); final String filter = Params.getParam(args, Params.FILTER); - boolean ok = new TxTester(new InternalTxLoader(source, output)).setOutput(output).execute(tx, version, filter); + boolean ok = new TxTester(new InternalTxLoader(source, output), tx).setOutput(output).execute(version, filter); System.exit(ok ? 1 : 0); } else { final String testModuleParam = Params.getParam(args, Params.TEST_MODULES); 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 f2fd731cf..711b28c4d 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 @@ -433,7 +433,7 @@ public class CliContext { @JsonProperty("sv") public CliContext setSv(String sv) { - if (sv != null && sv.startsWith("R")) { + if (sv != null && (sv.startsWith("R") || sv.startsWith("r"))) { this.sv = VersionUtilities.versionFromCode(sv.toLowerCase()); } else { this.sv = sv; 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 48b7cd4bd..4f633e68d 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 @@ -19,7 +19,7 @@ import org.hl7.fhir.r5.model.ElementDefinition; 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.terminologies.TerminologyClient; +import org.hl7.fhir.r5.terminologies.client.ITerminologyClient; import org.hl7.fhir.r5.utils.validation.IResourceValidator; import org.hl7.fhir.r5.utils.validation.IValidationPolicyAdvisor; import org.hl7.fhir.r5.utils.validation.IValidatorResourceFetcher; @@ -258,7 +258,7 @@ public class StandAloneValidatorFetcher implements IValidatorResourceFetcher, IV String root = getRoot(p, url); if (root != null) { - TerminologyClient c; + ITerminologyClient c; c = TerminologyClientFactory.makeClient("source", root, "fhir/validator", context.getVersion()); return c.read(p[p.length - 2], p[p.length - 1]); } else { 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 74f0e3846..72432e446 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 @@ -143,7 +143,7 @@ import org.hl7.fhir.r5.model.UriType; import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent; import org.hl7.fhir.r5.renderers.DataRenderer; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass; +import org.hl7.fhir.r5.terminologies.utilities.TerminologyServiceErrorClass; import org.hl7.fhir.r5.utils.BuildExtensions; import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException; import org.hl7.fhir.r5.utils.FHIRPathEngine; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/QuestionnaireValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/QuestionnaireValidator.java index ef74c7665..40941b8bf 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/QuestionnaireValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/QuestionnaireValidator.java @@ -20,10 +20,10 @@ import org.hl7.fhir.r5.model.Questionnaire; import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemAnswerOptionComponent; import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemComponent; import org.hl7.fhir.r5.model.Questionnaire.QuestionnaireItemType; +import org.hl7.fhir.r5.terminologies.utilities.TerminologyServiceErrorClass; import org.hl7.fhir.r5.model.StringType; import org.hl7.fhir.r5.model.TimeType; import org.hl7.fhir.r5.model.ValueSet; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass; import org.hl7.fhir.r5.utils.FHIRPathEngine; import org.hl7.fhir.r5.utils.XVerExtensionManager; import org.hl7.fhir.r5.utils.validation.ValidationContextCarrier; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java index 9b4f9e38b..9206557a2 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java @@ -29,8 +29,8 @@ import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent; import org.hl7.fhir.r5.terminologies.ConceptMapUtilities; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome; import org.hl7.fhir.r5.terminologies.ValueSetUtilities; +import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; import org.hl7.fhir.r5.utils.FHIRPathEngine; import org.hl7.fhir.r5.utils.XVerExtensionManager; import org.hl7.fhir.r5.utils.structuremap.ResolvedGroup; diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ValueSetValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ValueSetValidator.java index fc05f87dd..60d2e40ee 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ValueSetValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/ValueSetValidator.java @@ -10,7 +10,7 @@ import org.hl7.fhir.r5.elementmodel.Element; import org.hl7.fhir.r5.model.Coding; import org.hl7.fhir.r5.model.Resource; import org.hl7.fhir.r5.model.ValueSet; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass; +import org.hl7.fhir.r5.terminologies.utilities.TerminologyServiceErrorClass; import org.hl7.fhir.r5.utils.XVerExtensionManager; 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/instance/utils/FHIRPathExpressionFixer.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/FHIRPathExpressionFixer.java index b109c00b0..fb52b07a2 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/FHIRPathExpressionFixer.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/utils/FHIRPathExpressionFixer.java @@ -13,10 +13,9 @@ public class FHIRPathExpressionFixer { // return expr; // } - //TODO is this expression below correct? @grahamegrieve -// if ("probability is decimal implies (probability as decimal) <= 100".equals(expr)) { -// return "probability.empty() or ((probability is decimal) implies ((probability as decimal) <= 100))"; -// } + if ("probability is decimal implies (probability as decimal) <= 100".equals(expr)) { + return "(probability.exists() and (probability is decimal)) implies ((probability as decimal) <= 100)"; + } if ("enableWhen.count() > 2 implies enableBehavior.exists()".equals(expr)) { return "enableWhen.count() >= 2 implies enableBehavior.exists()"; } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/special/TxTester.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/special/TxTester.java index 55be38207..0b7ffcdb9 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/special/TxTester.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/special/TxTester.java @@ -32,7 +32,7 @@ import org.hl7.fhir.r5.model.Resource; import org.hl7.fhir.r5.model.OperationOutcome; import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent; -import org.hl7.fhir.r5.terminologies.TerminologyClient; +import org.hl7.fhir.r5.terminologies.client.ITerminologyClient; import org.hl7.fhir.r5.test.utils.CompareUtilities; import org.hl7.fhir.r5.utils.client.EFhirClientException; import org.hl7.fhir.utilities.FhirPublication; @@ -57,19 +57,20 @@ public class TxTester { private ITxTesterLoader loader; private String error; private String output; + private ITerminologyClient tx; - public TxTester(ITxTesterLoader loader) { + public TxTester(ITxTesterLoader loader, String server) { super(); + this.server = server; this.loader = loader; } public static void main(String[] args) throws Exception { - new TxTester(new InternalTxLoader(args[0])).execute(args[1], args[2], args[3]); + new TxTester(new InternalTxLoader(args[0]), args[1]).execute(args[2], args[3]); } - public boolean execute(String server, String version, String filter) throws IOException, URISyntaxException { - this.server = server; + public boolean execute(String version, String filter) throws IOException, URISyntaxException { if (output == null) { output = Utilities.path("[tmp]", serverId()); } @@ -89,7 +90,7 @@ public class TxTester { json.add("date", new SimpleDateFormat("EEE, MMM d, yyyy HH:mmZ", new Locale("en", "US")).format(Calendar.getInstance().getTime()) + timezone()); try { JsonObject tests = loadTests(); - TerminologyClient tx = connectToServer(); + ITerminologyClient tx = connectToServer(); boolean ok = checkClient(tx); for (JsonObject suite : tests.getJsonObjects("suites")) { ok = runSuite(suite, tx, filter, json.forceArray("suites")) && ok; @@ -121,7 +122,7 @@ public class TxTester { return offset; } - private boolean checkClient(TerminologyClient tx) { + private boolean checkClient(ITerminologyClient tx) { tx.getCapabilitiesStatementQuick(); tx.getTerminologyCapabilities(); return true; @@ -132,17 +133,18 @@ public class TxTester { return JsonParser.parseObject(loader.loadContent("test-cases.json")); } - private TerminologyClient connectToServer() throws URISyntaxException { + private ITerminologyClient connectToServer() throws URISyntaxException { System.out.println("Connect to "+server); return TerminologyClientFactory.makeClient("Test-Server", server, "Tools/Java", FhirPublication.R4); } - public String executeTest(JsonObject suite, JsonObject test, String server) throws URISyntaxException, FHIRFormatError, FileNotFoundException, IOException { - this.server = server; + public String executeTest(JsonObject suite, JsonObject test) throws URISyntaxException, FHIRFormatError, FileNotFoundException, IOException { error = null; - TerminologyClient tx = connectToServer(); - checkClient(tx); + if (tx == null) { + tx = connectToServer(); + checkClient(tx); + } List setup = loadSetupResources(suite); if (runTest(test, tx, setup, "*", null)) { return null; @@ -150,7 +152,7 @@ public class TxTester { return error; } } - private boolean runSuite(JsonObject suite, TerminologyClient tx, String filter, JsonArray output) throws FHIRFormatError, FileNotFoundException, IOException { + private boolean runSuite(JsonObject suite, ITerminologyClient tx, String filter, JsonArray output) throws FHIRFormatError, FileNotFoundException, IOException { System.out.println("Group "+suite.asString("name")); JsonObject outputS = new JsonObject(); if (output != null) { @@ -165,7 +167,7 @@ public class TxTester { return ok; } - private boolean runTest(JsonObject test, TerminologyClient tx, List setup, String filter, JsonArray output) throws FHIRFormatError, DefinitionException, FileNotFoundException, FHIRException, IOException { + private boolean runTest(JsonObject test, ITerminologyClient tx, List setup, String filter, JsonArray output) throws FHIRFormatError, DefinitionException, FileNotFoundException, FHIRException, IOException { JsonObject outputT = new JsonObject(); if (output != null) { output.add(outputT); @@ -229,7 +231,7 @@ public class TxTester { return new URI(server).getHost(); } - private String expand(TerminologyClient tx, List setup, Parameters p, String resp, String fp, Parameters profile) throws IOException { + private String expand(ITerminologyClient tx, List setup, Parameters p, String resp, String fp, Parameters profile) throws IOException { for (Resource r : setup) { p.addParameter().setName("tx-resource").setResource(r); } @@ -253,7 +255,7 @@ public class TxTester { return diff; } - private String validate(TerminologyClient tx, List setup, Parameters p, String resp, String fp, Parameters profile) throws IOException { + private String validate(ITerminologyClient tx, List setup, Parameters p, String resp, String fp, Parameters profile) throws IOException { for (Resource r : setup) { p.addParameter().setName("tx-resource").setResource(r); } diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/ExternalTerminologyServiceTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/ExternalTerminologyServiceTests.java index 5c9982ddc..bcfabd6c6 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/ExternalTerminologyServiceTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/ExternalTerminologyServiceTests.java @@ -48,8 +48,8 @@ public class ExternalTerminologyServiceTests implements ITxTesterLoader { private JsonObject test; } - private static final String SERVER = FhirSettings.getTxFhirDevelopment(); -// private static final String SERVER = FhirSettings.getTxFhirLocal(); +// private static final String SERVER = FhirSettings.getTxFhirDevelopment(); + private static final String SERVER = FhirSettings.getTxFhirLocal(); @Parameters(name = "{index}: id {0}") public static Iterable data() throws IOException { @@ -80,6 +80,7 @@ public class ExternalTerminologyServiceTests implements ITxTesterLoader { private static org.hl7.fhir.utilities.json.model.JsonObject manifest; private JsonObjectPair setup; private String version = "5.0.0"; + private static TxTester tester; public ExternalTerminologyServiceTests(String name, JsonObjectPair setup) { this.setup = setup; @@ -89,7 +90,10 @@ public class ExternalTerminologyServiceTests implements ITxTesterLoader { @Test public void test() throws Exception { if (SERVER != null) { - String err = new TxTester(this).executeTest(setup.suite, setup.test, SERVER); + if (tester == null) { + tester = new TxTester(this, SERVER); + } + String err = tester.executeTest(setup.suite, setup.test); Assertions.assertTrue(err == null, err); } else { Assertions.assertTrue(true); diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/TerminologyServiceTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/TerminologyServiceTests.java index b1eefac19..c167b2fd4 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/TerminologyServiceTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/TerminologyServiceTests.java @@ -35,8 +35,7 @@ import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; import org.hl7.fhir.r5.model.CodeableConcept; import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.TerminologyServiceErrorClass; -import org.hl7.fhir.r5.terminologies.ValueSetExpander.ValueSetExpansionOutcome; +import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; import org.hl7.fhir.r5.test.utils.CompareUtilities; import org.hl7.fhir.r5.test.utils.TestingUtilities; import org.hl7.fhir.terminology.tests.TerminologyServiceTests.JsonObjectPair; diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/utilities/TestUtilities.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/utilities/TestUtilities.java index c5ff3338e..69104d5db 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/utilities/TestUtilities.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/validation/tests/utilities/TestUtilities.java @@ -34,7 +34,7 @@ public class TestUtilities { public static ValidationEngine getValidationEngineNoTxServer(java.lang.String src, FhirPublication version, java.lang.String vString) throws Exception { - TestingUtilities.injectCorePackageLoader(); +// TestingUtilities.injectCorePackageLoader(); final ValidationEngine validationEngine = new ValidationEngine.ValidationEngineBuilder() .withCanRunWithoutTerminologyServer(true) diff --git a/pom.xml b/pom.xml index 63b2ef555..67fccdbee 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 6.4.1 - 1.3.4 + 1.3.5-SNAPSHOT 2.14.0 5.9.2 1.8.2 From f734f98c05062148b9f4cefd83ce9b55ce4d5377 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Fri, 5 May 2023 22:21:05 -0500 Subject: [PATCH 2/8] update for failing tests --- .../validation/ValueSetValidator.java | 2 +- .../context/codableConceptEmptyValueSet.json | 21 + .../codableConceptEmptyValueSetSystem.json | 23 + .../context/codingEmptyValueSet.json | 17 + .../context/codingEmptyValueSetSystem.json | 19 + .../src/test/resources/context/expansion.json | 28 + .../context/expansionHierarchical.json | 28 + .../utilities/settings/FhirSettingsPOJO.java | 3 +- .../hl7/fhir/validation/ValidationEngine.java | 12 +- .../ExternalTerminologyServiceTests.java | 4 +- .../txCache/org.hl7.fhir.r5/lang.cache | 2 +- .../txCache/org.hl7.fhir.r5/loinc.cache | 2 +- .../txCache/org.hl7.fhir.r5/mimetypes.cache | 2 +- .../txCache/org.hl7.fhir.r5/ucum.cache | 2 +- .../1.0.2/.capabilityStatement.cache | 2 +- .../1.4.0/.capabilityStatement.cache | 2 +- .../3.0.2/.capabilityStatement.cache | 2 +- .../3.0.2/all-systems.cache | 3 +- .../3.0.2/iso3166.cache | 9 +- .../org.hl7.fhir.validation/3.0.2/loinc.cache | 109 ++-- .../3.0.2/snomed.cache | 3 +- .../4.0.1/.capabilityStatement.cache | 2 +- .../4.0.1/.terminologyCapabilities.cache | 2 +- .../4.0.1/all-systems.cache | 124 ++-- .../4.0.1/condition-clinical.cache | 3 +- .../org.hl7.fhir.validation/4.0.1/cvx.cache | 3 +- .../http___nucc.org_provider-taxonomy.cache | 3 +- .../4.0.1/iso3166.cache | 3 +- .../org.hl7.fhir.validation/4.0.1/loinc.cache | 570 +++++++++--------- .../4.0.1/snomed.cache | 158 ++--- .../org.hl7.fhir.validation/4.0.1/ucum.cache | 68 ++- .../4.3.0/.capabilityStatement.cache | 2 +- .../4.3.0/.terminologyCapabilities.cache | 2 +- .../5.0.0/.capabilityStatement.cache | 2 +- .../5.0.0/.terminologyCapabilities.cache | 2 +- .../org.hl7.fhir.validation/5.0.0/loinc.cache | 102 +--- .../5.0.0/snomed.cache | 6 +- .../org.hl7.fhir.validation/5.0.0/ucum.cache | 3 +- 38 files changed, 748 insertions(+), 602 deletions(-) create mode 100644 org.hl7.fhir.r5/src/test/resources/context/codableConceptEmptyValueSet.json create mode 100644 org.hl7.fhir.r5/src/test/resources/context/codableConceptEmptyValueSetSystem.json create mode 100644 org.hl7.fhir.r5/src/test/resources/context/codingEmptyValueSet.json create mode 100644 org.hl7.fhir.r5/src/test/resources/context/codingEmptyValueSetSystem.json create mode 100644 org.hl7.fhir.r5/src/test/resources/context/expansion.json create mode 100644 org.hl7.fhir.r5/src/test/resources/context/expansionHierarchical.json diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValueSetValidator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValueSetValidator.java index 047d7809a..e184f5b93 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValueSetValidator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValueSetValidator.java @@ -1074,7 +1074,7 @@ public class ValueSetValidator { } private boolean codeInConceptIsAFilter(CodeSystem cs, ConceptSetFilterComponent f, String code, boolean excludeRoot) { - if (!excludeRoot && code.equals(f.getProperty())) { + if (!excludeRoot && code.equals(f.getValue())) { return true; } ConceptDefinitionComponent cc = findCodeInConcept(cs.getConcept(), f.getValue()); diff --git a/org.hl7.fhir.r5/src/test/resources/context/codableConceptEmptyValueSet.json b/org.hl7.fhir.r5/src/test/resources/context/codableConceptEmptyValueSet.json new file mode 100644 index 000000000..12fae5310 --- /dev/null +++ b/org.hl7.fhir.r5/src/test/resources/context/codableConceptEmptyValueSet.json @@ -0,0 +1,21 @@ +{ + "code": { + "coding": [ + { + "code": "dummyCode" + } + ] + }, + "valueSet": { + "resourceType": "ValueSet" + }, + "langs": "[]", + "useServer": "true", + "useClient": "true", + "guessSystem": "true", + "valueSetMode": "ALL_CHECKS", + "versionFlexible": "false", + "profile":{ + "resourceType":"Parameters" + } +} \ No newline at end of file diff --git a/org.hl7.fhir.r5/src/test/resources/context/codableConceptEmptyValueSetSystem.json b/org.hl7.fhir.r5/src/test/resources/context/codableConceptEmptyValueSetSystem.json new file mode 100644 index 000000000..92d38d523 --- /dev/null +++ b/org.hl7.fhir.r5/src/test/resources/context/codableConceptEmptyValueSetSystem.json @@ -0,0 +1,23 @@ +{ + "code": { + "coding": [ + { + "system": "dummySystem", + "version": "dummyVersion", + "code": "dummyCode" + } + ] + }, + "valueSet": { + "resourceType": "ValueSet" + }, + "langs": "[]", + "useServer": "true", + "useClient": "true", + "guessSystem": "true", + "valueSetMode": "ALL_CHECKS", + "versionFlexible": "false", + "profile":{ + "resourceType":"Parameters" + } +} diff --git a/org.hl7.fhir.r5/src/test/resources/context/codingEmptyValueSet.json b/org.hl7.fhir.r5/src/test/resources/context/codingEmptyValueSet.json new file mode 100644 index 000000000..72e9aa2ba --- /dev/null +++ b/org.hl7.fhir.r5/src/test/resources/context/codingEmptyValueSet.json @@ -0,0 +1,17 @@ +{ + "code": { + "code": "dummyCode" + }, + "valueSet": { + "resourceType": "ValueSet" + }, + "langs": "[]", + "useServer": "true", + "useClient": "true", + "guessSystem": "true", + "valueSetMode": "ALL_CHECKS", + "versionFlexible": "false", + "profile":{ + "resourceType":"Parameters" + } +} diff --git a/org.hl7.fhir.r5/src/test/resources/context/codingEmptyValueSetSystem.json b/org.hl7.fhir.r5/src/test/resources/context/codingEmptyValueSetSystem.json new file mode 100644 index 000000000..0295e2f50 --- /dev/null +++ b/org.hl7.fhir.r5/src/test/resources/context/codingEmptyValueSetSystem.json @@ -0,0 +1,19 @@ +{ + "code": { + "system": "dummySystem", + "version": "dummyVersion", + "code": "dummyCode" + }, + "valueSet": { + "resourceType": "ValueSet" + }, + "langs": "[]", + "useServer": "true", + "useClient": "true", + "guessSystem": "true", + "valueSetMode": "ALL_CHECKS", + "versionFlexible": "false", + "profile":{ + "resourceType":"Parameters" + } +} diff --git a/org.hl7.fhir.r5/src/test/resources/context/expansion.json b/org.hl7.fhir.r5/src/test/resources/context/expansion.json new file mode 100644 index 000000000..7f5b13d88 --- /dev/null +++ b/org.hl7.fhir.r5/src/test/resources/context/expansion.json @@ -0,0 +1,28 @@ +{ + "hierarchical": false, + "valueSet": { + "resourceType": "ValueSet", + "compose": { + "include": [ + { + "system": "dummyIncludeSystem", + "version": "dummyIncludeVersion" + } + ], + "exclude": [ + { + "system": "dummyExcludeSystem", + "version": "dummyExcludeVersion" + } + ] + }, + "expansion": { + "contains": [ + { + "system": "dummyContainsSystem", + "version": "dummyContainsVersion" + } + ] + } + } +} diff --git a/org.hl7.fhir.r5/src/test/resources/context/expansionHierarchical.json b/org.hl7.fhir.r5/src/test/resources/context/expansionHierarchical.json new file mode 100644 index 000000000..0221c0b04 --- /dev/null +++ b/org.hl7.fhir.r5/src/test/resources/context/expansionHierarchical.json @@ -0,0 +1,28 @@ +{ + "hierarchical": true, + "valueSet": { + "resourceType": "ValueSet", + "compose": { + "include": [ + { + "system": "dummyIncludeSystem", + "version": "dummyIncludeVersion" + } + ], + "exclude": [ + { + "system": "dummyExcludeSystem", + "version": "dummyExcludeVersion" + } + ] + }, + "expansion": { + "contains": [ + { + "system": "dummyContainsSystem", + "version": "dummyContainsVersion" + } + ] + } + } +} diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/settings/FhirSettingsPOJO.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/settings/FhirSettingsPOJO.java index 39b3b55de..170a2724e 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/settings/FhirSettingsPOJO.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/settings/FhirSettingsPOJO.java @@ -16,8 +16,7 @@ public class FhirSettingsPOJO { protected static final String TX_SERVER_PROD = "http://tx.fhir.org"; protected static final String TX_SERVER_DEV = "http://tx-dev.fhir.org"; -// protected static final String TX_SERVER_LOCAL = "http://local.fhir.org"; - protected static final String TX_SERVER_LOCAL = "http://localhost"; + protected static final String TX_SERVER_LOCAL = "http://local.fhir.org"; private String fhirDirectory; private Map apiKeys; 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 3eee4151e..bb7b1bc66 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 @@ -369,12 +369,12 @@ public class ValidationEngine implements IValidatorResourceFetcher, IValidationP } engine.setVersion(version); engine.setIgLoader(new IgLoader(engine.getPcm(), engine.getContext(), engine.getVersion(), engine.isDebug())); -// if (THO) { -// loadTx(engine); -// } -// if (VersionUtilities.isR5Plus(version)) { -// engine.loadPackage("hl7.fhir.uv.extensions", "1.0.0"); -// } + if (THO) { + loadTx(engine); + } + if (VersionUtilities.isR5Plus(version)) { + engine.loadPackage("hl7.fhir.uv.extensions", "1.0.0"); + } return engine; } diff --git a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/ExternalTerminologyServiceTests.java b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/ExternalTerminologyServiceTests.java index bcfabd6c6..c8dd54694 100644 --- a/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/ExternalTerminologyServiceTests.java +++ b/org.hl7.fhir.validation/src/test/java/org/hl7/fhir/terminology/tests/ExternalTerminologyServiceTests.java @@ -48,8 +48,8 @@ public class ExternalTerminologyServiceTests implements ITxTesterLoader { private JsonObject test; } -// private static final String SERVER = FhirSettings.getTxFhirDevelopment(); - private static final String SERVER = FhirSettings.getTxFhirLocal(); + private static final String SERVER = FhirSettings.getTxFhirDevelopment(); +// private static final String SERVER = FhirSettings.getTxFhirLocal(); @Parameters(name = "{index}: id {0}") public static Iterable data() throws IOException { diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.r5/lang.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.r5/lang.cache index 6b251f61b..f78b45815 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.r5/lang.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.r5/lang.cache @@ -9,6 +9,6 @@ } }}#### e: { - "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.TerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because \"this.txClient\" is null" + "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" } ------------------------------------------------------------------------------------- diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.r5/loinc.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.r5/loinc.cache index 91823f22f..0216bd7fe 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.r5/loinc.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.r5/loinc.cache @@ -41,6 +41,6 @@ } }}#### e: { - "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.TerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because \"this.txClient\" is null" + "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" } ------------------------------------------------------------------------------------- diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.r5/mimetypes.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.r5/mimetypes.cache index c8e1d4ded..5aa448890 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.r5/mimetypes.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.r5/mimetypes.cache @@ -9,6 +9,6 @@ } }}#### e: { - "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.TerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because \"this.txClient\" is null" + "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" } ------------------------------------------------------------------------------------- diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.r5/ucum.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.r5/ucum.cache index 1380054c6..ee9e71d25 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.r5/ucum.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.r5/ucum.cache @@ -93,6 +93,6 @@ } }}#### e: { - "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.TerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because \"this.txClient\" is null" + "error" : "Cannot invoke \"org.hl7.fhir.r5.terminologies.client.ITerminologyClient.expandValueset(org.hl7.fhir.r5.model.ValueSet, org.hl7.fhir.r5.model.Parameters, java.util.Map)\" because the return value of \"org.hl7.fhir.r5.terminologies.client.TerminologyClientContext.getClient()\" is null" } ------------------------------------------------------------------------------------- diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/1.0.2/.capabilityStatement.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/1.0.2/.capabilityStatement.cache index 73b076bb6..04b816b5c 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/1.0.2/.capabilityStatement.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/1.0.2/.capabilityStatement.cache @@ -16,7 +16,7 @@ "version" : "1.0.2-2.1.0", "name" : "FHIR Reference Server Conformance Statement", "status" : "active", - "date" : "2023-05-02T06:09:01.119Z", + "date" : "2023-05-06T00:21:06.818Z", "contact" : [{ "telecom" : [{ "system" : "other", diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/1.4.0/.capabilityStatement.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/1.4.0/.capabilityStatement.cache index 11b756931..2d29f73af 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/1.4.0/.capabilityStatement.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/1.4.0/.capabilityStatement.cache @@ -16,7 +16,7 @@ "version" : "3.0.2-2.1.0", "name" : "FHIR Reference Server Conformance Statement", "status" : "active", - "date" : "2023-05-02T06:09:03.886Z", + "date" : "2023-05-06T00:21:09.867Z", "contact" : [{ "telecom" : [{ "system" : "other", diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/.capabilityStatement.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/.capabilityStatement.cache index b1137cedc..016f45fc4 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/.capabilityStatement.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/.capabilityStatement.cache @@ -16,7 +16,7 @@ "version" : "3.0.2-2.1.0", "name" : "FHIR Reference Server Conformance Statement", "status" : "active", - "date" : "2023-05-02T06:09:06.190Z", + "date" : "2023-05-06T00:21:12.342Z", "contact" : [{ "telecom" : [{ "system" : "other", diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/all-systems.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/all-systems.cache index 7f601ec5e..77e5dbd60 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/all-systems.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/all-systems.cache @@ -26,7 +26,8 @@ v: { v: { "display" : "day", "code" : "d", - "system" : "http://unitsofmeasure.org" + "system" : "http://unitsofmeasure.org", + "version" : "2.0.1" } ------------------------------------------------------------------------------------- {"code" : { diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/iso3166.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/iso3166.cache index 7bbdeec9c..b0eed26fe 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/iso3166.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/iso3166.cache @@ -65,7 +65,8 @@ v: { v: { "display" : "Netherlands", "code" : "NL", - "system" : "urn:iso:std:iso:3166" + "system" : "urn:iso:std:iso:3166", + "version" : "2018" } ------------------------------------------------------------------------------------- {"code" : { @@ -81,7 +82,8 @@ v: { v: { "display" : "Netherlands", "code" : "NL", - "system" : "urn:iso:std:iso:3166" + "system" : "urn:iso:std:iso:3166", + "version" : "2018" } ------------------------------------------------------------------------------------- {"code" : { @@ -115,7 +117,8 @@ v: { v: { "display" : "United States of America", "code" : "US", - "system" : "urn:iso:std:iso:3166" + "system" : "urn:iso:std:iso:3166", + "version" : "2018" } ------------------------------------------------------------------------------------- {"code" : { diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/loinc.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/loinc.cache index dc5fdf2d6..1e2f7fb5f 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/loinc.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/loinc.cache @@ -17,6 +17,58 @@ v: { "version" : "2.74" } ------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://loinc.org", + "code" : "19935-6" +}, "url": "http://phr.kanta.fi/ValueSet/fiphr-vs-vitalsigns--0", "version": "0.03", "langs":"[fi]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Maximum expiratory gas flow Respiratory system airway by Peak flow meter", + "code" : "19935-6", + "system" : "http://loinc.org", + "version" : "2.74" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://loinc.org", + "code" : "19935-6", + "display" : "Maximum expiratory gas flow Respiratory system airway by Peak flow meter" +}, "url": "http://phr.kanta.fi/ValueSet/fiphr-vs-vitalsigns", "version": "0.03", "langs":"[fi]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Maximum expiratory gas flow Respiratory system airway by Peak flow meter", + "code" : "19935-6", + "system" : "http://loinc.org", + "version" : "2.74" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://loinc.org", + "code" : "19935-6" +}, "valueSet" :null, "langs":"[fi]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Maximum expiratory gas flow Respiratory system airway by Peak flow meter", + "code" : "19935-6", + "system" : "http://loinc.org", + "version" : "2.74" +} +------------------------------------------------------------------------------------- {"code" : { "system" : "http://loinc.org", "code" : "28655-9" @@ -30,7 +82,8 @@ v: { v: { "display" : "Attending Discharge summary", "code" : "28655-9", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -151,7 +204,8 @@ v: { v: { "display" : "Discharge summary", "code" : "18842-5", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -449,57 +503,6 @@ v: { "version" : "2.74" } ------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "code" : "19935-6" -}, "url": "http://phr.kanta.fi/ValueSet/fiphr-vs-vitalsigns--0", "version": "0.03", "langs":"[fi]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Maximum expiratory gas flow Respiratory system airway by Peak flow meter", - "code" : "19935-6", - "system" : "http://loinc.org" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "code" : "19935-6", - "display" : "Maximum expiratory gas flow Respiratory system airway by Peak flow meter" -}, "url": "http://phr.kanta.fi/ValueSet/fiphr-vs-vitalsigns", "version": "0.03", "langs":"[fi]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Maximum expiratory gas flow Respiratory system airway by Peak flow meter", - "code" : "19935-6", - "system" : "http://loinc.org", - "version" : "2.74" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "code" : "19935-6" -}, "valueSet" :null, "langs":"[fi]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Maximum expiratory gas flow Respiratory system airway by Peak flow meter", - "code" : "19935-6", - "system" : "http://loinc.org", - "version" : "2.74" -} -------------------------------------------------------------------------------------- {"code" : { "system" : "http://loinc.org", "code" : "29463-7", diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/snomed.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/snomed.cache index 54135cc07..7b26ed14e 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/snomed.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/3.0.2/snomed.cache @@ -546,7 +546,8 @@ v: { v: { "display" : "Steady", "code" : "55011004", - "system" : "http://snomed.info/sct" + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20230131" } ------------------------------------------------------------------------------------- {"code" : { diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/.capabilityStatement.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/.capabilityStatement.cache index 8c617f30f..c5058eb4a 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/.capabilityStatement.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/.capabilityStatement.cache @@ -12,7 +12,7 @@ "version" : "4.0.1-2.1.0", "name" : "FHIR Reference Server Conformance Statement", "status" : "active", - "date" : "2023-05-02T06:09:13.652Z", + "date" : "2023-05-06T00:21:18.691Z", "contact" : [{ "telecom" : [{ "system" : "other", diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/.terminologyCapabilities.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/.terminologyCapabilities.cache index e853c3d6b..6c9766385 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/.terminologyCapabilities.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/.terminologyCapabilities.cache @@ -5,7 +5,7 @@ "version" : "2.0.0", "name" : "FHIR Reference Server Teminology Capability Statement", "status" : "active", - "date" : "2023-05-02T06:09:13.666Z", + "date" : "2023-05-06T00:21:18.711Z", "contact" : [{ "telecom" : [{ "system" : "other", diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/all-systems.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/all-systems.cache index a71fbcc2f..3bf77b79b 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/all-systems.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/all-systems.cache @@ -91,7 +91,8 @@ v: { v: { "display" : "day", "code" : "d", - "system" : "http://unitsofmeasure.org" + "system" : "http://unitsofmeasure.org", + "version" : "2.0.1" } ------------------------------------------------------------------------------------- {"code" : { @@ -136,7 +137,8 @@ v: { v: { "display" : "min", "code" : "min", - "system" : "http://unitsofmeasure.org" + "system" : "http://unitsofmeasure.org", + "version" : "2.0.1" } ------------------------------------------------------------------------------------- {"code" : { @@ -151,7 +153,8 @@ v: { v: { "display" : "mmol/L", "code" : "mmol/L", - "system" : "http://unitsofmeasure.org" + "system" : "http://unitsofmeasure.org", + "version" : "2.0.1" } ------------------------------------------------------------------------------------- {"code" : { @@ -166,7 +169,8 @@ v: { v: { "display" : "%", "code" : "%", - "system" : "http://unitsofmeasure.org" + "system" : "http://unitsofmeasure.org", + "version" : "2.0.1" } ------------------------------------------------------------------------------------- {"code" : { @@ -181,7 +185,8 @@ v: { v: { "display" : "kg", "code" : "kg", - "system" : "http://unitsofmeasure.org" + "system" : "http://unitsofmeasure.org", + "version" : "2.0.1" } ------------------------------------------------------------------------------------- {"code" : { @@ -211,7 +216,8 @@ v: { v: { "display" : "cm", "code" : "cm", - "system" : "http://unitsofmeasure.org" + "system" : "http://unitsofmeasure.org", + "version" : "2.0.1" } ------------------------------------------------------------------------------------- {"code" : { @@ -289,7 +295,8 @@ v: { v: { "display" : "wk", "code" : "wk", - "system" : "http://unitsofmeasure.org" + "system" : "http://unitsofmeasure.org", + "version" : "2.0.1" } ------------------------------------------------------------------------------------- {"code" : { @@ -556,7 +563,8 @@ v: { v: { "display" : "kg", "code" : "kg", - "system" : "http://unitsofmeasure.org" + "system" : "http://unitsofmeasure.org", + "version" : "2.0.1" } ------------------------------------------------------------------------------------- {"code" : { @@ -586,7 +594,8 @@ v: { v: { "display" : "cm", "code" : "cm", - "system" : "http://unitsofmeasure.org" + "system" : "http://unitsofmeasure.org", + "version" : "2.0.1" } ------------------------------------------------------------------------------------- {"code" : { @@ -616,7 +625,8 @@ v: { v: { "display" : "kg/m2", "code" : "kg/m2", - "system" : "http://unitsofmeasure.org" + "system" : "http://unitsofmeasure.org", + "version" : "2.0.1" } ------------------------------------------------------------------------------------- {"code" : { @@ -631,7 +641,8 @@ v: { v: { "display" : "wk", "code" : "wk", - "system" : "http://unitsofmeasure.org" + "system" : "http://unitsofmeasure.org", + "version" : "2.0.1" } ------------------------------------------------------------------------------------- {"code" : { @@ -694,6 +705,44 @@ v: { "system" : "urn:ietf:bcp:13" } ------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://snomed.info/sct", + "code" : "371532007", + "display" : "Progress note" +}, "url": "http://fhir.ch/ig/ch-epr-term/ValueSet/DocumentEntry.typeCode", "version": "2.0.1", "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Progress report", + "code" : "371532007", + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20230131", + "severity" : "warning", + "error" : "Wrong Display Name 'Progress note' for http://snomed.info/sct#371532007 - should be one of 3 choices: 'Progress report, \"Report of subsequent visit\", \"Progress report (record artifact)\"' for the language(s) '--' (from Tx-Server)" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://snomed.info/sct", + "code" : "371525003", + "display" : "Clinical procedure report" +}, "url": "http://fhir.ch/ig/ch-epr-term/ValueSet/DocumentEntry.classCode", "version": "2.0.4", "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Clinical procedure report", + "code" : "371525003", + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20230131" +} +------------------------------------------------------------------------------------- {"code" : { "code" : "text/css" }, "url": "http://hl7.org/fhir/ValueSet/mimetypes", "version": "4.0.1", "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"true", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { @@ -856,7 +905,8 @@ v: { v: { "display" : "Not at all", "code" : "Not-at-all", - "system" : "http://hl7.org/fhir/uv/sdc/CodeSystem/CSPHQ9" + "system" : "http://hl7.org/fhir/uv/sdc/CodeSystem/CSPHQ9", + "version" : "3.0.0" } ------------------------------------------------------------------------------------- {"code" : { @@ -895,7 +945,8 @@ v: { v: { "display" : "Several days", "code" : "Several-days", - "system" : "http://hl7.org/fhir/uv/sdc/CodeSystem/CSPHQ9" + "system" : "http://hl7.org/fhir/uv/sdc/CodeSystem/CSPHQ9", + "version" : "3.0.0" } ------------------------------------------------------------------------------------- {"code" : { @@ -934,7 +985,8 @@ v: { v: { "display" : "More than half the days", "code" : "More than half the days", - "system" : "http://hl7.org/fhir/uv/sdc/CodeSystem/CSPHQ9" + "system" : "http://hl7.org/fhir/uv/sdc/CodeSystem/CSPHQ9", + "version" : "3.0.0" } ------------------------------------------------------------------------------------- {"code" : { @@ -973,7 +1025,8 @@ v: { v: { "display" : "Nearly every day", "code" : "Nearly every day", - "system" : "http://hl7.org/fhir/uv/sdc/CodeSystem/CSPHQ9" + "system" : "http://hl7.org/fhir/uv/sdc/CodeSystem/CSPHQ9", + "version" : "3.0.0" } ------------------------------------------------------------------------------------- {"code" : { @@ -1033,7 +1086,8 @@ v: { v: { "display" : "week", "code" : "wk", - "system" : "http://unitsofmeasure.org" + "system" : "http://unitsofmeasure.org", + "version" : "2.0.1" } ------------------------------------------------------------------------------------- {"code" : { @@ -1068,41 +1122,3 @@ v: { "class" : "UNKNOWN" } ------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://snomed.info/sct", - "code" : "371532007", - "display" : "Progress note" -}, "url": "http://fhir.ch/ig/ch-epr-term/ValueSet/DocumentEntry.typeCode", "version": "2.0.1", "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Progress report", - "code" : "371532007", - "system" : "http://snomed.info/sct", - "version" : "http://snomed.info/sct/900000000000207008/version/20230131", - "severity" : "warning", - "error" : "Wrong Display Name 'Progress note' for http://snomed.info/sct#371532007 - should be one of 3 choices: 'Progress report, \"Report of subsequent visit\", \"Progress report (record artifact)\"' for the language(s) '--' (from Tx-Server)" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://snomed.info/sct", - "code" : "371525003", - "display" : "Clinical procedure report" -}, "url": "http://fhir.ch/ig/ch-epr-term/ValueSet/DocumentEntry.classCode", "version": "2.0.4", "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Clinical procedure report", - "code" : "371525003", - "system" : "http://snomed.info/sct", - "version" : "http://snomed.info/sct/900000000000207008/version/20230131" -} -------------------------------------------------------------------------------------- diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/condition-clinical.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/condition-clinical.cache index 1c5363fda..bacff6342 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/condition-clinical.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/condition-clinical.cache @@ -12,7 +12,8 @@ v: { "display" : "Active", "code" : "active", - "system" : "http://terminology.hl7.org/CodeSystem/condition-clinical" + "system" : "http://terminology.hl7.org/CodeSystem/condition-clinical", + "version" : "2.0.0" } ------------------------------------------------------------------------------------- {"code" : { diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/cvx.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/cvx.cache index fffb0d7f9..8152b9dea 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/cvx.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/cvx.cache @@ -67,7 +67,8 @@ v: { v: { "display" : "SARS-COV-2 (COVID-19) vaccine, mRNA, spike protein, LNP, preservative free, 30 mcg/0.3mL dose", "code" : "208", - "system" : "http://hl7.org/fhir/sid/cvx" + "system" : "http://hl7.org/fhir/sid/cvx", + "version" : "20210406" } ------------------------------------------------------------------------------------- {"code" : { diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/http___nucc.org_provider-taxonomy.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/http___nucc.org_provider-taxonomy.cache index cf852c0a5..6daaee585 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/http___nucc.org_provider-taxonomy.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/http___nucc.org_provider-taxonomy.cache @@ -32,7 +32,8 @@ v: { v: { "display" : "General Practice Physician", "code" : "208D00000X", - "system" : "http://nucc.org/provider-taxonomy" + "system" : "http://nucc.org/provider-taxonomy", + "version" : "22.0" } ------------------------------------------------------------------------------------- {"code" : { diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/iso3166.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/iso3166.cache index bfb33e6b7..bd2ebe57d 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/iso3166.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/iso3166.cache @@ -30,7 +30,8 @@ v: { v: { "display" : "United States of America", "code" : "US", - "system" : "urn:iso:std:iso:3166" + "system" : "urn:iso:std:iso:3166", + "version" : "2018" } ------------------------------------------------------------------------------------- {"code" : { diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/loinc.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/loinc.cache index 49c660232..78192422a 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/loinc.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/loinc.cache @@ -75,6 +75,234 @@ v: { "error" : "Wrong Display Name 'Flow Rate' for http://loinc.org#3151-8 - should be one of 37 choices: 'Inhaled oxygen flow rate, \"Inhaled O2 flow rate\", \"O2\" (zh-CN), \"tO2\" (zh-CN), \"总氧\" (zh-CN), \"氧气 体积速率(单位时间)\" (zh-CN), \"单位时间内体积的变化速率\" (zh-CN), \"流量 可用数量表示的\" (zh-CN), \"定量性\" (zh-CN), \"数值型\" (zh-CN), \"数量型\" (zh-CN), \"连续数值型标尺 吸入气\" (zh-CN), \"吸入气体\" (zh-CN), \"吸入的空气 所吸入的氧\" (zh-CN), \"已吸入的氧气 时刻\" (zh-CN), \"随机\" (zh-CN), \"随意\" (zh-CN), \"瞬间 气 气体类 空气\" (zh-CN), \"Inhaled O2\" (pt-BR), \"vRate\" (pt-BR), \"Volume rate\" (pt-BR), \"Flow\" (pt-BR), \"Point in time\" (pt-BR), \"Random\" (pt-BR), \"IhG\" (pt-BR), \"Inhaled Gas\" (pt-BR), \"Inspired\" (pt-BR), \"Quantitative\" (pt-BR), \"QNT\" (pt-BR), \"Quant\" (pt-BR), \"Quan\" (pt-BR), \"Gases\" (pt-BR), \"Clinico Gas inalati Punto nel tempo (episodio) Tasso di Volume\" (it-IT), \"Количественный Объемная скорость Точка во времени\" (ru-RU), \"Момент\" (ru-RU), \"ingeademde O2\" (nl-NL), \"O2-Zufuhr\" (de-AT)' for the language(s) '--' (from Tx-Server)" } ------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://loinc.org", + "code" : "59408-5" +}, "url": "http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs--0", "version": "4.0.0", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Oxygen saturation in Arterial blood by Pulse oximetry", + "code" : "59408-5", + "system" : "http://loinc.org", + "version" : "2.74" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://loinc.org", + "code" : "2708-6" +}, "url": "http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs--0", "version": "4.0.0", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "severity" : "error", + "error" : "The provided code http://loinc.org#2708-6 is not in the value set 'http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs--0' (from Tx-Server)", + "class" : "UNKNOWN" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://loinc.org", + "code" : "2708-6" +}, "url": "http://hl7.org/fhir/ValueSet/observation-vitalsignresult--0", "version": "4.0.1", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Oxygen saturation in Arterial blood", + "code" : "2708-6", + "system" : "http://loinc.org", + "version" : "2.74" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://loinc.org", + "code" : "59408-5", + "display" : "O2 % BldC Oximetry" +}, "url": "http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs", "version": "4.0.0", "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Oxygen saturation in Arterial blood by Pulse oximetry", + "code" : "59408-5", + "system" : "http://loinc.org", + "version" : "2.74", + "severity" : "warning", + "error" : "Wrong Display Name 'O2 % BldC Oximetry' for http://loinc.org#59408-5 - should be one of 26 choices: 'Oxygen saturation in Arterial blood by Pulse oximetry, \"SaO2 % BldA PulseOx\", \"O2 SaO2\" (pl-PL), \"saturacja krwi tlenem\" (pl-PL), \"MFr O2\" (zh-CN), \"tO2\" (zh-CN), \"总氧\" (zh-CN), \"氧气 SaO2 动脉血 动脉血O2饱和度 可用数量表示的\" (zh-CN), \"定量性\" (zh-CN), \"数值型\" (zh-CN), \"数量型\" (zh-CN), \"连续数值型标尺 时刻\" (zh-CN), \"随机\" (zh-CN), \"随意\" (zh-CN), \"瞬间 肺部测量指标与呼吸机管理 脉搏血氧测定法\" (zh-CN), \"脉搏血氧定量\" (zh-CN), \"脉搏血氧测定\" (zh-CN), \"脉搏血氧仪 血氧测定法 饱和 饱和状态 饱和程度\" (zh-CN), \"O2-Sättigung\" (de-DE), \"Frazione di massa Gestione ventilazione polmonare Punto nel tempo (episodio) Sangue arterioso\" (it-IT), \"Oksijen doymuşluğu\" (tr-TR), \"Количественный Кровь артериальная Массовая доля Насыщение кислородом Оксигемометрия\" (ru-RU), \"Гемоксиметрия Точка во времени\" (ru-RU), \"Момент\" (ru-RU), \"zuurstofsaturatiemeting\" (nl-NL), \"O2 SatO2\" (fr-BE)' for the language(s) '--' (from Tx-Server)" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://loinc.org", + "code" : "2708-6", + "display" : "Oxygen saturation in Arterial blood" +}, "url": "http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs", "version": "4.0.0", "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Oxygen saturation in Arterial blood", + "code" : "2708-6", + "system" : "http://loinc.org", + "version" : "2.74" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://loinc.org", + "code" : "59408-5" +}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Oxygen saturation in Arterial blood by Pulse oximetry", + "code" : "59408-5", + "system" : "http://loinc.org", + "version" : "2.74" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://loinc.org", + "code" : "2708-6" +}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Oxygen saturation in Arterial blood", + "code" : "2708-6", + "system" : "http://loinc.org", + "version" : "2.74" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://loinc.org", + "code" : "3150-0" +}, "url": "http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs--0", "version": "4.0.0", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Inhaled oxygen concentration", + "code" : "3150-0", + "system" : "http://loinc.org", + "version" : "2.74" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://loinc.org", + "code" : "3150-0", + "display" : "Inhaled Oxygen Concentration" +}, "url": "http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs", "version": "4.0.0", "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Inhaled oxygen concentration", + "code" : "3150-0", + "system" : "http://loinc.org", + "version" : "2.74" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://loinc.org", + "code" : "3150-0" +}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Inhaled oxygen concentration", + "code" : "3150-0", + "system" : "http://loinc.org", + "version" : "2.74" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://loinc.org", + "code" : "3151-8" +}, "url": "http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs--0", "version": "4.0.0", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Inhaled oxygen flow rate", + "code" : "3151-8", + "system" : "http://loinc.org", + "version" : "2.74" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://loinc.org", + "code" : "3151-8", + "display" : "Flow Rate" +}, "url": "http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs", "version": "4.0.0", "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Inhaled oxygen flow rate", + "code" : "3151-8", + "system" : "http://loinc.org", + "version" : "2.74", + "severity" : "warning", + "error" : "Wrong Display Name 'Flow Rate' for http://loinc.org#3151-8 - should be one of 37 choices: 'Inhaled oxygen flow rate, \"Inhaled O2 flow rate\", \"O2\" (zh-CN), \"tO2\" (zh-CN), \"总氧\" (zh-CN), \"氧气 体积速率(单位时间)\" (zh-CN), \"单位时间内体积的变化速率\" (zh-CN), \"流量 可用数量表示的\" (zh-CN), \"定量性\" (zh-CN), \"数值型\" (zh-CN), \"数量型\" (zh-CN), \"连续数值型标尺 吸入气\" (zh-CN), \"吸入气体\" (zh-CN), \"吸入的空气 所吸入的氧\" (zh-CN), \"已吸入的氧气 时刻\" (zh-CN), \"随机\" (zh-CN), \"随意\" (zh-CN), \"瞬间 气 气体类 空气\" (zh-CN), \"Inhaled O2\" (pt-BR), \"vRate\" (pt-BR), \"Volume rate\" (pt-BR), \"Flow\" (pt-BR), \"Point in time\" (pt-BR), \"Random\" (pt-BR), \"IhG\" (pt-BR), \"Inhaled Gas\" (pt-BR), \"Inspired\" (pt-BR), \"Quantitative\" (pt-BR), \"QNT\" (pt-BR), \"Quant\" (pt-BR), \"Quan\" (pt-BR), \"Gases\" (pt-BR), \"Clinico Gas inalati Punto nel tempo (episodio) Tasso di Volume\" (it-IT), \"Количественный Объемная скорость Точка во времени\" (ru-RU), \"Момент\" (ru-RU), \"ingeademde O2\" (nl-NL), \"O2-Zufuhr\" (de-AT)' for the language(s) '--' (from Tx-Server)" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://loinc.org", + "code" : "3151-8" +}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Inhaled oxygen flow rate", + "code" : "3151-8", + "system" : "http://loinc.org", + "version" : "2.74" +} +------------------------------------------------------------------------------------- {"code" : { "system" : "http://loinc.org", "code" : "5792-7" @@ -105,7 +333,8 @@ v: { v: { "display" : "Laboratory report", "code" : "11502-2", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -155,7 +384,8 @@ v: { v: { "display" : "Patient summary Document", "code" : "60591-5", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -584,7 +814,8 @@ v: { v: { "display" : "Patient Consent", "code" : "59284-0", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -617,7 +848,8 @@ v: { v: { "display" : "INR in Capillary blood by Coagulation assay", "code" : "46418-0", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -668,7 +900,8 @@ v: { v: { "display" : "Creatinine [Moles/volume] in Serum, Plasma or Blood", "code" : "77140-2", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -719,7 +952,8 @@ v: { v: { "display" : "Cytotoxic percent reactive Ab [Presence] in Serum by Quick method", "code" : "4535-1", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -770,7 +1004,8 @@ v: { v: { "display" : "Body weight", "code" : "29463-7", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -821,7 +1056,8 @@ v: { v: { "display" : "Body height", "code" : "8302-2", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -872,7 +1108,8 @@ v: { v: { "display" : "Body mass index (BMI) [Ratio]", "code" : "39156-5", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -923,7 +1160,8 @@ v: { v: { "display" : "Blood pressure panel with all children optional", "code" : "85354-9", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -974,7 +1212,8 @@ v: { v: { "display" : "Systolic blood pressure", "code" : "8480-6", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -1025,7 +1264,8 @@ v: { v: { "display" : "Diastolic blood pressure", "code" : "8462-4", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -1220,7 +1460,8 @@ v: { v: { "display" : "Patient summary Document", "code" : "60591-5", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -1413,7 +1654,8 @@ v: { v: { "display" : "Medication summary Document", "code" : "56445-0", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -1482,7 +1724,8 @@ v: { v: { "display" : "Summary of episode note", "code" : "34133-9", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -1533,12 +1776,13 @@ v: { v: { "display" : "Summary of episode note", "code" : "34133-9", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { "system" : "http://loinc.org", - "version" : "2.73", + "version" : "2.74", "code" : "57852-6", "display" : "Problem list Narrative - Reported" }, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { @@ -1549,9 +1793,10 @@ v: { }] }}#### v: { - "severity" : "error", - "error" : "The CodeSystem http://loinc.org version 2.73 is unknown. Valid versions: [2.74]; The provided code http://loinc.org|2.73#57852-6 is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)", - "class" : "UNKNOWN" + "display" : "Problem list Narrative - Reported", + "code" : "57852-6", + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -1567,7 +1812,8 @@ v: { v: { "display" : "Discharge summary", "code" : "18842-5", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -1956,7 +2202,8 @@ v: { v: { "display" : "Genetic variant assessment", "code" : "69548-6", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -2001,7 +2248,8 @@ v: { v: { "display" : "Present", "code" : "LA9633-4", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -2058,7 +2306,8 @@ v: { v: { "display" : "Sequencing", "code" : "LA26398-0", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -2115,7 +2364,8 @@ v: { v: { "display" : "Somatic", "code" : "LA6684-0", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -2431,7 +2681,8 @@ v: { v: { "display" : "Medications", "code" : "LA20271-5", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -2503,7 +2754,8 @@ v: { v: { "display" : "Prescription or over-the-counter (including herbal supplements)", "code" : "LA20278-0", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -2555,7 +2807,8 @@ v: { v: { "display" : "Incorrect action (process failure or error) (e.g., such as administering overdose or incorrect medication)", "code" : "LA20275-6", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -2639,7 +2892,8 @@ v: { v: { "display" : "Incorrect patient", "code" : "LA20276-4", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -2703,7 +2957,8 @@ v: { v: { "display" : "Administering", "code" : "LA20296-2", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -2735,7 +2990,8 @@ v: { v: { "display" : "No", "code" : "LA32-8", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -2767,7 +3023,8 @@ v: { v: { "display" : "Yes", "code" : "LA33-6", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -2830,7 +3087,8 @@ v: { v: { "display" : "Yes", "code" : "LA33-6", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -2859,7 +3117,8 @@ v: { v: { "display" : "No", "code" : "LA32-8", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -2932,246 +3191,3 @@ v: { "version" : "2.74" } ------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "code" : "59408-5" -}, "url": "http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs--0", "version": "4.0.0", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Oxygen saturation in Arterial blood by Pulse oximetry", - "code" : "59408-5", - "system" : "http://loinc.org" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "code" : "2708-6" -}, "url": "http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs--0", "version": "4.0.0", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "severity" : "error", - "error" : "The provided code http://loinc.org#2708-6 is not in the value set 'http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs--0' (from Tx-Server)", - "class" : "UNKNOWN" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "code" : "2708-6" -}, "url": "http://hl7.org/fhir/ValueSet/observation-vitalsignresult--0", "version": "4.0.1", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Oxygen saturation in Arterial blood", - "code" : "2708-6", - "system" : "http://loinc.org" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "code" : "59408-5", - "display" : "O2 % BldC Oximetry" -}, "url": "http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs", "version": "4.0.0", "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Oxygen saturation in Arterial blood by Pulse oximetry", - "code" : "59408-5", - "system" : "http://loinc.org", - "version" : "2.74", - "severity" : "warning", - "error" : "Wrong Display Name 'O2 % BldC Oximetry' for http://loinc.org#59408-5 - should be one of 26 choices: 'Oxygen saturation in Arterial blood by Pulse oximetry, \"SaO2 % BldA PulseOx\", \"O2 SaO2\" (pl-PL), \"saturacja krwi tlenem\" (pl-PL), \"MFr O2\" (zh-CN), \"tO2\" (zh-CN), \"总氧\" (zh-CN), \"氧气 SaO2 动脉血 动脉血O2饱和度 可用数量表示的\" (zh-CN), \"定量性\" (zh-CN), \"数值型\" (zh-CN), \"数量型\" (zh-CN), \"连续数值型标尺 时刻\" (zh-CN), \"随机\" (zh-CN), \"随意\" (zh-CN), \"瞬间 肺部测量指标与呼吸机管理 脉搏血氧测定法\" (zh-CN), \"脉搏血氧定量\" (zh-CN), \"脉搏血氧测定\" (zh-CN), \"脉搏血氧仪 血氧测定法 饱和 饱和状态 饱和程度\" (zh-CN), \"O2-Sättigung\" (de-DE), \"Frazione di massa Gestione ventilazione polmonare Punto nel tempo (episodio) Sangue arterioso\" (it-IT), \"Oksijen doymuşluğu\" (tr-TR), \"Количественный Кровь артериальная Массовая доля Насыщение кислородом Оксигемометрия\" (ru-RU), \"Гемоксиметрия Точка во времени\" (ru-RU), \"Момент\" (ru-RU), \"zuurstofsaturatiemeting\" (nl-NL), \"O2 SatO2\" (fr-BE)' for the language(s) '--' (from Tx-Server)" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "code" : "2708-6", - "display" : "Oxygen saturation in Arterial blood" -}, "url": "http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs", "version": "4.0.0", "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Oxygen saturation in Arterial blood", - "code" : "2708-6", - "system" : "http://loinc.org", - "version" : "2.74" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "code" : "59408-5" -}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Oxygen saturation in Arterial blood by Pulse oximetry", - "code" : "59408-5", - "system" : "http://loinc.org", - "version" : "2.74" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "code" : "2708-6" -}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Oxygen saturation in Arterial blood", - "code" : "2708-6", - "system" : "http://loinc.org", - "version" : "2.74" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "code" : "3150-0" -}, "url": "http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs--0", "version": "4.0.0", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Inhaled oxygen concentration", - "code" : "3150-0", - "system" : "http://loinc.org" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "code" : "3150-0", - "display" : "Inhaled Oxygen Concentration" -}, "url": "http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs", "version": "4.0.0", "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Inhaled oxygen concentration", - "code" : "3150-0", - "system" : "http://loinc.org", - "version" : "2.74" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "code" : "3150-0" -}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Inhaled oxygen concentration", - "code" : "3150-0", - "system" : "http://loinc.org", - "version" : "2.74" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "code" : "3151-8" -}, "url": "http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs--0", "version": "4.0.0", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Inhaled oxygen flow rate", - "code" : "3151-8", - "system" : "http://loinc.org" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "code" : "3151-8", - "display" : "Flow Rate" -}, "url": "http://hl7.org/fhir/us/core/ValueSet/us-core-vital-signs", "version": "4.0.0", "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Inhaled oxygen flow rate", - "code" : "3151-8", - "system" : "http://loinc.org", - "version" : "2.74", - "severity" : "warning", - "error" : "Wrong Display Name 'Flow Rate' for http://loinc.org#3151-8 - should be one of 37 choices: 'Inhaled oxygen flow rate, \"Inhaled O2 flow rate\", \"O2\" (zh-CN), \"tO2\" (zh-CN), \"总氧\" (zh-CN), \"氧气 体积速率(单位时间)\" (zh-CN), \"单位时间内体积的变化速率\" (zh-CN), \"流量 可用数量表示的\" (zh-CN), \"定量性\" (zh-CN), \"数值型\" (zh-CN), \"数量型\" (zh-CN), \"连续数值型标尺 吸入气\" (zh-CN), \"吸入气体\" (zh-CN), \"吸入的空气 所吸入的氧\" (zh-CN), \"已吸入的氧气 时刻\" (zh-CN), \"随机\" (zh-CN), \"随意\" (zh-CN), \"瞬间 气 气体类 空气\" (zh-CN), \"Inhaled O2\" (pt-BR), \"vRate\" (pt-BR), \"Volume rate\" (pt-BR), \"Flow\" (pt-BR), \"Point in time\" (pt-BR), \"Random\" (pt-BR), \"IhG\" (pt-BR), \"Inhaled Gas\" (pt-BR), \"Inspired\" (pt-BR), \"Quantitative\" (pt-BR), \"QNT\" (pt-BR), \"Quant\" (pt-BR), \"Quan\" (pt-BR), \"Gases\" (pt-BR), \"Clinico Gas inalati Punto nel tempo (episodio) Tasso di Volume\" (it-IT), \"Количественный Объемная скорость Точка во времени\" (ru-RU), \"Момент\" (ru-RU), \"ingeademde O2\" (nl-NL), \"O2-Zufuhr\" (de-AT)' for the language(s) '--' (from Tx-Server)" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "code" : "3151-8" -}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Inhaled oxygen flow rate", - "code" : "3151-8", - "system" : "http://loinc.org", - "version" : "2.74" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "version" : "2.74", - "code" : "57852-6", - "display" : "Problem list Narrative - Reported" -}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Problem list Narrative - Reported", - "code" : "57852-6", - "system" : "http://loinc.org", - "version" : "2.74" -} -------------------------------------------------------------------------------------- diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/snomed.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/snomed.cache index f6c711ba0..160ff2dd7 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/snomed.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/snomed.cache @@ -66,7 +66,8 @@ v: { v: { "display" : "Mild", "code" : "255604002", - "system" : "http://snomed.info/sct" + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20230131" } ------------------------------------------------------------------------------------- {"code" : { @@ -135,7 +136,8 @@ v: { v: { "display" : "Moderate", "code" : "6736007", - "system" : "http://snomed.info/sct" + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20230131" } ------------------------------------------------------------------------------------- {"code" : { @@ -674,7 +676,8 @@ v: { v: { "display" : "Blood group A (finding)", "code" : "112144000", - "system" : "http://snomed.info/sct" + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20230131" } ------------------------------------------------------------------------------------- {"code" : { @@ -707,7 +710,8 @@ v: { v: { "display" : "Allergy record (record artifact)", "code" : "722446000", - "system" : "http://snomed.info/sct" + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20230131" } ------------------------------------------------------------------------------------- {"code" : { @@ -740,7 +744,8 @@ v: { v: { "display" : "Report of clinical encounter (record artifact)", "code" : "371531000", - "system" : "http://snomed.info/sct" + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20230131" } ------------------------------------------------------------------------------------- {"code" : { @@ -773,7 +778,8 @@ v: { v: { "display" : "Laboratory report (record artifact)", "code" : "4241000179101", - "system" : "http://snomed.info/sct" + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20230131" } ------------------------------------------------------------------------------------- {"code" : { @@ -806,7 +812,8 @@ v: { v: { "display" : "Summary clinical document (record artifact)", "code" : "422735006", - "system" : "http://snomed.info/sct" + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20230131" } ------------------------------------------------------------------------------------- {"code" : { @@ -915,6 +922,74 @@ v: { "version" : "http://snomed.info/sct/900000000000207008/version/20230131" } ------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://snomed.info/sct", + "code" : "371532007" +}, "url": "http://fhir.ch/ig/ch-epr-term/ValueSet/DocumentEntry.typeCode--0", "version": "2.0.1", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Progress report (record artifact)", + "code" : "371532007", + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20230131" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://snomed.info/sct", + "code" : "371532007" +}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Progress report", + "code" : "371532007", + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20230131" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://snomed.info/sct", + "code" : "371525003" +}, "url": "http://fhir.ch/ig/ch-epr-term/ValueSet/DocumentEntry.classCode--0", "version": "2.0.4", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Clinical procedure report (record artifact)", + "code" : "371525003", + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20230131" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://snomed.info/sct", + "code" : "371525003" +}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "Clinical procedure report", + "code" : "371525003", + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20230131" +} +------------------------------------------------------------------------------------- {"code" : { "system" : "http://snomed.info/sct", "code" : "419891008", @@ -1055,7 +1130,8 @@ v: { v: { "display" : "Old age (qualifier value)", "code" : "271872005", - "system" : "http://snomed.info/sct" + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20210731" } ------------------------------------------------------------------------------------- {"code" : { @@ -2058,69 +2134,3 @@ v: { "class" : "UNKNOWN" } ------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://snomed.info/sct", - "code" : "371532007" -}, "url": "http://fhir.ch/ig/ch-epr-term/ValueSet/DocumentEntry.typeCode--0", "version": "2.0.1", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Progress report (record artifact)", - "code" : "371532007", - "system" : "http://snomed.info/sct" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://snomed.info/sct", - "code" : "371532007" -}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Progress report", - "code" : "371532007", - "system" : "http://snomed.info/sct", - "version" : "http://snomed.info/sct/900000000000207008/version/20230131" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://snomed.info/sct", - "code" : "371525003" -}, "url": "http://fhir.ch/ig/ch-epr-term/ValueSet/DocumentEntry.classCode--0", "version": "2.0.4", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Clinical procedure report (record artifact)", - "code" : "371525003", - "system" : "http://snomed.info/sct" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://snomed.info/sct", - "code" : "371525003" -}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Clinical procedure report", - "code" : "371525003", - "system" : "http://snomed.info/sct", - "version" : "http://snomed.info/sct/900000000000207008/version/20230131" -} -------------------------------------------------------------------------------------- diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/ucum.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/ucum.cache index d2ee5bc60..c25d2d1f4 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/ucum.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.0.1/ucum.cache @@ -33,6 +33,39 @@ v: { "version" : "2.0.1" } ------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://unitsofmeasure.org", + "code" : "%" +}, "url": "http://hl7.org/fhir/ValueSet/ucum-vitals-common--0", "version": "4.0.1", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "display" : "percent", + "code" : "%", + "system" : "http://unitsofmeasure.org", + "version" : "2.0.1" +} +------------------------------------------------------------------------------------- +{"code" : { + "system" : "http://unitsofmeasure.org", + "code" : "L/min" +}, "url": "http://hl7.org/fhir/ValueSet/ucum-vitals-common--0", "version": "4.0.1", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { + "resourceType" : "Parameters", + "parameter" : [{ + "name" : "profile-url", + "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" + }] +}}#### +v: { + "severity" : "error", + "error" : "The provided code http://unitsofmeasure.org#L/min is not in the value set 'http://hl7.org/fhir/ValueSet/ucum-vitals-common--0' (from Tx-Server)", + "class" : "UNKNOWN" +} +------------------------------------------------------------------------------------- {"code" : { "system" : "http://unitsofmeasure.org", "code" : "cm" @@ -181,7 +214,8 @@ v: { v: { "display" : "millimeter of mercury", "code" : "mm[Hg]", - "system" : "http://unitsofmeasure.org" + "system" : "http://unitsofmeasure.org", + "version" : "2.0.1" } ------------------------------------------------------------------------------------- {"code" : { @@ -386,35 +420,3 @@ v: { "version" : "2.0.1" } ------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://unitsofmeasure.org", - "code" : "%" -}, "url": "http://hl7.org/fhir/ValueSet/ucum-vitals-common--0", "version": "4.0.1", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "percent", - "code" : "%", - "system" : "http://unitsofmeasure.org" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://unitsofmeasure.org", - "code" : "L/min" -}, "url": "http://hl7.org/fhir/ValueSet/ucum-vitals-common--0", "version": "4.0.1", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "severity" : "error", - "error" : "The provided code http://unitsofmeasure.org#L/min is not in the value set 'http://hl7.org/fhir/ValueSet/ucum-vitals-common--0' (from Tx-Server)", - "class" : "UNKNOWN" -} -------------------------------------------------------------------------------------- diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.3.0/.capabilityStatement.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.3.0/.capabilityStatement.cache index eec3774fe..20acc8947 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.3.0/.capabilityStatement.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.3.0/.capabilityStatement.cache @@ -12,7 +12,7 @@ "version" : "4.0.1-2.1.0", "name" : "FHIR Reference Server Conformance Statement", "status" : "active", - "date" : "2023-05-02T06:12:57.010Z", + "date" : "2023-05-06T00:24:19.944Z", "contact" : [{ "telecom" : [{ "system" : "other", diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.3.0/.terminologyCapabilities.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.3.0/.terminologyCapabilities.cache index 8c7a9bcdf..145dcf862 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.3.0/.terminologyCapabilities.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/4.3.0/.terminologyCapabilities.cache @@ -5,7 +5,7 @@ "version" : "2.0.0", "name" : "FHIR Reference Server Teminology Capability Statement", "status" : "active", - "date" : "2023-05-02T06:12:57.020Z", + "date" : "2023-05-06T00:24:19.953Z", "contact" : [{ "telecom" : [{ "system" : "other", diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/.capabilityStatement.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/.capabilityStatement.cache index 0887d6057..654d9a716 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/.capabilityStatement.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/.capabilityStatement.cache @@ -12,7 +12,7 @@ "version" : "4.0.1-2.1.0", "name" : "FHIR Reference Server Conformance Statement", "status" : "active", - "date" : "2023-05-02T06:13:01.479Z", + "date" : "2023-05-06T00:24:23.634Z", "contact" : [{ "telecom" : [{ "system" : "other", diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/.terminologyCapabilities.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/.terminologyCapabilities.cache index 72402084b..b2844014f 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/.terminologyCapabilities.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/.terminologyCapabilities.cache @@ -5,7 +5,7 @@ "version" : "2.0.0", "name" : "FHIR Reference Server Teminology Capability Statement", "status" : "active", - "date" : "2023-05-02T06:13:01.490Z", + "date" : "2023-05-06T00:24:23.641Z", "contact" : [{ "telecom" : [{ "system" : "other", diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/loinc.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/loinc.cache index d1e032d38..5f2d3023e 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/loinc.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/loinc.cache @@ -66,7 +66,8 @@ v: { v: { "display" : "Blood pressure panel with all children optional", "code" : "85354-9", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -117,7 +118,8 @@ v: { v: { "display" : "Systolic blood pressure", "code" : "8480-6", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -168,7 +170,8 @@ v: { v: { "display" : "Diastolic blood pressure", "code" : "8462-4", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -219,12 +222,13 @@ v: { v: { "display" : "Medication summary Document", "code" : "56445-0", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { "system" : "http://loinc.org", - "version" : "2.73", + "version" : "2.74", "code" : "56445-0", "display" : "Medication summary Doc" }, "url": "http://hl7.org/fhir/ValueSet/doc-typecodes", "version": "5.0.0", "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "versionFlexible":"false", "profile": { @@ -235,14 +239,15 @@ v: { }] }}#### v: { - "severity" : "error", - "error" : "The CodeSystem http://loinc.org version 2.73 is unknown. Valid versions: [2.74]; The provided code http://loinc.org|2.73#56445-0 is not in the value set 'http://hl7.org/fhir/ValueSet/doc-typecodes' (from Tx-Server)", - "class" : "UNKNOWN" + "display" : "Medication summary Document", + "code" : "56445-0", + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { "system" : "http://loinc.org", - "version" : "2.73", + "version" : "2.74", "code" : "56445-0" }, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { "resourceType" : "Parameters", @@ -252,14 +257,15 @@ v: { }] }}#### v: { - "severity" : "error", - "error" : "The CodeSystem http://loinc.org version 2.73 is unknown. Valid versions: [2.74]; The provided code http://loinc.org|2.73#56445-0 is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)", - "class" : "UNKNOWN" + "display" : "Medication summary Document", + "code" : "56445-0", + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { "system" : "http://loinc.org", - "version" : "2.73", + "version" : "2.74", "code" : "48765-2", "display" : "Allergies and adverse reactions" }, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { @@ -270,9 +276,12 @@ v: { }] }}#### v: { - "severity" : "error", - "error" : "The CodeSystem http://loinc.org version 2.73 is unknown. Valid versions: [2.74]; The provided code http://loinc.org|2.73#48765-2 is not in the value set 'http://hl7.org/fhir/ValueSet/@all' (from Tx-Server)", - "class" : "UNKNOWN" + "display" : "Allergies and adverse reactions Document", + "code" : "48765-2", + "system" : "http://loinc.org", + "version" : "2.74", + "severity" : "warning", + "error" : "Wrong Display Name 'Allergies and adverse reactions' for http://loinc.org#48765-2 - should be one of 28 choices: 'Allergies and adverse reactions Document, \"Allergies &or adverse reactions Doc\", \"临床文档型\" (zh-CN), \"临床文档\" (zh-CN), \"文档\" (zh-CN), \"文书\" (zh-CN), \"医疗文书\" (zh-CN), \"临床医疗文书 医疗服务对象\" (zh-CN), \"客户\" (zh-CN), \"病人\" (zh-CN), \"病患\" (zh-CN), \"病号\" (zh-CN), \"超系统 - 病人 发现是一个原子型临床观察指标,并不是作为印象的概括陈述。体格检查、病史、系统检查及其他此类观察指标的属性均为发现。它们的标尺对于编码型发现可能是名义型,而对于叙述型文本之中所报告的发现,则可能是叙述型。\" (zh-CN), \"发现物\" (zh-CN), \"所见\" (zh-CN), \"结果\" (zh-CN), \"结论 变态反应与不良反应 文档.其他\" (zh-CN), \"杂项类文档\" (zh-CN), \"其他文档 时刻\" (zh-CN), \"随机\" (zh-CN), \"随意\" (zh-CN), \"瞬间 杂项\" (zh-CN), \"杂项类\" (zh-CN), \"杂项试验 过敏反应\" (zh-CN), \"过敏\" (zh-CN), \"Allergie e reazioni avverse Documentazione miscellanea Miscellanea Osservazione paziente Punto nel tempo (episodio)\" (it-IT), \"Документ Точка во времени\" (ru-RU), \"Момент\" (ru-RU)' for the language(s) '--' (from Tx-Server)" } ------------------------------------------------------------------------------------- {"code" : { @@ -288,7 +297,8 @@ v: { v: { "display" : "Medication summary Document", "code" : "56445-0", - "system" : "http://loinc.org" + "system" : "http://loinc.org", + "version" : "2.74" } ------------------------------------------------------------------------------------- {"code" : { @@ -497,64 +507,6 @@ v: { "error" : "Wrong Display Name 'Triglyceride [Moles/​volume] in Serum or Plasma' for http://loinc.org#35217-9 - should be one of 50 choices: 'Triglyceride [Mass or Moles/volume] in Serum or Plasma, \"Trigl SerPl-msCnc\", \"TG\" (zh-CN), \"Trigly\" (zh-CN), \"甘油三脂\" (zh-CN), \"甘油三酸酯\" (zh-CN), \"三酸甘油酯\" (zh-CN), \"甘油三酸脂\" (zh-CN), \"三酸甘油脂 化学\" (zh-CN), \"化学检验项目\" (zh-CN), \"化学检验项目类\" (zh-CN), \"化学类\" (zh-CN), \"化学试验\" (zh-CN), \"非刺激耐受型化学检验项目\" (zh-CN), \"非刺激耐受型化学检验项目类\" (zh-CN), \"非刺激耐受型化学试验\" (zh-CN), \"非刺激耐受型化学试验类 可用数量表示的\" (zh-CN), \"定量性\" (zh-CN), \"数值型\" (zh-CN), \"数量型\" (zh-CN), \"连续数值型标尺 时刻\" (zh-CN), \"随机\" (zh-CN), \"随意\" (zh-CN), \"瞬间 血清或血浆 质量或摩尔浓度\" (zh-CN), \"质量或摩尔浓度(单位体积)\" (zh-CN), \"质量或物质的量浓度(单位体积)\" (zh-CN), \"Juhuslik Kvantitatiivne Plasma Seerum Seerum või plasma\" (et-EE), \"Trigl\" (pt-BR), \"Triglycrides\" (pt-BR), \"Trig\" (pt-BR), \"Triglycerides\" (pt-BR), \"Level\" (pt-BR), \"Point in time\" (pt-BR), \"Random\" (pt-BR), \"SerPl\" (pt-BR), \"SerPlas\" (pt-BR), \"SerP\" (pt-BR), \"Serum\" (pt-BR), \"SR\" (pt-BR), \"Plasma\" (pt-BR), \"Pl\" (pt-BR), \"Plsm\" (pt-BR), \"Quantitative\" (pt-BR), \"QNT\" (pt-BR), \"Quant\" (pt-BR), \"Quan\" (pt-BR), \"Chemistry\" (pt-BR), \"Chimica Concentrazione Sostanza o Massa Plasma Punto nel tempo (episodio) Siero Siero o Plasma\" (it-IT), \"Количественный Массовая или Молярная Концентрация Плазма Сыворотка Сыворотка или Плазма Точка во времени\" (ru-RU), \"Момент\" (ru-RU)' for the language(s) '--' (from Tx-Server)" } ------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "version" : "2.74", - "code" : "56445-0", - "display" : "Medication summary Doc" -}, "url": "http://hl7.org/fhir/ValueSet/doc-typecodes", "version": "5.0.0", "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Medication summary Document", - "code" : "56445-0", - "system" : "http://loinc.org", - "version" : "2.74" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "version" : "2.74", - "code" : "56445-0" -}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Medication summary Document", - "code" : "56445-0", - "system" : "http://loinc.org", - "version" : "2.74" -} -------------------------------------------------------------------------------------- -{"code" : { - "system" : "http://loinc.org", - "version" : "2.74", - "code" : "48765-2", - "display" : "Allergies and adverse reactions" -}, "valueSet" :null, "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false", "profile": { - "resourceType" : "Parameters", - "parameter" : [{ - "name" : "profile-url", - "valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891" - }] -}}#### -v: { - "display" : "Allergies and adverse reactions Document", - "code" : "48765-2", - "system" : "http://loinc.org", - "version" : "2.74", - "severity" : "warning", - "error" : "Wrong Display Name 'Allergies and adverse reactions' for http://loinc.org#48765-2 - should be one of 28 choices: 'Allergies and adverse reactions Document, \"Allergies &or adverse reactions Doc\", \"临床文档型\" (zh-CN), \"临床文档\" (zh-CN), \"文档\" (zh-CN), \"文书\" (zh-CN), \"医疗文书\" (zh-CN), \"临床医疗文书 医疗服务对象\" (zh-CN), \"客户\" (zh-CN), \"病人\" (zh-CN), \"病患\" (zh-CN), \"病号\" (zh-CN), \"超系统 - 病人 发现是一个原子型临床观察指标,并不是作为印象的概括陈述。体格检查、病史、系统检查及其他此类观察指标的属性均为发现。它们的标尺对于编码型发现可能是名义型,而对于叙述型文本之中所报告的发现,则可能是叙述型。\" (zh-CN), \"发现物\" (zh-CN), \"所见\" (zh-CN), \"结果\" (zh-CN), \"结论 变态反应与不良反应 文档.其他\" (zh-CN), \"杂项类文档\" (zh-CN), \"其他文档 时刻\" (zh-CN), \"随机\" (zh-CN), \"随意\" (zh-CN), \"瞬间 杂项\" (zh-CN), \"杂项类\" (zh-CN), \"杂项试验 过敏反应\" (zh-CN), \"过敏\" (zh-CN), \"Allergie e reazioni avverse Documentazione miscellanea Miscellanea Osservazione paziente Punto nel tempo (episodio)\" (it-IT), \"Документ Точка во времени\" (ru-RU), \"Момент\" (ru-RU)' for the language(s) '--' (from Tx-Server)" -} -------------------------------------------------------------------------------------- {"code" : { "system" : "http://loinc.org", "code" : "29463-7", diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/snomed.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/snomed.cache index eed96ab47..798657e67 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/snomed.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/snomed.cache @@ -141,7 +141,8 @@ v: { v: { "display" : "Anxiety disorder of childhood OR adolescence", "code" : "109006", - "system" : "http://snomed.info/sct" + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20230131" } ------------------------------------------------------------------------------------- {"code" : { @@ -251,7 +252,8 @@ v: { v: { "display" : "Posterior carpal region", "code" : "106004", - "system" : "http://snomed.info/sct" + "system" : "http://snomed.info/sct", + "version" : "http://snomed.info/sct/900000000000207008/version/20230131" } ------------------------------------------------------------------------------------- {"code" : { diff --git a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/ucum.cache b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/ucum.cache index 35fa46925..64020aaa3 100644 --- a/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/ucum.cache +++ b/org.hl7.fhir.validation/src/test/resources/txCache/org.hl7.fhir.validation/5.0.0/ucum.cache @@ -29,7 +29,8 @@ v: { v: { "display" : "millimeter of mercury", "code" : "mm[Hg]", - "system" : "http://unitsofmeasure.org" + "system" : "http://unitsofmeasure.org", + "version" : "2.0.1" } ------------------------------------------------------------------------------------- {"code" : { From 24b0cc2ee414fcfc6b85c96f702b775fd09ad070 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Sat, 6 May 2023 00:55:50 -0500 Subject: [PATCH 3/8] Fixes for kindling --- .../client/TerminologyClientContext.java | 16 ++++++++-------- .../terminologies/providers/URICodeSystem.java | 11 +++++------ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/client/TerminologyClientContext.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/client/TerminologyClientContext.java index 0e20b83fd..9133fe9be 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/client/TerminologyClientContext.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/client/TerminologyClientContext.java @@ -10,7 +10,7 @@ public class TerminologyClientContext { private boolean isTxCaching; private int serverQueryCount = 0; private final Set cached = new HashSet<>(); -// protected String tsServer; + protected String server; private ITerminologyClient client; private TerminologyCapabilities txcaps; @@ -42,13 +42,13 @@ public class TerminologyClientContext { return cached; } -// public String getTsServer() { -// return tsServer; -// } -// -// public void setTsServer(String tsServer) { -// this.tsServer = tsServer; -// } + public String getServer() { + return server; + } + + public void setServer(String server) { + this.server = server; + } public ITerminologyClient getClient() { return client; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/providers/URICodeSystem.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/providers/URICodeSystem.java index fe073698e..8deb9897e 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/providers/URICodeSystem.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/providers/URICodeSystem.java @@ -8,12 +8,11 @@ public class URICodeSystem extends SpecialCodeSystem { @Override public ConceptDefinitionComponent findConcept(Coding code) { - throw new Error("This is used"); -// if (Utilities.isAbsoluteUrl(code.getCode())) { -// return new ConceptDefinitionComponent(code.getCode()); -// } else { -// return null; -// } + if (Utilities.isAbsoluteUrl(code.getCode())) { + return new ConceptDefinitionComponent(code.getCode()); + } else { + return null; + } } } \ No newline at end of file From d35b881cf16287ad058b74bdc9e05cdee312bc50 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Sat, 6 May 2023 09:55:36 -0500 Subject: [PATCH 4/8] Fix FHIRPath split function --- .../src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java | 4 +++- .../java/org/hl7/fhir/utilities/settings/FhirSettings.java | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java index 3e6797757..2d805a672 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/FHIRPathEngine.java @@ -16,6 +16,7 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.commons.lang3.StringUtils; import org.fhir.ucum.Decimal; import org.fhir.ucum.Pair; import org.fhir.ucum.UcumException; @@ -4224,7 +4225,8 @@ public class FHIRPathEngine { List result = new ArrayList(); if (focus.size() == 1) { String cnt = focus.get(0).primitiveValue(); - for (String s : cnt.split(param)) { + String[] sl = Pattern.compile(param, Pattern.LITERAL).split(cnt); + for (String s : sl) { result.add(new StringType(s)); } } diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/settings/FhirSettings.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/settings/FhirSettings.java index 4d7b8130a..ca2aaa0df 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/settings/FhirSettings.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/settings/FhirSettings.java @@ -52,7 +52,7 @@ public class FhirSettings { getInstance(); return instance.fhirSettings.getApiKeys() != null ? instance.fhirSettings.getApiKeys().get(key) != null - : null; + : false; } public static String getNpmPath() { From c5f5689714f4f3aefaa036be7bc4b51d074d6093 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Sun, 7 May 2023 07:14:44 -0500 Subject: [PATCH 5/8] fixes for R5 redirector --- .../hl7/fhir/utilities/npm/NpmPackage.java | 2 +- .../hl7/fhir/utilities/xhtml/XhtmlNode.java | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java index b5b3679da..70a46f406 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/npm/NpmPackage.java @@ -580,7 +580,7 @@ public class NpmPackage { for (NpmPackageFolder folder : folders.values()) { if (folder.index != null) { for (JsonObject fi : folder.index.getJsonObjects("files")) { - if (Utilities.existsInList(fi.asString("resourceType"), types)) { + if (Utilities.existsInList(fi.asString("resourceType"), types) || types.isEmpty()) { res.add(new PackageResourceInformation(folder.folder == null ? "@"+folder.getName() : folder.folder.getAbsolutePath(), fi)); } } diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java index f4bad9f07..e08257375 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java @@ -837,4 +837,33 @@ public class XhtmlNode extends XhtmlFluent implements IBaseXhtml { return false; } + + public XhtmlNode getElementById(String id) { + if (id.equals(getAttribute("id"))) { + return this; + } + if (childNodes != null) { + for (XhtmlNode x : childNodes) { + XhtmlNode r = x.getElementById(id); + if (r != null) { + return r; + } + } + } + return null; + } + + + public List getChildren(String name) { + List res = new ArrayList<>(); + XhtmlNode x = getFirstElement(); + while (x != null) { + if (name.equals(x.getName())) { + res.add(x); + } + x = getNextElement(x); + } + return res; + } + } \ No newline at end of file From fa1e0c5a7127b64f25a0577c766e1821067aad53 Mon Sep 17 00:00:00 2001 From: Sean McIlvenna Date: Sun, 7 May 2023 10:03:12 -0500 Subject: [PATCH 6/8] Changes based on performance profiling validation of a large Bundle of 32 patients Reduced execution time from >2 minutes to 36 seconds --- .../org/hl7/fhir/r5/elementmodel/Element.java | 12 +++------- .../java/org/hl7/fhir/r5/model/Element.java | 24 +++++++++++++++---- .../org/hl7/fhir/r5/model/PrimitiveType.java | 11 +++++---- .../org/hl7/fhir/r5/utils/TypesUtilities.java | 6 +++-- 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java index 3937253a3..24b680eb7 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java @@ -32,14 +32,7 @@ import java.io.PrintStream; */ -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import org.apache.commons.lang3.Validate; import org.hl7.fhir.exceptions.FHIRException; @@ -77,6 +70,7 @@ import org.hl7.fhir.utilities.xhtml.XhtmlNode; * */ public class Element extends Base { + private static final HashSet extensionList = new HashSet<>(Arrays.asList("extension", "modifierExtension")); public enum SpecialElement { CONTAINED, BUNDLE_ENTRY, BUNDLE_OUTCOME, BUNDLE_ISSUES, PARAMETER, LOGICAL; @@ -1070,7 +1064,7 @@ public class Element extends Base { public Element getExtension(String url) { if (children != null) { for (Element child : children) { - if (Utilities.existsInList(child.getName(), "extension", "modifierExtension")) { + if (extensionList.contains(child.getName())) { String u = child.getChildValue("url"); if (url.equals(u)) { return child; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Element.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Element.java index 07c81b5d1..b93f37abb 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Element.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Element.java @@ -301,7 +301,9 @@ public abstract class Element extends Base implements IBaseHasExtensions, IBaseE } public boolean isEmpty() { - return super.isEmpty() && ca.uhn.fhir.util.ElementUtil.isEmpty(id, extension); + boolean idIsEmpty = id == null || id.isEmpty(); + boolean extensionIsEmpty = extension == null || extension.size() == 0; + return super.isEmpty() && idIsEmpty && extensionIsEmpty; } // Manual code (from Configuration.txt): @@ -393,8 +395,12 @@ public abstract class Element extends Base implements IBaseHasExtensions, IBaseE * @return an unmodifiable list containing all extensions on this element which match the given URL */ public List getExtensionsByUrl(String theUrl) { - org.apache.commons.lang3.Validate.notBlank(theUrl, "theUrl must not be blank or null"); - ArrayList retVal = new ArrayList(); + if (theUrl == null) { + throw new NullPointerException("theUrl must not be null"); + } else if (theUrl.length() == 0) { + throw new IllegalArgumentException("theUrl must not be empty"); + } + ArrayList retVal = new ArrayList<>(); for (Extension next : getExtension()) { if (theUrl.equals(next.getUrl())) { retVal.add(next); @@ -411,7 +417,17 @@ public abstract class Element extends Base implements IBaseHasExtensions, IBaseE * @param theUrl The URL. Must not be blank or null. */ public boolean hasExtension(String theUrl) { - return !getExtensionsByUrl(theUrl).isEmpty(); + if (extension == null || extension.size() == 0) { + return false; + } + + for (Extension ext : extension) { + if (theUrl.equals(ext.getUrl())) { + return true; + } + } + + return false; } /** diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/PrimitiveType.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/PrimitiveType.java index 49ac41018..fac70c899 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/PrimitiveType.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/PrimitiveType.java @@ -127,11 +127,12 @@ public abstract class PrimitiveType extends DataType implements IPrimitiveTyp public boolean hasValue() { return !StringUtils.isBlank(getValueAsString()); } - - @Override - public boolean isEmpty() { - return super.isEmpty() && StringUtils.isBlank(getValueAsString()); - } + + @Override + public boolean isEmpty() { + String value = getValueAsString(); + return !super.isEmpty() || (value != null && value.length() > 0); + } public boolean isPrimitive() { return true; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/TypesUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/TypesUtilities.java index 928e74f41..9a98a5f75 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/TypesUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/TypesUtilities.java @@ -32,13 +32,15 @@ package org.hl7.fhir.r5.utils; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; -import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.VersionUtilities; public class TypesUtilities { + private static final HashSet primitiveTypes = new HashSet<>(Arrays.asList("boolean", "integer", "integer64", "string", "decimal", "uri", "url", "canonical", "base64Binary", "instant", "date", "dateTime", "time", "code", "oid", "id", "uuid", "markdown", "unsignedInt", "positiveInt", "xhtml")); public enum TypeClassification { PRIMITIVE, DATATYPE, METADATATYPE, SPECIAL; @@ -170,6 +172,6 @@ public class TypesUtilities { } public static boolean isPrimitive(String code) { - return Utilities.existsInList(code, "boolean", "integer", "integer64", "string", "decimal", "uri", "url", "canonical", "base64Binary", "instant", "date", "dateTime", "time", "code", "oid", "id", "uuid", "markdown", "unsignedInt", "positiveInt", "xhtml"); + return primitiveTypes.contains(code); } } \ No newline at end of file From ae13abfc2a9134bb30b3922549fc6bf59d22ab3a Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Sun, 7 May 2023 11:04:04 -0500 Subject: [PATCH 7/8] performance related changes --- .../JavaExtensionsFactoryGenerator.java | 2 +- .../hl7/fhir/r4b/renderers/DataRenderer.java | 2 +- .../conformance/profile/ProfileUtilities.java | 4 +- .../org/hl7/fhir/r5/elementmodel/Element.java | 2 +- .../fhir/r5/model/StructureDefinition.java | 7 ++- .../fhir/r5/profilemodel/PEDefinition.java | 2 +- .../profilemodel/PEDefinitionExtension.java | 4 +- .../hl7/fhir/r5/renderers/DataRenderer.java | 2 +- .../validation/ValueSetValidator.java | 9 ++- .../hl7/fhir/r5/utils/BuildExtensions.java | 27 +++++--- .../hl7/fhir/r5/utils/ToolingExtensions.java | 29 +++++---- .../hl7/fhir/utilities/VersionUtilities.java | 8 ++- .../hl7/fhir/validation/BaseValidator.java | 2 +- .../instance/InstanceValidator.java | 61 +++++++++++-------- .../instance/SpecialExtensions.java | 24 +++++--- .../instance/type/StructureMapValidator.java | 2 +- 16 files changed, 110 insertions(+), 77 deletions(-) diff --git a/org.hl7.fhir.core.generator/src/org/hl7/fhir/core/generator/codegen/extensions/JavaExtensionsFactoryGenerator.java b/org.hl7.fhir.core.generator/src/org/hl7/fhir/core/generator/codegen/extensions/JavaExtensionsFactoryGenerator.java index 3c59a38c9..f932e2b2f 100644 --- a/org.hl7.fhir.core.generator/src/org/hl7/fhir/core/generator/codegen/extensions/JavaExtensionsFactoryGenerator.java +++ b/org.hl7.fhir.core.generator/src/org/hl7/fhir/core/generator/codegen/extensions/JavaExtensionsFactoryGenerator.java @@ -98,7 +98,7 @@ public class JavaExtensionsFactoryGenerator extends JavaBaseGenerator { ElementDefinition edRoot = sd.getSnapshot().getElementFirstRep(); boolean repeats = !edRoot.getMax().equals("1"); String verb = repeats ? "add" : "set"; - ElementDefinition edValue = sd.getSnapshot().getElementByPath("Extension.value[x]"); + ElementDefinition edValue = sd.getSnapshot().getElementByPath("Extension.value[x]", false); List types = analyseTypes(edValue); if (types.size() > 5) { src.append(" public static Extension make"+name+"(DataType value) {\r\n"); diff --git a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/renderers/DataRenderer.java b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/renderers/DataRenderer.java index 56cd3c6bd..3610c2fa7 100644 --- a/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/renderers/DataRenderer.java +++ b/org.hl7.fhir.r4b/src/main/java/org/hl7/fhir/r4b/renderers/DataRenderer.java @@ -338,7 +338,7 @@ public class DataRenderer extends Renderer { StructureDefinition sd = getContext().getWorker().fetchTypeDefinition(t); if (sd == null) return false; - if (Utilities.existsInList(t, VersionUtilities.getCanonicalResourceNames(getContext().getWorker().getVersion()))) { + if (VersionUtilities.getCanonicalResourceNames(getContext().getWorker().getVersion()).contains(t)) { return true; } if (Utilities.existsInList(t, diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java index b3e384870..9d8809b5d 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java @@ -3969,12 +3969,12 @@ public class ProfileUtilities extends TranslatingUtilities { if (!isExtensionDefinition(sd)) { return false; } - ElementDefinition value = sd.getSnapshot().getElementByPath("Extension.value"); + ElementDefinition value = sd.getSnapshot().getElementByPath("Extension.value", true); return value != null && !value.isProhibited(); } public static boolean isModifierExtension(StructureDefinition sd) { - ElementDefinition defn = sd.getSnapshot().getElementByPath("Extension"); + ElementDefinition defn = sd.getSnapshot().getElementByPath("Extension", true); return defn.getIsModifier(); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java index 3937253a3..807eb8681 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java @@ -1457,7 +1457,7 @@ public class Element extends Base { if (property.getStructure().hasExtension(ToolingExtensions.EXT_RESOURCE_IMPLEMENTS)) { StructureDefinition sd = property.getContext().fetchResource(StructureDefinition.class, ExtensionsUtils.getExtensionString(property.getStructure(), ToolingExtensions.EXT_RESOURCE_IMPLEMENTS)); if (sd != null) { - ElementDefinition ed = sd.getSnapshot().getElementByPath(property.getDefinition().getPath().replace(property.getStructure().getType(), sd.getType())); + ElementDefinition ed = sd.getSnapshot().getElementByPath(property.getDefinition().getPath().replace(property.getStructure().getType(), sd.getType()), true); if (ed != null) { return ed.getBase().getPath(); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java index 4815ded2b..255a75c3a 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java @@ -1233,12 +1233,15 @@ public class StructureDefinition extends CanonicalResource { // added from java-adornments.txt: - public ElementDefinition getElementByPath(String path) { + public ElementDefinition getElementByPath(String path, boolean autoChoice) { + if (autoChoice && path.endsWith("[x]")) { + path = path.substring(0, path.length()-3); + } if (path == null) { return null; } for (ElementDefinition ed : getElement()) { - if (path.equals(ed.getPath()) || (path+"[x]").equals(ed.getPath())) { + if (path.equals(ed.getPath()) || (autoChoice && (path+"[x]").equals(ed.getPath()))) { return ed; } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java index 911c390e4..7fbb0eb4f 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java @@ -129,7 +129,7 @@ public abstract class PEDefinition { type= type.substring(0, type.indexOf(".")); } StructureDefinition sd = builder.getContext().fetchTypeDefinition(type); - return sd.getSnapshot().getElementByPath(definition.getBase().getPath()); + return sd.getSnapshot().getElementByPath(definition.getBase().getPath(), true); } /** diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionExtension.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionExtension.java index bb66d9d8f..59d357191 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionExtension.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionExtension.java @@ -21,8 +21,8 @@ public class PEDefinitionExtension extends PEDefinition { super(builder, name, profile, definition, ppath); this.sliceDefinition = sliceDefinition; this.extension= extension; - eed = extension.getSnapshot().getElementByPath("Extension.extension"); - ved = extension.getSnapshot().getElementByPath("Extension.value[x]"); + eed = extension.getSnapshot().getElementByPath("Extension.extension", true); + ved = extension.getSnapshot().getElementByPath("Extension.value[x]", true); } @Override diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java index d277cd283..3a28f75bc 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java @@ -375,7 +375,7 @@ public class DataRenderer extends Renderer implements CodeResolver { StructureDefinition sd = getContext().getWorker().fetchTypeDefinition(t); if (sd == null) return false; - if (Utilities.existsInList(t, VersionUtilities.getCanonicalResourceNames(getContext().getWorker().getVersion()))) { + if (VersionUtilities.getCanonicalResourceNames(getContext().getWorker().getVersion()).contains(t)) { return true; } if (Utilities.existsInList(t, diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValueSetValidator.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValueSetValidator.java index e184f5b93..f9b7989c2 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValueSetValidator.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/validation/ValueSetValidator.java @@ -32,6 +32,7 @@ package org.hl7.fhir.r5.terminologies.validation; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.HashMap; @@ -471,10 +472,12 @@ public class ValueSetValidator { return res; } + private static final HashSet SERVER_SIDE_LIST = new HashSet<>(Arrays.asList("http://fdasis.nlm.nih.gov", "http://hl7.org/fhir/sid/ndc", "http://loinc.org", "http://snomed.info/sct", "http://unitsofmeasure.org", + "http://unstats.un.org/unsd/methods/m49/m49.htm", "http://varnomen.hgvs.org", "http://www.nlm.nih.gov/research/umls/rxnorm", "https://www.usps.com/", + "urn:ietf:bcp:13","urn:ietf:bcp:47","urn:ietf:rfc:3986", "urn:iso:std:iso:3166","urn:iso:std:iso:4217", "urn:oid:1.2.36.1.2001.1005.17")); + private boolean preferServerSide(String system) { - if (Utilities.existsInList(system, "http://fdasis.nlm.nih.gov", "http://hl7.org/fhir/sid/ndc", "http://loinc.org", "http://snomed.info/sct", "http://unitsofmeasure.org", - "http://unstats.un.org/unsd/methods/m49/m49.htm", "http://varnomen.hgvs.org", "http://www.nlm.nih.gov/research/umls/rxnorm", "https://www.usps.com/", - "urn:ietf:bcp:13","urn:ietf:bcp:47","urn:ietf:rfc:3986", "urn:iso:std:iso:3166","urn:iso:std:iso:4217", "urn:oid:1.2.36.1.2001.1005.17")) { + if (SERVER_SIDE_LIST.contains(system)) { return true; } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/BuildExtensions.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/BuildExtensions.java index 529b9fbc4..57ac24c39 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/BuildExtensions.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/BuildExtensions.java @@ -3,7 +3,9 @@ package org.hl7.fhir.r5.utils; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class BuildExtensions extends ToolingExtensions { @@ -51,19 +53,24 @@ public class BuildExtensions extends ToolingExtensions { public static final String EXT_BINDING_NAME = "http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName"; - public static List allConsts() { - List list = new ArrayList<>(); - for (Field field : BuildExtensions.class.getDeclaredFields()) { - int modifiers = field.getModifiers(); - if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) { - try { - list.add(field.get(field.getType()).toString()); - } catch (Exception e) { + private static Set cachedConsts; + + public static Set allConsts() { + if (cachedConsts == null) { + Set list = new HashSet<>(); + for (Field field : BuildExtensions.class.getDeclaredFields()) { + int modifiers = field.getModifiers(); + if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) { + try { + list.add(field.get(field.getType()).toString()); + } catch (Exception e) { + } } } + list.addAll(ToolingExtensions.allConsts()); + cachedConsts = list; } - list.addAll(ToolingExtensions.allConsts()); - return list; + return cachedConsts; } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java index a035ea485..21285e639 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java @@ -68,6 +68,8 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.HashSet; import org.apache.commons.lang3.StringUtils; import org.fhir.ucum.Utilities; @@ -236,8 +238,6 @@ public class ToolingExtensions { public static final String EXT_MAPPING_TGTTYPE = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-target-type"; public static final String EXT_MAPPING_TGTCARD = "http://hl7.org/fhir/tools/StructureDefinition/conceptmap-target-cardinality"; - - public static final String WEB_EXTENSION_STYLE = "http://build.fhir.org/ig/FHIR/fhir-tools-ig/format-extensions.html#extension-related-extensions"; public static final String EXT_IGDEP_COMMENT = "http://hl7.org/fhir/tools/StructureDefinition/implementationguide-dependency-comment"; public static final String EXT_XPATH_CONSTRAINT = "http://hl7.org/fhir/4.0/StructureDefinition/extension-ElementDefinition.constraint.xpath"; @@ -1029,20 +1029,23 @@ public class ToolingExtensions { return false; } - public static List allConsts() { - - List list = new ArrayList<>(); - for (Field field : ToolingExtensions.class.getDeclaredFields()) { - int modifiers = field.getModifiers(); - if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) { - try { - list.add(field.get(field.getType()).toString()); - } catch (Exception e) { + private static Set cachedConsts; + + public static Set allConsts() { + if (cachedConsts == null) { + Set list = new HashSet<>(); + for (Field field : ToolingExtensions.class.getDeclaredFields()) { + int modifiers = field.getModifiers(); + if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) { + try { + list.add(field.get(field.getType()).toString()); + } catch (Exception e) { + } } } + cachedConsts = list; } - return list; - + return cachedConsts; } public static boolean hasExtensions(ElementDefinition d, String... urls) { diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java index 0f55f94f2..4a967c6bc 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/VersionUtilities.java @@ -2,6 +2,8 @@ package org.hl7.fhir.utilities; import java.util.ArrayList; import java.util.List; +import java.util.Set; +import java.util.HashSet; import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.exceptions.FHIRException; @@ -393,8 +395,10 @@ public class VersionUtilities { return null; } - public static List getCanonicalResourceNames(String version) { - ArrayList res = new ArrayList(); + + public static Set getCanonicalResourceNames(String version) { + + Set res = new HashSet(); if (isR2Ver(version) || isR2BVer(version)) { res.add("ValueSet"); res.add("ConceptMap"); 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 c611b5173..2d0be1a81 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 @@ -1031,7 +1031,7 @@ public class BaseValidator implements IValidationContextResourceLoader { if (!Utilities.isAbsoluteUrl(ref)) { String[] p = ref.split("\\/"); List ml = new ArrayList<>(); - if (p.length >= 2 && Utilities.existsInList(p[0], context.getResourceNames()) && Utilities.isValidId(p[1])) { + if (p.length >= 2 && context.getResourceNamesAsSet().contains(p[0]) && Utilities.isValidId(p[1])) { for (int i = 0; i < entries.size(); i++) { Element we = entries.get(i); Element r = we.getNamedChild(RESOURCE); 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 72432e446..fb6f6d472 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 @@ -42,6 +42,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Collections; @@ -260,6 +261,29 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat private static final boolean STACK_TRACE = false; private static final boolean DEBUG_ELEMENT = false; + private static final HashSet NO_TX_SYSTEM_EXEMPT = new HashSet<>(Arrays.asList("http://loinc.org", "http://unitsofmeasure.org", "http://hl7.org/fhir/sid/icd-9-cm", "http://snomed.info/sct", "http://www.nlm.nih.gov/research/umls/rxnorm")); + private static final HashSet NO_HTTPS_LIST = new HashSet<>(Arrays.asList("https://loinc.org", "https://unitsofmeasure.org", "https://snomed.info/sct", "https://www.nlm.nih.gov/research/umls/rxnorm")); + private static final HashSet EXTENSION_CONTEXT_LIST = new HashSet<>(Arrays.asList("ElementDefinition.example.value", "ElementDefinition.pattern", "ElementDefinition.fixed")); + private static final HashSet ID_EXEMPT_LIST = new HashSet<>(Arrays.asList("id", "base64Binary", "markdown")); + private static final HashSet HTML_ELEMENTS = new HashSet<>(Arrays.asList( + "p", "br", "div", "h1", "h2", "h3", "h4", "h5", "h6", "a", "span", "b", "em", "i", "strong", + "small", "big", "tt", "small", "dfn", "q", "var", "abbr", "acronym", "cite", "blockquote", "hr", "address", "bdo", "kbd", "q", "sub", "sup", + "ul", "ol", "li", "dl", "dt", "dd", "pre", "table", "caption", "colgroup", "col", "thead", "tr", "tfoot", "tbody", "th", "td", + "code", "samp", "img", "map", "area")); + private static final HashSet HTML_ATTRIBUTES = new HashSet<>(Arrays.asList( + "title", "style", "class", "id", "lang", "xml:lang", "dir", "accesskey", "tabindex", + // tables + "span", "width", "align", "valign", "char", "charoff", "abbr", "axis", "headers", "scope", "rowspan", "colspan")); + + private static final HashSet HTML_COMBO_LIST = new HashSet<>(Arrays.asList( + "a.href", "a.name", "img.src", "img.border", "div.xmlns", "blockquote.cite", "q.cite", + "a.charset", "a.type", "a.name", "a.href", "a.hreflang", "a.rel", "a.rev", "a.shape", "a.coords", "img.src", + "img.alt", "img.longdesc", "img.height", "img.width", "img.usemap", "img.ismap", "map.name", "area.shape", + "area.coords", "area.href", "area.nohref", "area.alt", "table.summary", "table.width", "table.border", + "table.frame", "table.rules", "table.cellspacing", "table.cellpadding", "pre.space", "td.nowrap")); + private static final HashSet HTML_BLOCK_LIST = new HashSet<>(Arrays.asList("div", "blockquote", "table", "ol", "ul", "p")); + private static final HashSet RESOURCE_X_POINTS = new HashSet<>(Arrays.asList("Bundle.entry.resource", "Bundle.entry.response.outcome", "DomainResource.contained", "Parameters.parameter.resource", "Parameters.parameter.part.resource")); + private class ValidatorHostServices implements IEvaluationContext { @Override @@ -1024,7 +1048,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } return false; } - } else if (context.isNoTerminologyServer() && Utilities.existsInList(system, "http://loinc.org", "http://unitsofmeasure.org", "http://hl7.org/fhir/sid/icd-9-cm", "http://snomed.info/sct", "http://www.nlm.nih.gov/research/umls/rxnorm")) { + } else if (context.isNoTerminologyServer() && NO_TX_SYSTEM_EXEMPT.contains(system)) { return true; // no checks in this case } else if (startsWithButIsNot(system, "http://snomed.info/sct", "http://loinc.org", "http://unitsofmeasure.org", "http://www.nlm.nih.gov/research/umls/rxnorm")) { rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_SYSTEM_INVALID, system); @@ -1039,7 +1063,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (system.startsWith("https:") && system.length() > 7) { String ns = "http:"+system.substring(6); CodeSystem cs = getCodeSystem(ns); - if (cs != null || Utilities.existsInList(system, "https://loinc.org", "https://unitsofmeasure.org", "https://snomed.info/sct", "https://www.nlm.nih.gov/research/umls/rxnorm")) { + if (cs != null || NO_HTTPS_LIST.contains(system)) { rule(errors, NO_RULE_DATE, IssueType.CODEINVALID, element.line(), element.col(), path, false, I18nConstants.TERMINOLOGY_TX_SYSTEM_HTTPS, system); done = true; } @@ -1868,7 +1892,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } } else if (SpecialExtensions.isKnownExtension(url)) { ex = SpecialExtensions.getDefinition(url); - } else if (Utilities.existsInList(url, BuildExtensions.allConsts())) { + } else if (BuildExtensions.allConsts().contains(url)) { // nothing } else if (rule(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), path, allowUnknownExtension(url), I18nConstants.EXTENSION_EXT_UNKNOWN_NOTHERE, url)) { hint(errors, NO_RULE_DATE, IssueType.STRUCTURE, element.line(), element.col(), path, isKnownExtension(url), I18nConstants.EXTENSION_EXT_UNKNOWN, url); @@ -1964,7 +1988,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat for (String s : stack.getLogicalPaths()) { String p = stripIndexes(s); // all extensions are always allowed in ElementDefinition.example.value, and in fixed and pattern values. TODO: determine the logical paths from the path stated in the element definition.... - if (Utilities.existsInList(p, "ElementDefinition.example.value", "ElementDefinition.pattern", "ElementDefinition.fixed")) { + if (EXTENSION_CONTEXT_LIST.contains(p)) { return true; } plist.add(p); @@ -2549,9 +2573,8 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (context.hasPattern()) { ok = checkFixedValue(errors, path, e, context.getPattern(), profile.getVersionedUrl(), context.getSliceName(), null, true) && ok; } - - if (ok && !Utilities.existsInList(e.fhirType(), "id", "base64Binary", "markdown")) { // ids get checked elsewhere + if (ok && !ID_EXEMPT_LIST.contains(e.fhirType())) { // ids get checked elsewhere String regext = FHIRPathExpressionFixer.fixRegex(getRegexFromType(e.fhirType())); if (regext != null) { try { @@ -2757,7 +2780,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (!"url".equals(p[1])) { return false; } - return Utilities.existsInList(p[0], VersionUtilities.getCanonicalResourceNames(context.getVersion())); + return VersionUtilities.getCanonicalResourceNames(context.getVersion()).contains((p[0])); } private boolean containsHtmlTags(String cnt) { @@ -2852,30 +2875,16 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat rule(errors, NO_RULE_DATE, IssueType.INVALID, e.line(), e.col(), path, !node.getContent().startsWith("DOCTYPE"), I18nConstants.XHTML_XHTML_DOCTYPE_ILLEGAL); } if (node.getNodeType() == NodeType.Element) { - rule(errors, NO_RULE_DATE, IssueType.INVALID, e.line(), e.col(), path, Utilities.existsInList(node.getName(), - "p", "br", "div", "h1", "h2", "h3", "h4", "h5", "h6", "a", "span", "b", "em", "i", "strong", - "small", "big", "tt", "small", "dfn", "q", "var", "abbr", "acronym", "cite", "blockquote", "hr", "address", "bdo", "kbd", "q", "sub", "sup", - "ul", "ol", "li", "dl", "dt", "dd", "pre", "table", "caption", "colgroup", "col", "thead", "tr", "tfoot", "tbody", "th", "td", - "code", "samp", "img", "map", "area"), I18nConstants.XHTML_XHTML_ELEMENT_ILLEGAL, node.getName()); + rule(errors, NO_RULE_DATE, IssueType.INVALID, e.line(), e.col(), path, HTML_ELEMENTS.contains(node.getName()), I18nConstants.XHTML_XHTML_ELEMENT_ILLEGAL, node.getName()); for (String an : node.getAttributes().keySet()) { - boolean bok = an.startsWith("xmlns") || Utilities.existsInList(an, - "title", "style", "class", ID, "lang", "xml:lang", "dir", "accesskey", "tabindex", - // tables - "span", "width", "align", "valign", "char", "charoff", "abbr", "axis", "headers", "scope", "rowspan", "colspan") || - - Utilities.existsInList(node.getName() + "." + an, "a.href", "a.name", "img.src", "img.border", "div.xmlns", "blockquote.cite", "q.cite", - "a.charset", "a.type", "a.name", "a.href", "a.hreflang", "a.rel", "a.rev", "a.shape", "a.coords", "img.src", - "img.alt", "img.longdesc", "img.height", "img.width", "img.usemap", "img.ismap", "map.name", "area.shape", - "area.coords", "area.href", "area.nohref", "area.alt", "table.summary", "table.width", "table.border", - "table.frame", "table.rules", "table.cellspacing", "table.cellpadding", "pre.space", "td.nowrap" - ); + boolean bok = an.startsWith("xmlns") || HTML_ATTRIBUTES.contains(an) || HTML_COMBO_LIST.contains(node.getName() + "." + an); if (!bok) { rule(errors, NO_RULE_DATE, IssueType.INVALID, e.line(), e.col(), path, false, I18nConstants.XHTML_XHTML_ATTRIBUTE_ILLEGAL, an, node.getName()); } } - ok = rule(errors, NO_RULE_DATE, IssueType.INVALID, e.line(), e.col(), path, !(inPara && Utilities.existsInList(node.getName(), "div", "blockquote", "table", "ol", "ul", "p")) , I18nConstants.XHTML_XHTML_ELEMENT_ILLEGAL_IN_PARA, node.getName()) && ok; + ok = rule(errors, NO_RULE_DATE, IssueType.INVALID, e.line(), e.col(), path, !(inPara && HTML_BLOCK_LIST.contains(node.getName())) , I18nConstants.XHTML_XHTML_ELEMENT_ILLEGAL_IN_PARA, node.getName()) && ok; ok = checkInnerNames(errors, e, path, node.getChildNodes(), inPara || "p".equals(node.getName())) && ok; } @@ -3291,7 +3300,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat refType = "bundled"; } } - boolean conditional = ref.contains("?") && Utilities.existsInList(ref.substring(0, ref.indexOf("?")), context.getResourceNames()); + boolean conditional = ref.contains("?") && context.getResourceNamesAsSet().contains(ref.substring(0, ref.indexOf("?"))); ReferenceValidationPolicy pol; if (refType.equals("contained") || refType.equals("bundled")) { pol = ReferenceValidationPolicy.CHECK_VALID; @@ -5685,7 +5694,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat } private boolean isResourceAndTypes(ElementDefinition ed) { - if (!Utilities.existsInList(ed.getBase().getPath(), "Bundle.entry.resource", "Bundle.entry.response.outcome", "DomainResource.contained", "Parameters.parameter.resource", "Parameters.parameter.part.resource")) { + if (!RESOURCE_X_POINTS.contains(ed.getBase().getPath())) { return false; } for (TypeRefComponent tr : ed.getType()) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java index ebdec7f9f..ebe4c0b7e 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/SpecialExtensions.java @@ -1,6 +1,8 @@ package org.hl7.fhir.validation.instance; import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; import org.hl7.fhir.exceptions.FHIRFormatError; import org.hl7.fhir.r5.formats.JsonParser; @@ -18,17 +20,19 @@ public class SpecialExtensions { private static final String CONFORMANCE_DERIVED = "{ \"resourceType\" : \"StructureDefinition\", \"id\" : \"structuredefinition-conformance-derivedFrom\", \"extension\" : [{ \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-wg\", \"valueCode\" : \"fhir\" }, { \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm\", \"valueInteger\" : 1 }], \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-conformance-derivedFrom\", \"version\" : \"4.6.0\", \"name\" : \"fmm\", \"status\" : \"draft\", \"date\" : \"2014-01-31\", \"publisher\" : \"Health Level Seven, Inc. - [WG Name] WG\", \"contact\" : [{ \"telecom\" : [{ \"system\" : \"url\", \"value\" : \"http://hl7.org/special/committees/FHIR\" }] }], \"description\" : \"Indicates one of the resources that was used to infer the specified maturity or standards status\", \"fhirVersion\" : \"4.6.0\", \"mapping\" : [{ \"identity\" : \"rim\", \"uri\" : \"http://hl7.org/v3\", \"name\" : \"RIM Mapping\" }], \"kind\" : \"complex-type\", \"abstract\" : false, \"context\" : [{ \"type\" : \"fhirpath\", \"expression\" : \"extension('http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm').value\" }, { \"type\" : \"fhirpath\", \"expression\" : \"extension('http://hl7.org/fhir/StructureDefinition/structuredefinition-standards-status').value\" }], \"type\" : \"Extension\", \"baseDefinition\" : \"http://hl7.org/fhir/StructureDefinition/Extension\", \"derivation\" : \"constraint\", \"snapshot\" : { \"element\" : [{ \"id\" : \"Extension\", \"path\" : \"Extension\", \"short\" : \"FMM Level\", \"definition\" : \"Indicates one of the resources that was used to infer the specified maturity or standards status\", \"min\" : 0, \"max\" : \"*\", \"base\" : { \"path\" : \"Extension\", \"min\" : 0, \"max\" : \"*\" }, \"constraint\" : [{ \"key\" : \"ele-1\", \"severity\" : \"error\", \"human\" : \"All FHIR elements must have a @value or children\", \"expression\" : \"hasValue() or (children().count() > id.count())\", \"xpath\" : \"@value|f:*|h:div\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\" }, { \"key\" : \"ext-1\", \"severity\" : \"error\", \"human\" : \"Must have either extensions or value[x], not both\", \"expression\" : \"extension.exists() != value.exists()\", \"xpath\" : \"exists(f:extension)!=exists(f:*[starts-with(local-name(.), 'value')])\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Extension\" }], \"isModifier\" : false }, { \"id\" : \"Extension.id\", \"path\" : \"Extension.id\", \"representation\" : [\"xmlAttr\"], \"short\" : \"Unique id for inter-element referencing\", \"definition\" : \"Unique id for the element within a resource (for internal references). This may be any string value that does not contain spaces.\", \"min\" : 0, \"max\" : \"1\", \"base\" : { \"path\" : \"Element.id\", \"min\" : 0, \"max\" : \"1\" }, \"type\" : [{ \"extension\" : [{ \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type\", \"valueUrl\" : \"string\" }], \"code\" : \"http://hl7.org/fhirpath/System.String\" }], \"isModifier\" : false, \"isSummary\" : false, \"mapping\" : [{ \"identity\" : \"rim\", \"map\" : \"n/a\" }] }, { \"id\" : \"Extension.extension\", \"path\" : \"Extension.extension\", \"slicing\" : { \"discriminator\" : [{ \"type\" : \"value\", \"path\" : \"url\" }], \"description\" : \"Extensions are always sliced by (at least) url\", \"rules\" : \"open\" }, \"short\" : \"Extension\", \"definition\" : \"An Extension\", \"min\" : 0, \"max\" : \"0\", \"base\" : { \"path\" : \"Element.extension\", \"min\" : 0, \"max\" : \"*\" }, \"type\" : [{ \"code\" : \"Extension\" }], \"constraint\" : [{ \"key\" : \"ele-1\", \"severity\" : \"error\", \"human\" : \"All FHIR elements must have a @value or children\", \"expression\" : \"hasValue() or (children().count() > id.count())\", \"xpath\" : \"@value|f:*|h:div\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\" }, { \"key\" : \"ext-1\", \"severity\" : \"error\", \"human\" : \"Must have either extensions or value[x], not both\", \"expression\" : \"extension.exists() != value.exists()\", \"xpath\" : \"exists(f:extension)!=exists(f:*[starts-with(local-name(.), \\\"value\\\")])\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Extension\" }], \"isModifier\" : false, \"isSummary\" : false }, { \"id\" : \"Extension.url\", \"path\" : \"Extension.url\", \"representation\" : [\"xmlAttr\"], \"short\" : \"identifies the meaning of the extension\", \"definition\" : \"Source of the definition for the extension code - a logical name or a URL.\", \"comment\" : \"The definition may point directly to a computable or human-readable definition of the extensibility codes, or it may be a logical URI as declared in some other specification. The definition SHALL be a URI for the Structure Definition defining the extension.\", \"min\" : 1, \"max\" : \"1\", \"base\" : { \"path\" : \"Extension.url\", \"min\" : 1, \"max\" : \"1\" }, \"type\" : [{ \"extension\" : [{ \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type\", \"valueUrl\" : \"uri\" }], \"code\" : \"http://hl7.org/fhirpath/System.String\" }], \"fixedUri\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-conformance-derivedFrom\", \"isModifier\" : false, \"isSummary\" : false, \"mapping\" : [{ \"identity\" : \"rim\", \"map\" : \"N/A\" }] }, { \"id\" : \"Extension.value[x]\", \"path\" : \"Extension.value[x]\", \"short\" : \"Value of extension\", \"definition\" : \"Value of extension - must be one of a constrained set of the data types (see [Extensibility](extensibility.html) for a list).\", \"min\" : 1, \"max\" : \"1\", \"base\" : { \"path\" : \"Extension.value[x]\", \"min\" : 0, \"max\" : \"1\" }, \"type\" : [{ \"code\" : \"canonical\" }], \"constraint\" : [{ \"key\" : \"ele-1\", \"severity\" : \"error\", \"human\" : \"All FHIR elements must have a @value or children\", \"expression\" : \"hasValue() or (children().count() > id.count())\", \"xpath\" : \"@value|f:*|h:div\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\" }], \"isModifier\" : false, \"isSummary\" : false, \"mapping\" : [{ \"identity\" : \"rim\", \"map\" : \"N/A\" }] }] }, \"differential\" : { \"element\" : [{ \"id\" : \"Extension\", \"path\" : \"Extension\", \"short\" : \"FMM Level\", \"definition\" : \"Indicates one of the resources that was used to infer the specified maturity or standards status\", \"min\" : 0, \"max\" : \"*\" }, { \"id\" : \"Extension.extension\", \"path\" : \"Extension.extension\", \"max\" : \"0\" }, { \"id\" : \"Extension.url\", \"path\" : \"Extension.url\", \"fixedUri\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-conformance-derivedFrom\" }, { \"id\" : \"Extension.value[x]\", \"path\" : \"Extension.value[x]\", \"min\" : 1, \"type\" : [{ \"code\" : \"canonical\" }] }] } }"; private static final String FMM_SUPPORT = "{ \"resourceType\" : \"StructureDefinition\", \"id\" : \"structuredefinition-fmm-support\", \"extension\" : [{ \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-wg\", \"valueCode\" : \"fhir\" }, { \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm\", \"valueInteger\" : 1 }], \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm-support\", \"version\" : \"4.6.0\", \"name\" : \"fmm\", \"status\" : \"draft\", \"date\" : \"2014-01-31\", \"publisher\" : \"Health Level Seven, Inc. - [WG Name] WG\", \"contact\" : [{ \"telecom\" : [{ \"system\" : \"url\", \"value\" : \"http://hl7.org/special/committees/FHIR\" }] }], \"description\" : \"The documentation supporting the FMM level assigned to the artifact.\", \"fhirVersion\" : \"4.6.0\", \"mapping\" : [{ \"identity\" : \"rim\", \"uri\" : \"http://hl7.org/v3\", \"name\" : \"RIM Mapping\" }], \"kind\" : \"complex-type\", \"abstract\" : false, \"context\" : [{ \"type\" : \"element\", \"expression\" : \"Element\" }], \"type\" : \"Extension\", \"baseDefinition\" : \"http://hl7.org/fhir/StructureDefinition/Extension\", \"derivation\" : \"constraint\", \"snapshot\" : { \"element\" : [{ \"id\" : \"Extension\", \"path\" : \"Extension\", \"short\" : \"FMM Level\", \"definition\" : \"The documentation supporting the FMM level assigned to the artifact.\", \"comment\" : \"Though this is defined for resources, it can be used for any artifact.\", \"min\" : 0, \"max\" : \"1\", \"base\" : { \"path\" : \"Extension\", \"min\" : 0, \"max\" : \"*\" }, \"constraint\" : [{ \"key\" : \"ele-1\", \"severity\" : \"error\", \"human\" : \"All FHIR elements must have a @value or children\", \"expression\" : \"hasValue() or (children().count() > id.count())\", \"xpath\" : \"@value|f:*|h:div\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\" }, { \"key\" : \"ext-1\", \"severity\" : \"error\", \"human\" : \"Must have either extensions or value[x], not both\", \"expression\" : \"extension.exists() != value.exists()\", \"xpath\" : \"exists(f:extension)!=exists(f:*[starts-with(local-name(.), 'value')])\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Extension\" }], \"isModifier\" : false }, { \"id\" : \"Extension.id\", \"path\" : \"Extension.id\", \"representation\" : [\"xmlAttr\"], \"short\" : \"Unique id for inter-element referencing\", \"definition\" : \"Unique id for the element within a resource (for internal references). This may be any string value that does not contain spaces.\", \"min\" : 0, \"max\" : \"1\", \"base\" : { \"path\" : \"Element.id\", \"min\" : 0, \"max\" : \"1\" }, \"type\" : [{ \"extension\" : [{ \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type\", \"valueUrl\" : \"string\" }], \"code\" : \"http://hl7.org/fhirpath/System.String\" }], \"isModifier\" : false, \"isSummary\" : false, \"mapping\" : [{ \"identity\" : \"rim\", \"map\" : \"n/a\" }] }, { \"id\" : \"Extension.extension\", \"path\" : \"Extension.extension\", \"slicing\" : { \"discriminator\" : [{ \"type\" : \"value\", \"path\" : \"url\" }], \"description\" : \"Extensions are always sliced by (at least) url\", \"rules\" : \"open\" }, \"short\" : \"Extension\", \"definition\" : \"An Extension\", \"min\" : 0, \"max\" : \"0\", \"base\" : { \"path\" : \"Element.extension\", \"min\" : 0, \"max\" : \"*\" }, \"type\" : [{ \"code\" : \"Extension\" }], \"constraint\" : [{ \"key\" : \"ele-1\", \"severity\" : \"error\", \"human\" : \"All FHIR elements must have a @value or children\", \"expression\" : \"hasValue() or (children().count() > id.count())\", \"xpath\" : \"@value|f:*|h:div\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\" }, { \"key\" : \"ext-1\", \"severity\" : \"error\", \"human\" : \"Must have either extensions or value[x], not both\", \"expression\" : \"extension.exists() != value.exists()\", \"xpath\" : \"exists(f:extension)!=exists(f:*[starts-with(local-name(.), \\\"value\\\")])\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Extension\" }], \"isModifier\" : false, \"isSummary\" : false }, { \"id\" : \"Extension.url\", \"path\" : \"Extension.url\", \"representation\" : [\"xmlAttr\"], \"short\" : \"identifies the meaning of the extension\", \"definition\" : \"Source of the definition for the extension code - a logical name or a URL.\", \"comment\" : \"The definition may point directly to a computable or human-readable definition of the extensibility codes, or it may be a logical URI as declared in some other specification. The definition SHALL be a URI for the Structure Definition defining the extension.\", \"min\" : 1, \"max\" : \"1\", \"base\" : { \"path\" : \"Extension.url\", \"min\" : 1, \"max\" : \"1\" }, \"type\" : [{ \"extension\" : [{ \"url\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type\", \"valueUrl\" : \"uri\" }], \"code\" : \"http://hl7.org/fhirpath/System.String\" }], \"fixedUri\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm-support\", \"isModifier\" : false, \"isSummary\" : false, \"mapping\" : [{ \"identity\" : \"rim\", \"map\" : \"N/A\" }] }, { \"id\" : \"Extension.value[x]\", \"path\" : \"Extension.value[x]\", \"short\" : \"Value of extension\", \"definition\" : \"Value of extension - must be one of a constrained set of the data types (see [Extensibility](extensibility.html) for a list).\", \"min\" : 1, \"max\" : \"1\", \"base\" : { \"path\" : \"Extension.value[x]\", \"min\" : 0, \"max\" : \"1\" }, \"type\" : [{ \"code\" : \"markdown\" }], \"constraint\" : [{ \"key\" : \"ele-1\", \"severity\" : \"error\", \"human\" : \"All FHIR elements must have a @value or children\", \"expression\" : \"hasValue() or (children().count() > id.count())\", \"xpath\" : \"@value|f:*|h:div\", \"source\" : \"http://hl7.org/fhir/StructureDefinition/Element\" }], \"isModifier\" : false, \"isSummary\" : false, \"mapping\" : [{ \"identity\" : \"rim\", \"map\" : \"N/A\" }] }] }, \"differential\" : { \"element\" : [{ \"id\" : \"Extension\", \"path\" : \"Extension\", \"short\" : \"FMM Level\", \"definition\" : \"The documentation supporting the FMM level assigned to the artifact.\", \"comment\" : \"Though this is defined for resources, it can be used for any artifact.\", \"min\" : 0, \"max\" : \"1\" }, { \"id\" : \"Extension.extension\", \"path\" : \"Extension.extension\", \"max\" : \"0\" }, { \"id\" : \"Extension.url\", \"path\" : \"Extension.url\", \"fixedUri\" : \"http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm-support\" }, { \"id\" : \"Extension.value[x]\", \"path\" : \"Extension.value[x]\", \"min\" : 1, \"type\" : [{ \"code\" : \"markdown\" }] }] } }"; + private static final HashSet KNOWN_EXTENSIONS = new HashSet<>(Arrays.asList( + "http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support", + "http://hl7.org/fhir/StructureDefinition/instance-name", + "http://hl7.org/fhir/StructureDefinition/instance-description", + "http://hl7.org/fhir/build/StructureDefinition/definition", // wrongly defined in used in early R4B/R5 builds - changed to http://hl7.org/build/fhir/StructureDefinition/binding-definition + "http://hl7.org/fhir/StructureDefinition/codesystem-properties-mode", + "http://hl7.org/fhir/StructureDefinition/structuredefinition-rdf-type", + "http://hl7.org/fhir/StructureDefinition/structuredefinition-conformance-derivedFrom", // this is defined in R5, but needed earlier + "http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm-support" // this is defined in R5, but needed earlier + )); + public static boolean isKnownExtension(String url) { - return Utilities.existsInList(url, - "http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support", - "http://hl7.org/fhir/StructureDefinition/instance-name", - "http://hl7.org/fhir/StructureDefinition/instance-description", - "http://hl7.org/fhir/build/StructureDefinition/definition", // wrongly defined in used in early R4B/R5 builds - changed to http://hl7.org/build/fhir/StructureDefinition/binding-definition - "http://hl7.org/fhir/StructureDefinition/codesystem-properties-mode", - "http://hl7.org/fhir/StructureDefinition/structuredefinition-rdf-type", - "http://hl7.org/fhir/StructureDefinition/structuredefinition-conformance-derivedFrom", // this is defined in R5, but needed earlier - "http://hl7.org/fhir/StructureDefinition/structuredefinition-fmm-support" // this is defined in R5, but needed earlier - ); + return KNOWN_EXTENSIONS.contains(url); } public static StructureDefinition getDefinition(String url) { diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java index 9206557a2..c7eab1f83 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java @@ -1060,7 +1060,7 @@ public class StructureMapValidator extends BaseValidator { if (sdt == null) { throw new Error("Unable to resolve "+url); } else { - ElementDefinition t2 = sdt.getSnapshot().getElementByPath(path); + ElementDefinition t2 = sdt.getSnapshot().getElementByPath(path, true); if (t2 == null) { throw new Error("Unable to resolve "+path+" in "+url); } else { From 6232c54f15d68ebd4ca96992fe6a7326cdd0e6b7 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Sun, 7 May 2023 12:02:00 -0500 Subject: [PATCH 8/8] Fix core --- .../codegen/extensions/JavaExtensionsFactoryGenerator.java | 2 +- .../hl7/fhir/r5/conformance/profile/ProfileUtilities.java | 4 ++-- .../main/java/org/hl7/fhir/r5/elementmodel/Element.java | 2 +- .../src/main/java/org/hl7/fhir/r5/model/Element.java | 4 +--- .../src/main/java/org/hl7/fhir/r5/model/PrimitiveType.java | 3 +-- .../java/org/hl7/fhir/r5/model/StructureDefinition.java | 7 ++----- .../java/org/hl7/fhir/r5/profilemodel/PEDefinition.java | 2 +- .../hl7/fhir/r5/profilemodel/PEDefinitionExtension.java | 4 ++-- .../validation/instance/type/StructureMapValidator.java | 2 +- 9 files changed, 12 insertions(+), 18 deletions(-) diff --git a/org.hl7.fhir.core.generator/src/org/hl7/fhir/core/generator/codegen/extensions/JavaExtensionsFactoryGenerator.java b/org.hl7.fhir.core.generator/src/org/hl7/fhir/core/generator/codegen/extensions/JavaExtensionsFactoryGenerator.java index f932e2b2f..3c59a38c9 100644 --- a/org.hl7.fhir.core.generator/src/org/hl7/fhir/core/generator/codegen/extensions/JavaExtensionsFactoryGenerator.java +++ b/org.hl7.fhir.core.generator/src/org/hl7/fhir/core/generator/codegen/extensions/JavaExtensionsFactoryGenerator.java @@ -98,7 +98,7 @@ public class JavaExtensionsFactoryGenerator extends JavaBaseGenerator { ElementDefinition edRoot = sd.getSnapshot().getElementFirstRep(); boolean repeats = !edRoot.getMax().equals("1"); String verb = repeats ? "add" : "set"; - ElementDefinition edValue = sd.getSnapshot().getElementByPath("Extension.value[x]", false); + ElementDefinition edValue = sd.getSnapshot().getElementByPath("Extension.value[x]"); List types = analyseTypes(edValue); if (types.size() > 5) { src.append(" public static Extension make"+name+"(DataType value) {\r\n"); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java index 9d8809b5d..b3e384870 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java @@ -3969,12 +3969,12 @@ public class ProfileUtilities extends TranslatingUtilities { if (!isExtensionDefinition(sd)) { return false; } - ElementDefinition value = sd.getSnapshot().getElementByPath("Extension.value", true); + ElementDefinition value = sd.getSnapshot().getElementByPath("Extension.value"); return value != null && !value.isProhibited(); } public static boolean isModifierExtension(StructureDefinition sd) { - ElementDefinition defn = sd.getSnapshot().getElementByPath("Extension", true); + ElementDefinition defn = sd.getSnapshot().getElementByPath("Extension"); return defn.getIsModifier(); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java index 32656c6e7..24b680eb7 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/Element.java @@ -1451,7 +1451,7 @@ public class Element extends Base { if (property.getStructure().hasExtension(ToolingExtensions.EXT_RESOURCE_IMPLEMENTS)) { StructureDefinition sd = property.getContext().fetchResource(StructureDefinition.class, ExtensionsUtils.getExtensionString(property.getStructure(), ToolingExtensions.EXT_RESOURCE_IMPLEMENTS)); if (sd != null) { - ElementDefinition ed = sd.getSnapshot().getElementByPath(property.getDefinition().getPath().replace(property.getStructure().getType(), sd.getType()), true); + ElementDefinition ed = sd.getSnapshot().getElementByPath(property.getDefinition().getPath().replace(property.getStructure().getType(), sd.getType())); if (ed != null) { return ed.getBase().getPath(); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Element.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Element.java index b93f37abb..106750506 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Element.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/Element.java @@ -301,9 +301,7 @@ public abstract class Element extends Base implements IBaseHasExtensions, IBaseE } public boolean isEmpty() { - boolean idIsEmpty = id == null || id.isEmpty(); - boolean extensionIsEmpty = extension == null || extension.size() == 0; - return super.isEmpty() && idIsEmpty && extensionIsEmpty; + return super.isEmpty() && ca.uhn.fhir.util.ElementUtil.isEmpty(id, extension); } // Manual code (from Configuration.txt): diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/PrimitiveType.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/PrimitiveType.java index fac70c899..aed729203 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/PrimitiveType.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/PrimitiveType.java @@ -130,8 +130,7 @@ public abstract class PrimitiveType extends DataType implements IPrimitiveTyp @Override public boolean isEmpty() { - String value = getValueAsString(); - return !super.isEmpty() || (value != null && value.length() > 0); + return super.isEmpty() && StringUtils.isBlank(getValueAsString()); } public boolean isPrimitive() { diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java index 255a75c3a..4815ded2b 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java @@ -1233,15 +1233,12 @@ public class StructureDefinition extends CanonicalResource { // added from java-adornments.txt: - public ElementDefinition getElementByPath(String path, boolean autoChoice) { - if (autoChoice && path.endsWith("[x]")) { - path = path.substring(0, path.length()-3); - } + public ElementDefinition getElementByPath(String path) { if (path == null) { return null; } for (ElementDefinition ed : getElement()) { - if (path.equals(ed.getPath()) || (autoChoice && (path+"[x]").equals(ed.getPath()))) { + if (path.equals(ed.getPath()) || (path+"[x]").equals(ed.getPath())) { return ed; } } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java index 7fbb0eb4f..911c390e4 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinition.java @@ -129,7 +129,7 @@ public abstract class PEDefinition { type= type.substring(0, type.indexOf(".")); } StructureDefinition sd = builder.getContext().fetchTypeDefinition(type); - return sd.getSnapshot().getElementByPath(definition.getBase().getPath(), true); + return sd.getSnapshot().getElementByPath(definition.getBase().getPath()); } /** diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionExtension.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionExtension.java index 59d357191..bb66d9d8f 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionExtension.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/profilemodel/PEDefinitionExtension.java @@ -21,8 +21,8 @@ public class PEDefinitionExtension extends PEDefinition { super(builder, name, profile, definition, ppath); this.sliceDefinition = sliceDefinition; this.extension= extension; - eed = extension.getSnapshot().getElementByPath("Extension.extension", true); - ved = extension.getSnapshot().getElementByPath("Extension.value[x]", true); + eed = extension.getSnapshot().getElementByPath("Extension.extension"); + ved = extension.getSnapshot().getElementByPath("Extension.value[x]"); } @Override diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java index c7eab1f83..9206557a2 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureMapValidator.java @@ -1060,7 +1060,7 @@ public class StructureMapValidator extends BaseValidator { if (sdt == null) { throw new Error("Unable to resolve "+url); } else { - ElementDefinition t2 = sdt.getSnapshot().getElementByPath(path, true); + ElementDefinition t2 = sdt.getSnapshot().getElementByPath(path); if (t2 == null) { throw new Error("Unable to resolve "+path+" in "+url); } else {