Merge remote-tracking branch 'origin/master' into 2849_add_new_mdm_param

This commit is contained in:
Nick Goupinets 2021-08-27 09:42:08 -04:00
commit 8403b85429
153 changed files with 1707 additions and 532 deletions

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -266,12 +266,26 @@ public interface IValidationSupport {
* other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter. * other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter.
* @param theSystem The CodeSystem URL * @param theSystem The CodeSystem URL
* @param theCode The code * @param theCode The code
* @param theDisplayLanguage to filter out the designation by the display language, to return all designation, the this value to null
*/ */
@Nullable @Nullable
default LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode) { default LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode, String theDisplayLanguage) {
return null; return null;
} }
/**
* Look up a code using the system and code value
*
* @param theValidationSupportContext The validation support module will be passed in to this method. This is convenient in cases where the operation needs to make calls to
* other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter.
* @param theSystem The CodeSystem URL
* @param theCode The code
*/
@Nullable
default LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode) {
return lookupCode(theValidationSupportContext, theSystem, theCode, null);
}
/** /**
* Returns <code>true</code> if the given valueset can be validated by the given * Returns <code>true</code> if the given valueset can be validated by the given
* validation support module * validation support module

View File

@ -51,7 +51,7 @@ public enum SearchContainedModeEnum {
myCode = theCode; myCode = theCode;
} }
private String getCode() { public String getCode() {
return myCode; return myCode;
} }

View File

@ -76,6 +76,7 @@ public enum VersionEnum {
V5_4_2, V5_4_2,
V5_5_0, V5_5_0,
V5_6_0 V5_6_0
; ;
public static VersionEnum latestVersion() { public static VersionEnum latestVersion() {

View File

@ -3,14 +3,14 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-bom</artifactId> <artifactId>hapi-fhir-bom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>HAPI FHIR BOM</name> <name>HAPI FHIR BOM</name>
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -26,6 +26,7 @@ import org.apache.commons.cli.Options;
import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter; import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.csv.QuoteMode; import org.apache.commons.csv.QuoteMode;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.ConceptMap; import org.hl7.fhir.r4.model.ConceptMap;
@ -42,7 +43,6 @@ import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import static org.apache.commons.lang3.StringUtils.defaultString; import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.hl7.fhir.convertors.conv30_40.ConceptMap30_40.convertConceptMap;
public class ExportConceptMapToCsvCommand extends AbstractImportExportCsvConceptMapCommand { public class ExportConceptMapToCsvCommand extends AbstractImportExportCsvConceptMapCommand {
// TODO: Don't use qualified names for loggers in HAPI CLI. // TODO: Don't use qualified names for loggers in HAPI CLI.
@ -110,7 +110,7 @@ public class ExportConceptMapToCsvCommand extends AbstractImportExportCsvConcept
private void convertConceptMapToCsv(org.hl7.fhir.dstu3.model.ConceptMap theConceptMap) throws ExecutionException { private void convertConceptMapToCsv(org.hl7.fhir.dstu3.model.ConceptMap theConceptMap) throws ExecutionException {
try { try {
convertConceptMapToCsv(convertConceptMap(theConceptMap)); convertConceptMapToCsv((ConceptMap) VersionConvertorFactory_30_40.convertResource(theConceptMap));
} catch (FHIRException fe) { } catch (FHIRException fe) {
throw new ExecutionException(fe); throw new ExecutionException(fe);
} }

View File

@ -28,6 +28,7 @@ import org.apache.commons.cli.Options;
import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser; import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord; import org.apache.commons.csv.CSVRecord;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r4.model.ConceptMap; import org.hl7.fhir.r4.model.ConceptMap;
import org.hl7.fhir.r4.model.ConceptMap.ConceptMapGroupComponent; import org.hl7.fhir.r4.model.ConceptMap.ConceptMapGroupComponent;
@ -47,7 +48,6 @@ import java.util.concurrent.ExecutionException;
import static org.apache.commons.lang3.StringUtils.defaultString; import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.hl7.fhir.convertors.conv30_40.ConceptMap30_40.convertConceptMap;
public class ImportCsvToConceptMapCommand extends AbstractImportExportCsvConceptMapCommand { public class ImportCsvToConceptMapCommand extends AbstractImportExportCsvConceptMapCommand {
// TODO: Don't use qualified names for loggers in HAPI CLI. // TODO: Don't use qualified names for loggers in HAPI CLI.
@ -152,7 +152,7 @@ public class ImportCsvToConceptMapCommand extends AbstractImportExportCsvConcept
private org.hl7.fhir.dstu3.model.ConceptMap convertCsvToConceptMapDstu3() throws ExecutionException { private org.hl7.fhir.dstu3.model.ConceptMap convertCsvToConceptMapDstu3() throws ExecutionException {
try { try {
return convertConceptMap(convertCsvToConceptMapR4()); return (org.hl7.fhir.dstu3.model.ConceptMap) VersionConvertorFactory_30_40.convertResource(convertCsvToConceptMapR4());
} catch (FHIRException fe) { } catch (FHIRException fe) {
throw new ExecutionException(fe); throw new ExecutionException(fe);
} }

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-cli</artifactId> <artifactId>hapi-fhir-cli</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom</relativePath> <relativePath>../../hapi-deployable-pom</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>
@ -207,6 +207,16 @@
<artifactId>commons-compress</artifactId> <artifactId>commons-compress</artifactId>
<version>${commons_compress_version}</version> <version>${commons_compress_version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>22.0.0</version>
</dependency>
</additionalDependencies> </additionalDependencies>
</configuration> </configuration>
</plugin> </plugin>

View File

@ -29,11 +29,11 @@ import ca.uhn.fhir.rest.api.server.ResponseDetails;
import ca.uhn.fhir.rest.server.exceptions.AuthenticationException; import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.interceptor.InterceptorAdapter; import ca.uhn.fhir.rest.server.interceptor.InterceptorAdapter;
import org.hl7.fhir.converter.NullVersionConverterAdvisor30; import org.hl7.fhir.converter.NullVersionConverterAdvisor10_30;
import org.hl7.fhir.converter.NullVersionConverterAdvisor40; import org.hl7.fhir.converter.NullVersionConverterAdvisor10_40;
import org.hl7.fhir.convertors.VersionConvertor_10_30; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_30;
import org.hl7.fhir.convertors.VersionConvertor_10_40; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_40;
import org.hl7.fhir.convertors.VersionConvertor_30_40; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.Resource; import org.hl7.fhir.dstu3.model.Resource;
import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
@ -42,9 +42,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import static org.apache.commons.lang3.StringUtils.defaultString; import static org.apache.commons.lang3.StringUtils.*;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
/** /**
* <b>This is an experimental interceptor! Use with caution as * <b>This is an experimental interceptor! Use with caution as
@ -58,12 +56,12 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class VersionedApiConverterInterceptor extends InterceptorAdapter { public class VersionedApiConverterInterceptor extends InterceptorAdapter {
private final FhirContext myCtxDstu2; private final FhirContext myCtxDstu2;
private final FhirContext myCtxDstu2Hl7Org; private final FhirContext myCtxDstu2Hl7Org;
private final NullVersionConverterAdvisor40 advisor40; private final NullVersionConverterAdvisor10_40 advisor40;
private final NullVersionConverterAdvisor30 advisor30; private final NullVersionConverterAdvisor10_30 advisor30;
public VersionedApiConverterInterceptor() { public VersionedApiConverterInterceptor() {
advisor40 = new NullVersionConverterAdvisor40(); advisor40 = new NullVersionConverterAdvisor10_40();
advisor30 = new NullVersionConverterAdvisor30(); advisor30 = new NullVersionConverterAdvisor10_30();
myCtxDstu2 = FhirContext.forDstu2(); myCtxDstu2 = FhirContext.forDstu2();
myCtxDstu2Hl7Org = FhirContext.forDstu2Hl7Org(); myCtxDstu2Hl7Org = FhirContext.forDstu2Hl7Org();
@ -104,17 +102,17 @@ public class VersionedApiConverterInterceptor extends InterceptorAdapter {
IBaseResource converted = null; IBaseResource converted = null;
try { try {
if (wantVersion == FhirVersionEnum.R4 && haveVersion == FhirVersionEnum.DSTU3) { if (wantVersion == FhirVersionEnum.R4 && haveVersion == FhirVersionEnum.DSTU3) {
converted = VersionConvertor_30_40.convertResource(toDstu3(responseResource), true); converted = VersionConvertorFactory_30_40.convertResource(toDstu3(responseResource));
} else if (wantVersion == FhirVersionEnum.DSTU3 && haveVersion == FhirVersionEnum.R4) { } else if (wantVersion == FhirVersionEnum.DSTU3 && haveVersion == FhirVersionEnum.R4) {
converted = VersionConvertor_30_40.convertResource(toR4(responseResource), true); converted = VersionConvertorFactory_30_40.convertResource(toR4(responseResource));
} else if (wantVersion == FhirVersionEnum.DSTU2 && haveVersion == FhirVersionEnum.R4) { } else if (wantVersion == FhirVersionEnum.DSTU2 && haveVersion == FhirVersionEnum.R4) {
converted = VersionConvertor_10_40.convertResource(toR4(responseResource), advisor40); converted = VersionConvertorFactory_10_40.convertResource(toR4(responseResource), advisor40);
} else if (wantVersion == FhirVersionEnum.R4 && haveVersion == FhirVersionEnum.DSTU2) { } else if (wantVersion == FhirVersionEnum.R4 && haveVersion == FhirVersionEnum.DSTU2) {
converted = VersionConvertor_10_40.convertResource(toDstu2(responseResource), advisor40); converted = VersionConvertorFactory_10_40.convertResource(toDstu2(responseResource), advisor40);
} else if (wantVersion == FhirVersionEnum.DSTU2 && haveVersion == FhirVersionEnum.DSTU3) { } else if (wantVersion == FhirVersionEnum.DSTU2 && haveVersion == FhirVersionEnum.DSTU3) {
converted = VersionConvertor_10_30.convertResource(toDstu3(responseResource), advisor30); converted = VersionConvertorFactory_10_30.convertResource(toDstu3(responseResource), advisor30);
} else if (wantVersion == FhirVersionEnum.DSTU3 && haveVersion == FhirVersionEnum.DSTU2) { } else if (wantVersion == FhirVersionEnum.DSTU3 && haveVersion == FhirVersionEnum.DSTU2) {
converted = VersionConvertor_10_30.convertResource(toDstu2(responseResource), advisor30); converted = VersionConvertorFactory_10_30.convertResource(toDstu2(responseResource), advisor30);
} }
} catch (FHIRException e) { } catch (FHIRException e) {
throw new InternalErrorException(e); throw new InternalErrorException(e);

View File

@ -20,8 +20,7 @@ package org.hl7.fhir.converter;
* #L% * #L%
*/ */
import org.hl7.fhir.convertors.advisors.VersionConvertorAdvisor30; import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_10_30;
import org.hl7.fhir.dstu2.model.Resource;
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent; import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.dstu3.model.CodeSystem; import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.ValueSet; import org.hl7.fhir.dstu3.model.ValueSet;
@ -31,7 +30,7 @@ import org.hl7.fhir.r5.model.FhirPublication;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class NullVersionConverterAdvisor30 implements VersionConvertorAdvisor30 { public class NullVersionConverterAdvisor10_30 extends BaseAdvisor_10_30 {
@Nullable @Nullable

View File

@ -20,8 +20,7 @@ package org.hl7.fhir.converter;
* #L% * #L%
*/ */
import org.hl7.fhir.convertors.advisors.VersionConvertorAdvisor40; import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_10_40;
import org.hl7.fhir.dstu2.model.Resource;
import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent; import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r4.model.CodeSystem; import org.hl7.fhir.r4.model.CodeSystem;
@ -31,7 +30,7 @@ import org.hl7.fhir.r5.model.FhirPublication;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class NullVersionConverterAdvisor40 implements VersionConvertorAdvisor40 { public class NullVersionConverterAdvisor10_40 extends BaseAdvisor_10_40 {
@Nullable @Nullable

View File

@ -20,8 +20,8 @@ package org.hl7.fhir.converter;
* #L% * #L%
*/ */
import org.hl7.fhir.convertors.advisors.VersionConvertorAdvisor50; import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_10_50;
import org.hl7.fhir.dstu2.model.Resource; import org.hl7.fhir.convertors.conv10_50.VersionConvertor_10_50;
import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.r5.model.Bundle; import org.hl7.fhir.r5.model.Bundle;
import org.hl7.fhir.r5.model.CodeSystem; import org.hl7.fhir.r5.model.CodeSystem;
@ -32,7 +32,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.IdentityHashMap; import java.util.IdentityHashMap;
public class NullVersionConverterAdvisor50 implements VersionConvertorAdvisor50 { public class NullVersionConverterAdvisor10_50 extends BaseAdvisor_10_50 {
private IdentityHashMap<ValueSet, CodeSystem> myCodeSystems = new IdentityHashMap<>(); private IdentityHashMap<ValueSet, CodeSystem> myCodeSystems = new IdentityHashMap<>();

View File

@ -2,7 +2,7 @@ package org.hl7.fhir.converter;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import org.hl7.fhir.convertors.VersionConvertor_10_30; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_30;
import org.hl7.fhir.dstu3.model.*; import org.hl7.fhir.dstu3.model.*;
import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.dstu2.model.Resource; import org.hl7.fhir.dstu2.model.Resource;
@ -19,7 +19,7 @@ public class VersionConvertor_10_30Test {
org.hl7.fhir.dstu2.model.Observation input = new org.hl7.fhir.dstu2.model.Observation(); org.hl7.fhir.dstu2.model.Observation input = new org.hl7.fhir.dstu2.model.Observation();
input.setEncounter(new org.hl7.fhir.dstu2.model.Reference("Encounter/123")); input.setEncounter(new org.hl7.fhir.dstu2.model.Reference("Encounter/123"));
org.hl7.fhir.dstu3.model.Observation output = (Observation) VersionConvertor_10_30.convertResource(input); org.hl7.fhir.dstu3.model.Observation output = (Observation) VersionConvertorFactory_10_30.convertResource(input);
String context = output.getContext().getReference(); String context = output.getContext().getReference();
assertEquals("Encounter/123", context); assertEquals("Encounter/123", context);
@ -52,7 +52,7 @@ public class VersionConvertor_10_30Test {
Specimen.SpecimenContainerComponent specimenContainerComponent = new Specimen.SpecimenContainerComponent(); Specimen.SpecimenContainerComponent specimenContainerComponent = new Specimen.SpecimenContainerComponent();
specimenContainerComponent.getExtension().add(new Extension().setUrl("some_url").setValue(new StringType("some_value"))); specimenContainerComponent.getExtension().add(new Extension().setUrl("some_url").setValue(new StringType("some_value")));
spec.setContainer(Collections.singletonList(specimenContainerComponent)); spec.setContainer(Collections.singletonList(specimenContainerComponent));
Resource resource = VersionConvertor_10_30.convertResource(spec); Resource resource = VersionConvertorFactory_10_30.convertResource(spec);
} }

View File

@ -2,7 +2,7 @@ package org.hl7.fhir.converter;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import org.hl7.fhir.convertors.VersionConvertor_14_30; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_14_30;
import org.hl7.fhir.dstu3.model.Questionnaire; import org.hl7.fhir.dstu3.model.Questionnaire;
import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRException;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -15,7 +15,7 @@ public class VersionConvertor_14_30Test {
org.hl7.fhir.dstu2016may.model.Questionnaire input = new org.hl7.fhir.dstu2016may.model.Questionnaire(); org.hl7.fhir.dstu2016may.model.Questionnaire input = new org.hl7.fhir.dstu2016may.model.Questionnaire();
input.setTitle("My title"); input.setTitle("My title");
org.hl7.fhir.dstu3.model.Questionnaire output = (Questionnaire) VersionConvertor_14_30.convertResource(input); org.hl7.fhir.dstu3.model.Questionnaire output = (Questionnaire) VersionConvertorFactory_14_30.convertResource(input);
String context = output.getTitle(); String context = output.getTitle();
assertEquals("My title", context); assertEquals("My title", context);

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -20,36 +20,38 @@ package ca.uhn.hapi.fhir.docs;
* #L% * #L%
*/ */
import org.hl7.fhir.convertors.conv10_30.Observation10_30; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_30;
import org.hl7.fhir.convertors.conv14_30.Questionnaire14_30; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_14_30;
import org.hl7.fhir.dstu3.model.Observation;
import org.hl7.fhir.dstu3.model.Questionnaire;
import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRException;
public class ConverterExamples { public class ConverterExamples {
@SuppressWarnings("unused") @SuppressWarnings("unused")
public void c1020() throws FHIRException { public void c1020() throws FHIRException {
//START SNIPPET: 1020 //START SNIPPET: 1020
// Create an input resource to convert // Create an input resource to convert
org.hl7.fhir.dstu2.model.Observation input = new org.hl7.fhir.dstu2.model.Observation(); org.hl7.fhir.dstu2.model.Observation input = new org.hl7.fhir.dstu2.model.Observation();
input.setEncounter(new org.hl7.fhir.dstu2.model.Reference("Encounter/123")); input.setEncounter(new org.hl7.fhir.dstu2.model.Reference("Encounter/123"));
// Convert the resource // Convert the resource
org.hl7.fhir.dstu3.model.Observation output = Observation10_30.convertObservation(input); org.hl7.fhir.dstu3.model.Observation output = (Observation) VersionConvertorFactory_10_30.convertResource(input);
String context = output.getContext().getReference(); String context = output.getContext().getReference();
//END SNIPPET: 1020 //END SNIPPET: 1020
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
public void c1420() throws FHIRException { public void c1420() throws FHIRException {
//START SNIPPET: 1420 //START SNIPPET: 1420
// Create a resource to convert // Create a resource to convert
org.hl7.fhir.dstu2016may.model.Questionnaire input = new org.hl7.fhir.dstu2016may.model.Questionnaire(); org.hl7.fhir.dstu2016may.model.Questionnaire input = new org.hl7.fhir.dstu2016may.model.Questionnaire();
input.setTitle("My title"); input.setTitle("My title");
// Convert the resource // Convert the resource
org.hl7.fhir.dstu3.model.Questionnaire output = Questionnaire14_30.convertQuestionnaire(input); org.hl7.fhir.dstu3.model.Questionnaire output = (Questionnaire) VersionConvertorFactory_14_30.convertResource(input);
String context = output.getTitle(); String context = output.getTitle();
//END SNIPPET: 1420 //END SNIPPET: 1420
} }
} }

View File

@ -299,7 +299,7 @@ public class ValidatorExamples {
} }
@Override @Override
public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode) { public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode, String theDisplayLanguage) {
// TODO: implement (or return null if your implementation does not support this function) // TODO: implement (or return null if your implementation does not support this function)
return null; return null;
} }

View File

@ -0,0 +1,6 @@
---
type: fix
issue: 2868
jira: SMILE-1153
title: "Fixed a bug in transaction bundle processing, specifically for bundles which contained both a conditional create, and a resource which relied on this conditional create as a reference.
This would cause the referring resource to generate a contained resource instead of appropriately referencing the existing patient."

View File

@ -0,0 +1,5 @@
---
type: add
issue: 2871
title: "Modified the behaviour of the `:mdm` param qualifier. Previously, it used to only resolve IDs if the resource ID was a source resource.
Now, MDM expansion will work if you pass it the ID of a golden resource instead."

View File

@ -0,0 +1,6 @@
---
type: fix
issue: 2887
jira: SMILE-2896
title: "Fixed a bug where the search results cache was ignoring the value of `_contained` parameter when assigning a cache key.
This was causing queries run in a short period of time to return wrong cached results if one query used `_contained=true` and the other did not."

View File

@ -2,5 +2,4 @@
type: fix type: fix
issue: 2902 issue: 2902
jira: SMILE-3000 jira: SMILE-3000
backport: cust_fmc_5_3
title: "Fixed a bug wherein includes were not being included on revincludes." title: "Fixed a bug wherein includes were not being included on revincludes."

View File

@ -0,0 +1,4 @@
---
type: change
issue: 2904
title: "Change getPathItem method in OpenApiInterceptor from private to protected"

View File

@ -0,0 +1,4 @@
---
type: add
issue: 2905
title: "Added displayLanguage support for CodeSystem $lookup operation to filter out designation by language."

View File

@ -0,0 +1,6 @@
---
type: fix
issue: 2920
jira: SMILE-2971
title: "Previously, validation against bcp47 (urn:ietf:bcp:47) as a language would fail validation if the region was absent. This has been fixed, and the validate
operation will now correctly validate simple languages, e.g. `nl` instead of requiring `nl-DE` or `nl-NL`"

View File

@ -11,7 +11,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -40,6 +40,9 @@ public interface IFhirResourceDaoCodeSystem<T extends IBaseResource, CD, CC> ext
@Nonnull @Nonnull
IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, CD theCoding, RequestDetails theRequestDetails); IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, CD theCoding, RequestDetails theRequestDetails);
@Nonnull
IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, CD theCoding, IPrimitiveType<String> theDisplayLanguage, RequestDetails theRequestDetails);
SubsumesResult subsumes(IPrimitiveType<String> theCodeA, IPrimitiveType<String> theCodeB, IPrimitiveType<String> theSystem, CD theCodingA, CD theCodingB, RequestDetails theRequestDetails); SubsumesResult subsumes(IPrimitiveType<String> theCodeA, IPrimitiveType<String> theCodeB, IPrimitiveType<String> theSystem, CD theCodingA, CD theCodingB, RequestDetails theRequestDetails);
IValidationSupport.CodeValidationResult validateCode(IIdType theCodeSystemId, IPrimitiveType<String> theCodeSystemUrl, IPrimitiveType<String> theVersion, IPrimitiveType<String> theCode, IPrimitiveType<String> theDisplay, CD theCoding, CC theCodeableConcept, RequestDetails theRequestDetails); IValidationSupport.CodeValidationResult validateCode(IIdType theCodeSystemId, IPrimitiveType<String> theCodeSystemUrl, IPrimitiveType<String> theVersion, IPrimitiveType<String> theCode, IPrimitiveType<String> theDisplay, CD theCoding, CC theCodeableConcept, RequestDetails theRequestDetails);

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -20,6 +20,7 @@ package ca.uhn.fhir.jpa.cache;
* #L% * #L%
*/ */
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao; import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
@ -28,6 +29,7 @@ import ca.uhn.fhir.jpa.partition.SystemRequestDetails;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.util.QueryChunker; import ca.uhn.fhir.jpa.util.QueryChunker;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -36,12 +38,15 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.slf4j.LoggerFactory.getLogger;
/** /**
* This service builds a map of resource ids to versions based on a SearchParameterMap. * This service builds a map of resource ids to versions based on a SearchParameterMap.
* It is used by the in-memory resource-version cache to detect when resource versions have been changed by remote processes. * It is used by the in-memory resource-version cache to detect when resource versions have been changed by remote processes.
*/ */
@Service @Service
public class ResourceVersionSvcDaoImpl implements IResourceVersionSvc { public class ResourceVersionSvcDaoImpl implements IResourceVersionSvc {
private static final Logger ourLog = getLogger(ResourceVersionSvcDaoImpl.class);
@Autowired @Autowired
DaoRegistry myDaoRegistry; DaoRegistry myDaoRegistry;
@ -53,7 +58,11 @@ public class ResourceVersionSvcDaoImpl implements IResourceVersionSvc {
public ResourceVersionMap getVersionMap(String theResourceName, SearchParameterMap theSearchParamMap) { public ResourceVersionMap getVersionMap(String theResourceName, SearchParameterMap theSearchParamMap) {
IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(theResourceName); IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(theResourceName);
List<Long> matchingIds = dao.searchForIds(theSearchParamMap, new SystemRequestDetails()).stream() if (ourLog.isDebugEnabled()) {
ourLog.debug("About to retrieve version map for resource type: {}", theResourceName);
}
List<Long> matchingIds = dao.searchForIds(theSearchParamMap, new SystemRequestDetails().setRequestPartitionId(RequestPartitionId.allPartitions())).stream()
.map(ResourcePersistentId::getIdAsLong) .map(ResourcePersistentId::getIdAsLong)
.collect(Collectors.toList()); .collect(Collectors.toList());

View File

@ -94,6 +94,7 @@ import com.google.common.collect.Sets;
import com.google.common.hash.HashFunction; import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing; import com.google.common.hash.Hashing;
import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.NotImplementedException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBase;
@ -1162,10 +1163,8 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
validateResourceForStorage((T) theResource, entity); validateResourceForStorage((T) theResource, entity);
} }
} }
String resourceType = myContext.getResourceType(theResource); if (!StringUtils.isBlank(entity.getResourceType())) {
if (isNotBlank(entity.getResourceType()) && !entity.getResourceType().equals(resourceType)) { validateIncomingResourceTypeMatchesExisting(theResource, entity);
throw new UnprocessableEntityException(
"Existing resource ID[" + entity.getIdDt().toUnqualifiedVersionless() + "] is of type[" + entity.getResourceType() + "] - Cannot update with [" + resourceType + "]");
} }
} }
@ -1206,6 +1205,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
if (thePerformIndexing || ((ResourceTable) theEntity).getVersion() == 1) { if (thePerformIndexing || ((ResourceTable) theEntity).getVersion() == 1) {
newParams = new ResourceIndexedSearchParams(); newParams = new ResourceIndexedSearchParams();
mySearchParamWithInlineReferencesExtractor.populateFromResource(newParams, theTransactionDetails, entity, theResource, existingParams, theRequest, thePerformIndexing); mySearchParamWithInlineReferencesExtractor.populateFromResource(newParams, theTransactionDetails, entity, theResource, existingParams, theRequest, thePerformIndexing);
changed = populateResourceIntoEntity(theTransactionDetails, theRequest, theResource, entity, true); changed = populateResourceIntoEntity(theTransactionDetails, theRequest, theResource, entity, true);
@ -1415,6 +1415,14 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> extends BaseStora
return entity; return entity;
} }
private void validateIncomingResourceTypeMatchesExisting(IBaseResource theResource, ResourceTable entity) {
String resourceType = myContext.getResourceType(theResource);
if (!resourceType.equals(entity.getResourceType())) {
throw new UnprocessableEntityException(
"Existing resource ID[" + entity.getIdDt().toUnqualifiedVersionless() + "] is of type[" + entity.getResourceType() + "] - Cannot update with [" + resourceType + "]");
}
}
@Override @Override
public ResourceTable updateInternal(RequestDetails theRequestDetails, T theResource, boolean thePerformIndexing, boolean theForceUpdateVersion, public ResourceTable updateInternal(RequestDetails theRequestDetails, T theResource, boolean thePerformIndexing, boolean theForceUpdateVersion,
IBasePersistedResource theEntity, IIdType theResourceId, IBaseResource theOldResource, TransactionDetails theTransactionDetails) { IBasePersistedResource theEntity, IIdType theResourceId, IBaseResource theOldResource, TransactionDetails theTransactionDetails) {

View File

@ -90,6 +90,7 @@ import org.hl7.fhir.instance.model.api.IBaseReference;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.Task;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -803,6 +804,7 @@ public abstract class BaseTransactionProcessor {
String matchUrl = myVersionAdapter.getEntryRequestIfNoneExist(nextReqEntry); String matchUrl = myVersionAdapter.getEntryRequestIfNoneExist(nextReqEntry);
matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl); matchUrl = performIdSubstitutionsInMatchUrl(theIdSubstitutions, matchUrl);
outcome = resourceDao.create(res, matchUrl, false, theTransactionDetails, theRequest); outcome = resourceDao.create(res, matchUrl, false, theTransactionDetails, theRequest);
res.setId(outcome.getId());
if (nextResourceId != null) { if (nextResourceId != null) {
handleTransactionCreateOrUpdateOutcome(theIdSubstitutions, theIdToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res, theRequest); handleTransactionCreateOrUpdateOutcome(theIdSubstitutions, theIdToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res, theRequest);
} }
@ -1023,13 +1025,9 @@ public abstract class BaseTransactionProcessor {
for (IIdType next : theAllIds) { for (IIdType next : theAllIds) {
IIdType replacement = theIdSubstitutions.get(next); IIdType replacement = theIdSubstitutions.get(next);
if (replacement == null) { if (replacement != null && !replacement.equals(next)) {
continue; ourLog.debug("Placeholder resource ID \"{}\" was replaced with permanent ID \"{}\"", next, replacement);
} }
if (replacement.equals(next)) {
continue;
}
ourLog.debug("Placeholder resource ID \"{}\" was replaced with permanent ID \"{}\"", next, replacement);
} }
ListMultimap<Pointcut, HookParams> deferredBroadcastEvents = theTransactionDetails.endAcceptingDeferredInterceptorBroadcasts(); ListMultimap<Pointcut, HookParams> deferredBroadcastEvents = theTransactionDetails.endAcceptingDeferredInterceptorBroadcasts();
@ -1112,7 +1110,6 @@ public abstract class BaseTransactionProcessor {
} }
deferredIndexesForAutoVersioning.put(nextOutcome, referencesToAutoVersion); deferredIndexesForAutoVersioning.put(nextOutcome, referencesToAutoVersion);
} }
} }
// If we have any resources we'll be auto-versioning, index these next // If we have any resources we'll be auto-versioning, index these next

View File

@ -22,22 +22,14 @@ package ca.uhn.fhir.jpa.dao;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoSearchParameter; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoSearchParameter;
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoSearchParameterR4; import ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoSearchParameterR4;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor; import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
import ca.uhn.fhir.model.dstu2.resource.SearchParameter; import ca.uhn.fhir.model.dstu2.resource.SearchParameter;
import ca.uhn.fhir.model.dstu2.valueset.ResourceTypeEnum; import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_10_40;
import ca.uhn.fhir.model.dstu2.valueset.SearchParamTypeEnum; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_40;
import ca.uhn.fhir.model.primitive.BoundCodeDt;
import org.hl7.fhir.convertors.conv10_40.SearchParameter10_40;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
@ -79,7 +71,7 @@ public class FhirResourceDaoSearchParameterDstu2 extends BaseHapiFhirResourceDao
String encoded = getContext().newJsonParser().encodeResourceToString(theResource); String encoded = getContext().newJsonParser().encodeResourceToString(theResource);
org.hl7.fhir.dstu2.model.SearchParameter hl7Org = myDstu2Hl7OrgContext.newJsonParser().parseResource(org.hl7.fhir.dstu2.model.SearchParameter.class, encoded); org.hl7.fhir.dstu2.model.SearchParameter hl7Org = myDstu2Hl7OrgContext.newJsonParser().parseResource(org.hl7.fhir.dstu2.model.SearchParameter.class, encoded);
org.hl7.fhir.r4.model.SearchParameter convertedSp = SearchParameter10_40.convertSearchParameter(hl7Org); org.hl7.fhir.r4.model.SearchParameter convertedSp = (org.hl7.fhir.r4.model.SearchParameter) VersionConvertorFactory_10_40.convertResource(hl7Org, new BaseAdvisor_10_40(false));
if (isBlank(convertedSp.getExpression()) && isNotBlank(hl7Org.getXpath())) { if (isBlank(convertedSp.getExpression()) && isNotBlank(hl7Org.getXpath())) {
convertedSp.setExpression(hl7Org.getXpath()); convertedSp.setExpression(hl7Org.getXpath());
} }

View File

@ -230,7 +230,13 @@ public class FhirResourceDaoValueSetDstu2 extends BaseHapiFhirResourceDao<ValueS
@Nonnull @Nonnull
@Override @Override
public IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, CodingDt theCoding, RequestDetails theRequest) { public IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, CodingDt theCoding, RequestDetails theRequest) {
return lookupCode(theCode, theSystem, theCoding, null, theRequest);
}
@Nonnull
@Override
public IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, CodingDt theCoding, IPrimitiveType<String> theDisplayLanguage, RequestDetails theRequest) {
boolean haveCoding = theCoding != null && isNotBlank(theCoding.getSystem()) && isNotBlank(theCoding.getCode()); boolean haveCoding = theCoding != null && isNotBlank(theCoding.getSystem()) && isNotBlank(theCoding.getCode());
boolean haveCode = theCode != null && theCode.isEmpty() == false; boolean haveCode = theCode != null && theCode.isEmpty() == false;
boolean haveSystem = theSystem != null && theSystem.isEmpty() == false; boolean haveSystem = theSystem != null && theSystem.isEmpty() == false;

View File

@ -46,6 +46,7 @@ import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseBundle; import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import javax.annotation.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -61,10 +62,12 @@ import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root; import javax.persistence.criteria.Root;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.IdentityHashMap; import java.util.IdentityHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -218,18 +221,9 @@ public class TransactionProcessor extends BaseTransactionProcessor {
IQueryParameterType param = andList.get(0).get(0); IQueryParameterType param = andList.get(0).get(0);
if (param instanceof TokenParam) { if (param instanceof TokenParam) {
TokenParam tokenParam = (TokenParam) param; Predicate hashPredicate = buildHashPredicateFromTokenParam((TokenParam)param, requestPartitionId, cb, from, next);
Predicate hashPredicate = null;
if (isNotBlank(tokenParam.getValue()) && isNotBlank(tokenParam.getSystem())) {
next.myHashSystemAndValue = ResourceIndexedSearchParamToken.calculateHashSystemAndValue(myPartitionSettings, requestPartitionId, next.myResourceDefinition.getName(), next.myMatchUrlSearchMap.keySet().iterator().next(), tokenParam.getSystem(), tokenParam.getValue());
hashPredicate = cb.equal(from.get("myHashSystemAndValue").as(Long.class), next.myHashSystemAndValue);
} else if (isNotBlank(tokenParam.getValue())) {
next.myHashValue = ResourceIndexedSearchParamToken.calculateHashValue(myPartitionSettings, requestPartitionId, next.myResourceDefinition.getName(), next.myMatchUrlSearchMap.keySet().iterator().next(), tokenParam.getValue());
hashPredicate = cb.equal(from.get("myHashValue").as(Long.class), next.myHashValue);
}
if (hashPredicate != null) { if (hashPredicate != null) {
if (myPartitionSettings.isPartitioningEnabled() && !myPartitionSettings.isIncludePartitionInSearchHashes()) { if (myPartitionSettings.isPartitioningEnabled() && !myPartitionSettings.isIncludePartitionInSearchHashes()) {
if (requestPartitionId.isDefaultPartition()) { if (requestPartitionId.isDefaultPartition()) {
Predicate partitionIdCriteria = cb.isNull(from.get("myPartitionIdValue").as(Integer.class)); Predicate partitionIdCriteria = cb.isNull(from.get("myPartitionIdValue").as(Integer.class));
@ -250,35 +244,26 @@ public class TransactionProcessor extends BaseTransactionProcessor {
if (orPredicates.size() > 1) { if (orPredicates.size() > 1) {
cq.where(cb.or(orPredicates.toArray(EMPTY_PREDICATE_ARRAY))); cq.where(cb.or(orPredicates.toArray(EMPTY_PREDICATE_ARRAY)));
Map<Long, MatchUrlToResolve> hashToSearchMap = buildHashToSearchMap(searchParameterMapsToResolve);
TypedQuery<ResourceIndexedSearchParamToken> query = myEntityManager.createQuery(cq); TypedQuery<ResourceIndexedSearchParamToken> query = myEntityManager.createQuery(cq);
List<ResourceIndexedSearchParamToken> results = query.getResultList(); List<ResourceIndexedSearchParamToken> results = query.getResultList();
for (ResourceIndexedSearchParamToken nextResult : results) { for (ResourceIndexedSearchParamToken nextResult : results) {
Optional<MatchUrlToResolve> matchedSearch = Optional.ofNullable(hashToSearchMap.get(nextResult.getHashSystemAndValue()));
for (MatchUrlToResolve nextSearchParameterMap : searchParameterMapsToResolve) { if (!matchedSearch.isPresent()) {
if (nextSearchParameterMap.myHashSystemAndValue != null && nextSearchParameterMap.myHashSystemAndValue.equals(nextResult.getHashSystemAndValue())) { matchedSearch = Optional.ofNullable(hashToSearchMap.get(nextResult.getHashValue()));
idsToPreFetch.add(nextResult.getResourcePid());
myMatchResourceUrlService.matchUrlResolved(theTransactionDetails, nextSearchParameterMap.myResourceDefinition.getName(), nextSearchParameterMap.myRequestUrl, new ResourcePersistentId(nextResult.getResourcePid()));
theTransactionDetails.addResolvedMatchUrl(nextSearchParameterMap.myRequestUrl, new ResourcePersistentId(nextResult.getResourcePid()));
nextSearchParameterMap.myResolved = true;
}
if (nextSearchParameterMap.myHashValue != null && nextSearchParameterMap.myHashValue.equals(nextResult.getHashValue())) {
idsToPreFetch.add(nextResult.getResourcePid());
myMatchResourceUrlService.matchUrlResolved(theTransactionDetails, nextSearchParameterMap.myResourceDefinition.getName(), nextSearchParameterMap.myRequestUrl, new ResourcePersistentId(nextResult.getResourcePid()));
theTransactionDetails.addResolvedMatchUrl(nextSearchParameterMap.myRequestUrl, new ResourcePersistentId(nextResult.getResourcePid()));
nextSearchParameterMap.myResolved = true;
}
} }
matchedSearch.ifPresent(matchUrlToResolve -> setSearchToResolvedAndPrefetchFoundResourcePid(theTransactionDetails, idsToPreFetch, nextResult, matchUrlToResolve));
} }
//For each SP Map which did not return a result, tag it as not found.
for (MatchUrlToResolve nextSearchParameterMap : searchParameterMapsToResolve) { searchParameterMapsToResolve.stream()
// No matches // No matches
if (!nextSearchParameterMap.myResolved) { .filter(match -> !match.myResolved)
theTransactionDetails.addResolvedMatchUrl(nextSearchParameterMap.myRequestUrl, TransactionDetails.NOT_FOUND); .forEach(match -> {
} ourLog.warn("Was unable to match url {} from database", match.myRequestUrl);
} theTransactionDetails.addResolvedMatchUrl(match.myRequestUrl, TransactionDetails.NOT_FOUND);
});
} }
} }
@ -320,6 +305,45 @@ public class TransactionProcessor extends BaseTransactionProcessor {
return super.doTransactionWriteOperations(theRequest, theActionName, theTransactionDetails, theAllIds, theIdSubstitutions, theIdToPersistedOutcome, theResponse, theOriginalRequestOrder, theEntries, theTransactionStopWatch); return super.doTransactionWriteOperations(theRequest, theActionName, theTransactionDetails, theAllIds, theIdSubstitutions, theIdToPersistedOutcome, theResponse, theOriginalRequestOrder, theEntries, theTransactionStopWatch);
} }
/**
* Given a token parameter, build the query predicate based on its hash. Uses system and value if both are available, otherwise just value.
* If neither are available, it returns null.
*/
@Nullable
private Predicate buildHashPredicateFromTokenParam(TokenParam theTokenParam, RequestPartitionId theRequestPartitionId, CriteriaBuilder cb, Root<ResourceIndexedSearchParamToken> from, MatchUrlToResolve theMatchUrl) {
Predicate hashPredicate = null;
if (isNotBlank(theTokenParam.getValue()) && isNotBlank(theTokenParam.getSystem())) {
theMatchUrl.myHashSystemAndValue = ResourceIndexedSearchParamToken.calculateHashSystemAndValue(myPartitionSettings, theRequestPartitionId, theMatchUrl.myResourceDefinition.getName(), theMatchUrl.myMatchUrlSearchMap.keySet().iterator().next(), theTokenParam.getSystem(), theTokenParam.getValue());
hashPredicate = cb.equal(from.get("myHashSystemAndValue").as(Long.class), theMatchUrl.myHashSystemAndValue);
} else if (isNotBlank(theTokenParam.getValue())) {
theMatchUrl.myHashValue = ResourceIndexedSearchParamToken.calculateHashValue(myPartitionSettings, theRequestPartitionId, theMatchUrl.myResourceDefinition.getName(), theMatchUrl.myMatchUrlSearchMap.keySet().iterator().next(), theTokenParam.getValue());
hashPredicate = cb.equal(from.get("myHashValue").as(Long.class), theMatchUrl.myHashValue);
}
return hashPredicate;
}
private Map<Long, MatchUrlToResolve> buildHashToSearchMap(List<MatchUrlToResolve> searchParameterMapsToResolve) {
Map<Long, MatchUrlToResolve> hashToSearch = new HashMap<>();
//Build a lookup map so we don't have to iterate over the searches repeatedly.
for (MatchUrlToResolve nextSearchParameterMap : searchParameterMapsToResolve) {
if (nextSearchParameterMap.myHashSystemAndValue != null) {
hashToSearch.put(nextSearchParameterMap.myHashSystemAndValue, nextSearchParameterMap);
}
if (nextSearchParameterMap.myHashValue!= null) {
hashToSearch.put(nextSearchParameterMap.myHashValue, nextSearchParameterMap);
}
}
return hashToSearch;
}
private void setSearchToResolvedAndPrefetchFoundResourcePid(TransactionDetails theTransactionDetails, List<Long> idsToPreFetch, ResourceIndexedSearchParamToken nextResult, MatchUrlToResolve nextSearchParameterMap) {
ourLog.warn("Matched url {} from database", nextSearchParameterMap.myRequestUrl);
idsToPreFetch.add(nextResult.getResourcePid());
myMatchResourceUrlService.matchUrlResolved(theTransactionDetails, nextSearchParameterMap.myResourceDefinition.getName(), nextSearchParameterMap.myRequestUrl, new ResourcePersistentId(nextResult.getResourcePid()));
theTransactionDetails.addResolvedMatchUrl(nextSearchParameterMap.myRequestUrl, new ResourcePersistentId(nextResult.getResourcePid()));
nextSearchParameterMap.setResolved(true);
}
private List<ResourceTable> preFetchIndexes(List<Long> ids, String typeDesc, String fieldName) { private List<ResourceTable> preFetchIndexes(List<Long> ids, String typeDesc, String fieldName) {
TypedQuery<ResourceTable> query = myEntityManager.createQuery("FROM ResourceTable r LEFT JOIN FETCH r." + fieldName + " WHERE r.myId IN ( :IDS )", ResourceTable.class); TypedQuery<ResourceTable> query = myEntityManager.createQuery("FROM ResourceTable r LEFT JOIN FETCH r." + fieldName + " WHERE r.myId IN ( :IDS )", ResourceTable.class);
query.setParameter("IDS", ids); query.setParameter("IDS", ids);
@ -379,5 +403,8 @@ public class TransactionProcessor extends BaseTransactionProcessor {
myMatchUrlSearchMap = theMatchUrlSearchMap; myMatchUrlSearchMap = theMatchUrlSearchMap;
myResourceDefinition = theResourceDefinition; myResourceDefinition = theResourceDefinition;
} }
public void setResolved(boolean theResolved) {
myResolved = theResolved;
}
} }
} }

View File

@ -67,4 +67,7 @@ public interface IMdmLinkDao extends JpaRepository<MdmLink, Long> {
"AND ml.myMatchResult=:matchResult") "AND ml.myMatchResult=:matchResult")
List<MdmPidTuple> expandPidsBySourcePidAndMatchResult(@Param("sourcePid") Long theSourcePid, @Param("matchResult") MdmMatchResultEnum theMdmMatchResultEnum); List<MdmPidTuple> expandPidsBySourcePidAndMatchResult(@Param("sourcePid") Long theSourcePid, @Param("matchResult") MdmMatchResultEnum theMdmMatchResultEnum);
@Query("SELECT ml.myGoldenResourcePid as goldenPid, ml.mySourcePid as sourcePid FROM MdmLink ml WHERE ml.myGoldenResourcePid = :goldenPid and ml.myMatchResult = :matchResult")
List<MdmPidTuple> expandPidsByGoldenResourcePidAndMatchResult(@Param("goldenPid") Long theSourcePid, @Param("matchResult") MdmMatchResultEnum theMdmMatchResultEnum);
} }

View File

@ -27,16 +27,18 @@ import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoCodeSystem; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao; import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource; import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc; import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
import ca.uhn.fhir.jpa.util.LogicUtil; import ca.uhn.fhir.jpa.util.LogicUtil;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.CodeSystem; import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.CodeableConcept; import org.hl7.fhir.dstu3.model.CodeableConcept;
import org.hl7.fhir.dstu3.model.Coding; import org.hl7.fhir.dstu3.model.Coding;
@ -53,7 +55,6 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.hl7.fhir.convertors.conv30_40.CodeSystem30_40.convertCodeSystem;
@Transactional @Transactional
public class FhirResourceDaoCodeSystemDstu3 extends BaseHapiFhirResourceDao<CodeSystem> implements IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> { public class FhirResourceDaoCodeSystemDstu3 extends BaseHapiFhirResourceDao<CodeSystem> implements IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> {
@ -86,10 +87,17 @@ public class FhirResourceDaoCodeSystemDstu3 extends BaseHapiFhirResourceDao<Code
@Nonnull @Nonnull
@Override @Override
public IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, Coding theCoding, RequestDetails theRequestDetails) { public IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, Coding theCoding, RequestDetails theRequestDetails) {
return lookupCode(theCode, theSystem, theCoding, null, theRequestDetails);
}
@Nonnull
@Override
public IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, Coding theCoding, IPrimitiveType<String> theDisplayLanguage, RequestDetails theRequestDetails) {
boolean haveCoding = theCoding != null && isNotBlank(theCoding.getSystem()) && isNotBlank(theCoding.getCode()); boolean haveCoding = theCoding != null && isNotBlank(theCoding.getSystem()) && isNotBlank(theCoding.getCode());
boolean haveCode = theCode != null && theCode.isEmpty() == false; boolean haveCode = theCode != null && theCode.isEmpty() == false;
boolean haveSystem = theSystem != null && theSystem.isEmpty() == false; boolean haveSystem = theSystem != null && theSystem.isEmpty() == false;
boolean haveDisplayLanguage = theDisplayLanguage != null && theDisplayLanguage.isEmpty() == false;
if (!haveCoding && !(haveSystem && haveCode)) { if (!haveCoding && !(haveSystem && haveCode)) {
throw new InvalidRequestException("No code, coding, or codeableConcept provided to validate"); throw new InvalidRequestException("No code, coding, or codeableConcept provided to validate");
} }
@ -111,11 +119,16 @@ public class FhirResourceDaoCodeSystemDstu3 extends BaseHapiFhirResourceDao<Code
system = theSystem.getValue(); system = theSystem.getValue();
} }
String displayLanguage = null;
if (haveDisplayLanguage) {
displayLanguage = theDisplayLanguage.getValue();
}
ourLog.debug("Looking up {} / {}", system, code); ourLog.debug("Looking up {} / {}", system, code);
if (myValidationSupport.isCodeSystemSupported(new ValidationSupportContext(myValidationSupport), system)) { if (myValidationSupport.isCodeSystemSupported(new ValidationSupportContext(myValidationSupport), system)) {
ourLog.debug("Code system {} is supported", system); ourLog.debug("Code system {} is supported", system);
IValidationSupport.LookupCodeResult result = myValidationSupport.lookupCode(new ValidationSupportContext(myValidationSupport), system, code); IValidationSupport.LookupCodeResult result = myValidationSupport.lookupCode(new ValidationSupportContext(myValidationSupport), system, code, displayLanguage);
if (result != null) { if (result != null) {
return result; return result;
} }
@ -146,7 +159,7 @@ public class FhirResourceDaoCodeSystemDstu3 extends BaseHapiFhirResourceDao<Code
CodeSystem csDstu3 = (CodeSystem) theResource; CodeSystem csDstu3 = (CodeSystem) theResource;
org.hl7.fhir.r4.model.CodeSystem cs = convertCodeSystem(csDstu3); org.hl7.fhir.r4.model.CodeSystem cs = (org.hl7.fhir.r4.model.CodeSystem) VersionConvertorFactory_30_40.convertResource(csDstu3, new BaseAdvisor_30_40(false));
addPidToResource(theEntity, cs); addPidToResource(theEntity, cs);
myTerminologyCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(cs, (ResourceTable) theEntity); myTerminologyCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(cs, (ResourceTable) theEntity);
@ -157,9 +170,9 @@ public class FhirResourceDaoCodeSystemDstu3 extends BaseHapiFhirResourceDao<Code
} }
@Override @Override
public CodeValidationResult validateCode(IIdType theCodeSystemId, IPrimitiveType<String> theCodeSystemUrl, IPrimitiveType<String> theVersion, IPrimitiveType<String> theCode, public CodeValidationResult validateCode(IIdType theCodeSystemId, IPrimitiveType<String> theCodeSystemUrl, IPrimitiveType<String> theVersion, IPrimitiveType<String> theCode,
IPrimitiveType<String> theDisplay, Coding theCoding, CodeableConcept theCodeableConcept, RequestDetails theRequestDetails) { IPrimitiveType<String> theDisplay, Coding theCoding, CodeableConcept theCodeableConcept, RequestDetails theRequestDetails) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
} }

View File

@ -20,9 +20,9 @@ package ca.uhn.fhir.jpa.dao.dstu3;
* #L% * #L%
*/ */
import ca.uhn.fhir.context.support.TranslateConceptResults;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoConceptMap; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoConceptMap;
import ca.uhn.fhir.jpa.api.model.TranslationRequest; import ca.uhn.fhir.jpa.api.model.TranslationRequest;
import ca.uhn.fhir.context.support.TranslateConceptResults;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao; import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource; import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
@ -30,6 +30,8 @@ import ca.uhn.fhir.jpa.term.api.ITermConceptMappingSvc;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.ConceptMap; import org.hl7.fhir.dstu3.model.ConceptMap;
import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
@ -37,8 +39,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import java.util.Date; import java.util.Date;
import static org.hl7.fhir.convertors.conv30_40.ConceptMap30_40.convertConceptMap;
public class FhirResourceDaoConceptMapDstu3 extends BaseHapiFhirResourceDao<ConceptMap> implements IFhirResourceDaoConceptMap<ConceptMap> { public class FhirResourceDaoConceptMapDstu3 extends BaseHapiFhirResourceDao<ConceptMap> implements IFhirResourceDaoConceptMap<ConceptMap> {
@Autowired @Autowired
private ITermConceptMappingSvc myTermConceptMappingSvc; private ITermConceptMappingSvc myTermConceptMappingSvc;
@ -53,7 +53,6 @@ public class FhirResourceDaoConceptMapDstu3 extends BaseHapiFhirResourceDao<Conc
} }
@Override @Override
public ResourceTable updateEntity(RequestDetails theRequestDetails, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing, public ResourceTable updateEntity(RequestDetails theRequestDetails, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, TransactionDetails theTransactionDetails, boolean theForceUpdate, boolean theCreateNewHistoryEntry) { boolean theUpdateVersion, TransactionDetails theTransactionDetails, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
@ -63,7 +62,7 @@ public class FhirResourceDaoConceptMapDstu3 extends BaseHapiFhirResourceDao<Conc
if (retVal.getDeleted() == null) { if (retVal.getDeleted() == null) {
try { try {
ConceptMap conceptMap = (ConceptMap) theResource; ConceptMap conceptMap = (ConceptMap) theResource;
org.hl7.fhir.r4.model.ConceptMap converted = convertConceptMap(conceptMap); org.hl7.fhir.r4.model.ConceptMap converted = (org.hl7.fhir.r4.model.ConceptMap) VersionConvertorFactory_30_40.convertResource(conceptMap, new BaseAdvisor_30_40(false));
myTermConceptMappingSvc.storeTermConceptMapAndChildren(retVal, converted); myTermConceptMappingSvc.storeTermConceptMapAndChildren(retVal, converted);
} catch (FHIRException fe) { } catch (FHIRException fe) {
throw new InternalErrorException(fe); throw new InternalErrorException(fe);

View File

@ -1,20 +1,15 @@
package ca.uhn.fhir.jpa.dao.dstu3; package ca.uhn.fhir.jpa.dao.dstu3;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoSearchParameter; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoSearchParameter;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao; import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoSearchParameterR4; import ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoSearchParameterR4;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor; import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
import org.hl7.fhir.convertors.conv10_40.SearchParameter10_40; import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.conv30_40.SearchParameter30_40; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.CodeType;
import org.hl7.fhir.dstu3.model.Enumerations;
import org.hl7.fhir.dstu3.model.SearchParameter; import org.hl7.fhir.dstu3.model.SearchParameter;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/* /*
* #%L * #%L
* HAPI FHIR JPA Server * HAPI FHIR JPA Server
@ -69,7 +64,9 @@ public class FhirResourceDaoSearchParameterDstu3 extends BaseHapiFhirResourceDao
protected void validateResourceForStorage(SearchParameter theResource, ResourceTable theEntityToSave) { protected void validateResourceForStorage(SearchParameter theResource, ResourceTable theEntityToSave) {
super.validateResourceForStorage(theResource, theEntityToSave); super.validateResourceForStorage(theResource, theEntityToSave);
FhirResourceDaoSearchParameterR4.validateSearchParam(SearchParameter30_40.convertSearchParameter(theResource), getContext(), getConfig(), mySearchParamRegistry, mySearchParamExtractor); FhirResourceDaoSearchParameterR4.validateSearchParam(
(org.hl7.fhir.r4.model.SearchParameter) VersionConvertorFactory_30_40.convertResource(theResource, new BaseAdvisor_30_40(false)),
getContext(), getConfig(), mySearchParamRegistry, mySearchParamExtractor);
} }
} }

View File

@ -30,7 +30,8 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import org.hl7.fhir.convertors.conv30_40.ValueSet30_40; import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.CodeableConcept; import org.hl7.fhir.dstu3.model.CodeableConcept;
import org.hl7.fhir.dstu3.model.Coding; import org.hl7.fhir.dstu3.model.Coding;
import org.hl7.fhir.dstu3.model.ValueSet; import org.hl7.fhir.dstu3.model.ValueSet;
@ -42,7 +43,6 @@ import org.hl7.fhir.instance.model.api.IPrimitiveType;
import java.util.Date; import java.util.Date;
import static ca.uhn.fhir.jpa.dao.FhirResourceDaoValueSetDstu2.toStringOrNull; import static ca.uhn.fhir.jpa.dao.FhirResourceDaoValueSetDstu2.toStringOrNull;
import static org.hl7.fhir.convertors.conv30_40.ValueSet30_40.convertValueSet;
public class FhirResourceDaoValueSetDstu3 extends BaseHapiFhirResourceDao<ValueSet> implements IFhirResourceDaoValueSet<ValueSet, Coding, CodeableConcept> { public class FhirResourceDaoValueSetDstu3 extends BaseHapiFhirResourceDao<ValueSet> implements IFhirResourceDaoValueSet<ValueSet, Coding, CodeableConcept> {
@ -54,15 +54,15 @@ public class FhirResourceDaoValueSetDstu3 extends BaseHapiFhirResourceDao<ValueS
@Override @Override
public org.hl7.fhir.dstu3.model.ValueSet expand(org.hl7.fhir.dstu3.model.ValueSet theSource, ValueSetExpansionOptions theOptions) { public org.hl7.fhir.dstu3.model.ValueSet expand(org.hl7.fhir.dstu3.model.ValueSet theSource, ValueSetExpansionOptions theOptions) {
org.hl7.fhir.r4.model.ValueSet canonicalInput = ValueSet30_40.convertValueSet(theSource); org.hl7.fhir.r4.model.ValueSet canonicalInput = (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_30_40.convertResource(theSource, new BaseAdvisor_30_40(false));
org.hl7.fhir.r4.model.ValueSet canonicalOutput = myTerminologySvc.expandValueSet(theOptions, canonicalInput); org.hl7.fhir.r4.model.ValueSet canonicalOutput = myTerminologySvc.expandValueSet(theOptions, canonicalInput);
return ValueSet30_40.convertValueSet(canonicalOutput); return (ValueSet) VersionConvertorFactory_30_40.convertResource(canonicalOutput, new BaseAdvisor_30_40(false));
} }
@Override @Override
public org.hl7.fhir.dstu3.model.ValueSet expandByIdentifier(String theUri, ValueSetExpansionOptions theOptions) { public org.hl7.fhir.dstu3.model.ValueSet expandByIdentifier(String theUri, ValueSetExpansionOptions theOptions) {
org.hl7.fhir.r4.model.ValueSet canonicalOutput = myTerminologySvc.expandValueSet(theOptions, theUri); org.hl7.fhir.r4.model.ValueSet canonicalOutput = myTerminologySvc.expandValueSet(theOptions, theUri);
return ValueSet30_40.convertValueSet(canonicalOutput); return (ValueSet) VersionConvertorFactory_30_40.convertResource(canonicalOutput, new BaseAdvisor_30_40(false));
} }
@Override @Override
@ -86,7 +86,7 @@ public class FhirResourceDaoValueSetDstu3 extends BaseHapiFhirResourceDao<ValueS
if (retVal.getDeleted() == null) { if (retVal.getDeleted() == null) {
try { try {
ValueSet valueSet = (ValueSet) theResource; ValueSet valueSet = (ValueSet) theResource;
org.hl7.fhir.r4.model.ValueSet converted = convertValueSet(valueSet); org.hl7.fhir.r4.model.ValueSet converted = (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_30_40.convertResource(valueSet, new BaseAdvisor_30_40(false));
myTerminologySvc.storeTermValueSet(retVal, converted); myTerminologySvc.storeTermValueSet(retVal, converted);
} catch (FHIRException fe) { } catch (FHIRException fe) {
throw new InternalErrorException(fe); throw new InternalErrorException(fe);

View File

@ -55,7 +55,7 @@ import com.google.common.annotations.VisibleForTesting;
import org.hl7.fhir.instance.model.api.IBaseReference; import org.hl7.fhir.instance.model.api.IBaseReference;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.jetbrains.annotations.Nullable; import javax.annotation.Nullable;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;

View File

@ -25,15 +25,13 @@ import ca.uhn.fhir.jpa.dao.index.IdHelperService;
import ca.uhn.fhir.mdm.api.MdmMatchResultEnum; import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
import ca.uhn.fhir.mdm.log.Logs; import ca.uhn.fhir.mdm.log.Logs;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import javax.annotation.Nonnull;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -82,14 +80,50 @@ public class MdmLinkExpandSvc {
public Set<String> expandMdmBySourceResourcePid(Long theSourceResourcePid) { public Set<String> expandMdmBySourceResourcePid(Long theSourceResourcePid) {
ourLog.debug("About to expand source resource with PID {}", theSourceResourcePid); ourLog.debug("About to expand source resource with PID {}", theSourceResourcePid);
List<IMdmLinkDao.MdmPidTuple> goldenPidSourcePidTuples = myMdmLinkDao.expandPidsBySourcePidAndMatchResult(theSourceResourcePid, MdmMatchResultEnum.MATCH); List<IMdmLinkDao.MdmPidTuple> goldenPidSourcePidTuples = myMdmLinkDao.expandPidsBySourcePidAndMatchResult(theSourceResourcePid, MdmMatchResultEnum.MATCH);
return flattenPidTuplesToSet(theSourceResourcePid, goldenPidSourcePidTuples);
}
/**
* Given a PID of a golden resource, perform MDM expansion and return all the resource IDs of all resources that are
* MDM-Matched to this golden resource.
*
* @param theGoldenResourcePid The PID of the golden resource to MDM-Expand.
* @return A set of strings representing the FHIR ids of the expanded resources.
*/
public Set<String> expandMdmByGoldenResourceId(Long theGoldenResourcePid) {
ourLog.debug("About to expand golden resource with PID {}", theGoldenResourcePid);
List<IMdmLinkDao.MdmPidTuple> goldenPidSourcePidTuples = myMdmLinkDao.expandPidsByGoldenResourcePidAndMatchResult(theGoldenResourcePid, MdmMatchResultEnum.MATCH);
return flattenPidTuplesToSet(theGoldenResourcePid, goldenPidSourcePidTuples);
}
/**
* Given a resource ID of a golden resource, perform MDM expansion and return all the resource IDs of all resources that are
* MDM-Matched to this golden resource.
*
* @param theGoldenResourcePid The resource ID of the golden resource to MDM-Expand.
* @return A set of strings representing the FHIR ids of the expanded resources.
*/
public Set<String> expandMdmByGoldenResourcePid(Long theGoldenResourcePid) {
ourLog.debug("About to expand golden resource with PID {}", theGoldenResourcePid);
List<IMdmLinkDao.MdmPidTuple> goldenPidSourcePidTuples = myMdmLinkDao.expandPidsByGoldenResourcePidAndMatchResult(theGoldenResourcePid, MdmMatchResultEnum.MATCH);
return flattenPidTuplesToSet(theGoldenResourcePid, goldenPidSourcePidTuples);
}
public Set<String> expandMdmByGoldenResourceId(IdDt theId) {
ourLog.debug("About to expand golden resource with golden resource id {}", theId);
Long pidOrThrowException = myIdHelperService.getPidOrThrowException(theId);
return expandMdmByGoldenResourcePid(pidOrThrowException);
}
@Nonnull
private Set<String> flattenPidTuplesToSet(Long initialPid, List<IMdmLinkDao.MdmPidTuple> goldenPidSourcePidTuples) {
Set<Long> flattenedPids = new HashSet<>(); Set<Long> flattenedPids = new HashSet<>();
goldenPidSourcePidTuples.forEach(tuple -> { goldenPidSourcePidTuples.forEach(tuple -> {
flattenedPids.add(tuple.getSourcePid()); flattenedPids.add(tuple.getSourcePid());
flattenedPids.add(tuple.getGoldenPid()); flattenedPids.add(tuple.getGoldenPid());
}); });
Set<String> resourceIds = myIdHelperService.translatePidsToFhirResourceIds(flattenedPids); Set<String> resourceIds = myIdHelperService.translatePidsToFhirResourceIds(flattenedPids);
ourLog.debug("Pid {} has been expanded to [{}]", theSourceResourcePid, String.join(",", resourceIds)); ourLog.debug("Pid {} has been expanded to [{}]", initialPid, String.join(",", resourceIds));
return resourceIds; return resourceIds;
} }
} }

View File

@ -82,9 +82,16 @@ public class FhirResourceDaoCodeSystemR4 extends BaseHapiFhirResourceDao<CodeSys
@Nonnull @Nonnull
@Override @Override
public IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, Coding theCoding, RequestDetails theRequestDetails) { public IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, Coding theCoding, RequestDetails theRequestDetails) {
return lookupCode(theCode, theSystem, theCoding, null, theRequestDetails);
}
@Nonnull
@Override
public IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, Coding theCoding, IPrimitiveType<String> theDisplayLanguage, RequestDetails theRequestDetails) {
boolean haveCoding = theCoding != null && isNotBlank(theCoding.getSystem()) && isNotBlank(theCoding.getCode()); boolean haveCoding = theCoding != null && isNotBlank(theCoding.getSystem()) && isNotBlank(theCoding.getCode());
boolean haveCode = theCode != null && theCode.isEmpty() == false; boolean haveCode = theCode != null && theCode.isEmpty() == false;
boolean haveSystem = theSystem != null && theSystem.isEmpty() == false; boolean haveSystem = theSystem != null && theSystem.isEmpty() == false;
boolean haveDisplayLanguage = theDisplayLanguage != null && theDisplayLanguage.isEmpty() == false;
if (!haveCoding && !(haveSystem && haveCode)) { if (!haveCoding && !(haveSystem && haveCode)) {
throw new InvalidRequestException("No code, coding, or codeableConcept provided to validate"); throw new InvalidRequestException("No code, coding, or codeableConcept provided to validate");
@ -107,12 +114,17 @@ public class FhirResourceDaoCodeSystemR4 extends BaseHapiFhirResourceDao<CodeSys
system = theSystem.getValue(); system = theSystem.getValue();
} }
String displayLanguage = null;
if (haveDisplayLanguage) {
displayLanguage = theDisplayLanguage.getValue();
}
ourLog.debug("Looking up {} / {}", system, code); ourLog.debug("Looking up {} / {}", system, code);
if (myValidationSupport.isCodeSystemSupported(new ValidationSupportContext(myValidationSupport), system)) { if (myValidationSupport.isCodeSystemSupported(new ValidationSupportContext(myValidationSupport), system)) {
ourLog.debug("Code system {} is supported", system); ourLog.debug("Code system {} is supported", system);
IValidationSupport.LookupCodeResult retVal = myValidationSupport.lookupCode(new ValidationSupportContext(myValidationSupport), system, code); IValidationSupport.LookupCodeResult retVal = myValidationSupport.lookupCode(new ValidationSupportContext(myValidationSupport), system, code, displayLanguage);
if (retVal != null) { if (retVal != null) {
return retVal; return retVal;
} }

View File

@ -38,6 +38,8 @@ import ca.uhn.fhir.jpa.util.LogicUtil;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.hl7.fhir.instance.model.api.IPrimitiveType;
@ -53,7 +55,6 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import static ca.uhn.fhir.jpa.dao.FhirResourceDaoValueSetDstu2.toStringOrNull; import static ca.uhn.fhir.jpa.dao.FhirResourceDaoValueSetDstu2.toStringOrNull;
import static ca.uhn.fhir.jpa.dao.dstu3.FhirResourceDaoValueSetDstu3.vsValidateCodeOptions;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
public class FhirResourceDaoCodeSystemR5 extends BaseHapiFhirResourceDao<CodeSystem> implements IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> { public class FhirResourceDaoCodeSystemR5 extends BaseHapiFhirResourceDao<CodeSystem> implements IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> {
@ -85,10 +86,17 @@ public class FhirResourceDaoCodeSystemR5 extends BaseHapiFhirResourceDao<CodeSys
@Nonnull @Nonnull
@Override @Override
public IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, Coding theCoding, RequestDetails theRequestDetails) { public IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, Coding theCoding, RequestDetails theRequestDetails) {
return lookupCode(theCode, theSystem, theCoding, null, theRequestDetails);
}
@Nonnull
@Override
public IValidationSupport.LookupCodeResult lookupCode(IPrimitiveType<String> theCode, IPrimitiveType<String> theSystem, Coding theCoding, IPrimitiveType<String> theDisplayLanguage, RequestDetails theRequestDetails) {
boolean haveCoding = theCoding != null && isNotBlank(theCoding.getSystem()) && isNotBlank(theCoding.getCode()); boolean haveCoding = theCoding != null && isNotBlank(theCoding.getSystem()) && isNotBlank(theCoding.getCode());
boolean haveCode = theCode != null && theCode.isEmpty() == false; boolean haveCode = theCode != null && theCode.isEmpty() == false;
boolean haveSystem = theSystem != null && theSystem.isEmpty() == false; boolean haveSystem = theSystem != null && theSystem.isEmpty() == false;
boolean haveDisplayLanguage = theDisplayLanguage != null && theDisplayLanguage.isEmpty() == false;
if (!haveCoding && !(haveSystem && haveCode)) { if (!haveCoding && !(haveSystem && haveCode)) {
throw new InvalidRequestException("No code, coding, or codeableConcept provided to validate"); throw new InvalidRequestException("No code, coding, or codeableConcept provided to validate");
} }
@ -110,12 +118,17 @@ public class FhirResourceDaoCodeSystemR5 extends BaseHapiFhirResourceDao<CodeSys
system = theSystem.getValue(); system = theSystem.getValue();
} }
String displayLanguage = null;
if (haveDisplayLanguage) {
displayLanguage = theDisplayLanguage.getValue();
}
ourLog.info("Looking up {} / {}", system, code); ourLog.info("Looking up {} / {}", system, code);
if (myValidationSupport.isCodeSystemSupported(new ValidationSupportContext(myValidationSupport), system)) { if (myValidationSupport.isCodeSystemSupported(new ValidationSupportContext(myValidationSupport), system)) {
ourLog.info("Code system {} is supported", system); ourLog.info("Code system {} is supported", system);
IValidationSupport.LookupCodeResult retVal = myValidationSupport.lookupCode(new ValidationSupportContext(myValidationSupport), system, code); IValidationSupport.LookupCodeResult retVal = myValidationSupport.lookupCode(new ValidationSupportContext(myValidationSupport), system, code, displayLanguage);
if (retVal != null) { if (retVal != null) {
return retVal; return retVal;
} }
@ -149,7 +162,7 @@ public class FhirResourceDaoCodeSystemR5 extends BaseHapiFhirResourceDao<CodeSys
CodeSystem cs = (CodeSystem) theResource; CodeSystem cs = (CodeSystem) theResource;
addPidToResource(theEntity, theResource); addPidToResource(theEntity, theResource);
myTerminologyCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(org.hl7.fhir.convertors.conv40_50.CodeSystem40_50.convertCodeSystem(cs), (ResourceTable) theEntity); myTerminologyCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded((org.hl7.fhir.r4.model.CodeSystem) VersionConvertorFactory_40_50.convertResource(cs, new BaseAdvisor_40_50(false)), (ResourceTable) theEntity);
} }
return retVal; return retVal;

View File

@ -29,6 +29,8 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.api.ITermConceptMappingSvc; import ca.uhn.fhir.jpa.term.api.ITermConceptMappingSvc;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r5.model.ConceptMap; import org.hl7.fhir.r5.model.ConceptMap;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -56,7 +58,8 @@ public class FhirResourceDaoConceptMapR5 extends BaseHapiFhirResourceDao<Concept
if (retVal.getDeleted() == null) { if (retVal.getDeleted() == null) {
ConceptMap conceptMap = (ConceptMap) theResource; ConceptMap conceptMap = (ConceptMap) theResource;
myTermConceptMappingSvc.storeTermConceptMapAndChildren(retVal, org.hl7.fhir.convertors.conv40_50.ConceptMap40_50.convertConceptMap(conceptMap)); myTermConceptMappingSvc.storeTermConceptMapAndChildren(retVal,
(org.hl7.fhir.r4.model.ConceptMap) VersionConvertorFactory_40_50.convertResource(conceptMap, new BaseAdvisor_40_50(false)));
} else { } else {
myTermConceptMappingSvc.deleteConceptMapAndChildren(retVal); myTermConceptMappingSvc.deleteConceptMapAndChildren(retVal);
} }

View File

@ -1,19 +1,15 @@
package ca.uhn.fhir.jpa.dao.r5; package ca.uhn.fhir.jpa.dao.r5;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoSearchParameter; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoSearchParameter;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao; import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoSearchParameterR4; import ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoSearchParameterR4;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor; import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
import org.hl7.fhir.convertors.conv30_40.SearchParameter30_40; import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.conv40_50.SearchParameter40_50; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r5.model.SearchParameter; import org.hl7.fhir.r5.model.SearchParameter;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/* /*
* #%L * #%L
* HAPI FHIR JPA Server * HAPI FHIR JPA Server
@ -68,7 +64,9 @@ public class FhirResourceDaoSearchParameterR5 extends BaseHapiFhirResourceDao<Se
protected void validateResourceForStorage(SearchParameter theResource, ResourceTable theEntityToSave) { protected void validateResourceForStorage(SearchParameter theResource, ResourceTable theEntityToSave) {
super.validateResourceForStorage(theResource, theEntityToSave); super.validateResourceForStorage(theResource, theEntityToSave);
FhirResourceDaoSearchParameterR4.validateSearchParam(SearchParameter40_50.convertSearchParameter(theResource), getContext(), getConfig(), mySearchParamRegistry, mySearchParamExtractor); FhirResourceDaoSearchParameterR4.validateSearchParam(
(org.hl7.fhir.r4.model.SearchParameter) VersionConvertorFactory_40_50.convertResource(theResource, new BaseAdvisor_40_50(false)),
getContext(), getConfig(), mySearchParamRegistry, mySearchParamExtractor);
} }

View File

@ -28,7 +28,8 @@ import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import org.hl7.fhir.convertors.conv40_50.ValueSet40_50; import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.hl7.fhir.instance.model.api.IPrimitiveType;
@ -52,14 +53,14 @@ public class FhirResourceDaoValueSetR5 extends BaseHapiFhirResourceDao<ValueSet>
@Override @Override
public ValueSet expandByIdentifier(String theUri, ValueSetExpansionOptions theOptions) { public ValueSet expandByIdentifier(String theUri, ValueSetExpansionOptions theOptions) {
org.hl7.fhir.r4.model.ValueSet canonicalOutput = myTerminologySvc.expandValueSet(theOptions, theUri); org.hl7.fhir.r4.model.ValueSet canonicalOutput = myTerminologySvc.expandValueSet(theOptions, theUri);
return ValueSet40_50.convertValueSet(canonicalOutput); return (ValueSet) VersionConvertorFactory_40_50.convertResource(canonicalOutput, new BaseAdvisor_40_50(false));
} }
@Override @Override
public ValueSet expand(ValueSet theSource, ValueSetExpansionOptions theOptions) { public ValueSet expand(ValueSet theSource, ValueSetExpansionOptions theOptions) {
org.hl7.fhir.r4.model.ValueSet canonicalInput = ValueSet40_50.convertValueSet(theSource); org.hl7.fhir.r4.model.ValueSet canonicalInput = (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_40_50.convertResource(theSource, new BaseAdvisor_40_50(false));
org.hl7.fhir.r4.model.ValueSet canonicalOutput = myTerminologySvc.expandValueSet(theOptions, canonicalInput); org.hl7.fhir.r4.model.ValueSet canonicalOutput = myTerminologySvc.expandValueSet(theOptions, canonicalInput);
return ValueSet40_50.convertValueSet(canonicalOutput); return (ValueSet) VersionConvertorFactory_40_50.convertResource(canonicalOutput, new BaseAdvisor_40_50(false));
} }
@Override @Override
@ -82,7 +83,7 @@ public class FhirResourceDaoValueSetR5 extends BaseHapiFhirResourceDao<ValueSet>
if (getConfig().isPreExpandValueSets() && !retVal.isUnchangedInCurrentOperation()) { if (getConfig().isPreExpandValueSets() && !retVal.isUnchangedInCurrentOperation()) {
if (retVal.getDeleted() == null) { if (retVal.getDeleted() == null) {
ValueSet valueSet = (ValueSet) theResource; ValueSet valueSet = (ValueSet) theResource;
myTerminologySvc.storeTermValueSet(retVal, org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(valueSet)); myTerminologySvc.storeTermValueSet(retVal, (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_40_50.convertResource(valueSet, new BaseAdvisor_40_50(false)));
} else { } else {
myTerminologySvc.deleteValueSetAndChildren(retVal); myTerminologySvc.deleteValueSetAndChildren(retVal);
} }

View File

@ -76,8 +76,16 @@ public class MdmSearchExpandingInterceptor {
if (iQueryParameterType instanceof ReferenceParam) { if (iQueryParameterType instanceof ReferenceParam) {
ReferenceParam refParam = (ReferenceParam) iQueryParameterType; ReferenceParam refParam = (ReferenceParam) iQueryParameterType;
if (refParam.isMdmExpand()) { if (refParam.isMdmExpand()) {
ourLog.debug("Found a reference parameter to expand: {}", refParam.toString()); ourLog.debug("Found a reference parameter to expand: {}", refParam);
//First, attempt to expand as a source resource.
Set<String> expandedResourceIds = myMdmLinkExpandSvc.expandMdmBySourceResourceId(new IdDt(refParam.getValue())); Set<String> expandedResourceIds = myMdmLinkExpandSvc.expandMdmBySourceResourceId(new IdDt(refParam.getValue()));
// If we failed, attempt to expand as a golden resource
if (expandedResourceIds.isEmpty()) {
expandedResourceIds = myMdmLinkExpandSvc.expandMdmByGoldenResourceId(new IdDt(refParam.getValue()));
}
//Rebuild the search param list.
if (!expandedResourceIds.isEmpty()) { if (!expandedResourceIds.isEmpty()) {
ourLog.debug("Parameter has been expanded to: {}", String.join(", ", expandedResourceIds)); ourLog.debug("Parameter has been expanded to: {}", String.join(", ", expandedResourceIds));
toRemove.add(refParam); toRemove.add(refParam);

View File

@ -112,7 +112,7 @@ public class BaseJpaResourceProviderValueSetDstu2 extends JpaResourceProviderDst
startRequest(theServletRequest); startRequest(theServletRequest);
try { try {
IFhirResourceDaoCodeSystem<ValueSet, CodingDt, CodeableConceptDt> dao = (IFhirResourceDaoCodeSystem<ValueSet, CodingDt, CodeableConceptDt>) getDao(); IFhirResourceDaoCodeSystem<ValueSet, CodingDt, CodeableConceptDt> dao = (IFhirResourceDaoCodeSystem<ValueSet, CodingDt, CodeableConceptDt>) getDao();
IValidationSupport.LookupCodeResult result = dao.lookupCode(theCode, theSystem, theCoding, theRequestDetails); IValidationSupport.LookupCodeResult result = dao.lookupCode(theCode, theSystem, theCoding, null, theRequestDetails);
if (result.isFound() == false) { if (result.isFound() == false) {
throw new ResourceNotFoundException("Unable to find code[" + result.getSearchedForCode() + "] in system[" + result.getSearchedForSystem() + "]"); throw new ResourceNotFoundException("Unable to find code[" + result.getSearchedForCode() + "] in system[" + result.getSearchedForSystem() + "]");
} }

View File

@ -40,6 +40,10 @@ import ca.uhn.fhir.util.ValidateUtil;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.instance.model.api.IBaseParameters; import org.hl7.fhir.instance.model.api.IBaseParameters;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.ICompositeType; import org.hl7.fhir.instance.model.api.ICompositeType;
@ -58,10 +62,7 @@ import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.*;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.trim;
import static org.hl7.fhir.convertors.conv30_40.CodeSystem30_40.convertCodeSystem;
public class TerminologyUploaderProvider extends BaseJpaProvider { public class TerminologyUploaderProvider extends BaseJpaProvider {
@ -308,10 +309,10 @@ public class TerminologyUploaderProvider extends BaseJpaProvider {
CodeSystem nextCodeSystem; CodeSystem nextCodeSystem;
switch (getContext().getVersion().getVersion()) { switch (getContext().getVersion().getVersion()) {
case DSTU3: case DSTU3:
nextCodeSystem = convertCodeSystem((org.hl7.fhir.dstu3.model.CodeSystem) theCodeSystem); nextCodeSystem = (CodeSystem) VersionConvertorFactory_30_40.convertResource((org.hl7.fhir.dstu3.model.CodeSystem) theCodeSystem, new BaseAdvisor_30_40(false));
break; break;
case R5: case R5:
nextCodeSystem = org.hl7.fhir.convertors.conv40_50.CodeSystem40_50.convertCodeSystem((org.hl7.fhir.r5.model.CodeSystem) theCodeSystem); nextCodeSystem = (CodeSystem) VersionConvertorFactory_40_50.convertResource((org.hl7.fhir.r5.model.CodeSystem) theCodeSystem, new BaseAdvisor_40_50(false));
break; break;
default: default:
nextCodeSystem = (CodeSystem) theCodeSystem; nextCodeSystem = (CodeSystem) theCodeSystem;

View File

@ -53,7 +53,8 @@ public class BaseJpaResourceProviderCodeSystemDstu3 extends JpaResourceProviderD
@OperationParam(name = "code", min = 0, max = 1) CodeType theCode, @OperationParam(name = "code", min = 0, max = 1) CodeType theCode,
@OperationParam(name = "system", min = 0, max = 1) UriType theSystem, @OperationParam(name = "system", min = 0, max = 1) UriType theSystem,
@OperationParam(name = "coding", min = 0, max = 1) Coding theCoding, @OperationParam(name = "coding", min = 0, max = 1) Coding theCoding,
@OperationParam(name="version", min=0, max=1) StringType theVersion, @OperationParam(name = "version", min=0, max=1) StringType theVersion,
@OperationParam(name = "displayLanguage", min=0, max=1) CodeType theDisplayLanguage,
@OperationParam(name = "property", min = 0, max = OperationParam.MAX_UNLIMITED) List<CodeType> theProperties, @OperationParam(name = "property", min = 0, max = OperationParam.MAX_UNLIMITED) List<CodeType> theProperties,
RequestDetails theRequestDetails RequestDetails theRequestDetails
) { ) {
@ -63,9 +64,9 @@ public class BaseJpaResourceProviderCodeSystemDstu3 extends JpaResourceProviderD
IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> dao = (IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept>) getDao(); IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> dao = (IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept>) getDao();
IValidationSupport.LookupCodeResult result; IValidationSupport.LookupCodeResult result;
if (theVersion != null) { if (theVersion != null) {
result = dao.lookupCode(theCode, new UriType(theSystem.getValue() + "|" + theVersion), theCoding, theRequestDetails); result = dao.lookupCode(theCode, new UriType(theSystem.getValue() + "|" + theVersion), theCoding, theDisplayLanguage, theRequestDetails);
} else { } else {
result = dao.lookupCode(theCode, theSystem, theCoding, theRequestDetails); result = dao.lookupCode(theCode, theSystem, theCoding, theDisplayLanguage, theRequestDetails);
} }
result.throwNotFoundIfAppropriate(); result.throwNotFoundIfAppropriate();
return (Parameters) result.toParameters(theRequestDetails.getFhirContext(), theProperties); return (Parameters) result.toParameters(theRequestDetails.getFhirContext(), theProperties);

View File

@ -20,9 +20,9 @@ package ca.uhn.fhir.jpa.provider.dstu3;
* #L% * #L%
*/ */
import ca.uhn.fhir.context.support.TranslateConceptResults;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoConceptMap; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoConceptMap;
import ca.uhn.fhir.jpa.api.model.TranslationRequest; import ca.uhn.fhir.jpa.api.model.TranslationRequest;
import ca.uhn.fhir.context.support.TranslateConceptResults;
import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl; import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl;
import ca.uhn.fhir.rest.annotation.IdParam; import ca.uhn.fhir.rest.annotation.IdParam;
@ -31,7 +31,8 @@ import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.convertors.VersionConvertor_30_40; import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.BooleanType; import org.hl7.fhir.dstu3.model.BooleanType;
import org.hl7.fhir.dstu3.model.CodeType; import org.hl7.fhir.dstu3.model.CodeType;
import org.hl7.fhir.dstu3.model.CodeableConcept; import org.hl7.fhir.dstu3.model.CodeableConcept;
@ -45,8 +46,6 @@ import org.hl7.fhir.exceptions.FHIRException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import static org.hl7.fhir.convertors.conv30_40.Parameters30_40.convertParameters;
public class BaseJpaResourceProviderConceptMapDstu3 extends JpaResourceProviderDstu3<ConceptMap> { public class BaseJpaResourceProviderConceptMapDstu3 extends JpaResourceProviderDstu3<ConceptMap> {
@Operation(name = JpaConstants.OPERATION_TRANSLATE, idempotent = true, returnParameters = { @Operation(name = JpaConstants.OPERATION_TRANSLATE, idempotent = true, returnParameters = {
@OperationParam(name = "result", type = BooleanType.class, min = 1, max = 1), @OperationParam(name = "result", type = BooleanType.class, min = 1, max = 1),
@ -82,7 +81,7 @@ public class BaseJpaResourceProviderConceptMapDstu3 extends JpaResourceProviderD
&& theSourceValueSet.hasValue(); && theSourceValueSet.hasValue();
boolean haveSourceCoding = theSourceCoding != null boolean haveSourceCoding = theSourceCoding != null
&& theSourceCoding.hasCode(); && theSourceCoding.hasCode();
boolean haveSourceCodeableConcept= theSourceCodeableConcept != null boolean haveSourceCodeableConcept = theSourceCodeableConcept != null
&& theSourceCodeableConcept.hasCoding() && theSourceCodeableConcept.hasCoding()
&& theSourceCodeableConcept.getCodingFirstRep().hasCode(); && theSourceCodeableConcept.getCodingFirstRep().hasCode();
boolean haveTargetValueSet = theTargetValueSet != null boolean haveTargetValueSet = theTargetValueSet != null
@ -100,46 +99,46 @@ public class BaseJpaResourceProviderConceptMapDstu3 extends JpaResourceProviderD
TranslationRequest translationRequest = new TranslationRequest(); TranslationRequest translationRequest = new TranslationRequest();
try { try {
if (haveUrl) { if (haveUrl) {
translationRequest.setUrl(VersionConvertor_30_40.convertUri(theUrl)); translationRequest.setUrl((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_30_40.convertType(theUrl, new BaseAdvisor_30_40(false)));
} }
if (haveConceptMapVersion) { if (haveConceptMapVersion) {
translationRequest.setConceptMapVersion(VersionConvertor_30_40.convertString(theConceptMapVersion)); translationRequest.setConceptMapVersion((org.hl7.fhir.r4.model.StringType) VersionConvertorFactory_30_40.convertType(theConceptMapVersion, new BaseAdvisor_30_40(false)));
} }
// Convert from DSTU3 to R4 // Convert from DSTU3 to R4
if (haveSourceCode) { if (haveSourceCode) {
translationRequest.getCodeableConcept().addCoding().setCodeElement(VersionConvertor_30_40.convertCode(theSourceCode)); translationRequest.getCodeableConcept().addCoding().setCodeElement((org.hl7.fhir.r4.model.CodeType) VersionConvertorFactory_30_40.convertType(theSourceCode, new BaseAdvisor_30_40(false)));
if (haveSourceCodeSystem) { if (haveSourceCodeSystem) {
translationRequest.getCodeableConcept().getCodingFirstRep().setSystemElement(VersionConvertor_30_40.convertUri(theSourceCodeSystem)); translationRequest.getCodeableConcept().getCodingFirstRep().setSystemElement((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_30_40.convertType(theSourceCodeSystem, new BaseAdvisor_30_40(false)));
} }
if (haveSourceCodeSystemVersion) { if (haveSourceCodeSystemVersion) {
translationRequest.getCodeableConcept().getCodingFirstRep().setVersionElement(VersionConvertor_30_40.convertString(theSourceCodeSystemVersion)); translationRequest.getCodeableConcept().getCodingFirstRep().setVersionElement((org.hl7.fhir.r4.model.StringType) VersionConvertorFactory_30_40.convertType(theSourceCodeSystemVersion, new BaseAdvisor_30_40(false)));
} }
} else if (haveSourceCoding) { } else if (haveSourceCoding) {
translationRequest.getCodeableConcept().addCoding(VersionConvertor_30_40.convertCoding(theSourceCoding)); translationRequest.getCodeableConcept().addCoding((org.hl7.fhir.r4.model.Coding) VersionConvertorFactory_30_40.convertType(theSourceCoding, new BaseAdvisor_30_40(false)));
} else { } else {
translationRequest.setCodeableConcept(VersionConvertor_30_40.convertCodeableConcept(theSourceCodeableConcept)); translationRequest.setCodeableConcept((org.hl7.fhir.r4.model.CodeableConcept) VersionConvertorFactory_30_40.convertType(theSourceCodeableConcept, new BaseAdvisor_30_40(false)));
} }
if (haveSourceValueSet) { if (haveSourceValueSet) {
translationRequest.setSource(VersionConvertor_30_40.convertUri(theSourceValueSet)); translationRequest.setSource((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_30_40.convertType(theSourceValueSet, new BaseAdvisor_30_40(false)));
} }
if (haveTargetValueSet) { if (haveTargetValueSet) {
translationRequest.setTarget(VersionConvertor_30_40.convertUri(theTargetValueSet)); translationRequest.setTarget((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_30_40.convertType(theTargetValueSet, new BaseAdvisor_30_40(false)));
} }
if (haveTargetCodeSystem) { if (haveTargetCodeSystem) {
translationRequest.setTargetSystem(VersionConvertor_30_40.convertUri(theTargetCodeSystem)); translationRequest.setTargetSystem((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_30_40.convertType(theTargetCodeSystem, new BaseAdvisor_30_40(false)));
} }
if (haveReverse) { if (haveReverse) {
translationRequest.setReverse(VersionConvertor_30_40.convertBoolean(theReverse)); translationRequest.setReverse((org.hl7.fhir.r4.model.BooleanType) VersionConvertorFactory_30_40.convertType(theReverse, new BaseAdvisor_30_40(false)));
} }
if (haveId) { if (haveId) {
@ -155,7 +154,7 @@ public class BaseJpaResourceProviderConceptMapDstu3 extends JpaResourceProviderD
TranslateConceptResults result = dao.translate(translationRequest, theRequestDetails); TranslateConceptResults result = dao.translate(translationRequest, theRequestDetails);
// Convert from R4 to DSTU3 // Convert from R4 to DSTU3
return convertParameters(TermConceptMappingSvcImpl.toParameters(result)); return (Parameters) VersionConvertorFactory_30_40.convertResource(TermConceptMappingSvcImpl.toParameters(result), new BaseAdvisor_30_40(false));
} catch (FHIRException fe) { } catch (FHIRException fe) {
throw new InternalErrorException(fe); throw new InternalErrorException(fe);
} finally { } finally {

View File

@ -24,8 +24,6 @@ import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider; import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import static org.hl7.fhir.convertors.conv30_40.Parameters30_40.convertParameters;
public class JpaResourceProviderDstu3<T extends IAnyResource> extends BaseJpaResourceProvider<T> { public class JpaResourceProviderDstu3<T extends IAnyResource> extends BaseJpaResourceProvider<T> {
public JpaResourceProviderDstu3() { public JpaResourceProviderDstu3() {

View File

@ -24,7 +24,6 @@ import java.util.Map.Entry;
import java.util.TreeMap; import java.util.TreeMap;
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
import static org.hl7.fhir.convertors.conv30_40.Parameters30_40.convertParameters;
/* /*
* #%L * #%L

View File

@ -61,7 +61,8 @@ public class BaseJpaResourceProviderCodeSystemR4 extends JpaResourceProviderR4<C
@OperationParam(name="system", min=0, max=1) UriType theSystem, @OperationParam(name="system", min=0, max=1) UriType theSystem,
@OperationParam(name="coding", min=0, max=1) Coding theCoding, @OperationParam(name="coding", min=0, max=1) Coding theCoding,
@OperationParam(name="version", min=0, max=1) StringType theVersion, @OperationParam(name="version", min=0, max=1) StringType theVersion,
@OperationParam(name = "property", min = 0, max = OperationParam.MAX_UNLIMITED) List<CodeType> theProperties, @OperationParam(name="displayLanguage", min=0, max=1) CodeType theDisplayLanguage,
@OperationParam(name="property", min = 0, max = OperationParam.MAX_UNLIMITED) List<CodeType> theProperties,
RequestDetails theRequestDetails RequestDetails theRequestDetails
) { ) {
@ -70,9 +71,9 @@ public class BaseJpaResourceProviderCodeSystemR4 extends JpaResourceProviderR4<C
IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> dao = (IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept>) getDao(); IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> dao = (IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept>) getDao();
IValidationSupport.LookupCodeResult result; IValidationSupport.LookupCodeResult result;
if (theVersion != null) { if (theVersion != null) {
result = dao.lookupCode(theCode, new UriType(theSystem.getValue() + "|" + theVersion), theCoding, theRequestDetails); result = dao.lookupCode(theCode, new UriType(theSystem.getValue() + "|" + theVersion), theCoding, theDisplayLanguage, theRequestDetails);
} else { } else {
result = dao.lookupCode(theCode, theSystem, theCoding, theRequestDetails); result = dao.lookupCode(theCode, theSystem, theCoding, theDisplayLanguage, theRequestDetails);
} }
result.throwNotFoundIfAppropriate(); result.throwNotFoundIfAppropriate();
return (Parameters) result.toParameters(theRequestDetails.getFhirContext(), theProperties); return (Parameters) result.toParameters(theRequestDetails.getFhirContext(), theProperties);

View File

@ -60,6 +60,7 @@ public class BaseJpaResourceProviderCodeSystemR5 extends JpaResourceProviderR5<C
@OperationParam(name="system", min=0, max=1) UriType theSystem, @OperationParam(name="system", min=0, max=1) UriType theSystem,
@OperationParam(name="coding", min=0, max=1) Coding theCoding, @OperationParam(name="coding", min=0, max=1) Coding theCoding,
@OperationParam(name="version", min=0, max=1) StringType theVersion, @OperationParam(name="version", min=0, max=1) StringType theVersion,
@OperationParam(name="displayLanguage", min=0, max=1) CodeType theDisplayLanguage,
@OperationParam(name = "property", min = 0, max = OperationParam.MAX_UNLIMITED) List<CodeType> theProperties, @OperationParam(name = "property", min = 0, max = OperationParam.MAX_UNLIMITED) List<CodeType> theProperties,
RequestDetails theRequestDetails RequestDetails theRequestDetails
) { ) {
@ -69,9 +70,9 @@ public class BaseJpaResourceProviderCodeSystemR5 extends JpaResourceProviderR5<C
IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> dao = (IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept>) getDao(); IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> dao = (IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept>) getDao();
IValidationSupport.LookupCodeResult result; IValidationSupport.LookupCodeResult result;
if (theVersion != null) { if (theVersion != null) {
result = dao.lookupCode(theCode, new UriType(theSystem.getValue() + "|" + theVersion), theCoding, theRequestDetails); result = dao.lookupCode(theCode, new UriType(theSystem.getValue() + "|" + theVersion), theCoding, theDisplayLanguage, theRequestDetails);
} else { } else {
result = dao.lookupCode(theCode, theSystem, theCoding, theRequestDetails); result = dao.lookupCode(theCode, theSystem, theCoding, theDisplayLanguage, theRequestDetails);
} }
result.throwNotFoundIfAppropriate(); result.throwNotFoundIfAppropriate();
return (Parameters) result.toParameters(theRequestDetails.getFhirContext(), theProperties); return (Parameters) result.toParameters(theRequestDetails.getFhirContext(), theProperties);

View File

@ -20,9 +20,9 @@ package ca.uhn.fhir.jpa.provider.r5;
* #L% * #L%
*/ */
import ca.uhn.fhir.context.support.TranslateConceptResults;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoConceptMap; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoConceptMap;
import ca.uhn.fhir.jpa.api.model.TranslationRequest; import ca.uhn.fhir.jpa.api.model.TranslationRequest;
import ca.uhn.fhir.context.support.TranslateConceptResults;
import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl; import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl;
import ca.uhn.fhir.rest.annotation.IdParam; import ca.uhn.fhir.rest.annotation.IdParam;
@ -30,7 +30,8 @@ import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam; import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.convertors.VersionConvertor_40_50; import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.r5.model.BooleanType; import org.hl7.fhir.r5.model.BooleanType;
import org.hl7.fhir.r5.model.CodeType; import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r5.model.CodeableConcept; import org.hl7.fhir.r5.model.CodeableConcept;
@ -52,7 +53,7 @@ public class BaseJpaResourceProviderConceptMapR5 extends JpaResourceProviderR5<C
HttpServletRequest theServletRequest, HttpServletRequest theServletRequest,
@IdParam(optional = true) IdType theId, @IdParam(optional = true) IdType theId,
@OperationParam(name = "url", min = 0, max = 1) UriType theUrl, @OperationParam(name = "url", min = 0, max = 1) UriType theUrl,
@OperationParam(name = "conceptMapVersion", min = 0, max = 1) StringType theConceptMapVersion, @OperationParam(name = "conceptMapVersion", min = 0, max = 1) StringType theConceptMapVersion,
@OperationParam(name = "code", min = 0, max = 1) CodeType theSourceCode, @OperationParam(name = "code", min = 0, max = 1) CodeType theSourceCode,
@OperationParam(name = "system", min = 0, max = 1) UriType theSourceCodeSystem, @OperationParam(name = "system", min = 0, max = 1) UriType theSourceCodeSystem,
@OperationParam(name = "version", min = 0, max = 1) StringType theSourceCodeSystemVersion, @OperationParam(name = "version", min = 0, max = 1) StringType theSourceCodeSystemVersion,
@ -78,7 +79,7 @@ public class BaseJpaResourceProviderConceptMapR5 extends JpaResourceProviderR5<C
&& theSourceValueSet.hasValue(); && theSourceValueSet.hasValue();
boolean haveSourceCoding = theSourceCoding != null boolean haveSourceCoding = theSourceCoding != null
&& theSourceCoding.hasCode(); && theSourceCoding.hasCode();
boolean haveSourceCodeableConcept= theSourceCodeableConcept != null boolean haveSourceCodeableConcept = theSourceCodeableConcept != null
&& theSourceCodeableConcept.hasCoding() && theSourceCodeableConcept.hasCoding()
&& theSourceCodeableConcept.getCodingFirstRep().hasCode(); && theSourceCodeableConcept.getCodingFirstRep().hasCode();
boolean haveTargetValueSet = theTargetValueSet != null boolean haveTargetValueSet = theTargetValueSet != null
@ -97,43 +98,44 @@ public class BaseJpaResourceProviderConceptMapR5 extends JpaResourceProviderR5<C
TranslationRequest translationRequest = new TranslationRequest(); TranslationRequest translationRequest = new TranslationRequest();
if (haveUrl) { if (haveUrl) {
translationRequest.setUrl(VersionConvertor_40_50.convertUri(theUrl)); translationRequest.setUrl((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_40_50.convertType(theUrl, new BaseAdvisor_40_50(false)));
} }
if (haveConceptMapVersion) { if (haveConceptMapVersion) {
translationRequest.setConceptMapVersion(VersionConvertor_40_50.convertString(theConceptMapVersion)); translationRequest.setConceptMapVersion((org.hl7.fhir.r4.model.StringType) VersionConvertorFactory_40_50.convertType(theConceptMapVersion, new BaseAdvisor_40_50(false)));
} }
if (haveSourceCode) { if (haveSourceCode) {
translationRequest.getCodeableConcept().addCoding().setCodeElement(VersionConvertor_40_50.convertCode(theSourceCode)); translationRequest.getCodeableConcept().addCoding().setCodeElement((org.hl7.fhir.r4.model.CodeType) VersionConvertorFactory_40_50.convertType(theSourceCode, new BaseAdvisor_40_50(false)));
if (haveSourceCodeSystem) { if (haveSourceCodeSystem) {
translationRequest.getCodeableConcept().getCodingFirstRep().setSystemElement(VersionConvertor_40_50.convertUri(theSourceCodeSystem)); translationRequest.getCodeableConcept().getCodingFirstRep().setSystemElement((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_40_50.convertType(theSourceCodeSystem, new BaseAdvisor_40_50(false)));
} }
if (haveSourceCodeSystemVersion) { if (haveSourceCodeSystemVersion) {
translationRequest.getCodeableConcept().getCodingFirstRep().setVersionElement(VersionConvertor_40_50.convertString(theSourceCodeSystemVersion)); translationRequest.getCodeableConcept().getCodingFirstRep()
.setVersionElement((org.hl7.fhir.r4.model.StringType) VersionConvertorFactory_40_50.convertType(theSourceCodeSystemVersion, new BaseAdvisor_40_50(false)));
} }
} else if (haveSourceCoding) { } else if (haveSourceCoding) {
translationRequest.getCodeableConcept().addCoding(VersionConvertor_40_50.convertCoding(theSourceCoding)); translationRequest.getCodeableConcept().addCoding((org.hl7.fhir.r4.model.Coding) VersionConvertorFactory_40_50.convertType(theSourceCoding, new BaseAdvisor_40_50(false)));
} else { } else {
translationRequest.setCodeableConcept(VersionConvertor_40_50.convertCodeableConcept(theSourceCodeableConcept)); translationRequest.setCodeableConcept((org.hl7.fhir.r4.model.CodeableConcept) VersionConvertorFactory_40_50.convertType(theSourceCodeableConcept, new BaseAdvisor_40_50(false)));
} }
if (haveSourceValueSet) { if (haveSourceValueSet) {
translationRequest.setSource(VersionConvertor_40_50.convertUri(theSourceValueSet)); translationRequest.setSource((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_40_50.convertType(theSourceValueSet, new BaseAdvisor_40_50(false)));
} }
if (haveTargetValueSet) { if (haveTargetValueSet) {
translationRequest.setTarget(VersionConvertor_40_50.convertUri(theTargetValueSet)); translationRequest.setTarget((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_40_50.convertType(theTargetValueSet, new BaseAdvisor_40_50(false)));
} }
if (haveTargetCodeSystem) { if (haveTargetCodeSystem) {
translationRequest.setTargetSystem(VersionConvertor_40_50.convertUri(theTargetCodeSystem)); translationRequest.setTargetSystem((org.hl7.fhir.r4.model.UriType) VersionConvertorFactory_40_50.convertType(theTargetCodeSystem, new BaseAdvisor_40_50(false)));
} }
if (haveReverse) { if (haveReverse) {
translationRequest.setReverse(VersionConvertor_40_50.convertBoolean(theReverse)); translationRequest.setReverse((org.hl7.fhir.r4.model.BooleanType) VersionConvertorFactory_40_50.convertType(theReverse, new BaseAdvisor_40_50(false)));
} }
if (haveId) { if (haveId) {
@ -145,7 +147,7 @@ public class BaseJpaResourceProviderConceptMapR5 extends JpaResourceProviderR5<C
IFhirResourceDaoConceptMap<ConceptMap> dao = (IFhirResourceDaoConceptMap<ConceptMap>) getDao(); IFhirResourceDaoConceptMap<ConceptMap> dao = (IFhirResourceDaoConceptMap<ConceptMap>) getDao();
TranslateConceptResults result = dao.translate(translationRequest, theRequestDetails); TranslateConceptResults result = dao.translate(translationRequest, theRequestDetails);
org.hl7.fhir.r4.model.Parameters parameters = TermConceptMappingSvcImpl.toParameters(result); org.hl7.fhir.r4.model.Parameters parameters = TermConceptMappingSvcImpl.toParameters(result);
return org.hl7.fhir.convertors.conv40_50.Parameters40_50.convertParameters(parameters); return (Parameters) VersionConvertorFactory_40_50.convertResource(parameters, new BaseAdvisor_40_50(false));
} finally { } finally {
endRequest(theServletRequest); endRequest(theServletRequest);
} }

View File

@ -42,7 +42,7 @@ import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.concurrent.BasicThreadFactory; import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
import org.hl7.fhir.r4.model.InstantType; import org.hl7.fhir.r4.model.InstantType;
import org.jetbrains.annotations.Nullable; import javax.annotation.Nullable;
import org.quartz.JobExecutionContext; import org.quartz.JobExecutionContext;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View File

@ -1989,7 +1989,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
protected abstract ValueSet toCanonicalValueSet(IBaseResource theValueSet); protected abstract ValueSet toCanonicalValueSet(IBaseResource theValueSet);
protected IValidationSupport.LookupCodeResult lookupCode(String theSystem, String theCode) { protected IValidationSupport.LookupCodeResult lookupCode(String theSystem, String theCode, String theDisplayLanguage) {
TransactionTemplate txTemplate = new TransactionTemplate(myTransactionManager); TransactionTemplate txTemplate = new TransactionTemplate(myTransactionManager);
return txTemplate.execute(t -> { return txTemplate.execute(t -> {
Optional<TermConcept> codeOpt = findCode(theSystem, theCode); Optional<TermConcept> codeOpt = findCode(theSystem, theCode);
@ -2006,12 +2006,15 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
for (TermConceptDesignation next : code.getDesignations()) { for (TermConceptDesignation next : code.getDesignations()) {
IValidationSupport.ConceptDesignation designation = new IValidationSupport.ConceptDesignation(); IValidationSupport.ConceptDesignation designation = new IValidationSupport.ConceptDesignation();
designation.setLanguage(next.getLanguage()); // filter out the designation based on displayLanguage if any
designation.setUseSystem(next.getUseSystem()); if (isDisplayLanguageMatch(theDisplayLanguage, next.getLanguage())) {
designation.setUseCode(next.getUseCode()); designation.setLanguage(next.getLanguage());
designation.setUseDisplay(next.getUseDisplay()); designation.setUseSystem(next.getUseSystem());
designation.setValue(next.getValue()); designation.setUseCode(next.getUseCode());
result.getDesignations().add(designation); designation.setUseDisplay(next.getUseDisplay());
designation.setValue(next.getValue());
result.getDesignations().add(designation);
}
} }
for (TermConceptProperty next : code.getProperties()) { for (TermConceptProperty next : code.getProperties()) {
@ -2034,6 +2037,7 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
}); });
} }
@Nullable @Nullable
private ConceptSubsumptionOutcome testForSubsumption(SearchSession theSearchSession, TermConcept theLeft, TermConcept theRight, ConceptSubsumptionOutcome theOutput) { private ConceptSubsumptionOutcome testForSubsumption(SearchSession theSearchSession, TermConcept theLeft, TermConcept theRight, ConceptSubsumptionOutcome theOutput) {
List<TermConcept> fetch = theSearchSession.search(TermConcept.class) List<TermConcept> fetch = theSearchSession.search(TermConcept.class)
@ -2481,4 +2485,11 @@ public abstract class BaseTermReadSvcImpl implements ITermReadSvc {
return termConcept; return termConcept;
} }
static boolean isDisplayLanguageMatch(String theReqLang, String theStoredLang) {
// NOTE: return the designation when one of then is not specified.
if (theReqLang == null || theStoredLang == null)
return true;
return theReqLang.equalsIgnoreCase(theStoredLang);
}
} }

View File

@ -9,8 +9,8 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.api.ITermReadSvcDstu3; import ca.uhn.fhir.jpa.term.api.ITermReadSvcDstu3;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.ValidateUtil; import ca.uhn.fhir.util.ValidateUtil;
import org.hl7.fhir.convertors.VersionConvertor_30_40; import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.conv30_40.CodeSystem30_40; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.CodeSystem; import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.CodeableConcept; import org.hl7.fhir.dstu3.model.CodeableConcept;
import org.hl7.fhir.dstu3.model.Coding; import org.hl7.fhir.dstu3.model.Coding;
@ -25,8 +25,6 @@ import org.springframework.transaction.PlatformTransactionManager;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static org.hl7.fhir.convertors.conv30_40.ValueSet30_40.convertValueSet;
/* /*
* #%L * #%L
* HAPI FHIR JPA Server * HAPI FHIR JPA Server
@ -67,7 +65,7 @@ public class TermReadSvcDstu3 extends BaseTermReadSvcImpl implements IValidation
org.hl7.fhir.r4.model.ValueSet valueSetToExpandR4; org.hl7.fhir.r4.model.ValueSet valueSetToExpandR4;
valueSetToExpandR4 = toCanonicalValueSet(theValueSetToExpand); valueSetToExpandR4 = toCanonicalValueSet(theValueSetToExpand);
org.hl7.fhir.r4.model.ValueSet expandedR4 = super.expandValueSet(theExpansionOptions, valueSetToExpandR4); org.hl7.fhir.r4.model.ValueSet expandedR4 = super.expandValueSet(theExpansionOptions, valueSetToExpandR4);
return new ValueSetExpansionOutcome(convertValueSet(expandedR4), null); return new ValueSetExpansionOutcome(VersionConvertorFactory_30_40.convertResource(expandedR4, new BaseAdvisor_30_40(false)), null);
} catch (FHIRException e) { } catch (FHIRException e) {
throw new InternalErrorException(e); throw new InternalErrorException(e);
} }
@ -81,7 +79,7 @@ public class TermReadSvcDstu3 extends BaseTermReadSvcImpl implements IValidation
org.hl7.fhir.r4.model.ValueSet valueSetToExpandR4; org.hl7.fhir.r4.model.ValueSet valueSetToExpandR4;
valueSetToExpandR4 = toCanonicalValueSet(valueSetToExpand); valueSetToExpandR4 = toCanonicalValueSet(valueSetToExpand);
org.hl7.fhir.r4.model.ValueSet expandedR4 = super.expandValueSet(theExpansionOptions, valueSetToExpandR4); org.hl7.fhir.r4.model.ValueSet expandedR4 = super.expandValueSet(theExpansionOptions, valueSetToExpandR4);
return convertValueSet(expandedR4); return VersionConvertorFactory_30_40.convertResource(expandedR4, new BaseAdvisor_30_40(false));
} catch (FHIRException e) { } catch (FHIRException e) {
throw new InternalErrorException(e); throw new InternalErrorException(e);
} }
@ -90,31 +88,31 @@ public class TermReadSvcDstu3 extends BaseTermReadSvcImpl implements IValidation
@Override @Override
protected org.hl7.fhir.r4.model.ValueSet toCanonicalValueSet(IBaseResource theValueSet) throws FHIRException { protected org.hl7.fhir.r4.model.ValueSet toCanonicalValueSet(IBaseResource theValueSet) throws FHIRException {
org.hl7.fhir.r4.model.ValueSet valueSetToExpandR4; org.hl7.fhir.r4.model.ValueSet valueSetToExpandR4;
valueSetToExpandR4 = convertValueSet((ValueSet) theValueSet); valueSetToExpandR4 = (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_30_40.convertResource((ValueSet) theValueSet, new BaseAdvisor_30_40(false));
return valueSetToExpandR4; return valueSetToExpandR4;
} }
@Override @Override
protected org.hl7.fhir.r4.model.CodeSystem toCanonicalCodeSystem(IBaseResource theCodeSystem) { protected org.hl7.fhir.r4.model.CodeSystem toCanonicalCodeSystem(IBaseResource theCodeSystem) {
return CodeSystem30_40.convertCodeSystem((CodeSystem)theCodeSystem); return (org.hl7.fhir.r4.model.CodeSystem) VersionConvertorFactory_30_40.convertResource((CodeSystem)theCodeSystem, new BaseAdvisor_30_40(false));
} }
@Override @Override
@Nullable @Nullable
protected org.hl7.fhir.r4.model.Coding toCanonicalCoding(IBaseDatatype theCoding) { protected org.hl7.fhir.r4.model.Coding toCanonicalCoding(IBaseDatatype theCoding) {
return VersionConvertor_30_40.convertCoding((org.hl7.fhir.dstu3.model.Coding) theCoding); return (org.hl7.fhir.r4.model.Coding) VersionConvertorFactory_30_40.convertType((Coding) theCoding, new BaseAdvisor_30_40(false));
} }
@Override @Override
@Nullable @Nullable
protected org.hl7.fhir.r4.model.Coding toCanonicalCoding(IBaseCoding theCoding) { protected org.hl7.fhir.r4.model.Coding toCanonicalCoding(IBaseCoding theCoding) {
return VersionConvertor_30_40.convertCoding((org.hl7.fhir.dstu3.model.Coding) theCoding); return (org.hl7.fhir.r4.model.Coding) VersionConvertorFactory_30_40.convertType((org.hl7.fhir.dstu3.model.Coding) theCoding, new BaseAdvisor_30_40(false));
} }
@Override @Override
@Nullable @Nullable
protected org.hl7.fhir.r4.model.CodeableConcept toCanonicalCodeableConcept(IBaseDatatype theCoding) { protected org.hl7.fhir.r4.model.CodeableConcept toCanonicalCodeableConcept(IBaseDatatype theCoding) {
return VersionConvertor_30_40.convertCodeableConcept((org.hl7.fhir.dstu3.model.CodeableConcept) theCoding); return (org.hl7.fhir.r4.model.CodeableConcept) VersionConvertorFactory_30_40.convertType((CodeableConcept) theCoding, new BaseAdvisor_30_40(false));
} }
@ -147,8 +145,8 @@ public class TermReadSvcDstu3 extends BaseTermReadSvcImpl implements IValidation
} }
@Override @Override
public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode) { public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode, String theDisplayLanguage) {
return super.lookupCode(theSystem, theCode); return super.lookupCode(theSystem, theCode, theDisplayLanguage);
} }
@Override @Override
@ -160,7 +158,7 @@ public class TermReadSvcDstu3 extends BaseTermReadSvcImpl implements IValidation
public IValidationSupport.CodeValidationResult validateCodeIsInPreExpandedValueSet(ConceptValidationOptions theOptions, IBaseResource theValueSet, String theSystem, String theCode, String theDisplay, IBaseDatatype theCoding, IBaseDatatype theCodeableConcept) { public IValidationSupport.CodeValidationResult validateCodeIsInPreExpandedValueSet(ConceptValidationOptions theOptions, IBaseResource theValueSet, String theSystem, String theCode, String theDisplay, IBaseDatatype theCoding, IBaseDatatype theCodeableConcept) {
ValidateUtil.isNotNullOrThrowUnprocessableEntity(theValueSet, "ValueSet must not be null"); ValidateUtil.isNotNullOrThrowUnprocessableEntity(theValueSet, "ValueSet must not be null");
ValueSet valueSet = (ValueSet) theValueSet; ValueSet valueSet = (ValueSet) theValueSet;
org.hl7.fhir.r4.model.ValueSet valueSetR4 = convertValueSet(valueSet); org.hl7.fhir.r4.model.ValueSet valueSetR4 = (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_30_40.convertResource(valueSet, new BaseAdvisor_30_40(false));
Coding coding = (Coding) theCoding; Coding coding = (Coding) theCoding;
org.hl7.fhir.r4.model.Coding codingR4 = null; org.hl7.fhir.r4.model.Coding codingR4 = null;
@ -184,7 +182,7 @@ public class TermReadSvcDstu3 extends BaseTermReadSvcImpl implements IValidation
public boolean isValueSetPreExpandedForCodeValidation(IBaseResource theValueSet) { public boolean isValueSetPreExpandedForCodeValidation(IBaseResource theValueSet) {
ValidateUtil.isNotNullOrThrowUnprocessableEntity(theValueSet, "ValueSet must not be null"); ValidateUtil.isNotNullOrThrowUnprocessableEntity(theValueSet, "ValueSet must not be null");
ValueSet valueSet = (ValueSet) theValueSet; ValueSet valueSet = (ValueSet) theValueSet;
org.hl7.fhir.r4.model.ValueSet valueSetR4 = convertValueSet(valueSet); org.hl7.fhir.r4.model.ValueSet valueSetR4 = (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_30_40.convertResource(valueSet, new BaseAdvisor_30_40(false));
return super.isValueSetPreExpandedForCodeValidation(valueSetR4); return super.isValueSetPreExpandedForCodeValidation(valueSetR4);
} }
} }

View File

@ -92,8 +92,8 @@ public class TermReadSvcR4 extends BaseTermReadSvcImpl implements ITermReadSvcR4
} }
@Override @Override
public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode) { public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode, String theDisplayLanguage) {
return super.lookupCode(theSystem, theCode); return super.lookupCode(theSystem, theCode, theDisplayLanguage);
} }
@Override @Override

View File

@ -10,8 +10,8 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.term.api.ITermReadSvcR5; import ca.uhn.fhir.jpa.term.api.ITermReadSvcR5;
import ca.uhn.fhir.jpa.term.ex.ExpansionTooCostlyException; import ca.uhn.fhir.jpa.term.ex.ExpansionTooCostlyException;
import ca.uhn.fhir.util.ValidateUtil; import ca.uhn.fhir.util.ValidateUtil;
import org.hl7.fhir.convertors.VersionConvertor_40_50; import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.conv40_50.CodeSystem40_50; import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.instance.model.api.IBaseCoding; import org.hl7.fhir.instance.model.api.IBaseCoding;
import org.hl7.fhir.instance.model.api.IBaseDatatype; import org.hl7.fhir.instance.model.api.IBaseDatatype;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
@ -19,8 +19,6 @@ import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.CodeableConcept; import org.hl7.fhir.r5.model.CodeableConcept;
import org.hl7.fhir.r5.model.Coding; import org.hl7.fhir.r5.model.Coding;
import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.model.ValueSet;
import org.hl7.fhir.utilities.TerminologyServiceOptions;
import org.hl7.fhir.utilities.validation.ValidationOptions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
@ -59,15 +57,16 @@ public class TermReadSvcR5 extends BaseTermReadSvcImpl implements IValidationSup
@Transactional(dontRollbackOn = {ExpansionTooCostlyException.class}) @Transactional(dontRollbackOn = {ExpansionTooCostlyException.class})
public ValueSetExpansionOutcome expandValueSet(ValidationSupportContext theValidationSupportContext, ValueSetExpansionOptions theExpansionOptions, @Nonnull IBaseResource theValueSetToExpand) { public ValueSetExpansionOutcome expandValueSet(ValidationSupportContext theValidationSupportContext, ValueSetExpansionOptions theExpansionOptions, @Nonnull IBaseResource theValueSetToExpand) {
ValueSet valueSetToExpand = (ValueSet) theValueSetToExpand; ValueSet valueSetToExpand = (ValueSet) theValueSetToExpand;
org.hl7.fhir.r4.model.ValueSet expandedR4 = super.expandValueSet(theExpansionOptions, org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(valueSetToExpand)); org.hl7.fhir.r4.model.ValueSet expandedR4 = super.expandValueSet(theExpansionOptions,
return new ValueSetExpansionOutcome(org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(expandedR4)); (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_40_50.convertResource(valueSetToExpand, new BaseAdvisor_40_50(false)));
return new ValueSetExpansionOutcome(VersionConvertorFactory_40_50.convertResource(expandedR4, new BaseAdvisor_40_50(false)));
} }
@Override @Override
public IBaseResource expandValueSet(ValueSetExpansionOptions theExpansionOptions, IBaseResource theInput) { public IBaseResource expandValueSet(ValueSetExpansionOptions theExpansionOptions, IBaseResource theInput) {
org.hl7.fhir.r4.model.ValueSet valueSetToExpand = toCanonicalValueSet(theInput); org.hl7.fhir.r4.model.ValueSet valueSetToExpand = toCanonicalValueSet(theInput);
org.hl7.fhir.r4.model.ValueSet valueSetR4 = super.expandValueSet(theExpansionOptions, valueSetToExpand); org.hl7.fhir.r4.model.ValueSet valueSetR4 = super.expandValueSet(theExpansionOptions, valueSetToExpand);
return org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(valueSetR4); return VersionConvertorFactory_40_50.convertResource(valueSetR4, new BaseAdvisor_40_50(false));
} }
@Override @Override
@ -79,7 +78,7 @@ public class TermReadSvcR5 extends BaseTermReadSvcImpl implements IValidationSup
@Override @Override
protected org.hl7.fhir.r4.model.ValueSet getValueSetFromResourceTable(ResourceTable theResourceTable) { protected org.hl7.fhir.r4.model.ValueSet getValueSetFromResourceTable(ResourceTable theResourceTable) {
ValueSet valueSetR5 = myDaoRegistry.getResourceDao("ValueSet").toResource(ValueSet.class, theResourceTable, null, false); ValueSet valueSetR5 = myDaoRegistry.getResourceDao("ValueSet").toResource(ValueSet.class, theResourceTable, null, false);
return org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(valueSetR5); return (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_40_50.convertResource(valueSetR5, new BaseAdvisor_40_50(false));
} }
@Override @Override
@ -110,30 +109,30 @@ public class TermReadSvcR5 extends BaseTermReadSvcImpl implements IValidationSup
@Override @Override
@Nullable @Nullable
protected org.hl7.fhir.r4.model.Coding toCanonicalCoding(IBaseDatatype theCoding) { protected org.hl7.fhir.r4.model.Coding toCanonicalCoding(IBaseDatatype theCoding) {
return VersionConvertor_40_50.convertCoding((Coding) theCoding); return (org.hl7.fhir.r4.model.Coding) VersionConvertorFactory_40_50.convertType((Coding) theCoding, new BaseAdvisor_40_50(false));
} }
@Override @Override
@Nullable @Nullable
protected org.hl7.fhir.r4.model.Coding toCanonicalCoding(IBaseCoding theCoding) { protected org.hl7.fhir.r4.model.Coding toCanonicalCoding(IBaseCoding theCoding) {
return VersionConvertor_40_50.convertCoding((Coding) theCoding); return (org.hl7.fhir.r4.model.Coding) VersionConvertorFactory_40_50.convertType((Coding) theCoding, new BaseAdvisor_40_50(false));
} }
@Override @Override
@Nullable @Nullable
protected org.hl7.fhir.r4.model.CodeableConcept toCanonicalCodeableConcept(IBaseDatatype theCoding) { protected org.hl7.fhir.r4.model.CodeableConcept toCanonicalCodeableConcept(IBaseDatatype theCoding) {
return VersionConvertor_40_50.convertCodeableConcept((CodeableConcept) theCoding); return (org.hl7.fhir.r4.model.CodeableConcept) VersionConvertorFactory_40_50.convertType((CodeableConcept) theCoding, new BaseAdvisor_40_50(false));
} }
@Override @Override
protected org.hl7.fhir.r4.model.ValueSet toCanonicalValueSet(IBaseResource theValueSet) throws org.hl7.fhir.exceptions.FHIRException { protected org.hl7.fhir.r4.model.ValueSet toCanonicalValueSet(IBaseResource theValueSet) throws org.hl7.fhir.exceptions.FHIRException {
return org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet((ValueSet) theValueSet); return (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_40_50.convertResource((ValueSet) theValueSet, new BaseAdvisor_40_50(false));
} }
@Override @Override
protected org.hl7.fhir.r4.model.CodeSystem toCanonicalCodeSystem(IBaseResource theCodeSystem) { protected org.hl7.fhir.r4.model.CodeSystem toCanonicalCodeSystem(IBaseResource theCodeSystem) {
return CodeSystem40_50.convertCodeSystem((CodeSystem) theCodeSystem); return (org.hl7.fhir.r4.model.CodeSystem) VersionConvertorFactory_40_50.convertResource((CodeSystem) theCodeSystem, new BaseAdvisor_40_50(false));
} }
@Override @Override
@ -145,8 +144,8 @@ public class TermReadSvcR5 extends BaseTermReadSvcImpl implements IValidationSup
} }
@Override @Override
public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode) { public LookupCodeResult lookupCode(ValidationSupportContext theValidationSupportContext, String theSystem, String theCode, String theDisplayLanguage) {
return super.lookupCode(theSystem, theCode); return super.lookupCode(theSystem, theCode, theDisplayLanguage);
} }
} }

View File

@ -25,6 +25,8 @@ import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.UrlUtil; import ca.uhn.fhir.util.UrlUtil;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.CodeSystem; import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.ConceptMap; import org.hl7.fhir.dstu3.model.ConceptMap;
import org.hl7.fhir.dstu3.model.ValueSet; import org.hl7.fhir.dstu3.model.ValueSet;
@ -36,9 +38,6 @@ import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener; import org.springframework.context.event.EventListener;
import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.hl7.fhir.convertors.conv30_40.CodeSystem30_40.convertCodeSystem;
import static org.hl7.fhir.convertors.conv30_40.ConceptMap30_40.convertConceptMap;
import static org.hl7.fhir.convertors.conv30_40.ValueSet30_40.convertValueSet;
public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl implements ITermVersionAdapterSvc { public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl implements ITermVersionAdapterSvc {
@ -56,7 +55,7 @@ public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl im
/** /**
* Initialize the beans that are used by this service. * Initialize the beans that are used by this service.
* * <p>
* Note: There is a circular dependency here where the CodeSystem DAO * Note: There is a circular dependency here where the CodeSystem DAO
* needs terminology services, and the term services need the CodeSystem DAO. * needs terminology services, and the term services need the CodeSystem DAO.
* So we look these up in a refresh event instead of just autowiring them * So we look these up in a refresh event instead of just autowiring them
@ -70,11 +69,11 @@ public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl im
myConceptMapResourceDao = (IFhirResourceDao<ConceptMap>) myAppCtx.getBean("myConceptMapDaoDstu3"); myConceptMapResourceDao = (IFhirResourceDao<ConceptMap>) myAppCtx.getBean("myConceptMapDaoDstu3");
} }
@Override @Override
public IIdType createOrUpdateCodeSystem(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource, RequestDetails theRequestDetails) { public IIdType createOrUpdateCodeSystem(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource, RequestDetails theRequestDetails) {
CodeSystem resourceToStore; CodeSystem resourceToStore;
try { try {
resourceToStore = convertCodeSystem(theCodeSystemResource); resourceToStore = (CodeSystem) VersionConvertorFactory_30_40.convertResource(theCodeSystemResource, new BaseAdvisor_30_40(false));
} catch (FHIRException e) { } catch (FHIRException e) {
throw new InternalErrorException(e); throw new InternalErrorException(e);
} }
@ -91,7 +90,7 @@ public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl im
public void createOrUpdateConceptMap(org.hl7.fhir.r4.model.ConceptMap theConceptMap) { public void createOrUpdateConceptMap(org.hl7.fhir.r4.model.ConceptMap theConceptMap) {
ConceptMap resourceToStore; ConceptMap resourceToStore;
try { try {
resourceToStore = convertConceptMap(theConceptMap); resourceToStore = (ConceptMap) VersionConvertorFactory_30_40.convertResource(theConceptMap, new BaseAdvisor_30_40(false));
} catch (FHIRException e) { } catch (FHIRException e) {
throw new InternalErrorException(e); throw new InternalErrorException(e);
} }
@ -107,7 +106,7 @@ public class TermVersionAdapterSvcDstu3 extends BaseTermVersionAdapterSvcImpl im
public void createOrUpdateValueSet(org.hl7.fhir.r4.model.ValueSet theValueSet) { public void createOrUpdateValueSet(org.hl7.fhir.r4.model.ValueSet theValueSet) {
ValueSet valueSetDstu3; ValueSet valueSetDstu3;
try { try {
valueSetDstu3 = convertValueSet(theValueSet); valueSetDstu3 = (ValueSet) VersionConvertorFactory_30_40.convertResource(theValueSet, new BaseAdvisor_30_40(false));
} catch (FHIRException e) { } catch (FHIRException e) {
throw new InternalErrorException(e); throw new InternalErrorException(e);
} }

View File

@ -24,6 +24,8 @@ import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc; import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.util.UrlUtil; import ca.uhn.fhir.util.UrlUtil;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r5.model.CodeSystem; import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.ConceptMap; import org.hl7.fhir.r5.model.ConceptMap;
@ -63,7 +65,7 @@ public class TermVersionAdapterSvcR5 extends BaseTermVersionAdapterSvcImpl imple
public IIdType createOrUpdateCodeSystem(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource, RequestDetails theRequestDetails) { public IIdType createOrUpdateCodeSystem(org.hl7.fhir.r4.model.CodeSystem theCodeSystemResource, RequestDetails theRequestDetails) {
validateCodeSystemForStorage(theCodeSystemResource); validateCodeSystemForStorage(theCodeSystemResource);
CodeSystem codeSystemR4 = org.hl7.fhir.convertors.conv40_50.CodeSystem40_50.convertCodeSystem(theCodeSystemResource); CodeSystem codeSystemR4 = (CodeSystem) VersionConvertorFactory_40_50.convertResource(theCodeSystemResource, new BaseAdvisor_40_50(false));
if (isBlank(theCodeSystemResource.getIdElement().getIdPart())) { if (isBlank(theCodeSystemResource.getIdElement().getIdPart())) {
String matchUrl = "CodeSystem?url=" + UrlUtil.escapeUrlParam(theCodeSystemResource.getUrl()); String matchUrl = "CodeSystem?url=" + UrlUtil.escapeUrlParam(theCodeSystemResource.getUrl());
return myCodeSystemResourceDao.update(codeSystemR4, matchUrl, theRequestDetails).getId(); return myCodeSystemResourceDao.update(codeSystemR4, matchUrl, theRequestDetails).getId();
@ -75,7 +77,7 @@ public class TermVersionAdapterSvcR5 extends BaseTermVersionAdapterSvcImpl imple
@Override @Override
public void createOrUpdateConceptMap(org.hl7.fhir.r4.model.ConceptMap theConceptMap) { public void createOrUpdateConceptMap(org.hl7.fhir.r4.model.ConceptMap theConceptMap) {
ConceptMap conceptMapR4 = org.hl7.fhir.convertors.conv40_50.ConceptMap40_50.convertConceptMap(theConceptMap); ConceptMap conceptMapR4 = (ConceptMap) VersionConvertorFactory_40_50.convertResource(theConceptMap, new BaseAdvisor_40_50(false));
if (isBlank(theConceptMap.getIdElement().getIdPart())) { if (isBlank(theConceptMap.getIdElement().getIdPart())) {
String matchUrl = "ConceptMap?url=" + UrlUtil.escapeUrlParam(theConceptMap.getUrl()); String matchUrl = "ConceptMap?url=" + UrlUtil.escapeUrlParam(theConceptMap.getUrl());
@ -88,7 +90,7 @@ public class TermVersionAdapterSvcR5 extends BaseTermVersionAdapterSvcImpl imple
@Override @Override
public void createOrUpdateValueSet(org.hl7.fhir.r4.model.ValueSet theValueSet) { public void createOrUpdateValueSet(org.hl7.fhir.r4.model.ValueSet theValueSet) {
ValueSet valueSetR4 = org.hl7.fhir.convertors.conv40_50.ValueSet40_50.convertValueSet(theValueSet); ValueSet valueSetR4 = (ValueSet) VersionConvertorFactory_40_50.convertResource(theValueSet, new BaseAdvisor_40_50(false));
if (isBlank(theValueSet.getIdElement().getIdPart())) { if (isBlank(theValueSet.getIdElement().getIdPart())) {
String matchUrl = "ValueSet?url=" + UrlUtil.escapeUrlParam(theValueSet.getUrl()); String matchUrl = "ValueSet?url=" + UrlUtil.escapeUrlParam(theValueSet.getUrl());

View File

@ -27,7 +27,9 @@ import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import org.hl7.fhir.common.hapi.validation.validator.VersionSpecificWorkerContextWrapper; import org.hl7.fhir.common.hapi.validation.validator.VersionSpecificWorkerContextWrapper;
import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.IdType; import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r5.elementmodel.Element; import org.hl7.fhir.r5.elementmodel.Element;
@ -39,6 +41,9 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.Locale; import java.util.Locale;
public class ValidatorResourceFetcher implements IResourceValidator.IValidatorResourceFetcher { public class ValidatorResourceFetcher implements IResourceValidator.IValidatorResourceFetcher {
@ -60,10 +65,8 @@ public class ValidatorResourceFetcher implements IResourceValidator.IValidatorRe
myVersionSpecificCOntextWrapper = VersionSpecificWorkerContextWrapper.newVersionSpecificWorkerContextWrapper(myValidationSupport); myVersionSpecificCOntextWrapper = VersionSpecificWorkerContextWrapper.newVersionSpecificWorkerContextWrapper(myValidationSupport);
} }
@Override @Override
public Element fetch(Object appContext, String theUrl) throws FHIRException { public Element fetch(IResourceValidator iResourceValidator, Object appContext, String theUrl) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
IdType id = new IdType(theUrl); IdType id = new IdType(theUrl);
String resourceType = id.getResourceType(); String resourceType = id.getResourceType();
IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(resourceType); IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(resourceType);
@ -83,7 +86,8 @@ public class ValidatorResourceFetcher implements IResourceValidator.IValidatorRe
} }
@Override @Override
public IResourceValidator.ReferenceValidationPolicy validationPolicy(Object appContext, String path, String url) { public IResourceValidator.ReferenceValidationPolicy validationPolicy(IResourceValidator iResourceValidator,
Object appContext, String path, String url) {
int slashIdx = url.indexOf("/"); int slashIdx = url.indexOf("/");
if (slashIdx > 0 && myFhirContext.getResourceTypes().contains(url.substring(0, slashIdx))) { if (slashIdx > 0 && myFhirContext.getResourceTypes().contains(url.substring(0, slashIdx))) {
return myValidationSettings.getLocalReferenceValidationDefaultPolicy(); return myValidationSettings.getLocalReferenceValidationDefaultPolicy();
@ -93,12 +97,12 @@ public class ValidatorResourceFetcher implements IResourceValidator.IValidatorRe
} }
@Override @Override
public boolean resolveURL(Object appContext, String path, String url, String type) throws FHIRException { public boolean resolveURL(IResourceValidator iResourceValidator, Object o, String s, String s1, String s2) throws IOException, FHIRException {
return true; return true;
} }
@Override @Override
public byte[] fetchRaw(String url) { public byte[] fetchRaw(IResourceValidator iResourceValidator, String s) throws MalformedURLException, IOException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@ -109,13 +113,12 @@ public class ValidatorResourceFetcher implements IResourceValidator.IValidatorRe
} }
@Override @Override
public CanonicalResource fetchCanonicalResource(String url) { public CanonicalResource fetchCanonicalResource(IResourceValidator iResourceValidator, String s) throws URISyntaxException {
throw new UnsupportedOperationException(); return null;
} }
@Override @Override
public boolean fetchesCanonicalResource(String url) { public boolean fetchesCanonicalResource(IResourceValidator iResourceValidator, String s) {
return false; return false;
} }
} }

View File

@ -78,7 +78,8 @@ public class FhirResourceDaoValueSetDstu2Test extends BaseJpaDstu2Test {
CodingDt coding = null; CodingDt coding = null;
CodeableConceptDt codeableConcept = null; CodeableConceptDt codeableConcept = null;
IValidationSupport.CodeValidationResult result = myValueSetDao.validateCode(valueSetIdentifier, id, code, system, display, coding, codeableConcept, mySrd); IValidationSupport.CodeValidationResult result = myValueSetDao.validateCode(valueSetIdentifier, id, code, system, display, coding, codeableConcept, mySrd);
assertFalse(result.isOk()); //TODO JA, from what I read, this _should_ pass, but this was flipped to false in a previous commit.
assertTrue(result.isOk());
} }
@Test @Test

View File

@ -38,7 +38,6 @@ import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3;
import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider; import ca.uhn.fhir.jpa.search.DatabaseBackedPagingProvider;
import ca.uhn.fhir.jpa.search.IStaleSearchDeletingSvc; import ca.uhn.fhir.jpa.search.IStaleSearchDeletingSvc;
import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc; import ca.uhn.fhir.jpa.search.reindex.IResourceReindexingSvc;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc; import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
import ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl; import ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl;
import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl; import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl;
@ -53,10 +52,13 @@ import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory; import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
import ca.uhn.fhir.util.UrlUtil; import ca.uhn.fhir.util.UrlUtil;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.hibernate.search.mapper.orm.Search; import org.hibernate.search.mapper.orm.Search;
import org.hibernate.search.mapper.orm.session.SearchSession; import org.hibernate.search.mapper.orm.session.SearchSession;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.dstu3.model.AllergyIntolerance; import org.hl7.fhir.dstu3.model.AllergyIntolerance;
import org.hl7.fhir.dstu3.model.Appointment; import org.hl7.fhir.dstu3.model.Appointment;
import org.hl7.fhir.dstu3.model.AuditEvent; import org.hl7.fhir.dstu3.model.AuditEvent;
@ -125,7 +127,6 @@ import java.io.InputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Map; import java.util.Map;
import static org.hl7.fhir.convertors.conv30_40.ConceptMap30_40.convertConceptMap;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
@ExtendWith(SpringExtension.class) @ExtendWith(SpringExtension.class)
@ -378,7 +379,7 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
@BeforeEach @BeforeEach
public void beforeFlushFT() { public void beforeFlushFT() {
runInTransaction(() -> { runInTransaction(() -> {
SearchSession searchSession = Search.session(myEntityManager); SearchSession searchSession = Search.session(myEntityManager);
searchSession.workspace(ResourceTable.class).purge(); searchSession.workspace(ResourceTable.class).purge();
// searchSession.workspace(ResourceIndexedSearchParamString.class).purge(); // searchSession.workspace(ResourceIndexedSearchParamString.class).purge();
searchSession.indexingPlan().execute(); searchSession.indexingPlan().execute();
@ -462,7 +463,7 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
*/ */
public static ConceptMap createConceptMap() { public static ConceptMap createConceptMap() {
try { try {
return convertConceptMap(BaseJpaR4Test.createConceptMap()); return (ConceptMap) VersionConvertorFactory_30_40.convertResource(BaseJpaR4Test.createConceptMap(), new BaseAdvisor_30_40(false));
} catch (FHIRException fe) { } catch (FHIRException fe) {
throw new InternalErrorException(fe); throw new InternalErrorException(fe);
} }

View File

@ -104,7 +104,6 @@ import org.hl7.fhir.r4.model.Organization;
import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.Period; import org.hl7.fhir.r4.model.Period;
import org.hl7.fhir.r4.model.Practitioner; import org.hl7.fhir.r4.model.Practitioner;
import org.hl7.fhir.r4.model.Procedure;
import org.hl7.fhir.r4.model.Provenance; import org.hl7.fhir.r4.model.Provenance;
import org.hl7.fhir.r4.model.Quantity; import org.hl7.fhir.r4.model.Quantity;
import org.hl7.fhir.r4.model.Questionnaire; import org.hl7.fhir.r4.model.Questionnaire;
@ -5304,7 +5303,6 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
createObservationWithEffective("YES22", "2011-01-02T00:00:00+10:00"); createObservationWithEffective("YES22", "2011-01-02T00:00:00+10:00");
createObservationWithEffective("YES23", "2011-01-02T00:00:00+11:00"); createObservationWithEffective("YES23", "2011-01-02T00:00:00+11:00");
SearchParameterMap map = new SearchParameterMap(); SearchParameterMap map = new SearchParameterMap();
map.setLoadSynchronous(true); map.setLoadSynchronous(true);
map.add(Observation.SP_DATE, new DateParam("2011-01-02")); map.add(Observation.SP_DATE, new DateParam("2011-01-02"));

View File

@ -779,7 +779,5 @@ public class FhirResourceDaoR4VersionedReferenceTest extends BaseJpaR4Test {
assertEquals(observationId.getValue(), resources.get(0).getIdElement().getValue()); assertEquals(observationId.getValue(), resources.get(0).getIdElement().getValue());
assertEquals(patientId.withVersion("2").getValue(), resources.get(1).getIdElement().getValue()); assertEquals(patientId.withVersion("2").getValue(), resources.get(1).getIdElement().getValue());
} }
} }
} }

View File

@ -1,6 +1,7 @@
package ca.uhn.fhir.jpa.dao.r4; package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao; import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel; import ca.uhn.fhir.jpa.model.entity.NormalizedQuantitySearchLevel;
import ca.uhn.fhir.jpa.model.entity.ResourceEncodingEnum; import ca.uhn.fhir.jpa.model.entity.ResourceEncodingEnum;
@ -63,6 +64,7 @@ import org.hl7.fhir.r4.model.Practitioner;
import org.hl7.fhir.r4.model.Quantity; import org.hl7.fhir.r4.model.Quantity;
import org.hl7.fhir.r4.model.Reference; import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.Resource; import org.hl7.fhir.r4.model.Resource;
import org.hl7.fhir.r4.model.Task;
import org.hl7.fhir.r4.model.ValueSet; import org.hl7.fhir.r4.model.ValueSet;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
@ -1002,6 +1004,23 @@ public class FhirSystemDaoR4Test extends BaseJpaR4SystemTest {
} }
@Test
public void testTransactionNoContainedRedux() throws IOException {
//Pre-create the patient, which will cause the ifNoneExist to prevent a new creation during bundle transaction
Patient patient = loadResourceFromClasspath(Patient.class, "/r4/preexisting-patient.json");
myPatientDao.create(patient);
//Post the Bundle containing a conditional POST with an identical patient from the above resource.
Bundle request = loadResourceFromClasspath(Bundle.class, "/r4/transaction-no-contained-2.json");
Bundle outcome = mySystemDao.transaction(mySrd, request);
IdType taskId = new IdType(outcome.getEntry().get(0).getResponse().getLocation());
Task task = myTaskDao.read(taskId, mySrd);
assertThat(task.getBasedOn().get(0).getReference(), matchesPattern("Patient/[0-9]+"));
}
@Test @Test
public void testTransactionNoContained() throws IOException { public void testTransactionNoContained() throws IOException {

View File

@ -10,10 +10,8 @@ import ca.uhn.fhir.jpa.entity.SearchTypeEnum;
import ca.uhn.fhir.jpa.model.search.SearchStatusEnum; import ca.uhn.fhir.jpa.model.search.SearchStatusEnum;
import ca.uhn.fhir.jpa.search.cache.DatabaseSearchCacheSvcImpl; import ca.uhn.fhir.jpa.search.cache.DatabaseSearchCacheSvcImpl;
import ca.uhn.fhir.jpa.search.cache.ISearchCacheSvc; import ca.uhn.fhir.jpa.search.cache.ISearchCacheSvc;
import ca.uhn.fhir.util.TestUtil;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -40,7 +38,7 @@ public class SearchCoordinatorSvcImplTest extends BaseJpaR4Test {
private ISearchCoordinatorSvc mySearchCoordinator; private ISearchCoordinatorSvc mySearchCoordinator;
@Autowired @Autowired
private ISearchCacheSvc myDataaseCacheSvc; private ISearchCacheSvc myDatabaseCacheSvc;
@AfterEach @AfterEach
public void after() { public void after() {
@ -92,7 +90,7 @@ public class SearchCoordinatorSvcImplTest extends BaseJpaR4Test {
assertEquals(30, mySearchResultDao.count()); assertEquals(30, mySearchResultDao.count());
}); });
myDataaseCacheSvc.pollForStaleSearchesAndDeleteThem(); myDatabaseCacheSvc.pollForStaleSearchesAndDeleteThem();
runInTransaction(()->{ runInTransaction(()->{
// We should delete up to 10, but 3 don't get deleted since they have too many results to delete in one pass // We should delete up to 10, but 3 don't get deleted since they have too many results to delete in one pass
assertEquals(13, mySearchDao.count()); assertEquals(13, mySearchDao.count());
@ -101,7 +99,7 @@ public class SearchCoordinatorSvcImplTest extends BaseJpaR4Test {
assertEquals(15, mySearchResultDao.count()); assertEquals(15, mySearchResultDao.count());
}); });
myDataaseCacheSvc.pollForStaleSearchesAndDeleteThem(); myDatabaseCacheSvc.pollForStaleSearchesAndDeleteThem();
runInTransaction(()->{ runInTransaction(()->{
// Once again we attempt to delete 10, but the first 3 don't get deleted and still remain // Once again we attempt to delete 10, but the first 3 don't get deleted and still remain
// (total is 6 because 3 weren't deleted, and they blocked another 3 that might have been) // (total is 6 because 3 weren't deleted, and they blocked another 3 that might have been)
@ -110,7 +108,7 @@ public class SearchCoordinatorSvcImplTest extends BaseJpaR4Test {
assertEquals(0, mySearchResultDao.count()); assertEquals(0, mySearchResultDao.count());
}); });
myDataaseCacheSvc.pollForStaleSearchesAndDeleteThem(); myDatabaseCacheSvc.pollForStaleSearchesAndDeleteThem();
runInTransaction(()->{ runInTransaction(()->{
assertEquals(0, mySearchDao.count()); assertEquals(0, mySearchDao.count());
assertEquals(0, mySearchDao.countDeleted()); assertEquals(0, mySearchDao.countDeleted());

View File

@ -1,8 +1,10 @@
package ca.uhn.fhir.jpa.provider; package ca.uhn.fhir.jpa.provider;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.rest.api.SearchContainedModeEnum;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -41,6 +43,24 @@ public class SearchParameterMapTest {
assertEquals("?birthdate=ge2001&birthdate=lt2002&name=bouvier,simpson&name=homer,jay&name:exact=ZZZ?", UrlUtil.unescape(queryString)); assertEquals("?birthdate=ge2001&birthdate=lt2002&name=bouvier,simpson&name=homer,jay&name:exact=ZZZ?", UrlUtil.unescape(queryString));
} }
@Test
public void testContainedParameterIsIncludedInNormalizedString() {
SearchParameterMap map = new SearchParameterMap();
map.add("name", new StringParam("Smith"));
map.setSearchContainedMode(SearchContainedModeEnum.TRUE);
String containedQueryString = map.toNormalizedQueryString(ourCtx);
SearchParameterMap uncontainedMap = new SearchParameterMap();
uncontainedMap.add("name", new StringParam("Smith"));
uncontainedMap.setSearchContainedMode(SearchContainedModeEnum.FALSE);
String uncontainedQueryString = uncontainedMap.toNormalizedQueryString(ourCtx);
ourLog.info(containedQueryString);
ourLog.info(uncontainedQueryString);
assertNotEquals(containedQueryString, uncontainedQueryString);
}
@Test @Test
public void testToQueryStringEmpty() { public void testToQueryStringEmpty() {
SearchParameterMap map = new SearchParameterMap(); SearchParameterMap map = new SearchParameterMap();

View File

@ -0,0 +1,173 @@
package ca.uhn.fhir.jpa.provider.dstu3;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.hl7.fhir.dstu3.model.BooleanType;
import org.hl7.fhir.dstu3.model.CodeSystem;
import org.hl7.fhir.dstu3.model.CodeType;
import org.hl7.fhir.dstu3.model.Parameters;
import org.hl7.fhir.dstu3.model.Parameters.ParametersParameterComponent;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.dstu3.model.UriType;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.transaction.annotation.Transactional;
public class ResourceProviderR3CodeSystemDesignationTest extends BaseResourceProviderDstu3Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderR3CodeSystemDesignationTest.class);
private static final String CS_ACME_URL = "http://acme.org";
@BeforeEach
@Transactional
public void before02() throws IOException {
CodeSystem cs = loadResourceFromClasspath(CodeSystem.class, "/extensional-case-3-cs-with-designations-lang.xml");
myCodeSystemDao.create(cs, mySrd).getId().toUnqualifiedVersionless();
}
@Test
public void testLookupWithDisplayLanguage() {
Parameters respParam = ourClient
.operation()
.onType(CodeSystem.class)
.named("lookup")
.withParameter(Parameters.class, "code", new CodeType("8494-7"))
.andParameter("system", new UriType(CS_ACME_URL))
.andParameter("displayLanguage",new CodeType("de-AT"))
.execute();
String resp = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);
List<ParametersParameterComponent> parameterList = respParam.getParameter();
List<ParametersParameterComponent> designationList = getDesignations(parameterList);
assertEquals("display", respParam.getParameter().get(0).getName());
assertEquals(("Systolic blood pressure 12 hour minimum"), ((StringType) respParam.getParameter().get(0).getValue()).getValue());
assertEquals("abstract", respParam.getParameter().get(1).getName());
assertEquals(false, ((BooleanType) respParam.getParameter().get(1).getValue()).getValue());
//-- designationList
assertEquals(2, designationList.size());
// 1. de-AT:Systolic blood pressure 12 hour minimum
ParametersParameterComponent designation = designationList.get(0);
assertEquals("language", designation.getPart().get(0).getName());
assertEquals("de-AT", designation.getPart().get(0).getValue().toString());
assertEquals("value", designation.getPart().get(2).getName());
assertEquals("de-AT:Systolic blood pressure 12 hour minimum", designation.getPart().get(2).getValue().toString());
// 2. Systolic blood pressure 12 hour minimum (no language)
designation = designationList.get(1);
assertEquals("language", designation.getPart().get(0).getName());
assertNull(designation.getPart().get(0).getValue());
assertEquals("value", designation.getPart().get(2).getName());
assertEquals("Systolic blood pressure 12 hour minimum", designation.getPart().get(2).getValue().toString());
}
@Test
public void testLookupWithNonExistLanguage() {
Parameters respParam = ourClient
.operation()
.onType(CodeSystem.class)
.named("lookup")
.withParameter(Parameters.class, "code", new CodeType("8494-7"))
.andParameter("system", new UriType(CS_ACME_URL))
.andParameter("displayLanguage",new CodeType("zh-CN"))
.execute();
String resp = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);
List<ParametersParameterComponent> parameterList = respParam.getParameter();
List<ParametersParameterComponent> designationList = getDesignations(parameterList);
assertEquals("display", respParam.getParameter().get(0).getName());
assertEquals(("Systolic blood pressure 12 hour minimum"), ((StringType) respParam.getParameter().get(0).getValue()).getValue());
assertEquals("abstract", respParam.getParameter().get(1).getName());
assertEquals(false, ((BooleanType) respParam.getParameter().get(1).getValue()).getValue());
//-- designationList
assertEquals(1, designationList.size());
// 1. Systolic blood pressure 12 hour minimum (no language)
ParametersParameterComponent designation = designationList.get(0);
assertEquals("language", designation.getPart().get(0).getName());
assertNull(designation.getPart().get(0).getValue());
assertEquals("value", designation.getPart().get(2).getName());
assertEquals("Systolic blood pressure 12 hour minimum", designation.getPart().get(2).getValue().toString());
}
@Test
public void testLookupWithoutDisplayLanguage() {
Parameters respParam = ourClient
.operation()
.onType(CodeSystem.class)
.named("lookup")
.withParameter(Parameters.class, "code", new CodeType("8494-7"))
.andParameter("system", new UriType(CS_ACME_URL))
.execute();
String resp = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);
List<ParametersParameterComponent> parameterList = respParam.getParameter();
List<ParametersParameterComponent> designationList = getDesignations(parameterList);
assertEquals("display", respParam.getParameter().get(0).getName());
assertEquals(("Systolic blood pressure 12 hour minimum"), ((StringType) respParam.getParameter().get(0).getValue()).getValue());
assertEquals("abstract", respParam.getParameter().get(1).getName());
assertEquals(false, ((BooleanType) respParam.getParameter().get(1).getValue()).getValue());
//-- designationList
assertEquals(3, designationList.size());
// 1. fr-FR:Systolic blood pressure 12 hour minimum
ParametersParameterComponent designation = designationList.get(0);
assertEquals("language", designation.getPart().get(0).getName());
assertEquals("fr-FR", designation.getPart().get(0).getValue().toString());
assertEquals("value", designation.getPart().get(2).getName());
assertEquals("fr-FR:Systolic blood pressure 12 hour minimum", designation.getPart().get(2).getValue().toString());
// 2. de-AT:Systolic blood pressure 12 hour minimum
designation = designationList.get(1);
assertEquals("language", designation.getPart().get(0).getName());
assertEquals("de-AT", designation.getPart().get(0).getValue().toString());
assertEquals("value", designation.getPart().get(2).getName());
assertEquals("de-AT:Systolic blood pressure 12 hour minimum", designation.getPart().get(2).getValue().toString());
// 3. Systolic blood pressure 12 hour minimum (no language)
designation = designationList.get(2);
assertEquals("language", designation.getPart().get(0).getName());
assertNull(designation.getPart().get(0).getValue());
assertEquals("value", designation.getPart().get(2).getName());
assertEquals("Systolic blood pressure 12 hour minimum", designation.getPart().get(2).getValue().toString());
}
private List<ParametersParameterComponent> getDesignations(List<ParametersParameterComponent> parameterList) {
List<ParametersParameterComponent> designationList = new ArrayList<>();
for (ParametersParameterComponent parameter : parameterList) {
if ("designation".equals(parameter.getName()))
designationList.add(parameter);
}
return designationList;
}
}

View File

@ -1,5 +1,35 @@
package ca.uhn.fhir.jpa.provider.r4; package ca.uhn.fhir.jpa.provider.r4;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.Parameters.ParametersParameterComponent;
import org.hl7.fhir.r4.model.Patient;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.DispatcherServlet;
import ca.uhn.fhir.context.support.IValidationSupport; import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.jpa.api.dao.DaoRegistry; import ca.uhn.fhir.jpa.api.dao.DaoRegistry;
import ca.uhn.fhir.jpa.api.svc.ISearchCoordinatorSvc; import ca.uhn.fhir.jpa.api.svc.ISearchCoordinatorSvc;
@ -26,35 +56,6 @@ import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor;
import ca.uhn.fhir.rest.server.provider.DeleteExpungeProvider; import ca.uhn.fhir.rest.server.provider.DeleteExpungeProvider;
import ca.uhn.fhir.rest.server.provider.ReindexProvider; import ca.uhn.fhir.rest.server.provider.ReindexProvider;
import ca.uhn.fhir.test.utilities.JettyUtil; import ca.uhn.fhir.test.utilities.JettyUtil;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.Parameters.ParametersParameterComponent;
import org.hl7.fhir.r4.model.Patient;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.DispatcherServlet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public abstract class BaseResourceProviderR4Test extends BaseJpaR4Test { public abstract class BaseResourceProviderR4Test extends BaseJpaR4Test {

View File

@ -0,0 +1,173 @@
package ca.uhn.fhir.jpa.provider.r4;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.hl7.fhir.r4.model.BooleanType;
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.CodeType;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.Parameters.ParametersParameterComponent;
import org.hl7.fhir.r4.model.StringType;
import org.hl7.fhir.r4.model.UriType;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.transaction.annotation.Transactional;
public class ResourceProviderR4CodeSystemDesignationTest extends BaseResourceProviderR4Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderR4CodeSystemDesignationTest.class);
private static final String CS_ACME_URL = "http://acme.org";
@BeforeEach
@Transactional
public void before02() throws IOException {
CodeSystem cs = loadResourceFromClasspath(CodeSystem.class, "/extensional-case-3-cs-with-designations-lang.xml");
myCodeSystemDao.create(cs, mySrd).getId().toUnqualifiedVersionless();
}
@Test
public void testLookupWithDisplayLanguage() {
Parameters respParam = myClient
.operation()
.onType(CodeSystem.class)
.named("lookup")
.withParameter(Parameters.class, "code", new CodeType("8494-7"))
.andParameter("system", new UriType(CS_ACME_URL))
.andParameter("displayLanguage",new CodeType("de-AT"))
.execute();
String resp = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);
List<ParametersParameterComponent> parameterList = respParam.getParameter();
List<ParametersParameterComponent> designationList = getDesignations(parameterList);
assertEquals("display", respParam.getParameter().get(0).getName());
assertEquals(("Systolic blood pressure 12 hour minimum"), ((StringType) respParam.getParameter().get(0).getValue()).getValue());
assertEquals("abstract", respParam.getParameter().get(1).getName());
assertEquals(false, ((BooleanType) respParam.getParameter().get(1).getValue()).getValue());
//-- designationList
assertEquals(2, designationList.size());
// 1. de-AT:Systolic blood pressure 12 hour minimum
ParametersParameterComponent designation = designationList.get(0);
assertEquals("language", designation.getPart().get(0).getName());
assertEquals("de-AT", designation.getPart().get(0).getValue().toString());
assertEquals("value", designation.getPart().get(2).getName());
assertEquals("de-AT:Systolic blood pressure 12 hour minimum", designation.getPart().get(2).getValue().toString());
// 2. Systolic blood pressure 12 hour minimum (no language)
designation = designationList.get(1);
assertEquals("language", designation.getPart().get(0).getName());
assertNull(designation.getPart().get(0).getValue());
assertEquals("value", designation.getPart().get(2).getName());
assertEquals("Systolic blood pressure 12 hour minimum", designation.getPart().get(2).getValue().toString());
}
@Test
public void testLookupWithNonExistLanguage() {
Parameters respParam = myClient
.operation()
.onType(CodeSystem.class)
.named("lookup")
.withParameter(Parameters.class, "code", new CodeType("8494-7"))
.andParameter("system", new UriType(CS_ACME_URL))
.andParameter("displayLanguage",new CodeType("zh-CN"))
.execute();
String resp = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);
List<ParametersParameterComponent> parameterList = respParam.getParameter();
List<ParametersParameterComponent> designationList = getDesignations(parameterList);
assertEquals("display", respParam.getParameter().get(0).getName());
assertEquals(("Systolic blood pressure 12 hour minimum"), ((StringType) respParam.getParameter().get(0).getValue()).getValue());
assertEquals("abstract", respParam.getParameter().get(1).getName());
assertEquals(false, ((BooleanType) respParam.getParameter().get(1).getValue()).getValue());
//-- designationList
assertEquals(1, designationList.size());
// 1. Systolic blood pressure 12 hour minimum (no language)
ParametersParameterComponent designation = designationList.get(0);
assertEquals("language", designation.getPart().get(0).getName());
assertNull(designation.getPart().get(0).getValue());
assertEquals("value", designation.getPart().get(2).getName());
assertEquals("Systolic blood pressure 12 hour minimum", designation.getPart().get(2).getValue().toString());
}
@Test
public void testLookupWithoutDisplayLanguage() {
Parameters respParam = myClient
.operation()
.onType(CodeSystem.class)
.named("lookup")
.withParameter(Parameters.class, "code", new CodeType("8494-7"))
.andParameter("system", new UriType(CS_ACME_URL))
.execute();
String resp = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);
List<ParametersParameterComponent> parameterList = respParam.getParameter();
List<ParametersParameterComponent> designationList = getDesignations(parameterList);
assertEquals("display", respParam.getParameter().get(0).getName());
assertEquals(("Systolic blood pressure 12 hour minimum"), ((StringType) respParam.getParameter().get(0).getValue()).getValue());
assertEquals("abstract", respParam.getParameter().get(1).getName());
assertEquals(false, ((BooleanType) respParam.getParameter().get(1).getValue()).getValue());
//-- designationList
assertEquals(3, designationList.size());
// 1. fr-FR:Systolic blood pressure 12 hour minimum
ParametersParameterComponent designation = designationList.get(0);
assertEquals("language", designation.getPart().get(0).getName());
assertEquals("fr-FR", designation.getPart().get(0).getValue().toString());
assertEquals("value", designation.getPart().get(2).getName());
assertEquals("fr-FR:Systolic blood pressure 12 hour minimum", designation.getPart().get(2).getValue().toString());
// 2. de-AT:Systolic blood pressure 12 hour minimum
designation = designationList.get(1);
assertEquals("language", designation.getPart().get(0).getName());
assertEquals("de-AT", designation.getPart().get(0).getValue().toString());
assertEquals("value", designation.getPart().get(2).getName());
assertEquals("de-AT:Systolic blood pressure 12 hour minimum", designation.getPart().get(2).getValue().toString());
// 3. Systolic blood pressure 12 hour minimum (no language)
designation = designationList.get(2);
assertEquals("language", designation.getPart().get(0).getName());
assertNull(designation.getPart().get(0).getValue());
assertEquals("value", designation.getPart().get(2).getName());
assertEquals("Systolic blood pressure 12 hour minimum", designation.getPart().get(2).getValue().toString());
}
private List<ParametersParameterComponent> getDesignations(List<ParametersParameterComponent> parameterList) {
List<ParametersParameterComponent> designationList = new ArrayList<>();
for (ParametersParameterComponent parameter : parameterList) {
if ("designation".equals(parameter.getName()))
designationList.add(parameter);
}
return designationList;
}
}

View File

@ -284,7 +284,6 @@ public class ResourceProviderR4SearchContainedTest extends BaseResourceProviderR
assertEquals(0L, oids.size()); assertEquals(0L, oids.size());
} }
@Test @Test
public void testContainedSearchByNumber() throws Exception { public void testContainedSearchByNumber() throws Exception {
@ -975,6 +974,11 @@ public class ResourceProviderR4SearchContainedTest extends BaseResourceProviderR
assertEquals(1L, oids.size()); assertEquals(1L, oids.size());
assertThat(oids, contains(oid1.getValue())); assertThat(oids, contains(oid1.getValue()));
}
//See https://github.com/hapifhir/hapi-fhir/issues/2887
@Test
public void testContainedResourceParameterIsUsedInCache() {
} }

View File

@ -0,0 +1,173 @@
package ca.uhn.fhir.jpa.provider.r5;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.hl7.fhir.r5.model.BooleanType;
import org.hl7.fhir.r5.model.CodeSystem;
import org.hl7.fhir.r5.model.CodeType;
import org.hl7.fhir.r5.model.Parameters;
import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent;
import org.hl7.fhir.r5.model.StringType;
import org.hl7.fhir.r5.model.UriType;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.transaction.annotation.Transactional;
public class ResourceProviderR5CodeSystemDesignationTest extends BaseResourceProviderR5Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderR5CodeSystemDesignationTest.class);
private static final String CS_ACME_URL = "http://acme.org";
@BeforeEach
@Transactional
public void before02() throws IOException {
CodeSystem cs = loadResourceFromClasspath(CodeSystem.class, "/extensional-case-3-cs-with-designations-lang.xml");
myCodeSystemDao.create(cs, mySrd).getId().toUnqualifiedVersionless();
}
@Test
public void testLookupWithDisplayLanguage() {
Parameters respParam = myClient
.operation()
.onType(CodeSystem.class)
.named("lookup")
.withParameter(Parameters.class, "code", new CodeType("8494-7"))
.andParameter("system", new UriType(CS_ACME_URL))
.andParameter("displayLanguage",new CodeType("de-AT"))
.execute();
String resp = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);
List<ParametersParameterComponent> parameterList = respParam.getParameter();
List<ParametersParameterComponent> designationList = getDesignations(parameterList);
assertEquals("display", respParam.getParameter().get(0).getName());
assertEquals(("Systolic blood pressure 12 hour minimum"), ((StringType) respParam.getParameter().get(0).getValue()).getValue());
assertEquals("abstract", respParam.getParameter().get(1).getName());
assertEquals(false, ((BooleanType) respParam.getParameter().get(1).getValue()).getValue());
//-- designationList
assertEquals(2, designationList.size());
// 1. de-AT:Systolic blood pressure 12 hour minimum
ParametersParameterComponent designation = designationList.get(0);
assertEquals("language", designation.getPart().get(0).getName());
assertEquals("de-AT", designation.getPart().get(0).getValue().toString());
assertEquals("value", designation.getPart().get(2).getName());
assertEquals("de-AT:Systolic blood pressure 12 hour minimum", designation.getPart().get(2).getValue().toString());
// 2. Systolic blood pressure 12 hour minimum (no language)
designation = designationList.get(1);
assertEquals("language", designation.getPart().get(0).getName());
assertNull(designation.getPart().get(0).getValue());
assertEquals("value", designation.getPart().get(2).getName());
assertEquals("Systolic blood pressure 12 hour minimum", designation.getPart().get(2).getValue().toString());
}
@Test
public void testLookupWithNonExistLanguage() {
Parameters respParam = myClient
.operation()
.onType(CodeSystem.class)
.named("lookup")
.withParameter(Parameters.class, "code", new CodeType("8494-7"))
.andParameter("system", new UriType(CS_ACME_URL))
.andParameter("displayLanguage",new CodeType("zh-CN"))
.execute();
String resp = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);
List<ParametersParameterComponent> parameterList = respParam.getParameter();
List<ParametersParameterComponent> designationList = getDesignations(parameterList);
assertEquals("display", respParam.getParameter().get(0).getName());
assertEquals(("Systolic blood pressure 12 hour minimum"), ((StringType) respParam.getParameter().get(0).getValue()).getValue());
assertEquals("abstract", respParam.getParameter().get(1).getName());
assertEquals(false, ((BooleanType) respParam.getParameter().get(1).getValue()).getValue());
//-- designationList
assertEquals(1, designationList.size());
// 1. Systolic blood pressure 12 hour minimum (no language)
ParametersParameterComponent designation = designationList.get(0);
assertEquals("language", designation.getPart().get(0).getName());
assertNull(designation.getPart().get(0).getValue());
assertEquals("value", designation.getPart().get(2).getName());
assertEquals("Systolic blood pressure 12 hour minimum", designation.getPart().get(2).getValue().toString());
}
@Test
public void testLookupWithoutDisplayLanguage() {
Parameters respParam = myClient
.operation()
.onType(CodeSystem.class)
.named("lookup")
.withParameter(Parameters.class, "code", new CodeType("8494-7"))
.andParameter("system", new UriType(CS_ACME_URL))
.execute();
String resp = myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(respParam);
ourLog.info(resp);
List<ParametersParameterComponent> parameterList = respParam.getParameter();
List<ParametersParameterComponent> designationList = getDesignations(parameterList);
assertEquals("display", respParam.getParameter().get(0).getName());
assertEquals(("Systolic blood pressure 12 hour minimum"), ((StringType) respParam.getParameter().get(0).getValue()).getValue());
assertEquals("abstract", respParam.getParameter().get(1).getName());
assertEquals(false, ((BooleanType) respParam.getParameter().get(1).getValue()).getValue());
//-- designationList
assertEquals(3, designationList.size());
// 1. fr-FR:Systolic blood pressure 12 hour minimum
ParametersParameterComponent designation = designationList.get(0);
assertEquals("language", designation.getPart().get(0).getName());
assertEquals("fr-FR", designation.getPart().get(0).getValue().toString());
assertEquals("value", designation.getPart().get(2).getName());
assertEquals("fr-FR:Systolic blood pressure 12 hour minimum", designation.getPart().get(2).getValue().toString());
// 2. de-AT:Systolic blood pressure 12 hour minimum
designation = designationList.get(1);
assertEquals("language", designation.getPart().get(0).getName());
assertEquals("de-AT", designation.getPart().get(0).getValue().toString());
assertEquals("value", designation.getPart().get(2).getName());
assertEquals("de-AT:Systolic blood pressure 12 hour minimum", designation.getPart().get(2).getValue().toString());
// 3. Systolic blood pressure 12 hour minimum (no language)
designation = designationList.get(2);
assertEquals("language", designation.getPart().get(0).getName());
assertNull(designation.getPart().get(0).getValue());
assertEquals("value", designation.getPart().get(2).getName());
assertEquals("Systolic blood pressure 12 hour minimum", designation.getPart().get(2).getValue().toString());
}
private List<ParametersParameterComponent> getDesignations(List<ParametersParameterComponent> parameterList) {
List<ParametersParameterComponent> designationList = new ArrayList<>();
for (ParametersParameterComponent parameter : parameterList) {
if ("designation".equals(parameter.getName()))
designationList.add(parameter);
}
return designationList;
}
}

View File

@ -369,7 +369,7 @@ public class TerminologySvcDeltaR4Test extends BaseJpaR4Test {
assertEquals("http://foo", outcome.getUrl()); assertEquals("http://foo", outcome.getUrl());
assertEquals(CodeSystem.CodeSystemContentMode.NOTPRESENT, outcome.getContent()); assertEquals(CodeSystem.CodeSystemContentMode.NOTPRESENT, outcome.getContent());
IValidationSupport.LookupCodeResult lookup = myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport), "http://foo", "CBC"); IValidationSupport.LookupCodeResult lookup = myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport), "http://foo", "CBC", null);
assertEquals("Complete Blood Count", lookup.getCodeDisplay()); assertEquals("Complete Blood Count", lookup.getCodeDisplay());
} }
@ -433,7 +433,7 @@ public class TerminologySvcDeltaR4Test extends BaseJpaR4Test {
UploadStatistics outcome = myTermCodeSystemStorageSvc.applyDeltaCodeSystemsAdd("http://foo", delta); UploadStatistics outcome = myTermCodeSystemStorageSvc.applyDeltaCodeSystemsAdd("http://foo", delta);
assertEquals(2, outcome.getUpdatedConceptCount()); assertEquals(2, outcome.getUpdatedConceptCount());
assertEquals("CODEA0", myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport), "http://foo", "codea").getCodeDisplay()); assertEquals("CODEA0", myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport), "http://foo", "codea", null).getCodeDisplay());
// Add codes again with different display // Add codes again with different display
delta = new CustomTerminologySet(); delta = new CustomTerminologySet();
@ -441,12 +441,12 @@ public class TerminologySvcDeltaR4Test extends BaseJpaR4Test {
delta.addRootConcept("codeb", "CODEB1"); delta.addRootConcept("codeb", "CODEB1");
outcome = myTermCodeSystemStorageSvc.applyDeltaCodeSystemsAdd("http://foo", delta); outcome = myTermCodeSystemStorageSvc.applyDeltaCodeSystemsAdd("http://foo", delta);
assertEquals(2, outcome.getUpdatedConceptCount()); assertEquals(2, outcome.getUpdatedConceptCount());
assertEquals("CODEA1", myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport), "http://foo", "codea").getCodeDisplay()); assertEquals("CODEA1", myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport), "http://foo", "codea", null).getCodeDisplay());
// Add codes again with no changes // Add codes again with no changes
outcome = myTermCodeSystemStorageSvc.applyDeltaCodeSystemsAdd("http://foo", delta); outcome = myTermCodeSystemStorageSvc.applyDeltaCodeSystemsAdd("http://foo", delta);
assertEquals(2, outcome.getUpdatedConceptCount()); assertEquals(2, outcome.getUpdatedConceptCount());
assertEquals("CODEA1", myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport), "http://foo", "codea").getCodeDisplay()); assertEquals("CODEA1", myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport), "http://foo", "codea", null).getCodeDisplay());
} }
@Test @Test
@ -483,7 +483,7 @@ public class TerminologySvcDeltaR4Test extends BaseJpaR4Test {
.setCode("useless_sct_code") .setCode("useless_sct_code")
.setValue(new Coding("http://snomed.info", "1234567", "Choked on large meal (finding)")); .setValue(new Coding("http://snomed.info", "1234567", "Choked on large meal (finding)"));
IValidationSupport.LookupCodeResult result = myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport), "http://foo/cs", "lunch"); IValidationSupport.LookupCodeResult result = myTermSvc.lookupCode(new ValidationSupportContext(myValidationSupport), "http://foo/cs", "lunch", null);
assertEquals(true, result.isFound()); assertEquals(true, result.isFound());
assertEquals("lunch", result.getSearchedForCode()); assertEquals("lunch", result.getSearchedForCode());
assertEquals("http://foo/cs", result.getSearchedForSystem()); assertEquals("http://foo/cs", result.getSearchedForSystem());

View File

@ -0,0 +1,204 @@
<CodeSystem xmlns="http://hl7.org/fhir">
<url value="http://acme.org" />
<concept>
<code value="8450-9" />
<display value="Systolic blood pressure--expiration" />
<designation>
<language value="nl"/>
<use>
<system value="http://snomed.info/sct"/>
<code value="900000000000013009"/>
<display value="Synonym"/>
</use>
<value value="Systolische bloeddruk - expiratie"/>
</designation>
<designation>
<language value="sv"/>
<use>
<system value="http://snomed.info/sct"/>
<code value="900000000000013009"/>
<display value="Synonym"/>
</use>
<value value="Systoliskt blodtryck - utgång"/>
</designation>
</concept>
<concept>
<code value="11378-7" />
<display value="Systolic blood pressure at First encounter" />
<designation>
<language value="nl"/>
<use>
<system value="http://snomed.info/sct"/>
<code value="900000000000013009"/>
<display value="Synonym"/>
</use>
<value value="NL:Systolic blood pressure at First encounter"/>
</designation>
<designation>
<language value="sv"/>
<use>
<system value="http://snomed.info/sct"/>
<code value="900000000000013009"/>
<display value="Synonym"/>
</use>
<value value="SV:Systolic blood pressure at First encounter"/>
</designation>
</concept>
<concept>
<code value="8493-9" />
<display value="Systolic blood pressure 10 hour minimum" />
<designation>
<language value="fr-FR"/>
<use>
<system value="http://snomed.info/sct"/>
<code value="900000000000013009"/>
<display value="Synonym"/>
</use>
<value value="fr-FR:Systolic blood pressure 10 hour minimum"/>
</designation>
<designation>
<language value="de-AT"/>
<use>
<system value="http://snomed.info/sct"/>
<code value="900000000000013009"/>
<display value="Synonym"/>
</use>
<value value="de-AT:Systolic blood pressure 10 hour minimum"/>
</designation>
</concept>
<concept>
<code value="8494-7" />
<display value="Systolic blood pressure 12 hour minimum" />
<designation>
<language value="fr-FR"/>
<use>
<system value="http://snomed.info/sct"/>
<code value="900000000000013009"/>
<display value="Synonym"/>
</use>
<value value="fr-FR:Systolic blood pressure 12 hour minimum"/>
</designation>
<designation>
<language value="de-AT"/>
<use>
<system value="http://snomed.info/sct"/>
<code value="900000000000013009"/>
<display value="Synonym"/>
</use>
<value value="de-AT:Systolic blood pressure 12 hour minimum"/>
</designation>
<designation>
<use>
<system value="http://snomed.info/sct"/>
<code value="900000000000013009"/>
<display value="Synonym"/>
</use>
<value value="Systolic blood pressure 12 hour minimum"/>
</designation>
</concept>
<concept>
<code value="8495-4" />
<display value="Systolic blood pressure 24 hour minimum" />
<designation>
<use>
<system value="http://snomed.info/sct"/>
<code value="900000000000013009"/>
<display value="Synonym"/>
</use>
<value value="Systolic blood pressure 12 hour minimum"/>
</designation>
<designation>
<use>
<system value="http://snomed.info/sct"/>
<code value="900000000000013009"/>
<display value="Synonym"/>
</use>
<value value="de-AT:Systolic blood pressure 12 hour minimum"/>
</designation>
</concept>
<concept>
<code value="8451-7" />
<display value="Systolic blood pressure--inspiration" />
</concept>
<concept>
<code value="8452-5" />
<display value="Systolic blood pressure.inspiration - expiration" />
</concept>
<concept>
<code value="8459-0" />
<display value="Systolic blood pressure--sitting" />
</concept>
<concept>
<code value="8460-8" />
<display value="Systolic blood pressure--standing" />
</concept>
<concept>
<code value="8461-6" />
<display value="Systolic blood pressure--supine" />
</concept>
<concept>
<code value="8479-8" />
<display value="Systolic blood pressure by palpation" />
</concept>
<concept>
<code value="8480-6" />
<display value="Systolic blood pressure" />
</concept>
<concept>
<code value="8481-4" />
<display value="Systolic blood pressure 1 hour maximum" />
</concept>
<concept>
<code value="8482-2" />
<display value="Systolic blood pressure 8 hour maximum" />
</concept>
<concept>
<code value="8483-0" />
<display value="Systolic blood pressure 10 hour maximum" />
</concept>
<concept>
<code value="8484-8" />
<display value="Systolic blood pressure 12 hour maximum" />
</concept>
<concept>
<code value="8485-5" />
<display value="Systolic blood pressure 24 hour maximum" />
</concept>
<concept>
<code value="8486-3" />
<display value="Systolic blood pressure 1 hour mean" />
</concept>
<concept>
<code value="8487-1" />
<display value="Systolic blood pressure 8 hour mean" />
</concept>
<concept>
<code value="8488-9" />
<display value="Systolic blood pressure 10 hour mean" />
</concept>
<concept>
<code value="8489-7" />
<display value="Systolic blood pressure 12 hour mean" />
</concept>
<concept>
<code value="8490-5" />
<display value="Systolic blood pressure 24 hour mean" />
</concept>
<concept>
<code value="8491-3" />
<display value="Systolic blood pressure 1 hour minimum" />
<designation>
<language value="nl"/>
<use>
<system value="http://snomed.info/sct"/>
<code value="900000000000013009"/>
<display value="Synonym"/>
</use>
<value value="Systolische bloeddruk minimaal 1 uur"/>
</designation>
</concept>
<concept>
<code value="8492-1" />
<display value="Systolic blood pressure 8 hour minimum" />
</concept>
</CodeSystem>

View File

@ -0,0 +1,13 @@
{
"resourceType": "Patient",
"identifier": [
{
"system": "https://example.org/fhir/memberidentifier",
"value": "12345670"
},
{
"system": "https://example.org/fhir/memberuniqueidentifier",
"value": "12345670TT"
}
]
}

View File

@ -0,0 +1,49 @@
{
"resourceType": "Bundle",
"type": "transaction",
"entry": [
{
"fullUrl": "urn:uuid:1f3b9e25-fd45-4342-a82b-7ca5755923bb",
"resource": {
"resourceType": "Task",
"language": "en-US",
"identifier": [
{
"system": "https://example.org/fhir/taskidentifier",
"value": "101019"
}
],
"basedOn": [
{
"reference": "urn:uuid:47c6d106-3441-41c0-8a2c-054ad9897ced"
}
]
},
"request": {
"method": "PUT",
"url": "/Task?identifier\u003dhttps%3A%2F%2Fexample.org%2Ffhir%2Ftaskidentifier|101019"
}
},
{
"fullUrl": "urn:uuid:47c6d106-3441-41c0-8a2c-054ad9897ced",
"resource": {
"resourceType": "Patient",
"identifier": [
{
"system": "https://example.org/fhir/memberidentifier",
"value": "12345670"
},
{
"system": "https://example.org/fhir/memberuniqueidentifier",
"value": "12345670TT"
}
]
},
"request": {
"method": "POST",
"url": "/Patient",
"ifNoneExist": "Patient?identifier\u003dhttps%3A%2F%2Fexample.org%2Ffhir%2Fmemberuniqueidentifier|12345670TT"
}
}
]
}

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -7,7 +7,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -62,7 +62,7 @@ import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.Practitioner; import org.hl7.fhir.r4.model.Practitioner;
import org.hl7.fhir.r4.model.Reference; import org.hl7.fhir.r4.model.Reference;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import javax.annotation.Nullable;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;

View File

@ -2,14 +2,18 @@ package ca.uhn.fhir.jpa.mdm.interceptor;
import ca.uhn.fhir.jpa.api.config.DaoConfig; import ca.uhn.fhir.jpa.api.config.DaoConfig;
import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome; import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
import ca.uhn.fhir.jpa.entity.MdmLink;
import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test; import ca.uhn.fhir.jpa.mdm.BaseMdmR4Test;
import ca.uhn.fhir.jpa.mdm.helper.MdmHelperConfig; import ca.uhn.fhir.jpa.mdm.helper.MdmHelperConfig;
import ca.uhn.fhir.jpa.mdm.helper.MdmHelperR4; import ca.uhn.fhir.jpa.mdm.helper.MdmHelperR4;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.mdm.api.MdmConstants; import ca.uhn.fhir.mdm.api.MdmConstants;
import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
import ca.uhn.fhir.rest.param.ReferenceOrListParam; import ca.uhn.fhir.rest.param.ReferenceOrListParam;
import ca.uhn.fhir.rest.param.ReferenceParam; import ca.uhn.fhir.rest.param.ReferenceParam;
import org.elasticsearch.common.collect.Set;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.model.CodeableConcept; import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Observation; import org.hl7.fhir.r4.model.Observation;
import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Patient;
@ -21,6 +25,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
@ -73,6 +79,19 @@ public class MdmSearchExpandingInterceptorIT extends BaseMdmR4Test {
myDaoConfig.setAllowMdmExpansion(true); myDaoConfig.setAllowMdmExpansion(true);
search = myObservationDao.search(searchParameterMap); search = myObservationDao.search(searchParameterMap);
assertThat(search.size(), is(equalTo(4))); assertThat(search.size(), is(equalTo(4)));
List<MdmLink> all = myMdmLinkDao.findAll();
Long goldenPid = all.get(0).getGoldenResourcePid();
IIdType goldenId = myIdHelperService.translatePidIdToForcedId(myFhirContext, "Patient", new ResourcePersistentId(goldenPid));
//Verify that expansion by the golden resource id resolves down to everything its links have.
SearchParameterMap goldenSpMap = new SearchParameterMap();
goldenSpMap.setLoadSynchronous(true);
ReferenceOrListParam goldenReferenceOrListParam = new ReferenceOrListParam();
goldenReferenceOrListParam.addOr(new ReferenceParam(goldenId).setMdmExpand(true));
goldenSpMap.add(Observation.SP_SUBJECT, goldenReferenceOrListParam);
search = myObservationDao.search(goldenSpMap);
assertThat(search.size(), is(equalTo(4)));
} }
@Test @Test

View File

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-deployable-pom</artifactId> <artifactId>hapi-deployable-pom</artifactId>
<version>5.6.0-PRE1-SNAPSHOT</version> <version>5.6.0-PRE2-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -511,6 +511,15 @@ public class SearchParameterMap implements Serializable {
b.append(getSearchTotalMode().getCode()); b.append(getSearchTotalMode().getCode());
} }
//Contained mode
//For some reason, instead of null here, we default to false. That said, ommitting it is identical to setting it to false.
if (getSearchContainedMode() != SearchContainedModeEnum.FALSE) {
addUrlParamSeparator(b);
b.append(Constants.PARAM_CONTAINED);
b.append("=");
b.append(getSearchContainedMode().getCode());
}
if (b.length() == 0) { if (b.length() == 0) {
b.append('?'); b.append('?');
} }

View File

@ -78,6 +78,7 @@ import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
@ -964,6 +965,18 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
return retVal; return retVal;
} }
/**
* Helper function to determine if a set of SPs for a resource uses a resolve as part of its fhir path.
*/
private boolean anySearchParameterUsesResolve(Collection<RuntimeSearchParam> searchParams, RestSearchParameterTypeEnum theSearchParamType) {
return searchParams.stream()
.filter(param -> param.getParamType() != theSearchParamType)
.map(RuntimeSearchParam::getPath)
.filter(Objects::nonNull)
.anyMatch(path-> path.contains("resolve"));
}
/** /**
* HAPI FHIR Reference objects (e.g. {@link org.hl7.fhir.r4.model.Reference}) can hold references either by text * HAPI FHIR Reference objects (e.g. {@link org.hl7.fhir.r4.model.Reference}) can hold references either by text
* (e.g. "#3") or by resource (e.g. "new Reference(patientInstance)"). The FHIRPath evaluator only understands the * (e.g. "#3") or by resource (e.g. "new Reference(patientInstance)"). The FHIRPath evaluator only understands the
@ -974,17 +987,12 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
* if we think there's actually a chance * if we think there's actually a chance
*/ */
private void cleanUpContainedResourceReferences(IBaseResource theResource, RestSearchParameterTypeEnum theSearchParamType, Collection<RuntimeSearchParam> searchParams) { private void cleanUpContainedResourceReferences(IBaseResource theResource, RestSearchParameterTypeEnum theSearchParamType, Collection<RuntimeSearchParam> searchParams) {
boolean havePathWithResolveExpression = myModelConfig.isIndexOnContainedResources(); boolean havePathWithResolveExpression =
for (RuntimeSearchParam nextSpDef : searchParams) { myModelConfig.isIndexOnContainedResources()
if (nextSpDef.getParamType() != theSearchParamType) { || anySearchParameterUsesResolve(searchParams, theSearchParamType);
continue;
}
if (defaultString(nextSpDef.getPath()).contains("resolve")) {
havePathWithResolveExpression = true;
break;
}
}
if (havePathWithResolveExpression) { if (havePathWithResolveExpression) {
//TODO GGG/JA: At this point, if the Task.basedOn.reference.resource does _not_ have an ID, we will attempt to contain it internally. Wild
myContext.newTerser().containResources(theResource, FhirTerser.OptionsEnum.MODIFY_RESOURCE, FhirTerser.OptionsEnum.STORE_AND_REUSE_RESULTS); myContext.newTerser().containResources(theResource, FhirTerser.OptionsEnum.MODIFY_RESOURCE, FhirTerser.OptionsEnum.STORE_AND_REUSE_RESULTS);
} }
} }

Some files were not shown because too many files have changed in this diff Show More