Add R4B Support (#4150)

* Add r4b stuff

* Work on R4B

* Core version bump

* Revert some changes

* Add R4B

* Docs

* Test fixes

* Work on R4B

* Tests passgin

* Add config

* Work on merging

* Work

* Work

* Work

* Test fix

* Fixes

* Test fixes

* Test fix

* Work

* Work

* Fixes

* Test fixes

* Fixes

* Test fix

* Test fix

* Test fix

* Version bump

* Test fix

* Test fix

* ompile fixes

* Fix

* Resolve build warnings

* Updates

* Test fixes

* Fix docs
This commit is contained in:
James Agnew 2022-10-20 16:57:06 -04:00 committed by GitHub
parent c8312662d7
commit a71b8fad56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
393 changed files with 9218 additions and 6041 deletions

View File

@ -24,6 +24,8 @@ stages:
module: hapi-fhir-jpaserver-test-dstu3 module: hapi-fhir-jpaserver-test-dstu3
- name: hapi_fhir_jpaserver_test_r4 - name: hapi_fhir_jpaserver_test_r4
module: hapi-fhir-jpaserver-test-r4 module: hapi-fhir-jpaserver-test-r4
- name: hapi_fhir_jpaserver_test_r4b
module: hapi-fhir-jpaserver-test-r4b
- name: hapi_fhir_jpaserver_test_r5 - name: hapi_fhir_jpaserver_test_r5
module: hapi-fhir-jpaserver-test-r5 module: hapi-fhir-jpaserver-test-r5
- name: hapi_fhir_jpaserver_test_utilities - name: hapi_fhir_jpaserver_test_utilities

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>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-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>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-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>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -194,6 +194,8 @@ public class FhirContext {
myVersion = FhirVersionEnum.DSTU3.getVersionImplementation(); myVersion = FhirVersionEnum.DSTU3.getVersionImplementation();
} else if (FhirVersionEnum.R4.isPresentOnClasspath()) { } else if (FhirVersionEnum.R4.isPresentOnClasspath()) {
myVersion = FhirVersionEnum.R4.getVersionImplementation(); myVersion = FhirVersionEnum.R4.getVersionImplementation();
} else if (FhirVersionEnum.R4B.isPresentOnClasspath()) {
myVersion = FhirVersionEnum.R4B.getVersionImplementation();
} else { } else {
throw new IllegalStateException(Msg.code(1681) + getLocalizer().getMessage(FhirContext.class, "noStructures")); throw new IllegalStateException(Msg.code(1681) + getLocalizer().getMessage(FhirContext.class, "noStructures"));
} }
@ -238,6 +240,14 @@ public class FhirContext {
return forCached(FhirVersionEnum.DSTU2); return forCached(FhirVersionEnum.DSTU2);
} }
/**
* @since 6.2.0
*/
public static FhirContext forDstu2Hl7OrgCached() {
return forCached(FhirVersionEnum.DSTU2_HL7ORG);
}
/** /**
* @since 5.5.0 * @since 5.5.0
*/ */
@ -252,6 +262,13 @@ public class FhirContext {
return forCached(FhirVersionEnum.R4); return forCached(FhirVersionEnum.R4);
} }
/**
* @since 6.1.0
*/
public static FhirContext forR4BCached() {
return forCached(FhirVersionEnum.R4B);
}
/** /**
* @since 5.5.0 * @since 5.5.0
*/ */
@ -1180,6 +1197,15 @@ public class FhirContext {
return new FhirContext(FhirVersionEnum.R4); return new FhirContext(FhirVersionEnum.R4);
} }
/**
* Creates and returns a new FhirContext with version {@link FhirVersionEnum#R4B R4B}
*
* @since 6.2.0
*/
public static FhirContext forR4B() {
return new FhirContext(FhirVersionEnum.R4B);
}
/** /**
* Creates and returns a new FhirContext with version {@link FhirVersionEnum#R5 R5} * Creates and returns a new FhirContext with version {@link FhirVersionEnum#R5 R5}
* *
@ -1217,4 +1243,5 @@ public class FhirContext {
} }
return retVal; return retVal;
} }
} }

View File

@ -45,6 +45,8 @@ public enum FhirVersionEnum {
R4("org.hl7.fhir.r4.hapi.ctx.FhirR4", null, true, new R4Version()), R4("org.hl7.fhir.r4.hapi.ctx.FhirR4", null, true, new R4Version()),
R4B("org.hl7.fhir.r4b.hapi.ctx.FhirR4B", null, true, new R4BVersion()),
R5("org.hl7.fhir.r5.hapi.ctx.FhirR5", null, true, new R5Version()); R5("org.hl7.fhir.r5.hapi.ctx.FhirR5", null, true, new R5Version());
// If you add new constants, add to the various methods below too! // If you add new constants, add to the various methods below too!
@ -139,6 +141,8 @@ public enum FhirVersionEnum {
return FhirContext.forDstu3(); return FhirContext.forDstu3();
case R4: case R4:
return FhirContext.forR4(); return FhirContext.forR4();
case R4B:
return FhirContext.forR4B();
case R5: case R5:
return FhirContext.forR5(); return FhirContext.forR5();
} }
@ -232,6 +236,26 @@ public enum FhirVersionEnum {
} }
private static class R4BVersion implements IVersionProvider {
private String myVersion;
R4BVersion() {
try {
Class<?> c = Class.forName("org.hl7.fhir.r4b.model.Constants");
myVersion = (String) c.getDeclaredField("VERSION").get(null);
} catch (Exception e) {
myVersion = "4.3.0";
}
}
@Override
public String provideVersion() {
return myVersion;
}
}
private static class R5Version implements IVersionProvider { private static class R5Version implements IVersionProvider {
private String myVersion; private String myVersion;

View File

@ -341,6 +341,10 @@ class ModelScanner {
if (resourceDef.getStructureVersion() == myVersion) { if (resourceDef.getStructureVersion() == myVersion) {
myNameToResourceDefinitions.put(resourceNameLowerCase, resourceDef); myNameToResourceDefinitions.put(resourceNameLowerCase, resourceDef);
} }
// TODO: Address this when core lib version is bumped
if (resourceDef.getStructureVersion() == FhirVersionEnum.R5 && myVersion == FhirVersionEnum.R4B) {
myNameToResourceDefinitions.put(resourceNameLowerCase, resourceDef);
}
} }
myIdToResourceDefinition.put(resourceId, resourceDef); myIdToResourceDefinition.put(resourceId, resourceDef);

View File

@ -65,7 +65,14 @@ public class RuntimeResourceDefinition extends BaseRuntimeElementCompositeDefini
} }
myStructureVersion = instance.getStructureFhirVersionEnum(); myStructureVersion = instance.getStructureFhirVersionEnum();
if (myStructureVersion != theContext.getVersion().getVersion()) { if (myStructureVersion != theContext.getVersion().getVersion()) {
throw new ConfigurationException(Msg.code(1731) + myContext.getLocalizer().getMessage(getClass(), "typeWrongVersion", theContext.getVersion().getVersion(), theClass.getName(), myStructureVersion)); if (myStructureVersion == FhirVersionEnum.R5 && theContext.getVersion().getVersion() == FhirVersionEnum.R4B) {
// TODO: remove this exception once we've bumped FHIR core to a new version
// TODO: also fix the TODO in ModelScanner
// TODO: also fix the TODO in RestfulServerUtils
// TODO: also fix the TODO in BaseParser
} else {
throw new ConfigurationException(Msg.code(1731) + myContext.getLocalizer().getMessage(getClass(), "typeWrongVersion", theContext.getVersion().getVersion(), theClass.getName(), myStructureVersion));
}
} }
} }

View File

@ -288,6 +288,9 @@ public abstract class BaseParser implements IParser {
Validate.notNull(theWriter, "theWriter can not be null"); Validate.notNull(theWriter, "theWriter can not be null");
Validate.notNull(theEncodeContext, "theEncodeContext can not be null"); Validate.notNull(theEncodeContext, "theEncodeContext can not be null");
if (myContext.getVersion().getVersion() == FhirVersionEnum.R4B && theResource.getStructureFhirVersionEnum() == FhirVersionEnum.R5) {
// TODO: remove once we've bumped the core lib version
} else
if (theResource.getStructureFhirVersionEnum() != myContext.getVersion().getVersion()) { if (theResource.getStructureFhirVersionEnum() != myContext.getVersion().getVersion()) {
throw new IllegalArgumentException(Msg.code(1829) + "This parser is for FHIR version " + myContext.getVersion().getVersion() + " - Can not encode a structure for version " + theResource.getStructureFhirVersionEnum()); throw new IllegalArgumentException(Msg.code(1829) + "This parser is for FHIR version " + myContext.getVersion().getVersion() + " - Can not encode a structure for version " + theResource.getStructureFhirVersionEnum());
} }

View File

@ -1,13 +1,13 @@
ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.expansionRefersToUnknownCs=Unknown CodeSystem URI "{0}" referenced from ValueSet ca.uhn.fhir.jpa.term.TermReadSvcImpl.expansionRefersToUnknownCs=Unknown CodeSystem URI "{0}" referenced from ValueSet
ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.valueSetNotYetExpanded=ValueSet "{0}" has not yet been pre-expanded. Performing in-memory expansion without parameters. Current status: {1} | {2} ca.uhn.fhir.jpa.term.TermReadSvcImpl.valueSetNotYetExpanded=ValueSet "{0}" has not yet been pre-expanded. Performing in-memory expansion without parameters. Current status: {1} | {2}
ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.valueSetNotYetExpanded_OffsetNotAllowed=ValueSet expansion can not combine "offset" with "ValueSet.compose.exclude" unless the ValueSet has been pre-expanded. ValueSet "{0}" must be pre-expanded for this operation to work. ca.uhn.fhir.jpa.term.TermReadSvcImpl.valueSetNotYetExpanded_OffsetNotAllowed=ValueSet expansion can not combine "offset" with "ValueSet.compose.exclude" unless the ValueSet has been pre-expanded. ValueSet "{0}" must be pre-expanded for this operation to work.
ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.valueSetExpandedUsingPreExpansion=ValueSet was expanded using an expansion that was pre-calculated at {0} ca.uhn.fhir.jpa.term.TermReadSvcImpl.valueSetExpandedUsingPreExpansion=ValueSet was expanded using an expansion that was pre-calculated at {0}
ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.valueSetExpandedUsingInMemoryExpansion=ValueSet with URL "{0}" was expanded using an in-memory expansion ca.uhn.fhir.jpa.term.TermReadSvcImpl.valueSetExpandedUsingInMemoryExpansion=ValueSet with URL "{0}" was expanded using an in-memory expansion
ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.validationPerformedAgainstPreExpansion=Code validation occurred using a ValueSet expansion that was pre-calculated at {0} ca.uhn.fhir.jpa.term.TermReadSvcImpl.validationPerformedAgainstPreExpansion=Code validation occurred using a ValueSet expansion that was pre-calculated at {0}
ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.valueSetNotFoundInTerminologyDatabase=ValueSet can not be found in terminology database: {0} ca.uhn.fhir.jpa.term.TermReadSvcImpl.valueSetNotFoundInTerminologyDatabase=ValueSet can not be found in terminology database: {0}
ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.valueSetPreExpansionInvalidated=ValueSet with URL "{0}" precaluclated expansion with {1} concept(s) has been invalidated ca.uhn.fhir.jpa.term.TermReadSvcImpl.valueSetPreExpansionInvalidated=ValueSet with URL "{0}" precaluclated expansion with {1} concept(s) has been invalidated
ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.valueSetCantInvalidateNotYetPrecalculated=ValueSet with URL "{0}" already has status: {1} ca.uhn.fhir.jpa.term.TermReadSvcImpl.valueSetCantInvalidateNotYetPrecalculated=ValueSet with URL "{0}" already has status: {1}
# Core Library Messages # Core Library Messages
@ -146,14 +146,14 @@ ca.uhn.fhir.jpa.binary.provider.BinaryAccessProvider.unknownPath=Unable to find
ca.uhn.fhir.jpa.binary.provider.BinaryAccessProvider.unknownType=Content in resource of type {0} at path {1} is not appropriate for binary storage: {2} ca.uhn.fhir.jpa.binary.provider.BinaryAccessProvider.unknownType=Content in resource of type {0} at path {1} is not appropriate for binary storage: {2}
ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.cannotCreateDuplicateCodeSystemUrl=Can not create multiple CodeSystem resources with CodeSystem.url "{0}", already have one with resource ID: {1} ca.uhn.fhir.jpa.term.TermReadSvcImpl.cannotCreateDuplicateCodeSystemUrl=Can not create multiple CodeSystem resources with CodeSystem.url "{0}", already have one with resource ID: {1}
ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.cannotCreateDuplicateCodeSystemUrlAndVersion=Can not create multiple CodeSystem resources with CodeSystem.url "{0}" and CodeSystem.version "{1}", already have one with resource ID: {2} ca.uhn.fhir.jpa.term.TermReadSvcImpl.cannotCreateDuplicateCodeSystemUrlAndVersion=Can not create multiple CodeSystem resources with CodeSystem.url "{0}" and CodeSystem.version "{1}", already have one with resource ID: {2}
ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.cannotCreateDuplicateConceptMapUrl=Can not create multiple ConceptMap resources with ConceptMap.url "{0}", already have one with resource ID: {1} ca.uhn.fhir.jpa.term.TermReadSvcImpl.cannotCreateDuplicateConceptMapUrl=Can not create multiple ConceptMap resources with ConceptMap.url "{0}", already have one with resource ID: {1}
ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.cannotCreateDuplicateConceptMapUrlAndVersion=Can not create multiple ConceptMap resources with ConceptMap.url "{0}" and ConceptMap.version "{1}", already have one with resource ID: {2} ca.uhn.fhir.jpa.term.TermReadSvcImpl.cannotCreateDuplicateConceptMapUrlAndVersion=Can not create multiple ConceptMap resources with ConceptMap.url "{0}" and ConceptMap.version "{1}", already have one with resource ID: {2}
ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.cannotCreateDuplicateValueSetUrl=Can not create multiple ValueSet resources with ValueSet.url "{0}", already have one with resource ID: {1} ca.uhn.fhir.jpa.term.TermReadSvcImpl.cannotCreateDuplicateValueSetUrl=Can not create multiple ValueSet resources with ValueSet.url "{0}", already have one with resource ID: {1}
ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.expansionTooLarge=Expansion of ValueSet produced too many codes (maximum {0}) - Operation aborted! ca.uhn.fhir.jpa.term.TermReadSvcImpl.expansionTooLarge=Expansion of ValueSet produced too many codes (maximum {0}) - Operation aborted!
ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.cannotCreateDuplicateValueSetUrlAndVersion=Can not create multiple ValueSet resources with ValueSet.url "{0}" and ValueSet.version "{1}", already have one with resource ID: {2} ca.uhn.fhir.jpa.term.TermReadSvcImpl.cannotCreateDuplicateValueSetUrlAndVersion=Can not create multiple ValueSet resources with ValueSet.url "{0}" and ValueSet.version "{1}", already have one with resource ID: {2}
ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl.cannotUpdateUrlOrVersionForValueSetResource=Cannot update URL or version for ValueSet resource. Existing ValueSet resource with resource ID {0} found with ValueSet.url "{1}" and ValueSet.version "{2}" ca.uhn.fhir.jpa.term.TermReadSvcImpl.cannotUpdateUrlOrVersionForValueSetResource=Cannot update URL or version for ValueSet resource. Existing ValueSet resource with resource ID {0} found with ValueSet.url "{1}" and ValueSet.version "{2}"
ca.uhn.fhir.jpa.patch.JsonPatchUtils.failedToApplyPatch=Failed to apply JSON patch to {0}: {1} ca.uhn.fhir.jpa.patch.JsonPatchUtils.failedToApplyPatch=Failed to apply JSON patch to {0}: {1}

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>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

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>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-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>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-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-fhir</artifactId> <artifactId>hapi-fhir</artifactId>
<version>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-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>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -33,7 +33,7 @@
<!-- <!--
It's useful to have this log when uploading big terminologies It's useful to have this log when uploading big terminologies
--> -->
<logger name="ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl" additivity="false" level="info"> <logger name="ca.uhn.fhir.jpa.term.TermReadSvcImpl" additivity="false" level="info">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</logger> </logger>
<logger name="ca.uhn.fhir.jpa.term.TermCodeSystemStorageSvcImpl" additivity="false" level="info"> <logger name="ca.uhn.fhir.jpa.term.TermCodeSystemStorageSvcImpl" additivity="false" level="info">

View File

@ -34,7 +34,7 @@
<!-- <!--
It's useful to have this log when uploading big terminologies It's useful to have this log when uploading big terminologies
--> -->
<logger name="ca.uhn.fhir.jpa.term.BaseTermReadSvcImpl" additivity="false" level="info"> <logger name="ca.uhn.fhir.jpa.term.TermReadSvcImpl" additivity="false" level="info">
<appender-ref ref="STDOUT" /> <appender-ref ref="STDOUT" />
</logger> </logger>
<logger name="ca.uhn.fhir.jpa.term.TermCodeSystemStorageSvcImpl" additivity="false" level="info"> <logger name="ca.uhn.fhir.jpa.term.TermCodeSystemStorageSvcImpl" additivity="false" level="info">

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>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-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>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-SNAPSHOT</version>
<relativePath>../../hapi-deployable-pom</relativePath> <relativePath>../../hapi-deployable-pom</relativePath>
</parent> </parent>

View File

@ -34,11 +34,9 @@ import ca.uhn.fhir.jpa.delete.ThreadSafeResourceDeleterSvc;
import ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor; import ca.uhn.fhir.jpa.interceptor.CascadingDeleteInterceptor;
import ca.uhn.fhir.jpa.provider.JpaCapabilityStatementProvider; import ca.uhn.fhir.jpa.provider.JpaCapabilityStatementProvider;
import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2; import ca.uhn.fhir.jpa.provider.JpaConformanceProviderDstu2;
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2; import ca.uhn.fhir.jpa.provider.JpaSystemProvider;
import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider; import ca.uhn.fhir.jpa.provider.TerminologyUploaderProvider;
import ca.uhn.fhir.jpa.provider.dstu3.JpaConformanceProviderDstu3; import ca.uhn.fhir.jpa.provider.dstu3.JpaConformanceProviderDstu3;
import ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3;
import ca.uhn.fhir.jpa.provider.r4.JpaSystemProviderR4;
import ca.uhn.fhir.model.dstu2.composite.MetaDt; import ca.uhn.fhir.model.dstu2.composite.MetaDt;
import ca.uhn.fhir.model.dstu2.resource.Bundle; import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator; import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
@ -103,17 +101,15 @@ public class JpaServerDemo extends RestfulServer {
*/ */
List<Object> systemProvider = new ArrayList<Object>(); List<Object> systemProvider = new ArrayList<Object>();
if (fhirVersion == FhirVersionEnum.DSTU2) { if (fhirVersion == FhirVersionEnum.DSTU2) {
systemProvider.add(myAppCtx.getBean("mySystemProviderDstu2", JpaSystemProviderDstu2.class));
} else if (fhirVersion == FhirVersionEnum.DSTU3) { } else if (fhirVersion == FhirVersionEnum.DSTU3) {
systemProvider.add(myAppCtx.getBean("mySystemProviderDstu3", JpaSystemProviderDstu3.class));
systemProvider.add(myAppCtx.getBean(TerminologyUploaderProvider.class)); systemProvider.add(myAppCtx.getBean(TerminologyUploaderProvider.class));
} else if (fhirVersion == FhirVersionEnum.R4) { } else if (fhirVersion == FhirVersionEnum.R4) {
systemProvider.add(myAppCtx.getBean("mySystemProviderR4", JpaSystemProviderR4.class));
systemProvider.add(myAppCtx.getBean(TerminologyUploaderProvider.class)); systemProvider.add(myAppCtx.getBean(TerminologyUploaderProvider.class));
systemProvider.add(myAppCtx.getBean(JpaConfig.GRAPHQL_PROVIDER_NAME)); systemProvider.add(myAppCtx.getBean(JpaConfig.GRAPHQL_PROVIDER_NAME));
} else { } else {
throw new IllegalStateException(Msg.code(1533)); throw new IllegalStateException(Msg.code(1533));
} }
systemProvider.add(myAppCtx.getBean(JpaSystemProvider.class));
registerProviders(systemProvider); registerProviders(systemProvider);
/* /*

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>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-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>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-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>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-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>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -0,0 +1,447 @@
package ca.uhn.hapi.converters.canonical;
/*-
* #%L
* HAPI FHIR - Converter
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_10_40;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_10_50;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_50;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_43_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_10_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_40;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_30_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_43_50;
import org.hl7.fhir.dstu2.model.Resource;
import org.hl7.fhir.instance.model.api.IBaseCoding;
import org.hl7.fhir.instance.model.api.IBaseDatatype;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.CodeSystem;
import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.ConceptMap;
import org.hl7.fhir.r4.model.ValueSet;
import org.hl7.fhir.r5.model.CapabilityStatement;
import java.util.List;
/**
* This class converts versions of various resources to/from a canonical version
* of the resource. The specific version that is considered canonical is arbitrary
* for historical reasons, generally it will be R4 or R5 but this varies by resource
* type.
* <p>
* This class is an internal HAPI FHIR API and can change without notice at any time.
* Use with caution!
* </p>
*/
public class VersionCanonicalizer {
private static final BaseAdvisor_30_50 ADVISOR_30_50 = new BaseAdvisor_30_50(false);
private static final BaseAdvisor_30_40 ADVISOR_30_40 = new BaseAdvisor_30_40(false);
private static final BaseAdvisor_10_40 ADVISOR_10_40 = new BaseAdvisor_10_40(false);
private static final BaseAdvisor_10_50 ADVISOR_10_50 = new BaseAdvisor_10_50(false);
private static final BaseAdvisor_40_50 ADVISOR_40_50 = new BaseAdvisor_40_50(false);
private static final BaseAdvisor_43_50 ADVISOR_43_50 = new BaseAdvisor_43_50(false);
@SuppressWarnings("rawtypes")
private final IStrategy myStrategy;
public VersionCanonicalizer(FhirContext theTargetContext) {
this(theTargetContext.getVersion().getVersion());
}
@SuppressWarnings("EnumSwitchStatementWhichMissesCases")
public VersionCanonicalizer(FhirVersionEnum theTargetVersion) {
switch (theTargetVersion) {
case DSTU2:
myStrategy = new Dstu2Strategy();
break;
case DSTU3:
myStrategy = new Dstu3Strategy();
break;
case R4:
myStrategy = new R4Strategy();
break;
case R4B:
myStrategy = new R4BStrategy();
break;
case R5:
myStrategy = new R5Strategy();
break;
default:
throw new IllegalStateException(Msg.code(193) + "Can't handle version: " + theTargetVersion);
}
}
/**
* Canonical version: R5
*/
public CapabilityStatement capabilityStatementToCanonical(IBaseResource theCapabilityStatement) {
return myStrategy.capabilityStatementToCanonical(theCapabilityStatement);
}
/**
* Canonical version: R4
*/
public CodeableConcept codeableConceptToCanonical(IBaseDatatype theCodeableConcept) {
if (theCodeableConcept == null) {
return null;
}
return myStrategy.codeableConceptToCanonical(theCodeableConcept);
}
/**
* Canonical version: R4
*/
public Coding codingToCanonical(IBaseCoding theCodingToValidate) {
if (theCodingToValidate == null) {
return null;
}
return myStrategy.codingToCanonical(theCodingToValidate);
}
/**
* Canonical version: R4
*/
public ValueSet valueSetToCanonical(IBaseResource theValueSet) {
if (theValueSet == null) {
return null;
}
return myStrategy.valueSetToCanonical(theValueSet);
}
/**
* Canonical version: R4
*/
public CodeSystem codeSystemToCanonical(IBaseResource theCodeSystem) {
return myStrategy.codeSystemToCanonical(theCodeSystem);
}
/**
* Canonical version: R4
*/
public IBaseResource valueSetFromCanonical(ValueSet theValueSet) {
return myStrategy.valueSetFromCanonical(theValueSet);
}
/**
* Canonical version: R4
*/
public ConceptMap conceptMapToCanonical(IBaseResource theConceptMap) {
return myStrategy.conceptMapToCanonical(theConceptMap);
}
private interface IStrategy<T extends IBaseResource> {
CapabilityStatement capabilityStatementToCanonical(T theCapabilityStatement);
Coding codingToCanonical(IBaseCoding theCoding);
CodeableConcept codeableConceptToCanonical(IBaseDatatype theCodeableConcept);
ValueSet valueSetToCanonical(IBaseResource theValueSet);
CodeSystem codeSystemToCanonical(IBaseResource theCodeSystem);
IBaseResource valueSetFromCanonical(ValueSet theValueSet);
ConceptMap conceptMapToCanonical(IBaseResource theConceptMap);
}
private class Dstu2Strategy implements IStrategy<ca.uhn.fhir.model.dstu2.resource.BaseResource> {
private final FhirContext myDstu2Hl7OrgContext = FhirContext.forDstu2Hl7OrgCached();
private final FhirContext myDstu2Context = FhirContext.forDstu2Cached();
@Override
public CapabilityStatement capabilityStatementToCanonical(ca.uhn.fhir.model.dstu2.resource.BaseResource theCapabilityStatement) {
org.hl7.fhir.dstu2.model.Resource reencoded = reencodeToHl7Org(theCapabilityStatement);
return (CapabilityStatement) VersionConvertorFactory_10_50.convertResource(reencoded, ADVISOR_10_50);
}
@Override
public Coding codingToCanonical(IBaseCoding theCoding) {
CodingDt coding = (CodingDt) theCoding;
Coding retVal = new Coding();
retVal.setCode(coding.getCode());
retVal.setSystem(coding.getSystem());
retVal.setDisplay(coding.getDisplay());
retVal.setVersion(coding.getVersion());
if (coding.getUserSelected() != null) {
retVal.setUserSelected(coding.getUserSelected());
}
return retVal;
}
@Override
public CodeableConcept codeableConceptToCanonical(IBaseDatatype theCodeableConcept) {
CodeableConceptDt codeableConcept = (CodeableConceptDt) theCodeableConcept;
CodeableConcept retVal = new CodeableConcept();
retVal.setText(codeableConcept.getText());
for (CodingDt next : codeableConcept.getCoding()) {
retVal.addCoding(codingToCanonical(next));
}
return retVal;
}
@Override
public ValueSet valueSetToCanonical(IBaseResource theValueSet) {
org.hl7.fhir.dstu2.model.Resource reencoded = reencodeToHl7Org(theValueSet);
return (ValueSet) VersionConvertorFactory_10_40.convertResource(reencoded, ADVISOR_10_40);
}
@Override
public CodeSystem codeSystemToCanonical(IBaseResource theCodeSystem) {
CodeSystem retVal = new CodeSystem();
ca.uhn.fhir.model.dstu2.resource.ValueSet input = (ca.uhn.fhir.model.dstu2.resource.ValueSet) theCodeSystem;
retVal.setUrl(input.getUrl());
for (ca.uhn.fhir.model.dstu2.resource.ValueSet.CodeSystemConcept next : input.getCodeSystem().getConcept()) {
translateAndAddConcept(next, retVal.getConcept());
}
return retVal;
}
private void translateAndAddConcept(ca.uhn.fhir.model.dstu2.resource.ValueSet.CodeSystemConcept theSource, List<CodeSystem.ConceptDefinitionComponent> theTarget) {
CodeSystem.ConceptDefinitionComponent targetConcept = new CodeSystem.ConceptDefinitionComponent();
targetConcept.setCode(theSource.getCode());
targetConcept.setDisplay(theSource.getDisplay());
for (ca.uhn.fhir.model.dstu2.resource.ValueSet.CodeSystemConceptDesignation next : theSource.getDesignation()) {
CodeSystem.ConceptDefinitionDesignationComponent targetDesignation = targetConcept.addDesignation();
targetDesignation.setLanguage(next.getLanguage());
targetDesignation.setValue(next.getValue());
if (next.getUse() != null) {
targetDesignation.setUse(codingToCanonical(next.getUse()));
}
}
for (ca.uhn.fhir.model.dstu2.resource.ValueSet.CodeSystemConcept nextChild : theSource.getConcept()) {
translateAndAddConcept(nextChild, targetConcept.getConcept());
}
theTarget.add(targetConcept);
}
@Override
public IBaseResource valueSetFromCanonical(ValueSet theValueSet) {
Resource valueSetDstu2Hl7Org = VersionConvertorFactory_10_40.convertResource(theValueSet, ADVISOR_10_40);
return reencodeFromHl7Org(valueSetDstu2Hl7Org);
}
@Override
public ConceptMap conceptMapToCanonical(IBaseResource theConceptMap) {
org.hl7.fhir.dstu2.model.Resource reencoded = reencodeToHl7Org(theConceptMap);
return (ConceptMap) VersionConvertorFactory_10_40.convertResource(reencoded, ADVISOR_10_40);
}
private Resource reencodeToHl7Org(IBaseResource theInput) {
return (Resource) myDstu2Hl7OrgContext.newJsonParser().parseResource(myDstu2Context.newJsonParser().encodeResourceToString(theInput));
}
private IBaseResource reencodeFromHl7Org(Resource theInput) {
return myDstu2Context.newJsonParser().parseResource(myDstu2Hl7OrgContext.newJsonParser().encodeResourceToString(theInput));
}
}
private class Dstu3Strategy implements IStrategy<org.hl7.fhir.dstu3.model.Resource> {
@Override
public CapabilityStatement capabilityStatementToCanonical(org.hl7.fhir.dstu3.model.Resource theCapabilityStatement) {
return (CapabilityStatement) VersionConvertorFactory_30_50.convertResource(theCapabilityStatement, ADVISOR_30_50);
}
@Override
public Coding codingToCanonical(IBaseCoding theCoding) {
return (org.hl7.fhir.r4.model.Coding) VersionConvertorFactory_30_40.convertType((org.hl7.fhir.dstu3.model.Coding) theCoding, ADVISOR_30_40);
}
@Override
public CodeableConcept codeableConceptToCanonical(IBaseDatatype theCodeableConcept) {
return (org.hl7.fhir.r4.model.CodeableConcept) VersionConvertorFactory_30_40.convertType((org.hl7.fhir.dstu3.model.CodeableConcept) theCodeableConcept, ADVISOR_30_40);
}
@Override
public ValueSet valueSetToCanonical(IBaseResource theValueSet) {
return (ValueSet) VersionConvertorFactory_30_40.convertResource((org.hl7.fhir.dstu3.model.Resource) theValueSet, ADVISOR_30_40);
}
@Override
public CodeSystem codeSystemToCanonical(IBaseResource theCodeSystem) {
return (CodeSystem) VersionConvertorFactory_30_40.convertResource((org.hl7.fhir.dstu3.model.Resource) theCodeSystem, ADVISOR_30_40);
}
@Override
public IBaseResource valueSetFromCanonical(ValueSet theValueSet) {
return VersionConvertorFactory_30_40.convertResource(theValueSet, ADVISOR_30_40);
}
@Override
public ConceptMap conceptMapToCanonical(IBaseResource theConceptMap) {
return (ConceptMap) VersionConvertorFactory_30_40.convertResource((org.hl7.fhir.dstu3.model.Resource) theConceptMap, ADVISOR_30_40);
}
}
private class R4Strategy implements IStrategy<org.hl7.fhir.r4.model.Resource> {
@Override
public CapabilityStatement capabilityStatementToCanonical(org.hl7.fhir.r4.model.Resource theCapabilityStatement) {
return (CapabilityStatement) VersionConvertorFactory_40_50.convertResource(theCapabilityStatement, ADVISOR_40_50);
}
@Override
public Coding codingToCanonical(IBaseCoding theCoding) {
return (Coding) theCoding;
}
@Override
public CodeableConcept codeableConceptToCanonical(IBaseDatatype theCodeableConcept) {
return (CodeableConcept) theCodeableConcept;
}
@Override
public ValueSet valueSetToCanonical(IBaseResource theValueSet) {
return (ValueSet) theValueSet;
}
@Override
public CodeSystem codeSystemToCanonical(IBaseResource theCodeSystem) {
return (CodeSystem) theCodeSystem;
}
@Override
public IBaseResource valueSetFromCanonical(ValueSet theValueSet) {
return theValueSet;
}
@Override
public ConceptMap conceptMapToCanonical(IBaseResource theConceptMap) {
return (ConceptMap) theConceptMap;
}
}
private class R4BStrategy implements IStrategy<org.hl7.fhir.r4b.model.Resource> {
@Override
public CapabilityStatement capabilityStatementToCanonical(org.hl7.fhir.r4b.model.Resource theCapabilityStatement) {
return (CapabilityStatement) VersionConvertorFactory_43_50.convertResource(theCapabilityStatement, ADVISOR_43_50);
}
@Override
public Coding codingToCanonical(IBaseCoding theCoding) {
org.hl7.fhir.r5.model.Coding r5coding = (org.hl7.fhir.r5.model.Coding) VersionConvertorFactory_43_50.convertType((org.hl7.fhir.r4b.model.Coding) theCoding, ADVISOR_43_50);
return (org.hl7.fhir.r4.model.Coding) VersionConvertorFactory_40_50.convertType(r5coding, ADVISOR_40_50);
}
@Override
public CodeableConcept codeableConceptToCanonical(IBaseDatatype theCodeableConcept) {
org.hl7.fhir.r5.model.CodeableConcept r5coding = (org.hl7.fhir.r5.model.CodeableConcept) VersionConvertorFactory_43_50.convertType((org.hl7.fhir.r4b.model.CodeableConcept) theCodeableConcept, ADVISOR_43_50);
return (org.hl7.fhir.r4.model.CodeableConcept) VersionConvertorFactory_40_50.convertType(r5coding, ADVISOR_40_50);
}
@Override
public ValueSet valueSetToCanonical(IBaseResource theValueSet) {
org.hl7.fhir.r5.model.ValueSet valueSetR5 = (org.hl7.fhir.r5.model.ValueSet) VersionConvertorFactory_43_50.convertResource((org.hl7.fhir.r4b.model.Resource) theValueSet, ADVISOR_43_50);
return (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_40_50.convertResource(valueSetR5, ADVISOR_40_50);
}
@Override
public CodeSystem codeSystemToCanonical(IBaseResource theCodeSystem) {
org.hl7.fhir.r5.model.CodeSystem codeSystemR5 = (org.hl7.fhir.r5.model.CodeSystem) VersionConvertorFactory_43_50.convertResource((org.hl7.fhir.r4b.model.Resource) theCodeSystem, ADVISOR_43_50);
return (org.hl7.fhir.r4.model.CodeSystem) VersionConvertorFactory_40_50.convertResource(codeSystemR5, ADVISOR_40_50);
}
@Override
public IBaseResource valueSetFromCanonical(ValueSet theValueSet) {
org.hl7.fhir.r5.model.ValueSet valueSetR5 = (org.hl7.fhir.r5.model.ValueSet) VersionConvertorFactory_40_50.convertResource(theValueSet, ADVISOR_40_50);
return VersionConvertorFactory_43_50.convertResource(valueSetR5, ADVISOR_43_50);
}
@Override
public ConceptMap conceptMapToCanonical(IBaseResource theConceptMap) {
org.hl7.fhir.r5.model.ConceptMap conceptMapR5 = (org.hl7.fhir.r5.model.ConceptMap) VersionConvertorFactory_43_50.convertResource((org.hl7.fhir.r4b.model.Resource) theConceptMap, ADVISOR_43_50);
return (ConceptMap) VersionConvertorFactory_40_50.convertResource(conceptMapR5, ADVISOR_40_50);
}
}
private class R5Strategy implements IStrategy<org.hl7.fhir.r5.model.Resource> {
@Override
public CapabilityStatement capabilityStatementToCanonical(org.hl7.fhir.r5.model.Resource theCapabilityStatement) {
return (CapabilityStatement) theCapabilityStatement;
}
@Override
public Coding codingToCanonical(IBaseCoding theCoding) {
return (org.hl7.fhir.r4.model.Coding) VersionConvertorFactory_40_50.convertType((org.hl7.fhir.r5.model.Coding) theCoding, ADVISOR_40_50);
}
@Override
public CodeableConcept codeableConceptToCanonical(IBaseDatatype theCodeableConcept) {
return (org.hl7.fhir.r4.model.CodeableConcept) VersionConvertorFactory_40_50.convertType((org.hl7.fhir.r5.model.CodeableConcept) theCodeableConcept, ADVISOR_40_50);
}
@Override
public ValueSet valueSetToCanonical(IBaseResource theValueSet) {
return (ValueSet) VersionConvertorFactory_40_50.convertResource((org.hl7.fhir.r5.model.ValueSet) theValueSet, ADVISOR_40_50);
}
@Override
public CodeSystem codeSystemToCanonical(IBaseResource theCodeSystem) {
return (CodeSystem) VersionConvertorFactory_40_50.convertResource((org.hl7.fhir.r5.model.CodeSystem) theCodeSystem, ADVISOR_40_50);
}
@Override
public IBaseResource valueSetFromCanonical(ValueSet theValueSet) {
return VersionConvertorFactory_40_50.convertResource(theValueSet, ADVISOR_40_50);
}
@Override
public ConceptMap conceptMapToCanonical(IBaseResource theConceptMap) {
return (ConceptMap) VersionConvertorFactory_40_50.convertResource((org.hl7.fhir.r5.model.ConceptMap) theConceptMap, ADVISOR_40_50);
}
}
}

View File

@ -0,0 +1,23 @@
package ca.uhn.hapi.converters.canonical;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
import org.hl7.fhir.instance.model.api.IBaseCoding;
import org.hl7.fhir.r4.model.Coding;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class VersionCanonicalizerTest {
@Test
public void testToCanonicalCoding() {
VersionCanonicalizer canonicalizer = new VersionCanonicalizer(FhirVersionEnum.DSTU2);
IBaseCoding coding = new CodingDt("dstuSystem", "dstuCode");
Coding convertedCoding = canonicalizer.codingToCanonical(coding);
assertEquals("dstuCode", convertedCoding.getCode());
assertEquals("dstuSystem", convertedCoding.getSystem());
}
}

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>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-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>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>

View File

@ -0,0 +1,4 @@
---
issue: 4150
type: add
title: "Support has been added for FHIR R4B (4.3.0). See the [R4B Documentation](/hapi-fhir/docs/getting_started/r4b.html) for more information on what this means."

View File

@ -16,6 +16,7 @@ page.getting_started.introduction=Introduction
page.getting_started.versions=FHIR and HAPI FHIR Versions page.getting_started.versions=FHIR and HAPI FHIR Versions
page.getting_started.modules=HAPI FHIR Modules page.getting_started.modules=HAPI FHIR Modules
page.getting_started.downloading_and_importing=Downloading and Importing page.getting_started.downloading_and_importing=Downloading and Importing
page.getting_started.r4b=FHIR R4B Support
section.model.title=Working With The FHIR Model section.model.title=Working With The FHIR Model
page.model.working_with_resources=Working With Resources page.model.working_with_resources=Working With Resources

View File

@ -0,0 +1,20 @@
# FHIR R4B
FHIR R4B is an unusual FHIR release meant to help certain users take advantage of certain FHIR R5 models and features before the release and adoption of FHIR R5. Functionally, R4B is mainly identical to FHIR R4 but with specific resources backported from R5.
As of HAPI FHIR 6.2.0, this version is now supported. See [FHIR and HAPI FHIR Versions](versions.html) for a complete table of FHIR specification version support in HAPI FHIR software versions.
**Support for FHIR R4B is experimental** and may never be completely implemented. It has not been extensively tested and we are not currently aiming for feature parity with normal FHIR version support.
The following notes outline current support and limitations.
* **FHIR Parsers/Serializers** are well tested and should be fully functional, as there is no need for any specific R4B code in this part of the codebase.
* **FHIR Client** is well tested and should be fully functional, as there is no need for any specific R4B code in this part of the codebase.
* **Plain Server** is well tested and should be fully functional, as there is no need for any specific R4B code in this part of the codebase.
* **Validator** does not currently work with R4B and may crash or cause unexpected results. Note that the underlying InstanceValidator is able to validate R4B resources, so this could be fixed in a future release if demand is there. The [FHIR Validator Site](https://validator.fhir.org/) can also be used.
* **JPA Server** is able to store data, and supports all basic storage interactions (CRUD). Search also works, including built-in and custom search parameters. However most other functionality has not been implemented or tested, including Subscriptions, Terminology Services, etc.

View File

@ -21,10 +21,44 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td><b>DSTU2.1</b></td> <td><b>DSTU2.1</b></td>
<td><b>DSTU3</b></td> <td><b>DSTU3</b></td>
<td><b>R4</b></td> <td><b>R4</b></td>
<td><b>R4B</b></td>
<td><b>R5</b></td> <td><b>R5</b></td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr>
<td>HAPI FHIR 6.2.0</td>
<td>JDK11</td>
<td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-draft">1.0.2</td>
<td class="versions-table-cell-release">1.4.0</td>
<td class="versions-table-cell-draft">3.0.2</td>
<td class="versions-table-cell-draft">4.0.1</td>
<td class="versions-table-cell-draft">4.3.0</td>
<td class="versions-table-cell-release">5.0.0-ballot<span class="download-version-hash"><br/>9a044604c1</span></td>
</tr>
<tr>
<td>HAPI FHIR 6.1.0</td>
<td>JDK11</td>
<td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-draft">1.0.2</td>
<td class="versions-table-cell-release">1.4.0</td>
<td class="versions-table-cell-draft">3.0.2</td>
<td class="versions-table-cell-draft">4.0.1</td>
<td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-release">4.6.0<span class="download-version-hash"><br/>ba4c12bc30</span></td>
</tr>
<tr>
<td>HAPI FHIR 6.0.0</td>
<td>JDK11</td>
<td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-draft">1.0.2</td>
<td class="versions-table-cell-release">1.4.0</td>
<td class="versions-table-cell-draft">3.0.2</td>
<td class="versions-table-cell-draft">4.0.1</td>
<td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-release">5.0.0-snapshot1<span class="download-version-hash"><br/>0394b96b14</span></td>
</tr>
<tr> <tr>
<td>HAPI FHIR 5.7.0</td> <td>HAPI FHIR 5.7.0</td>
<td>JDK8</td> <td>JDK8</td>
@ -33,6 +67,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-release">1.4.0</td> <td class="versions-table-cell-release">1.4.0</td>
<td class="versions-table-cell-draft">3.0.2</td> <td class="versions-table-cell-draft">3.0.2</td>
<td class="versions-table-cell-draft">4.0.1</td> <td class="versions-table-cell-draft">4.0.1</td>
<td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-release">5.0.0-snapshot1<span class="download-version-hash"><br/>0394b96b14</span></td> <td class="versions-table-cell-release">5.0.0-snapshot1<span class="download-version-hash"><br/>0394b96b14</span></td>
</tr> </tr>
<tr> <tr>
@ -43,6 +78,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-release">1.4.0</td> <td class="versions-table-cell-release">1.4.0</td>
<td class="versions-table-cell-draft">3.0.2</td> <td class="versions-table-cell-draft">3.0.2</td>
<td class="versions-table-cell-draft">4.0.1</td> <td class="versions-table-cell-draft">4.0.1</td>
<td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-release">4.6.0<span class="download-version-hash"><br/>9b829d9714</span></td> <td class="versions-table-cell-release">4.6.0<span class="download-version-hash"><br/>9b829d9714</span></td>
</tr> </tr>
<tr> <tr>
@ -53,6 +89,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-release">1.4.0</td> <td class="versions-table-cell-release">1.4.0</td>
<td class="versions-table-cell-draft">3.0.2</td> <td class="versions-table-cell-draft">3.0.2</td>
<td class="versions-table-cell-draft">4.0.1</td> <td class="versions-table-cell-draft">4.0.1</td>
<td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-release">4.6.0<span class="download-version-hash"><br/>9b829d9714</span></td> <td class="versions-table-cell-release">4.6.0<span class="download-version-hash"><br/>9b829d9714</span></td>
</tr> </tr>
<tr> <tr>
@ -63,6 +100,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-release">1.4.0</td> <td class="versions-table-cell-release">1.4.0</td>
<td class="versions-table-cell-draft">3.0.2</td> <td class="versions-table-cell-draft">3.0.2</td>
<td class="versions-table-cell-draft">4.0.1</td> <td class="versions-table-cell-draft">4.0.1</td>
<td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-release">4.6.0<span class="download-version-hash"><br/>9b829d9714</span></td> <td class="versions-table-cell-release">4.6.0<span class="download-version-hash"><br/>9b829d9714</span></td>
</tr> </tr>
<tr> <tr>
@ -73,6 +111,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-release">1.4.0</td> <td class="versions-table-cell-release">1.4.0</td>
<td class="versions-table-cell-draft">3.0.2</td> <td class="versions-table-cell-draft">3.0.2</td>
<td class="versions-table-cell-draft">4.0.1</td> <td class="versions-table-cell-draft">4.0.1</td>
<td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-release">4.5.0<span class="download-version-hash"><br/>6cd0af3b8c</span></td> <td class="versions-table-cell-release">4.5.0<span class="download-version-hash"><br/>6cd0af3b8c</span></td>
</tr> </tr>
<tr> <tr>
@ -83,6 +122,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-release">1.4.0</td> <td class="versions-table-cell-release">1.4.0</td>
<td class="versions-table-cell-draft">3.0.2</td> <td class="versions-table-cell-draft">3.0.2</td>
<td class="versions-table-cell-draft">4.0.1</td> <td class="versions-table-cell-draft">4.0.1</td>
<td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-release">4.5.0<span class="download-version-hash"><br/>6cd0af3b8c</span></td> <td class="versions-table-cell-release">4.5.0<span class="download-version-hash"><br/>6cd0af3b8c</span></td>
</tr> </tr>
<tr> <tr>
@ -93,6 +133,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-release">1.4.0</td> <td class="versions-table-cell-release">1.4.0</td>
<td class="versions-table-cell-draft">3.0.2</td> <td class="versions-table-cell-draft">3.0.2</td>
<td class="versions-table-cell-draft">4.0.1</td> <td class="versions-table-cell-draft">4.0.1</td>
<td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-release">4.4.0<span class="download-version-hash"><br/>56b0acf73f</span></td> <td class="versions-table-cell-release">4.4.0<span class="download-version-hash"><br/>56b0acf73f</span></td>
</tr> </tr>
<tr> <tr>
@ -103,6 +144,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-release">1.4.0</td> <td class="versions-table-cell-release">1.4.0</td>
<td class="versions-table-cell-draft">3.0.2</td> <td class="versions-table-cell-draft">3.0.2</td>
<td class="versions-table-cell-draft">4.0.1</td> <td class="versions-table-cell-draft">4.0.1</td>
<td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-release">4.4.0<span class="download-version-hash"><br/>56b0acf73f</span></td> <td class="versions-table-cell-release">4.4.0<span class="download-version-hash"><br/>56b0acf73f</span></td>
</tr> </tr>
<tr> <tr>
@ -113,6 +155,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-release">1.4.0</td> <td class="versions-table-cell-release">1.4.0</td>
<td class="versions-table-cell-draft">3.0.2</td> <td class="versions-table-cell-draft">3.0.2</td>
<td class="versions-table-cell-draft">4.0.1</td> <td class="versions-table-cell-draft">4.0.1</td>
<td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-release">4.2.0<span class="download-version-hash"><br/>e0f3f5cc2c</span></td> <td class="versions-table-cell-release">4.2.0<span class="download-version-hash"><br/>e0f3f5cc2c</span></td>
</tr> </tr>
<tr> <tr>
@ -123,6 +166,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-release">1.4.0</td> <td class="versions-table-cell-release">1.4.0</td>
<td class="versions-table-cell-draft">3.0.2</td> <td class="versions-table-cell-draft">3.0.2</td>
<td class="versions-table-cell-draft">4.0.1</td> <td class="versions-table-cell-draft">4.0.1</td>
<td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-release">4.1.0<span class="download-version-hash"><br/>1a7623d866</span></td> <td class="versions-table-cell-release">4.1.0<span class="download-version-hash"><br/>1a7623d866</span></td>
</tr> </tr>
<tr> <tr>
@ -133,6 +177,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-release">1.4.0</td> <td class="versions-table-cell-release">1.4.0</td>
<td class="versions-table-cell-draft">3.0.1</td> <td class="versions-table-cell-draft">3.0.1</td>
<td class="versions-table-cell-draft">4.0.0</td> <td class="versions-table-cell-draft">4.0.0</td>
<td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-release">4.1.0<span class="download-version-hash"><br/>e0e3caf9ba</span></td> <td class="versions-table-cell-release">4.1.0<span class="download-version-hash"><br/>e0e3caf9ba</span></td>
</tr> </tr>
<tr> <tr>
@ -144,6 +189,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-draft">3.0.1</td> <td class="versions-table-cell-draft">3.0.1</td>
<td class="versions-table-cell-draft">4.0.0</td> <td class="versions-table-cell-draft">4.0.0</td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 3.7.0</td> <td>HAPI FHIR 3.7.0</td>
@ -154,6 +200,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-draft">3.0.1</td> <td class="versions-table-cell-draft">3.0.1</td>
<td class="versions-table-cell-draft">4.0.0</td> <td class="versions-table-cell-draft">4.0.0</td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 3.6.0</td> <td>HAPI FHIR 3.6.0</td>
@ -164,6 +211,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-draft">3.0.1</td> <td class="versions-table-cell-draft">3.0.1</td>
<td class="versions-table-cell-release">3.6.0<span class="download-version-hash"><br/>1202b2eed0f</span></td> <td class="versions-table-cell-release">3.6.0<span class="download-version-hash"><br/>1202b2eed0f</span></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 3.5.0</td> <td>HAPI FHIR 3.5.0</td>
@ -174,6 +222,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-draft">3.0.1</td> <td class="versions-table-cell-draft">3.0.1</td>
<td class="versions-table-cell-release">3.4.0<span class="download-version-hash"><br/>13732</span></td> <td class="versions-table-cell-release">3.4.0<span class="download-version-hash"><br/>13732</span></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 3.4.0</td> <td>HAPI FHIR 3.4.0</td>
@ -184,6 +233,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-draft">3.0.1</td> <td class="versions-table-cell-draft">3.0.1</td>
<td class="versions-table-cell-release">3.4.0<span class="download-version-hash"><br/>13732</span></td> <td class="versions-table-cell-release">3.4.0<span class="download-version-hash"><br/>13732</span></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 3.3.0</td> <td>HAPI FHIR 3.3.0</td>
@ -194,6 +244,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-draft">3.0.1</td> <td class="versions-table-cell-draft">3.0.1</td>
<td class="versions-table-cell-release">3.2.0<span class="download-version-hash"><br/>13271</span></td> <td class="versions-table-cell-release">3.2.0<span class="download-version-hash"><br/>13271</span></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 3.2.0</td> <td>HAPI FHIR 3.2.0</td>
@ -204,6 +255,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-draft">3.0.1</td> <td class="versions-table-cell-draft">3.0.1</td>
<td class="versions-table-cell-release">3.2.0<span class="download-version-hash"><br/>12917</span></td> <td class="versions-table-cell-release">3.2.0<span class="download-version-hash"><br/>12917</span></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 3.1.0</td> <td>HAPI FHIR 3.1.0</td>
@ -214,6 +266,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-draft">3.0.1</td> <td class="versions-table-cell-draft">3.0.1</td>
<td class="versions-table-cell-release">3.1.0<span class="download-version-hash"><br/>12370</span></td> <td class="versions-table-cell-release">3.1.0<span class="download-version-hash"><br/>12370</span></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 3.0.0</td> <td>HAPI FHIR 3.0.0</td>
@ -224,6 +277,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-draft">3.0.1</td> <td class="versions-table-cell-draft">3.0.1</td>
<td class="versions-table-cell-release">3.1.0<span class="download-version-hash"><br/>12370</span></td> <td class="versions-table-cell-release">3.1.0<span class="download-version-hash"><br/>12370</span></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 2.5</td> <td>HAPI FHIR 2.5</td>
@ -234,6 +288,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-draft">3.0.1</td> <td class="versions-table-cell-draft">3.0.1</td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 2.4</td> <td>HAPI FHIR 2.4</td>
@ -244,6 +299,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-draft">3.0.1</td> <td class="versions-table-cell-draft">3.0.1</td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 2.3</td> <td>HAPI FHIR 2.3</td>
@ -254,6 +310,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-release">1.9.0<span class="download-version-hash"><br/>11501</span></td> <td class="versions-table-cell-release">1.9.0<span class="download-version-hash"><br/>11501</span></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 2.2</td> <td>HAPI FHIR 2.2</td>
@ -264,6 +321,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-release">1.8.0<span class="download-version-hash"><br/>10528</span></td> <td class="versions-table-cell-release">1.8.0<span class="download-version-hash"><br/>10528</span></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 2.1</td> <td>HAPI FHIR 2.1</td>
@ -274,6 +332,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-release">1.7.0<span class="download-version-hash"><br/>10129</span></td> <td class="versions-table-cell-release">1.7.0<span class="download-version-hash"><br/>10129</span></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 2.0</td> <td>HAPI FHIR 2.0</td>
@ -284,6 +343,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-release">1.6.0<span class="download-version-hash"><br/>9663</span></td> <td class="versions-table-cell-release">1.6.0<span class="download-version-hash"><br/>9663</span></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 1.6</td> <td>HAPI FHIR 1.6</td>
@ -294,6 +354,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-release">1.4.0<span class="download-version-hash"><br/>8636</span></td> <td class="versions-table-cell-release">1.4.0<span class="download-version-hash"><br/>8636</span></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 1.5</td> <td>HAPI FHIR 1.5</td>
@ -304,6 +365,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-release">1.4.0<span class="download-version-hash"><br/>8138</span></td> <td class="versions-table-cell-release">1.4.0<span class="download-version-hash"><br/>8138</span></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 1.4</td> <td>HAPI FHIR 1.4</td>
@ -314,6 +376,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-release">1.3.0<span class="download-version-hash"><br/>7602</span></td> <td class="versions-table-cell-release">1.3.0<span class="download-version-hash"><br/>7602</span></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 1.3</td> <td>HAPI FHIR 1.3</td>
@ -324,6 +387,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 1.2</td> <td>HAPI FHIR 1.2</td>
@ -334,6 +398,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
<tr> <tr>
<td>HAPI FHIR 1.1</td> <td>HAPI FHIR 1.1</td>
@ -344,6 +409,7 @@ Note also that after the release of the FHIR DSTU2 specification, the FHIR
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td> <td class="versions-table-cell-empty"></td>
<td class="versions-table-cell-empty"></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

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>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>
@ -111,6 +111,11 @@
<artifactId>hapi-fhir-jpaserver-test-r4</artifactId> <artifactId>hapi-fhir-jpaserver-test-r4</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-jpaserver-test-r4b</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-jpaserver-test-r5</artifactId> <artifactId>hapi-fhir-jpaserver-test-r5</artifactId>

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>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-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>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

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>6.2.0-PRE16-SNAPSHOT</version> <version>6.2.0-PRE17-SNAPSHOT</version>
<relativePath>../hapi-deployable-pom/pom.xml</relativePath> <relativePath>../hapi-deployable-pom/pom.xml</relativePath>
</parent> </parent>
@ -97,6 +97,11 @@
<artifactId>hapi-fhir-structures-r4</artifactId> <artifactId>hapi-fhir-structures-r4</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-r4b</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-r5</artifactId> <artifactId>hapi-fhir-structures-r5</artifactId>
@ -495,6 +500,22 @@
</excludeResourceNames> </excludeResourceNames>
</configuration> </configuration>
</execution> </execution>
<execution>
<id>build_r4b</id>
<goals>
<goal>generate-jparest-server</goal>
</goals>
<configuration>
<version>r4b</version>
<configPackageBase>ca.uhn.fhir.jpa.config</configPackageBase>
<packageBase>ca.uhn.fhir.jpa.rp.r4b</packageBase>
<targetResourceSpringBeansFile>hapi-fhir-server-resourceproviders-r4b.xml
</targetResourceSpringBeansFile>
<baseResourceNames></baseResourceNames>
<excludeResourceNames>
</excludeResourceNames>
</configuration>
</execution>
<execution> <execution>
<id>build_r5</id> <id>build_r5</id>
<goals> <goals>

View File

@ -111,8 +111,10 @@ import ca.uhn.fhir.jpa.searchparam.nickname.NicknameInterceptor;
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamProvider; import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamProvider;
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc; import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
import ca.uhn.fhir.jpa.sp.SearchParamPresenceSvcImpl; import ca.uhn.fhir.jpa.sp.SearchParamPresenceSvcImpl;
import ca.uhn.fhir.jpa.term.TermReadSvcImpl;
import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl; import ca.uhn.fhir.jpa.term.TermConceptMappingSvcImpl;
import ca.uhn.fhir.jpa.term.api.ITermConceptMappingSvc; import ca.uhn.fhir.jpa.term.api.ITermConceptMappingSvc;
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
import ca.uhn.fhir.jpa.term.config.TermCodeSystemConfig; import ca.uhn.fhir.jpa.term.config.TermCodeSystemConfig;
import ca.uhn.fhir.jpa.util.MemoryCacheService; import ca.uhn.fhir.jpa.util.MemoryCacheService;
import ca.uhn.fhir.jpa.validation.ResourceLoaderImpl; import ca.uhn.fhir.jpa.validation.ResourceLoaderImpl;
@ -125,6 +127,7 @@ import ca.uhn.fhir.rest.server.interceptor.ResponseTerminologyTranslationInterce
import ca.uhn.fhir.rest.server.interceptor.ResponseTerminologyTranslationSvc; import ca.uhn.fhir.rest.server.interceptor.ResponseTerminologyTranslationSvc;
import ca.uhn.fhir.rest.server.interceptor.consent.IConsentContextServices; import ca.uhn.fhir.rest.server.interceptor.consent.IConsentContextServices;
import ca.uhn.fhir.rest.server.interceptor.partition.RequestTenantPartitionInterceptor; import ca.uhn.fhir.rest.server.interceptor.partition.RequestTenantPartitionInterceptor;
import ca.uhn.hapi.converters.canonical.VersionCanonicalizer;
import org.hl7.fhir.common.hapi.validation.support.UnknownCodeSystemWarningValidationSupport; import org.hl7.fhir.common.hapi.validation.support.UnknownCodeSystemWarningValidationSupport;
import org.hl7.fhir.utilities.graphql.IGraphQLStorageServices; import org.hl7.fhir.utilities.graphql.IGraphQLStorageServices;
import org.hl7.fhir.utilities.npm.PackageClient; import org.hl7.fhir.utilities.npm.PackageClient;
@ -707,12 +710,6 @@ public class JpaConfig {
return new UnknownCodeSystemWarningValidationSupport(theFhirContext); return new UnknownCodeSystemWarningValidationSupport(theFhirContext);
} }
@Lazy
@Bean
public MemberMatcherR4Helper memberMatcherR4Helper(FhirContext theFhirContext) {
return new MemberMatcherR4Helper(theFhirContext);
}
@Lazy @Lazy
@Bean @Bean
public NicknameInterceptor nicknameInterceptor() throws IOException { public NicknameInterceptor nicknameInterceptor() throws IOException {
@ -723,4 +720,17 @@ public class JpaConfig {
public ISynchronousSearchSvc synchronousSearchSvc(){ public ISynchronousSearchSvc synchronousSearchSvc(){
return new SynchronousSearchSvcImpl(); return new SynchronousSearchSvcImpl();
} }
@Bean
public VersionCanonicalizer versionCanonicalizer(FhirContext theFhirContext) {
return new VersionCanonicalizer(theFhirContext);
}
@Bean
public ITermReadSvc terminologyService() {
return new TermReadSvcImpl();
}
} }

View File

@ -4,9 +4,8 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao; import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.dao.ITransactionProcessorVersionAdapter; import ca.uhn.fhir.jpa.dao.ITransactionProcessorVersionAdapter;
import ca.uhn.fhir.jpa.dao.TransactionProcessorVersionAdapterDstu2; import ca.uhn.fhir.jpa.dao.TransactionProcessorVersionAdapterDstu2;
import ca.uhn.fhir.jpa.term.TermReadSvcDstu2; import ca.uhn.fhir.jpa.provider.JpaSystemProvider;
import ca.uhn.fhir.jpa.term.TermVersionAdapterSvcDstu2; import ca.uhn.fhir.jpa.term.TermVersionAdapterSvcDstu2;
import ca.uhn.fhir.jpa.term.api.ITermReadSvc;
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc; import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
import ca.uhn.fhir.model.dstu2.composite.MetaDt; import ca.uhn.fhir.model.dstu2.composite.MetaDt;
import ca.uhn.fhir.model.dstu2.resource.Bundle; import ca.uhn.fhir.model.dstu2.resource.Bundle;
@ -60,15 +59,11 @@ public class JpaDstu2Config {
} }
@Bean(name = "mySystemProviderDstu2") @Bean(name = "mySystemProviderDstu2")
public ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2 systemProviderDstu2(FhirContext theFhirContext) { public JpaSystemProvider<Bundle, MetaDt> systemProviderDstu2(FhirContext theFhirContext) {
ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2 retVal = new ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2(); JpaSystemProvider<Bundle, MetaDt> retVal = new ca.uhn.fhir.jpa.provider.JpaSystemProvider<>();
retVal.setDao(systemDaoDstu2()); retVal.setDao(systemDaoDstu2());
retVal.setContext(theFhirContext); retVal.setContext(theFhirContext);
return retVal; return retVal;
} }
@Bean
public ITermReadSvc terminologyService() {
return new TermReadSvcDstu2();
}
} }

View File

@ -11,13 +11,12 @@ import ca.uhn.fhir.jpa.dao.ITransactionProcessorVersionAdapter;
import ca.uhn.fhir.jpa.dao.dstu3.TransactionProcessorVersionAdapterDstu3; import ca.uhn.fhir.jpa.dao.dstu3.TransactionProcessorVersionAdapterDstu3;
import ca.uhn.fhir.jpa.graphql.GraphQLProvider; import ca.uhn.fhir.jpa.graphql.GraphQLProvider;
import ca.uhn.fhir.jpa.graphql.GraphQLProviderWithIntrospection; import ca.uhn.fhir.jpa.graphql.GraphQLProviderWithIntrospection;
import ca.uhn.fhir.jpa.provider.JpaSystemProvider;
import ca.uhn.fhir.jpa.term.TermLoaderSvcImpl; import ca.uhn.fhir.jpa.term.TermLoaderSvcImpl;
import ca.uhn.fhir.jpa.term.TermReadSvcDstu3;
import ca.uhn.fhir.jpa.term.TermVersionAdapterSvcDstu3; import ca.uhn.fhir.jpa.term.TermVersionAdapterSvcDstu3;
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.term.api.ITermDeferredStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc; import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
import ca.uhn.fhir.jpa.term.api.ITermReadSvcDstu3;
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc; import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
import org.hl7.fhir.dstu3.model.Bundle; import org.hl7.fhir.dstu3.model.Bundle;
@ -80,8 +79,8 @@ public class JpaDstu3Config {
} }
@Bean(name = "mySystemProviderDstu3") @Bean(name = "mySystemProviderDstu3")
public ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3 systemProviderDstu3(FhirContext theFhirContext) { public JpaSystemProvider<Bundle, Meta> systemProviderDstu3(FhirContext theFhirContext) {
ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3 retVal = new ca.uhn.fhir.jpa.provider.dstu3.JpaSystemProviderDstu3(); JpaSystemProvider<Bundle, Meta> retVal = new JpaSystemProvider<>();
retVal.setContext(theFhirContext); retVal.setContext(theFhirContext);
retVal.setDao(systemDaoDstu3()); retVal.setDao(systemDaoDstu3());
return retVal; return retVal;
@ -92,9 +91,4 @@ public class JpaDstu3Config {
return new TermLoaderSvcImpl(theDeferredStorageSvc, theCodeSystemStorageSvc); return new TermLoaderSvcImpl(theDeferredStorageSvc, theCodeSystemStorageSvc);
} }
@Bean
public ITermReadSvcDstu3 terminologyService() {
return new TermReadSvcDstu3();
}
} }

View File

@ -11,14 +11,16 @@ import ca.uhn.fhir.jpa.dao.ITransactionProcessorVersionAdapter;
import ca.uhn.fhir.jpa.dao.r4.TransactionProcessorVersionAdapterR4; import ca.uhn.fhir.jpa.dao.r4.TransactionProcessorVersionAdapterR4;
import ca.uhn.fhir.jpa.graphql.GraphQLProvider; import ca.uhn.fhir.jpa.graphql.GraphQLProvider;
import ca.uhn.fhir.jpa.graphql.GraphQLProviderWithIntrospection; import ca.uhn.fhir.jpa.graphql.GraphQLProviderWithIntrospection;
import ca.uhn.fhir.jpa.provider.JpaSystemProvider;
import ca.uhn.fhir.jpa.provider.r4.MemberMatchR4ResourceProvider;
import ca.uhn.fhir.jpa.provider.r4.MemberMatcherR4Helper;
import ca.uhn.fhir.jpa.term.TermLoaderSvcImpl; import ca.uhn.fhir.jpa.term.TermLoaderSvcImpl;
import ca.uhn.fhir.jpa.term.TermReadSvcR4;
import ca.uhn.fhir.jpa.term.TermVersionAdapterSvcR4; import ca.uhn.fhir.jpa.term.TermVersionAdapterSvcR4;
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.term.api.ITermDeferredStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc; import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
import ca.uhn.fhir.jpa.term.api.ITermReadSvcR4;
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc; import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
import ca.uhn.fhir.rest.server.provider.ResourceProviderFactory;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
import org.hl7.fhir.r4.model.Bundle; import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Meta; import org.hl7.fhir.r4.model.Meta;
@ -72,7 +74,7 @@ public class JpaR4Config {
@Bean(name = JpaConfig.GRAPHQL_PROVIDER_NAME) @Bean(name = JpaConfig.GRAPHQL_PROVIDER_NAME)
@Lazy @Lazy
public GraphQLProvider graphQLProvider(FhirContext theFhirContext, IGraphQLStorageServices theGraphqlStorageServices, IValidationSupport theValidationSupport, ISearchParamRegistry theSearchParamRegistry, IDaoRegistry theDaoRegistry) { public GraphQLProvider graphQLProvider(FhirContext theFhirContext, IGraphQLStorageServices theGraphqlStorageServices, IValidationSupport theValidationSupport, ISearchParamRegistry theSearchParamRegistry, IDaoRegistry theDaoRegistry) {
return new GraphQLProviderWithIntrospection(theFhirContext, theValidationSupport, theGraphqlStorageServices, theSearchParamRegistry, theDaoRegistry); return new GraphQLProviderWithIntrospection(theFhirContext, theValidationSupport, theGraphqlStorageServices, theSearchParamRegistry, theDaoRegistry);
} }
@Bean(name = "mySystemDaoR4") @Bean(name = "mySystemDaoR4")
@ -82,8 +84,8 @@ public class JpaR4Config {
} }
@Bean(name = "mySystemProviderR4") @Bean(name = "mySystemProviderR4")
public ca.uhn.fhir.jpa.provider.r4.JpaSystemProviderR4 systemProviderR4(FhirContext theFhirContext) { public JpaSystemProvider<Bundle, Meta> systemProviderR4(FhirContext theFhirContext) {
ca.uhn.fhir.jpa.provider.r4.JpaSystemProviderR4 retVal = new ca.uhn.fhir.jpa.provider.r4.JpaSystemProviderR4(); JpaSystemProvider<Bundle, Meta> retVal = new JpaSystemProvider<>();
retVal.setContext(theFhirContext); retVal.setContext(theFhirContext);
retVal.setDao(systemDaoR4()); retVal.setDao(systemDaoR4());
return retVal; return retVal;
@ -95,8 +97,27 @@ public class JpaR4Config {
} }
@Bean @Bean
public ITermReadSvcR4 terminologyService() { public MemberMatcherR4Helper memberMatcherR4Helper(FhirContext theFhirContext) {
return new TermReadSvcR4(); return new MemberMatcherR4Helper(theFhirContext);
} }
@Bean
public MemberMatchR4ResourceProvider memberMatchR4ResourceProvider(FhirContext theFhirContext, MemberMatcherR4Helper theMemberMatchR4Helper) {
return new MemberMatchR4ResourceProvider(theFhirContext, theMemberMatchR4Helper);
}
@Bean
public ProviderLoader r4ProviderLoader(ResourceProviderFactory theResourceProviderFactory, MemberMatchR4ResourceProvider theMemberMatchR4ResourceProvider) {
return new ProviderLoader(theResourceProviderFactory, theMemberMatchR4ResourceProvider);
}
public static class ProviderLoader {
public ProviderLoader(ResourceProviderFactory theResourceProviderFactory, MemberMatchR4ResourceProvider theMemberMatchR4ResourceProvider) {
theResourceProviderFactory.addSupplier(()->theMemberMatchR4ResourceProvider);
}
}
} }

View File

@ -0,0 +1,43 @@
package ca.uhn.fhir.jpa.config.r4b;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.ParserOptions;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
public class FhirContextR4BConfig {
public static final String DEFAULT_PRESERVE_VERSION_REFS = "AuditEvent.entity.what";
@Bean(name = "primaryFhirContext")
@Primary
public FhirContext fhirContextR4B() {
FhirContext retVal = FhirContext.forR4B();
// Don't strip versions in some places
ParserOptions parserOptions = retVal.getParserOptions();
parserOptions.setDontStripVersionsFromReferencesAtPaths(DEFAULT_PRESERVE_VERSION_REFS);
return retVal;
}
}

View File

@ -0,0 +1,96 @@
package ca.uhn.fhir.jpa.config.r4b;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.jpa.api.IDaoRegistry;
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.config.GeneratedDaoAndResourceProviderConfigR4B;
import ca.uhn.fhir.jpa.config.JpaConfig;
import ca.uhn.fhir.jpa.config.SharedConfigDstu3Plus;
import ca.uhn.fhir.jpa.dao.ITransactionProcessorVersionAdapter;
import ca.uhn.fhir.jpa.dao.r4b.TransactionProcessorVersionAdapterR4B;
import ca.uhn.fhir.jpa.graphql.GraphQLProvider;
import ca.uhn.fhir.jpa.graphql.GraphQLProviderWithIntrospection;
import ca.uhn.fhir.jpa.provider.JpaSystemProvider;
import ca.uhn.fhir.jpa.term.TermLoaderSvcImpl;
import ca.uhn.fhir.jpa.term.TermVersionAdapterSvcR4B;
import ca.uhn.fhir.jpa.term.api.ITermCodeSystemStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermDeferredStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
import org.hl7.fhir.r4b.model.Bundle;
import org.hl7.fhir.r4b.model.Meta;
import org.hl7.fhir.utilities.graphql.IGraphQLStorageServices;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
@Configuration
@EnableTransactionManagement
@Import({
FhirContextR4BConfig.class,
GeneratedDaoAndResourceProviderConfigR4B.class,
SharedConfigDstu3Plus.class,
JpaConfig.class
})
public class JpaR4BConfig {
@Bean
public ITermVersionAdapterSvc terminologyVersionAdapterSvc() {
return new TermVersionAdapterSvcR4B();
}
@Bean
public ITransactionProcessorVersionAdapter transactionProcessorVersionFacade() {
return new TransactionProcessorVersionAdapterR4B();
}
@Bean(name = JpaConfig.GRAPHQL_PROVIDER_NAME)
@Lazy
public GraphQLProvider graphQLProvider(FhirContext theFhirContext, IGraphQLStorageServices theGraphqlStorageServices, IValidationSupport theValidationSupport, ISearchParamRegistry theSearchParamRegistry, IDaoRegistry theDaoRegistry) {
return new GraphQLProviderWithIntrospection(theFhirContext, theValidationSupport, theGraphqlStorageServices, theSearchParamRegistry, theDaoRegistry);
}
@Bean(name = "mySystemDaoR4B")
public IFhirSystemDao<Bundle, Meta> systemDaoR4() {
ca.uhn.fhir.jpa.dao.r4b.FhirSystemDaoR4B retVal = new ca.uhn.fhir.jpa.dao.r4b.FhirSystemDaoR4B();
return retVal;
}
@Bean(name = "mySystemProviderR4B")
public JpaSystemProvider<Bundle, Meta> systemProviderR4(FhirContext theFhirContext) {
JpaSystemProvider<Bundle, Meta> retVal = new JpaSystemProvider<>();
retVal.setContext(theFhirContext);
retVal.setDao(systemDaoR4());
return retVal;
}
@Bean
public ITermLoaderSvc termLoaderService(ITermDeferredStorageSvc theDeferredStorageSvc, ITermCodeSystemStorageSvc theCodeSystemStorageSvc) {
return new TermLoaderSvcImpl(theDeferredStorageSvc, theCodeSystemStorageSvc);
}
}

View File

@ -11,13 +11,12 @@ import ca.uhn.fhir.jpa.dao.ITransactionProcessorVersionAdapter;
import ca.uhn.fhir.jpa.dao.r5.TransactionProcessorVersionAdapterR5; import ca.uhn.fhir.jpa.dao.r5.TransactionProcessorVersionAdapterR5;
import ca.uhn.fhir.jpa.graphql.GraphQLProvider; import ca.uhn.fhir.jpa.graphql.GraphQLProvider;
import ca.uhn.fhir.jpa.graphql.GraphQLProviderWithIntrospection; import ca.uhn.fhir.jpa.graphql.GraphQLProviderWithIntrospection;
import ca.uhn.fhir.jpa.provider.JpaSystemProvider;
import ca.uhn.fhir.jpa.term.TermLoaderSvcImpl; import ca.uhn.fhir.jpa.term.TermLoaderSvcImpl;
import ca.uhn.fhir.jpa.term.TermReadSvcR5;
import ca.uhn.fhir.jpa.term.TermVersionAdapterSvcR5; import ca.uhn.fhir.jpa.term.TermVersionAdapterSvcR5;
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.term.api.ITermDeferredStorageSvc;
import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc; import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
import ca.uhn.fhir.jpa.term.api.ITermReadSvcR5;
import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc; import ca.uhn.fhir.jpa.term.api.ITermVersionAdapterSvc;
import ca.uhn.fhir.rest.server.util.ISearchParamRegistry; import ca.uhn.fhir.rest.server.util.ISearchParamRegistry;
import org.hl7.fhir.r5.model.Bundle; import org.hl7.fhir.r5.model.Bundle;
@ -73,7 +72,7 @@ public class JpaR5Config {
@Bean(name = JpaConfig.GRAPHQL_PROVIDER_NAME) @Bean(name = JpaConfig.GRAPHQL_PROVIDER_NAME)
@Lazy @Lazy
public GraphQLProvider graphQLProvider(FhirContext theFhirContext, IGraphQLStorageServices theGraphqlStorageServices, IValidationSupport theValidationSupport, ISearchParamRegistry theSearchParamRegistry, IDaoRegistry theDaoRegistry) { public GraphQLProvider graphQLProvider(FhirContext theFhirContext, IGraphQLStorageServices theGraphqlStorageServices, IValidationSupport theValidationSupport, ISearchParamRegistry theSearchParamRegistry, IDaoRegistry theDaoRegistry) {
return new GraphQLProviderWithIntrospection(theFhirContext, theValidationSupport, theGraphqlStorageServices, theSearchParamRegistry, theDaoRegistry); return new GraphQLProviderWithIntrospection(theFhirContext, theValidationSupport, theGraphqlStorageServices, theSearchParamRegistry, theDaoRegistry);
} }
@Bean(name = "mySystemDaoR5") @Bean(name = "mySystemDaoR5")
@ -83,8 +82,8 @@ public class JpaR5Config {
} }
@Bean(name = "mySystemProviderR5") @Bean(name = "mySystemProviderR5")
public ca.uhn.fhir.jpa.provider.r5.JpaSystemProviderR5 systemProviderR5(FhirContext theFhirContext) { public JpaSystemProvider<Bundle, Meta> systemProviderR5(FhirContext theFhirContext) {
ca.uhn.fhir.jpa.provider.r5.JpaSystemProviderR5 retVal = new ca.uhn.fhir.jpa.provider.r5.JpaSystemProviderR5(); JpaSystemProvider<Bundle, Meta> retVal = new JpaSystemProvider<>();
retVal.setContext(theFhirContext); retVal.setContext(theFhirContext);
retVal.setDao(systemDaoR5()); retVal.setDao(systemDaoR5());
return retVal; return retVal;
@ -95,9 +94,4 @@ public class JpaR5Config {
return new TermLoaderSvcImpl(theDeferredStorageSvc, theCodeSystemStorageSvc); return new TermLoaderSvcImpl(theDeferredStorageSvc, theCodeSystemStorageSvc);
} }
@Bean
public ITermReadSvcR5 terminologyService() {
return new TermReadSvcR5();
}
} }

View File

@ -1,68 +0,0 @@
package ca.uhn.fhir.jpa.dao;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoEncounter;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu2.resource.Encounter;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.StringParam;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
public class FhirResourceDaoEncounterDstu2 extends BaseHapiFhirResourceDao<Encounter>implements IFhirResourceDaoEncounter<Encounter> {
@Override
public IBundleProvider encounterInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort) {
SearchParameterMap paramMap = new SearchParameterMap();
if (theCount != null) {
paramMap.setCount(theCount.getValue());
}
if (theOffset != null) {
throw new IllegalArgumentException(Msg.code(944) + "Everything operation does not support offset searching");
}
// paramMap.setRevIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
paramMap.setEverythingMode(theId != null ? EverythingModeEnum.ENCOUNTER_INSTANCE : EverythingModeEnum.ENCOUNTER_TYPE);
paramMap.setSort(theSort);
paramMap.setLastUpdated(theLastUpdated);
if (theId != null) {
paramMap.add("_id", new StringParam(theId.getIdPart()));
}
IBundleProvider retVal = search(paramMap);
return retVal;
}
@Override
public IBundleProvider encounterTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort) {
return encounterInstanceEverything(theServletRequest, null, theCount, theOffset, theLastUpdated, theSort);
}
}

View File

@ -1,105 +0,0 @@
package ca.uhn.fhir.jpa.dao;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.api.dao.PatientEverythingParameters;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient;
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.StringAndListParam;
import ca.uhn.fhir.rest.param.TokenOrListParam;
import ca.uhn.fhir.rest.param.TokenParam;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
public class FhirResourceDaoPatientDstu2 extends BaseHapiFhirResourceDao<Patient> implements IFhirResourceDaoPatient<Patient> {
@Autowired
private IRequestPartitionHelperSvc myPartitionHelperSvc;
public FhirResourceDaoPatientDstu2() {
super();
}
private IBundleProvider doEverythingOperation(TokenOrListParam theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, StringAndListParam theTypes, RequestDetails theRequest) {
SearchParameterMap paramMap = new SearchParameterMap();
if (theCount != null) {
paramMap.setCount(theCount.getValue());
}
if (theOffset != null) {
throw new IllegalArgumentException(Msg.code(954) + "Everything operation does not support offset searching");
}
if (theContent != null) {
paramMap.add(Constants.PARAM_CONTENT, theContent);
}
if (theNarrative != null) {
paramMap.add(Constants.PARAM_TEXT, theNarrative);
}
if (theTypes != null) {
paramMap.add(Constants.PARAM_TYPE, theTypes);
}
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
paramMap.setEverythingMode(theId != null ? EverythingModeEnum.PATIENT_INSTANCE : EverythingModeEnum.PATIENT_TYPE);
paramMap.setSort(theSort);
paramMap.setLastUpdated(theLastUpdated);
if (theId != null) {
paramMap.add("_id", theId);
}
if (!isPagingProviderDatabaseBacked(theRequest)) {
paramMap.setLoadSynchronous(true);
}
RequestPartitionId requestPartitionId = myPartitionHelperSvc.determineReadPartitionForRequestForSearchType(theRequest, getResourceName(), paramMap, null);
return mySearchCoordinatorSvc.registerSearch(this, paramMap, getResourceName(), new CacheControlDirective().parse(theRequest.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequest, requestPartitionId);
}
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, RequestDetails theRequestDetails, PatientEverythingParameters theQueryParams, IIdType theId) {
TokenOrListParam id = new TokenOrListParam().add(new TokenParam(theId.getIdPart()));
return doEverythingOperation(id, theQueryParams.getCount(), theQueryParams.getOffset(), theQueryParams.getLastUpdated(), theQueryParams.getSort(), theQueryParams.getContent(), theQueryParams.getNarrative(), theQueryParams.getFilter(), theQueryParams.getTypes(), theRequestDetails);
}
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, RequestDetails theRequestDetails, PatientEverythingParameters theQueryParams, TokenOrListParam theIds) {
return doEverythingOperation(theIds, theQueryParams.getCount(), theQueryParams.getOffset(), theQueryParams.getLastUpdated(), theQueryParams.getSort(), theQueryParams.getContent(), theQueryParams.getNarrative(), theQueryParams.getFilter(), theQueryParams.getTypes(), theRequestDetails);
}
}

View File

@ -1,27 +0,0 @@
package ca.uhn.fhir.jpa.dao;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.model.dstu2.resource.QuestionnaireResponse;
public class FhirResourceDaoQuestionnaireResponseDstu2 extends BaseHapiFhirResourceDao<QuestionnaireResponse> {
// nothing
}

View File

@ -20,27 +20,29 @@ package ca.uhn.fhir.jpa.dao;
* #L% * #L%
*/ */
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.model.dstu2.resource.Bundle; import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry; import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
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.UnprocessableEntityException; 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 java.util.Set;
import static org.apache.commons.lang3.StringUtils.defaultString; import static org.apache.commons.lang3.StringUtils.defaultString;
public class FhirResourceDaoBundleDstu2 extends BaseHapiFhirResourceDao<Bundle> { public class JpaResourceDaoBundle<T extends IBaseBundle> extends BaseHapiFhirResourceDao<T> {
@Override @Override
protected void preProcessResourceForStorage(IBaseResource theResource, RequestDetails theRequestDetails, TransactionDetails theTransactionDetails, boolean thePerformIndexing) { protected void preProcessResourceForStorage(IBaseResource theResource, RequestDetails theRequestDetails, TransactionDetails theTransactionDetails, boolean thePerformIndexing) {
super.preProcessResourceForStorage(theResource, theRequestDetails, theTransactionDetails, thePerformIndexing); super.preProcessResourceForStorage(theResource, theRequestDetails, theTransactionDetails, thePerformIndexing);
for (Entry next : ((Bundle)theResource).getEntry()) { if (getContext().getVersion().getVersion() == FhirVersionEnum.DSTU2) {
next.setFullUrl((String) null); for (Entry next : ((Bundle) theResource).getEntry()) {
next.setFullUrl((String) null);
}
} }
} }
} }

View File

@ -1,4 +1,4 @@
package ca.uhn.fhir.jpa.dao.r4; package ca.uhn.fhir.jpa.dao;
/* /*
* #%L * #%L
@ -24,29 +24,25 @@ import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.TranslateConceptResults; 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.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;
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.instance.model.api.IBase; import ca.uhn.hapi.converters.canonical.VersionCanonicalizer;
import org.hl7.fhir.instance.model.api.IBaseCoding;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.ConceptMap; import org.hl7.fhir.r4.model.ConceptMap;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List;
public class FhirResourceDaoConceptMapR4 extends BaseHapiFhirResourceDao<ConceptMap> implements IFhirResourceDaoConceptMap<ConceptMap> { public class JpaResourceDaoConceptMap<T extends IBaseResource> extends JpaResourceDao<T> implements IFhirResourceDaoConceptMap<T> {
@Autowired @Autowired
private ITermConceptMappingSvc myTermConceptMappingSvc; private ITermConceptMappingSvc myTermConceptMappingSvc;
@Autowired @Autowired
private IValidationSupport myValidationSupport; private IValidationSupport myValidationSupport;
@Autowired
private VersionCanonicalizer myVersionCanonicalizer;
@Override @Override
public TranslateConceptResults translate(TranslationRequest theTranslationRequest, RequestDetails theRequestDetails) { public TranslateConceptResults translate(TranslationRequest theTranslationRequest, RequestDetails theRequestDetails) {
@ -61,7 +57,7 @@ public class FhirResourceDaoConceptMapR4 extends BaseHapiFhirResourceDao<Concept
if (!retVal.isUnchangedInCurrentOperation()) { if (!retVal.isUnchangedInCurrentOperation()) {
if (retVal.getDeleted() == null) { if (retVal.getDeleted() == null) {
ConceptMap conceptMap = (ConceptMap) theResource; ConceptMap conceptMap = myVersionCanonicalizer.conceptMapToCanonical(theResource);
myTermConceptMappingSvc.storeTermConceptMapAndChildren(retVal, conceptMap); myTermConceptMappingSvc.storeTermConceptMapAndChildren(retVal, conceptMap);
} else { } else {
myTermConceptMappingSvc.deleteConceptMapAndChildren(retVal); myTermConceptMappingSvc.deleteConceptMapAndChildren(retVal);

View File

@ -1,4 +1,4 @@
package ca.uhn.fhir.jpa.dao.r5; package ca.uhn.fhir.jpa.dao;
/* /*
* #%L * #%L
@ -22,7 +22,6 @@ package ca.uhn.fhir.jpa.dao.r5;
import ca.uhn.fhir.i18n.Msg; import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoEncounter; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoEncounter;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum;
import ca.uhn.fhir.rest.api.SortSpec; import ca.uhn.fhir.rest.api.SortSpec;
@ -32,12 +31,11 @@ import ca.uhn.fhir.rest.param.StringParam;
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.r5.model.Encounter;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.Collections; import java.util.Collections;
public class FhirResourceDaoEncounterR5 extends BaseHapiFhirResourceDao<Encounter> implements IFhirResourceDaoEncounter<Encounter> { public class JpaResourceDaoEncounter<T extends IBaseResource> extends BaseHapiFhirResourceDao<T> implements IFhirResourceDaoEncounter<T> {
@Override @Override
public IBundleProvider encounterInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort) { public IBundleProvider encounterInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort) {

View File

@ -1,4 +1,4 @@
package ca.uhn.fhir.jpa.dao.r4; package ca.uhn.fhir.jpa.dao;
/* /*
* #%L * #%L
@ -22,9 +22,8 @@ package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.i18n.Msg; import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.interceptor.model.RequestPartitionId; import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.api.dao.PatientEverythingParameters;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao; import ca.uhn.fhir.jpa.api.dao.PatientEverythingParameters;
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc; import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum;
@ -34,10 +33,13 @@ import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.SortSpec; import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.*; import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.StringAndListParam;
import ca.uhn.fhir.rest.param.TokenOrListParam;
import ca.uhn.fhir.rest.param.TokenParam;
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.Patient;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -46,7 +48,7 @@ import javax.servlet.http.HttpServletRequest;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
public class FhirResourceDaoPatientR4 extends BaseHapiFhirResourceDao<Patient> implements IFhirResourceDaoPatient<Patient> { public class JpaResourceDaoPatient<T extends IBaseResource> extends BaseHapiFhirResourceDao<T> implements IFhirResourceDaoPatient<T> {
@Autowired @Autowired
private IRequestPartitionHelperSvc myPartitionHelperSvc; private IRequestPartitionHelperSvc myPartitionHelperSvc;

View File

@ -1,37 +0,0 @@
package ca.uhn.fhir.jpa.dao.dstu3;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.Bundle.BundleType;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import java.util.Set;
import static org.apache.commons.lang3.StringUtils.defaultString;
public class FhirResourceDaoBundleDstu3 extends BaseHapiFhirResourceDao<Bundle> {
// nothing
}

View File

@ -54,6 +54,7 @@ import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import static ca.uhn.fhir.jpa.dao.FhirResourceDaoValueSetDstu2.toStringOrNull;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
@Transactional @Transactional
@ -172,7 +173,7 @@ 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(Msg.code(1077)); return myTerminologySvc.codeSystemValidateCode(theCodeSystemId, toStringOrNull(theCodeSystemUrl), toStringOrNull(theVersion), toStringOrNull(theCode), toStringOrNull(theDisplay), theCoding, theCodeableConcept);
} }
} }

View File

@ -1,69 +0,0 @@
package ca.uhn.fhir.jpa.dao.dstu3;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoEncounter;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.StringParam;
import org.hl7.fhir.dstu3.model.Encounter;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
public class FhirResourceDaoEncounterDstu3 extends BaseHapiFhirResourceDao<Encounter> implements IFhirResourceDaoEncounter<Encounter> {
@Override
public IBundleProvider encounterInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort) {
SearchParameterMap paramMap = new SearchParameterMap();
if (theCount != null) {
paramMap.setCount(theCount.getValue());
}
if (theOffset != null) {
throw new IllegalArgumentException(Msg.code(1081) + "Everything operation does not support offset searching");
}
// paramMap.setRevIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
paramMap.setEverythingMode(theId != null ? EverythingModeEnum.ENCOUNTER_INSTANCE : EverythingModeEnum.ENCOUNTER_TYPE);
paramMap.setSort(theSort);
paramMap.setLastUpdated(theLastUpdated);
if (theId != null) {
paramMap.add("_id", new StringParam(theId.getIdPart()));
}
IBundleProvider retVal = search(paramMap);
return retVal;
}
@Override
public IBundleProvider encounterTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort) {
return encounterInstanceEverything(theServletRequest, null, theCount, theOffset, theLastUpdated, theSort);
}
}

View File

@ -1,104 +0,0 @@
package ca.uhn.fhir.jpa.dao.dstu3;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.api.dao.PatientEverythingParameters;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.*;
import org.hl7.fhir.dstu3.model.Patient;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Collections;
public class FhirResourceDaoPatientDstu3 extends BaseHapiFhirResourceDao<Patient> implements IFhirResourceDaoPatient<Patient> {
@Autowired
private IRequestPartitionHelperSvc myPartitionHelperSvc;
private IBundleProvider doEverythingOperation(TokenOrListParam theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theFilter, StringAndListParam theTypes, RequestDetails theRequest) {
SearchParameterMap paramMap = new SearchParameterMap();
if (theCount != null) {
paramMap.setCount(theCount.getValue());
}
if (theOffset != null) {
throw new IllegalArgumentException(Msg.code(1082) + "Everything operation does not support offset searching");
}
if (theContent != null) {
paramMap.add(Constants.PARAM_CONTENT, theContent);
}
if (theNarrative != null) {
paramMap.add(Constants.PARAM_TEXT, theNarrative);
}
if (theTypes != null) {
paramMap.add(Constants.PARAM_TYPE, theTypes);
}
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
paramMap.setEverythingMode(theId != null ? EverythingModeEnum.PATIENT_INSTANCE : EverythingModeEnum.PATIENT_TYPE);
paramMap.setSort(theSort);
paramMap.setLastUpdated(theLastUpdated);
if (theId != null) {
if (theRequest.getParameters().containsKey("_mdm")) {
String[] paramVal = theRequest.getParameters().get("_mdm");
if (Arrays.asList(paramVal).contains("true")) {
theId.getValuesAsQueryTokens().stream().forEach(param -> param.setMdmExpand(true));
}
}
paramMap.add("_id", theId);
}
if (!isPagingProviderDatabaseBacked(theRequest)) {
paramMap.setLoadSynchronous(true);
}
RequestPartitionId requestPartitionId = myPartitionHelperSvc.determineReadPartitionForRequestForSearchType(theRequest, getResourceName(), paramMap, null);
return mySearchCoordinatorSvc.registerSearch(this, paramMap, getResourceName(), new CacheControlDirective().parse(theRequest.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequest, requestPartitionId);
}
@Override
@Transactional(propagation = Propagation.SUPPORTS)
public IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, RequestDetails theRequestDetails, PatientEverythingParameters theQueryParams, IIdType theId) {
TokenOrListParam id = new TokenOrListParam().addOr(new TokenParam(theId.getIdPart()));
return doEverythingOperation(id, theQueryParams.getCount(), theQueryParams.getOffset(), theQueryParams.getLastUpdated(), theQueryParams.getSort(), theQueryParams.getContent(), theQueryParams.getNarrative(), theQueryParams.getFilter(), theQueryParams.getTypes(), theRequestDetails);
}
@Override
public IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, RequestDetails theRequestDetails, PatientEverythingParameters theQueryParams, TokenOrListParam theId) {
return doEverythingOperation(theId, theQueryParams.getCount(), theQueryParams.getOffset(), theQueryParams.getLastUpdated(), theQueryParams.getSort(), theQueryParams.getContent(), theQueryParams.getNarrative(), theQueryParams.getFilter(), theQueryParams.getTypes(), theRequestDetails);
}
}

View File

@ -1,87 +0,0 @@
package ca.uhn.fhir.jpa.dao.dstu3;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import org.hl7.fhir.dstu3.model.QuestionnaireResponse;
public class FhirResourceDaoQuestionnaireResponseDstu3 extends BaseHapiFhirResourceDao<QuestionnaireResponse> {
// @Override
// protected void validateResourceForStorage(QuestionnaireResponse theResource, ResourceTable theEntityToSave, RequestDetails theRequestDetails) {
// super.validateResourceForStorage(theResource, theEntityToSave, theRequestDetails);
// if (!myValidateResponses) {
// return;
// }
//
// if (theResource == null || theResource.getQuestionnaire() == null || theResource.getQuestionnaire().getReference() == null || theResource.getQuestionnaire().getReference().isEmpty()) {
// return;
// }
//
// FhirValidator val = getContext().newValidator();
// val.setValidateAgainstStandardSchema(false);
// val.setValidateAgainstStandardSchematron(false);
//
// val.registerValidatorModule(myQuestionnaireResponseValidatorDstu3);
//
// ValidationResult result = val.validateWithResult(getContext().newJsonParser().parseResource(getContext().newJsonParser().encodeResourceToString(theResource)));
// if (!result.isSuccessful()) {
// IBaseOperationOutcome oo = getContext().newJsonParser().parseResource(OperationOutcome.class, getContext().newJsonParser().encodeResourceToString(result.toOperationOutcome()));
// throw new UnprocessableEntityException(Msg.code(1078) + getContext(), oo);
// }
// }
//
// public class ResourceLoaderImpl implements IResourceLoader {
//
// private RequestDetails myRequestDetails;
//
// public ResourceLoaderImpl(RequestDetails theRequestDetails) {
// super();
// myRequestDetails = theRequestDetails;
// }
//
// @Override
// public <T extends IBaseResource> T load(Class<T> theType, IIdType theId) throws ResourceNotFoundException {
//
// /*
// * The QuestionnaireResponse validator uses RI structures, so for now we need to convert between that and HAPI
// * structures. This is a bit hackish, but hopefully it will go away at some point.
// */
// if ("ValueSet".equals(theType.getSimpleName())) {
// IFhirResourceDao<ValueSet> dao = getDao(ValueSet.class);
// ValueSet in = dao.read(theId, myRequestDetails);
// return (T) in;
// } else if ("Questionnaire".equals(theType.getSimpleName())) {
// IFhirResourceDao<Questionnaire> dao = getDao(Questionnaire.class);
// Questionnaire vs = dao.read(theId, myRequestDetails);
// return (T) vs;
// } else {
// // Should not happen, validator will only ask for these two
// throw new IllegalStateException(Msg.code(1079) + "Unexpected request to load resource of type " + theType);
// }
//
// }
//
// }
}

View File

@ -1,38 +0,0 @@
package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Bundle.BundleType;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import java.util.Set;
import java.util.TreeSet;
import static org.apache.commons.lang3.StringUtils.defaultString;
public class FhirResourceDaoBundleR4 extends BaseHapiFhirResourceDao<Bundle> {
// nothing for now
}

View File

@ -1,69 +0,0 @@
package ca.uhn.fhir.jpa.dao.r4;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoEncounter;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.StringParam;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.Encounter;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
public class FhirResourceDaoEncounterR4 extends BaseHapiFhirResourceDao<Encounter> implements IFhirResourceDaoEncounter<Encounter> {
@Override
public IBundleProvider encounterInstanceEverything(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort) {
SearchParameterMap paramMap = new SearchParameterMap();
if (theCount != null) {
paramMap.setCount(theCount.getValue());
}
if (theOffset != null) {
throw new IllegalArgumentException(Msg.code(1107) + "Everything operation does not support offset searching");
}
// paramMap.setRevIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
paramMap.setIncludes(Collections.singleton(IResource.INCLUDE_ALL.asRecursive()));
paramMap.setEverythingMode(theId != null ? EverythingModeEnum.ENCOUNTER_INSTANCE : EverythingModeEnum.ENCOUNTER_TYPE);
paramMap.setSort(theSort);
paramMap.setLastUpdated(theLastUpdated);
if (theId != null) {
paramMap.add("_id", new StringParam(theId.getIdPart()));
}
IBundleProvider retVal = search(paramMap);
return retVal;
}
@Override
public IBundleProvider encounterTypeEverything(HttpServletRequest theServletRequest, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort) {
return encounterInstanceEverything(theServletRequest, null, theCount, theOffset, theLastUpdated, theSort);
}
}

View File

@ -1,87 +0,0 @@
package ca.uhn.fhir.jpa.dao.r4;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import org.hl7.fhir.r4.model.QuestionnaireResponse;
public class FhirResourceDaoQuestionnaireResponseR4 extends BaseHapiFhirResourceDao<QuestionnaireResponse> {
// @Override
// protected void validateResourceForStorage(QuestionnaireResponse theResource, ResourceTable theEntityToSave, RequestDetails theRequestDetails) {
// super.validateResourceForStorage(theResource, theEntityToSave, theRequestDetails);
// if (!myValidateResponses) {
// return;
// }
//
// if (theResource == null || theResource.getQuestionnaire() == null || theResource.getQuestionnaire().getReference() == null || theResource.getQuestionnaire().getReference().isEmpty()) {
// return;
// }
//
// FhirValidator val = getContext().newValidator();
// val.setValidateAgainstStandardSchema(false);
// val.setValidateAgainstStandardSchematron(false);
//
// val.registerValidatorModule(myQuestionnaireResponseValidatorR4);
//
// ValidationResult result = val.validateWithResult(getContext().newJsonParser().parseResource(getContext().newJsonParser().encodeResourceToString(theResource)));
// if (!result.isSuccessful()) {
// IBaseOperationOutcome oo = getContext().newJsonParser().parseResource(OperationOutcome.class, getContext().newJsonParser().encodeResourceToString(result.toOperationOutcome()));
// throw new UnprocessableEntityException(Msg.code(1104) + getContext(), oo);
// }
// }
//
// public class ResourceLoaderImpl implements IResourceLoader {
//
// private RequestDetails myRequestDetails;
//
// public ResourceLoaderImpl(RequestDetails theRequestDetails) {
// super();
// myRequestDetails = theRequestDetails;
// }
//
// @Override
// public <T extends IBaseResource> T load(Class<T> theType, IIdType theId) throws ResourceNotFoundException {
//
// /*
// * The QuestionnaireResponse validator uses RI structures, so for now we need to convert between that and HAPI
// * structures. This is a bit hackish, but hopefully it will go away at some point.
// */
// if ("ValueSet".equals(theType.getSimpleName())) {
// IFhirResourceDao<ValueSet> dao = getDao(ValueSet.class);
// ValueSet in = dao.read(theId, myRequestDetails);
// return (T) in;
// } else if ("Questionnaire".equals(theType.getSimpleName())) {
// IFhirResourceDao<Questionnaire> dao = getDao(Questionnaire.class);
// Questionnaire vs = dao.read(theId, myRequestDetails);
// return (T) vs;
// } else {
// // Should not happen, validator will only ask for these two
// throw new IllegalStateException(Msg.code(1105) + "Unexpected request to load resource of type " + theType);
// }
//
// }
//
// }
}

View File

@ -1,10 +1,10 @@
package ca.uhn.fhir.jpa.dao.r5; package ca.uhn.fhir.jpa.dao.r4b;
/* /*
* #%L * #%L
* HAPI FHIR JPA Server * HAPI FHIR JPA Server
* %% * %%
* Copyright (C) 2014 - 2021 Smile CDR, Inc. * Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %% * %%
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -22,58 +22,61 @@ package ca.uhn.fhir.jpa.dao.r5;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.IValidationSupport; import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.context.support.IValidationSupport.CodeValidationResult; import ca.uhn.fhir.context.support.IValidationSupport.CodeValidationResult;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoCodeSystem; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.api.svc.IIdHelperService;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao; import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.index.IdHelperService;
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_40_50;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_43_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_43_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;
import org.hl7.fhir.r5.model.CodeSystem; import org.hl7.fhir.r4b.model.CodeSystem;
import org.hl7.fhir.r5.model.CodeableConcept; import org.hl7.fhir.r4b.model.CodeableConcept;
import org.hl7.fhir.r5.model.Coding; import org.hl7.fhir.r4b.model.Coding;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
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 FhirResourceDaoCodeSystemR4B extends BaseHapiFhirResourceDao<CodeSystem> implements IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoCodeSystemR5.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoCodeSystemR4B.class);
@Autowired @Autowired
protected ITermCodeSystemStorageSvc myTerminologyCodeSystemStorageSvc; protected ITermCodeSystemStorageSvc myTerminologyCodeSystemStorageSvc;
@Autowired @Autowired
protected IdHelperService myIdHelperService; protected IIdHelperService myIdHelperService;
@Autowired
protected ITermDeferredStorageSvc myTermDeferredStorageSvc;
@Autowired @Autowired
private IValidationSupport myValidationSupport; private IValidationSupport myValidationSupport;
@Autowired @Autowired
private FhirContext myFhirContext; private FhirContext myFhirContext;
@Autowired
protected ITermDeferredStorageSvc myTermDeferredStorageSvc;
@Override @Override
public List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem, RequestDetails theRequest) { public List<IIdType> findCodeSystemIdsContainingSystemAndCode(String theCode, String theSystem, RequestDetails theRequest) {
List<IIdType> valueSetIds; List<IIdType> valueSetIds;
Set<ResourcePersistentId> ids = searchForIds(new SearchParameterMap(CodeSystem.SP_CODE, new TokenParam(theSystem, theCode)), theRequest); List<ResourcePersistentId> ids = searchForIds(new SearchParameterMap(org.hl7.fhir.r4.model.CodeSystem.SP_CODE, new TokenParam(theSystem, theCode)), theRequest);
valueSetIds = new ArrayList<>(); valueSetIds = new ArrayList<>();
for (ResourcePersistentId next : ids) { for (ResourcePersistentId next : ids) {
IIdType id = myIdHelperService.translatePidIdToForcedId(myFhirContext, "CodeSystem", next); IIdType id = myIdHelperService.translatePidIdToForcedId(myFhirContext, "CodeSystem", next);
@ -85,15 +88,22 @@ 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(Msg.code(2148) + "No code, coding, or codeableConcept provided to validate");
} }
if (!LogicUtil.multiXor(haveCoding, (haveSystem && haveCode)) || (haveSystem != haveCode)) { if (!LogicUtil.multiXor(haveCoding, (haveSystem && haveCode)) || (haveSystem != haveCode)) {
throw new InvalidRequestException("$lookup can only validate (system AND code) OR (coding.system AND coding.code)"); throw new InvalidRequestException(Msg.code(2149) + "$lookup can only validate (system AND code) OR (coding.system AND coding.code)");
} }
String code; String code;
@ -110,12 +120,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;
} }
@ -133,8 +148,8 @@ public class FhirResourceDaoCodeSystemR5 extends BaseHapiFhirResourceDao<CodeSys
} }
@Override @Override
protected void preDelete(CodeSystem theResourceToDelete, ResourceTable theEntityToDelete) { protected void preDelete(CodeSystem theResourceToDelete, ResourceTable theEntityToDelete, RequestDetails theRequestDetails) {
super.preDelete(theResourceToDelete, theEntityToDelete); super.preDelete(theResourceToDelete, theEntityToDelete, theRequestDetails);
myTermDeferredStorageSvc.deleteCodeSystemForResource(theEntityToDelete); myTermDeferredStorageSvc.deleteCodeSystemForResource(theEntityToDelete);
@ -146,10 +161,13 @@ public class FhirResourceDaoCodeSystemR5 extends BaseHapiFhirResourceDao<CodeSys
ResourceTable retVal = super.updateEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theTransactionDetails, theForceUpdate, theCreateNewHistoryEntry); ResourceTable retVal = super.updateEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theTransactionDetails, theForceUpdate, theCreateNewHistoryEntry);
if (!retVal.isUnchangedInCurrentOperation()) { if (!retVal.isUnchangedInCurrentOperation()) {
CodeSystem cs = (CodeSystem) theResource; CodeSystem csR4b = (CodeSystem) theResource;
addPidToResource(theEntity, theResource);
myTerminologyCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(org.hl7.fhir.convertors.conv40_50.CodeSystem40_50.convertCodeSystem(cs), (ResourceTable) theEntity); org.hl7.fhir.r5.model.CodeSystem csR5 = (org.hl7.fhir.r5.model.CodeSystem) VersionConvertorFactory_43_50.convertResource(csR4b, new BaseAdvisor_43_50(false));
org.hl7.fhir.r4.model.CodeSystem csR4 = (org.hl7.fhir.r4.model.CodeSystem) VersionConvertorFactory_40_50.convertResource(csR5, new BaseAdvisor_40_50(false));
addPidToResource(theEntity, csR4);
myTerminologyCodeSystemStorageSvc.storeNewCodeSystemVersionIfNeeded(csR4, (ResourceTable) theEntity);
} }
return retVal; return retVal;
@ -157,8 +175,8 @@ public class FhirResourceDaoCodeSystemR5 extends BaseHapiFhirResourceDao<CodeSys
@Override @Override
public CodeValidationResult validateCode(IIdType theCodeSystemId, IPrimitiveType<String> theCodeSystemUrl, public CodeValidationResult validateCode(IIdType theCodeSystemId, IPrimitiveType<String> theCodeSystemUrl,
IPrimitiveType<String> theVersion, IPrimitiveType<String> theCode, IPrimitiveType<String> theDisplay, IPrimitiveType<String> theVersion, IPrimitiveType<String> theCode, IPrimitiveType<String> theDisplay,
Coding theCoding, CodeableConcept theCodeableConcept, RequestDetails theRequestDetails) { Coding theCoding, CodeableConcept theCodeableConcept, RequestDetails theRequestDetails) {
return myTerminologySvc.codeSystemValidateCode(theCodeSystemId, toStringOrNull(theCodeSystemUrl), toStringOrNull(theVersion), toStringOrNull(theCode), toStringOrNull(theDisplay), theCoding, theCodeableConcept); return myTerminologySvc.codeSystemValidateCode(theCodeSystemId, toStringOrNull(theCodeSystemUrl), toStringOrNull(theVersion), toStringOrNull(theCode), toStringOrNull(theDisplay), theCoding, theCodeableConcept);
} }

View File

@ -0,0 +1,59 @@
package ca.uhn.fhir.jpa.dao.r4b;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoComposition;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.StringParam;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4b.model.Composition;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
public class FhirResourceDaoCompositionR4B extends BaseHapiFhirResourceDao<Composition> implements IFhirResourceDaoComposition<Composition> {
@Override
public IBundleProvider getDocumentForComposition(HttpServletRequest theServletRequest, IIdType theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdate, SortSpec theSort, RequestDetails theRequestDetails) {
SearchParameterMap paramMap = new SearchParameterMap();
if (theCount != null) {
paramMap.setCount(theCount.getValue());
}
if (theOffset != null) {
paramMap.setOffset(theOffset.getValue());
}
paramMap.setIncludes(Collections.singleton(IBaseResource.INCLUDE_ALL.asRecursive()));
paramMap.setSort(theSort);
paramMap.setLastUpdated(theLastUpdate);
if (theId != null) {
paramMap.add("_id", new StringParam(theId.getIdPart()));
}
return search(paramMap, theRequestDetails);
}
}

View File

@ -0,0 +1,45 @@
package ca.uhn.fhir.jpa.dao.r4b;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.TranslateConceptResults;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoConceptMap;
import ca.uhn.fhir.jpa.api.model.TranslationRequest;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.term.api.ITermConceptMappingSvc;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.r4b.model.ConceptMap;
import org.springframework.beans.factory.annotation.Autowired;
public class FhirResourceDaoConceptMapR4B extends BaseHapiFhirResourceDao<ConceptMap> implements IFhirResourceDaoConceptMap<ConceptMap> {
@Autowired
private ITermConceptMappingSvc myTermConceptMappingSvc;
@Autowired
private IValidationSupport myValidationSupport;
@Override
public TranslateConceptResults translate(TranslationRequest theTranslationRequest, RequestDetails theRequestDetails) {
IValidationSupport.TranslateCodeRequest translateCodeRequest = theTranslationRequest.asTranslateCodeRequest();
return myValidationSupport.translateConcept(translateCodeRequest);
}
}

View File

@ -1,12 +1,4 @@
package ca.uhn.fhir.jpa.dao.r5; package ca.uhn.fhir.jpa.dao.r4b;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import org.hl7.fhir.r5.model.Bundle;
import java.util.Set;
import static org.apache.commons.lang3.StringUtils.defaultString;
/* /*
* #%L * #%L
@ -28,8 +20,10 @@ import static org.apache.commons.lang3.StringUtils.defaultString;
* #L% * #L%
*/ */
public class FhirResourceDaoBundleR5 extends BaseHapiFhirResourceDao<Bundle> { import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoMessageHeader;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
// nothing import org.hl7.fhir.r4b.model.MessageHeader;
public class FhirResourceDaoMessageHeaderR4B extends BaseHapiFhirResourceDao<MessageHeader> implements IFhirResourceDaoMessageHeader<MessageHeader> {
// nothing right now
} }

View File

@ -0,0 +1,83 @@
package ca.uhn.fhir.jpa.dao.r4b;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDaoObservation;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4b.model.Observation;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
public class FhirResourceDaoObservationR4B extends BaseHapiFhirResourceDaoObservation<Observation> {
@Autowired
private IRequestPartitionHelperSvc myPartitionHelperSvc;
@Override
public IBundleProvider observationsLastN(SearchParameterMap theSearchParameterMap, RequestDetails theRequestDetails, HttpServletResponse theServletResponse) {
updateSearchParamsForLastn(theSearchParameterMap, theRequestDetails);
RequestPartitionId requestPartitionId = myPartitionHelperSvc.determineReadPartitionForRequestForSearchType(theRequestDetails, getResourceName(), theSearchParameterMap, null);
return mySearchCoordinatorSvc.registerSearch(this, theSearchParameterMap, getResourceName(), new CacheControlDirective().parse(theRequestDetails.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequestDetails, requestPartitionId);
}
@Override
protected String getEffectiveParamName() {
return org.hl7.fhir.r4.model.Observation.SP_DATE;
}
@Override
protected String getCodeParamName() {
return org.hl7.fhir.r4.model.Observation.SP_CODE;
}
@Override
protected String getSubjectParamName() {
return org.hl7.fhir.r4.model.Observation.SP_SUBJECT;
}
@Override
protected String getPatientParamName() {
return org.hl7.fhir.r4.model.Observation.SP_PATIENT;
}
@Override
public ResourceTable updateEntity(RequestDetails theRequest, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, TransactionDetails theTransactionDetails, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
return updateObservationEntity(theRequest, theResource, theEntity, theDeletedTimestampOrNull,
thePerformIndexing, theUpdateVersion, theTransactionDetails, theForceUpdate,
theCreateNewHistoryEntry);
}
}

View File

@ -0,0 +1,83 @@
package ca.uhn.fhir.jpa.dao.r4b;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoSearchParameter;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.dao.r4.FhirResourceDaoSearchParameterR4;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.extractor.ISearchParamExtractor;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_43_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_43_50;
import org.hl7.fhir.r4b.model.CodeType;
import org.hl7.fhir.r4b.model.SearchParameter;
import org.hl7.fhir.r5.model.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import java.util.stream.Collectors;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public class FhirResourceDaoSearchParameterR4B extends BaseHapiFhirResourceDao<SearchParameter> implements IFhirResourceDaoSearchParameter<SearchParameter> {
@Autowired
private ISearchParamExtractor mySearchParamExtractor;
protected void refactorAffectedResources(SearchParameter theResource, RequestDetails theRequestDetails) {
Boolean reindex = theResource != null ? CURRENTLY_REINDEXING.get(theResource) : null;
String expression = theResource != null ? theResource.getExpression() : null;
List<String> base = theResource != null ? theResource.getBase().stream().map(CodeType::getCode).collect(Collectors.toList()) : null;
requestReindexForRelatedResources(reindex, base, theRequestDetails);
}
@Override
protected void postPersist(ResourceTable theEntity, SearchParameter theResource, RequestDetails theRequestDetails) {
super.postPersist(theEntity, theResource, theRequestDetails);
refactorAffectedResources(theResource, theRequestDetails);
}
@Override
protected void postUpdate(ResourceTable theEntity, SearchParameter theResource, RequestDetails theRequestDetails) {
super.postUpdate(theEntity, theResource, theRequestDetails);
refactorAffectedResources(theResource, theRequestDetails);
}
@Override
protected void preDelete(SearchParameter theResourceToDelete, ResourceTable theEntityToDelete, RequestDetails theRequestDetails) {
super.preDelete(theResourceToDelete, theEntityToDelete, theRequestDetails);
refactorAffectedResources(theResourceToDelete, theRequestDetails);
}
@Override
protected void validateResourceForStorage(SearchParameter theResource, ResourceTable theEntityToSave) {
super.validateResourceForStorage(theResource, theEntityToSave);
Resource resR5 = VersionConvertorFactory_43_50.convertResource(theResource, new BaseAdvisor_43_50(false));
FhirResourceDaoSearchParameterR4.validateSearchParam(
(org.hl7.fhir.r4.model.SearchParameter) VersionConvertorFactory_40_50.convertResource(resR5, new BaseAdvisor_40_50(false)),
getContext(), getConfig(), mySearchParamRegistry, mySearchParamExtractor);
}
}

View File

@ -0,0 +1,43 @@
package ca.uhn.fhir.jpa.dao.r4b;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoStructureDefinition;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.r4b.model.StructureDefinition;
import org.springframework.beans.factory.annotation.Autowired;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public class FhirResourceDaoStructureDefinitionR4B extends BaseHapiFhirResourceDao<StructureDefinition> implements IFhirResourceDaoStructureDefinition<StructureDefinition> {
@Autowired
private IValidationSupport myValidationSupport;
@Override
public StructureDefinition generateSnapshot(StructureDefinition theInput, String theUrl, String theWebUrl, String theName) {
StructureDefinition output = (StructureDefinition) myValidationSupport.generateSnapshot(new ValidationSupportContext(myValidationSupport), theInput, theUrl, theWebUrl, theName);
Validate.notNull(output);
return output;
}
}

View File

@ -0,0 +1,38 @@
package ca.uhn.fhir.jpa.dao.r4b;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoSubscription;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4b.model.Subscription;
public class FhirResourceDaoSubscriptionR4B extends BaseHapiFhirResourceDao<Subscription> implements IFhirResourceDaoSubscription<Subscription> {
@Override
public Long getSubscriptionTablePidForSubscriptionResource(IIdType theId, RequestDetails theRequest, TransactionDetails theTransactionDetails) {
throw new UnsupportedOperationException(Msg.code(2150));
}
}

View File

@ -0,0 +1,102 @@
package ca.uhn.fhir.jpa.dao.r4b;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.ValueSetExpansionOptions;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoValueSet;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_40_50;
import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_43_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_40_50;
import org.hl7.fhir.convertors.factory.VersionConvertorFactory_43_50;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4b.model.CodeableConcept;
import org.hl7.fhir.r4b.model.Coding;
import org.hl7.fhir.r4b.model.ValueSet;
import java.util.Date;
import static ca.uhn.fhir.jpa.dao.FhirResourceDaoValueSetDstu2.toStringOrNull;
import static ca.uhn.fhir.jpa.dao.dstu3.FhirResourceDaoValueSetDstu3.vsValidateCodeOptions;
public class FhirResourceDaoValueSetR4B extends BaseHapiFhirResourceDao<ValueSet> implements IFhirResourceDaoValueSet<ValueSet, Coding, CodeableConcept> {
@Override
public ValueSet expand(IIdType theId, ValueSetExpansionOptions theOptions, RequestDetails theRequestDetails) {
ValueSet source = read(theId, theRequestDetails);
return expand(source, theOptions);
}
@Override
public ValueSet expandByIdentifier(String theUri, ValueSetExpansionOptions theOptions) {
org.hl7.fhir.r4.model.ValueSet canonicalOutput = myTerminologySvc.expandValueSet(theOptions, theUri);
org.hl7.fhir.r5.model.ValueSet valueSetR5 = (org.hl7.fhir.r5.model.ValueSet) VersionConvertorFactory_40_50.convertResource(canonicalOutput, new BaseAdvisor_40_50(false));
return (ValueSet) VersionConvertorFactory_43_50.convertResource(valueSetR5, new BaseAdvisor_43_50(false));
}
@Override
public ValueSet expand(ValueSet theSource, ValueSetExpansionOptions theOptions) {
org.hl7.fhir.r5.model.ValueSet canonicalInputR5 = (org.hl7.fhir.r5.model.ValueSet) VersionConvertorFactory_43_50.convertResource(theSource, new BaseAdvisor_43_50(false));
org.hl7.fhir.r4.model.ValueSet canonicalInput = (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_40_50.convertResource(canonicalInputR5, new BaseAdvisor_40_50(false));
org.hl7.fhir.r4.model.ValueSet canonicalOutput = myTerminologySvc.expandValueSet(theOptions, canonicalInput);
org.hl7.fhir.r5.model.ValueSet outputR5 = (org.hl7.fhir.r5.model.ValueSet) VersionConvertorFactory_40_50.convertResource(canonicalOutput, new BaseAdvisor_40_50(false));
return (ValueSet) VersionConvertorFactory_43_50.convertResource(outputR5, new BaseAdvisor_43_50(false));
}
@Override
public IValidationSupport.CodeValidationResult validateCode(IPrimitiveType<String> theValueSetIdentifier, IIdType theId, IPrimitiveType<String> theCode,
IPrimitiveType<String> theSystem, IPrimitiveType<String> theDisplay, Coding theCoding,
CodeableConcept theCodeableConcept, RequestDetails theRequestDetails) {
return myTerminologySvc.validateCode(vsValidateCodeOptions(), theId, toStringOrNull(theValueSetIdentifier), toStringOrNull(theSystem), toStringOrNull(theCode), toStringOrNull(theDisplay), theCoding, theCodeableConcept);
}
@Override
public void purgeCaches() {
// nothing
}
@Override
public ResourceTable updateEntity(RequestDetails theRequestDetails, IBaseResource theResource, IBasePersistedResource theEntity, Date theDeletedTimestampOrNull, boolean thePerformIndexing,
boolean theUpdateVersion, TransactionDetails theTransactionDetails, boolean theForceUpdate, boolean theCreateNewHistoryEntry) {
ResourceTable retVal = super.updateEntity(theRequestDetails, theResource, theEntity, theDeletedTimestampOrNull, thePerformIndexing, theUpdateVersion, theTransactionDetails, theForceUpdate, theCreateNewHistoryEntry);
if (getConfig().isPreExpandValueSets() && !retVal.isUnchangedInCurrentOperation()) {
if (retVal.getDeleted() == null) {
ValueSet valueSet = (ValueSet) theResource;
org.hl7.fhir.r5.model.ValueSet valueSetR5 = (org.hl7.fhir.r5.model.ValueSet) VersionConvertorFactory_43_50.convertResource(valueSet, new BaseAdvisor_43_50(false));
org.hl7.fhir.r4.model.ValueSet valueSetR4 = (org.hl7.fhir.r4.model.ValueSet) VersionConvertorFactory_40_50.convertResource(valueSetR5, new BaseAdvisor_40_50(false));
myTerminologySvc.storeTermValueSet(retVal, valueSetR4);
} else {
myTerminologySvc.deleteValueSetAndChildren(retVal);
}
}
return retVal;
}
}

View File

@ -0,0 +1,73 @@
package ca.uhn.fhir.jpa.dao.r4b;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.dao.BaseHapiFhirSystemDao;
import ca.uhn.fhir.jpa.dao.FhirResourceDaoMessageHeaderDstu2;
import ca.uhn.fhir.jpa.model.entity.TagDefinition;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.r4b.model.Bundle;
import org.hl7.fhir.r4b.model.Meta;
import javax.persistence.TypedQuery;
import java.util.Collection;
import java.util.List;
public class FhirSystemDaoR4B extends BaseHapiFhirSystemDao<Bundle, Meta> {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirSystemDaoR4B.class);
@Override
public Meta metaGetOperation(RequestDetails theRequestDetails) {
String sql = "SELECT d FROM TagDefinition d WHERE d.myId IN (SELECT DISTINCT t.myTagId FROM ResourceTag t)";
TypedQuery<TagDefinition> q = myEntityManager.createQuery(sql, TagDefinition.class);
List<TagDefinition> tagDefinitions = q.getResultList();
return toMeta(tagDefinitions);
}
@Override
public IBaseBundle processMessage(RequestDetails theRequestDetails, IBaseBundle theMessage) {
return FhirResourceDaoMessageHeaderDstu2.throwProcessMessageNotImplemented();
}
protected Meta toMeta(Collection<TagDefinition> tagDefinitions) {
Meta retVal = new Meta();
for (TagDefinition next : tagDefinitions) {
switch (next.getTagType()) {
case PROFILE:
retVal.addProfile(next.getCode());
break;
case SECURITY_LABEL:
retVal.addSecurity().setSystem(next.getSystem()).setCode(next.getCode()).setDisplay(next.getDisplay());
break;
case TAG:
retVal.addTag().setSystem(next.getSystem()).setCode(next.getCode()).setDisplay(next.getDisplay());
break;
}
}
return retVal;
}
}

View File

@ -0,0 +1,174 @@
package ca.uhn.fhir.jpa.dao.r4b;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.dao.ITransactionProcessorVersionAdapter;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4b.model.Bundle;
import org.hl7.fhir.r4b.model.OperationOutcome;
import org.hl7.fhir.r4b.model.Resource;
import java.util.Date;
import java.util.List;
public class TransactionProcessorVersionAdapterR4B implements ITransactionProcessorVersionAdapter<Bundle, Bundle.BundleEntryComponent> {
@Override
public void setResponseStatus(Bundle.BundleEntryComponent theBundleEntry, String theStatus) {
theBundleEntry.getResponse().setStatus(theStatus);
}
@Override
public void setResponseLastModified(Bundle.BundleEntryComponent theBundleEntry, Date theLastModified) {
theBundleEntry.getResponse().setLastModified(theLastModified);
}
@Override
public void setResource(Bundle.BundleEntryComponent theBundleEntry, IBaseResource theResource) {
theBundleEntry.setResource((Resource) theResource);
}
@Override
public IBaseResource getResource(Bundle.BundleEntryComponent theBundleEntry) {
return theBundleEntry.getResource();
}
@Override
public String getBundleType(Bundle theRequest) {
if (theRequest.getType() == null) {
return null;
}
return theRequest.getTypeElement().getValue().toCode();
}
@Override
public void populateEntryWithOperationOutcome(BaseServerResponseException theCaughtEx, Bundle.BundleEntryComponent theEntry) {
OperationOutcome oo = new OperationOutcome();
oo.addIssue()
.setSeverity(OperationOutcome.IssueSeverity.ERROR)
.setDiagnostics(theCaughtEx.getMessage())
.setCode(OperationOutcome.IssueType.EXCEPTION);
theEntry.getResponse().setOutcome(oo);
}
@Override
public Bundle createBundle(String theBundleType) {
Bundle resp = new Bundle();
try {
resp.setType(Bundle.BundleType.fromCode(theBundleType));
} catch (FHIRException theE) {
throw new InternalErrorException(Msg.code(2151) + "Unknown bundle type: " + theBundleType);
}
return resp;
}
@Override
public List<Bundle.BundleEntryComponent> getEntries(Bundle theRequest) {
return theRequest.getEntry();
}
@Override
public void addEntry(Bundle theBundle, Bundle.BundleEntryComponent theEntry) {
theBundle.addEntry(theEntry);
}
@Override
public Bundle.BundleEntryComponent addEntry(Bundle theBundle) {
return theBundle.addEntry();
}
@Override
public String getEntryRequestVerb(FhirContext theContext, Bundle.BundleEntryComponent theEntry) {
String retVal = null;
Bundle.HTTPVerb value = theEntry.getRequest().getMethodElement().getValue();
if (value != null) {
retVal = value.toCode();
}
return retVal;
}
@Override
public String getFullUrl(Bundle.BundleEntryComponent theEntry) {
return theEntry.getFullUrl();
}
@Override
public void setFullUrl(Bundle.BundleEntryComponent theEntry, String theFullUrl) {
theEntry.setFullUrl(theFullUrl);
}
@Override
public String getEntryIfNoneExist(Bundle.BundleEntryComponent theEntry) {
return theEntry.getRequest().getIfNoneExist();
}
@Override
public String getEntryRequestUrl(Bundle.BundleEntryComponent theEntry) {
return theEntry.getRequest().getUrl();
}
@Override
public void setResponseLocation(Bundle.BundleEntryComponent theEntry, String theResponseLocation) {
theEntry.getResponse().setLocation(theResponseLocation);
}
@Override
public void setResponseETag(Bundle.BundleEntryComponent theEntry, String theEtag) {
theEntry.getResponse().setEtag(theEtag);
}
@Override
public String getEntryRequestIfMatch(Bundle.BundleEntryComponent theEntry) {
return theEntry.getRequest().getIfMatch();
}
@Override
public String getEntryRequestIfNoneExist(Bundle.BundleEntryComponent theEntry) {
return theEntry.getRequest().getIfNoneExist();
}
@Override
public String getEntryRequestIfNoneMatch(Bundle.BundleEntryComponent theEntry) {
return theEntry.getRequest().getIfNoneMatch();
}
@Override
public void setResponseOutcome(Bundle.BundleEntryComponent theEntry, IBaseOperationOutcome theOperationOutcome) {
theEntry.getResponse().setOutcome((Resource) theOperationOutcome);
}
@Override
public void setRequestVerb(Bundle.BundleEntryComponent theEntry, String theVerb) {
theEntry.getRequest().setMethod(Bundle.HTTPVerb.fromCode(theVerb));
}
@Override
public void setRequestUrl(Bundle.BundleEntryComponent theEntry, String theUrl) {
theEntry.getRequest().setUrl(theUrl);
}
}

View File

@ -1,101 +0,0 @@
package ca.uhn.fhir.jpa.dao.r5;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.interceptor.model.RequestPartitionId;
import ca.uhn.fhir.jpa.api.dao.PatientEverythingParameters;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum;
import ca.uhn.fhir.rest.api.CacheControlDirective;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.*;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r5.model.Patient;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Collections;
public class FhirResourceDaoPatientR5 extends BaseHapiFhirResourceDao<Patient> implements IFhirResourceDaoPatient<Patient> {
@Autowired
private IRequestPartitionHelperSvc myPartitionHelperSvc;
private IBundleProvider doEverythingOperation(TokenOrListParam theId, IPrimitiveType<Integer> theCount, IPrimitiveType<Integer> theOffset, DateRangeParam theLastUpdated, SortSpec theSort, StringAndListParam theContent, StringAndListParam theNarrative, StringAndListParam theTypes, RequestDetails theRequest) {
SearchParameterMap paramMap = new SearchParameterMap();
if (theCount != null) {
paramMap.setCount(theCount.getValue());
}
if (theOffset != null) {
throw new IllegalArgumentException(Msg.code(1122) + "Everything operation does not support offset searching");
}
if (theContent != null) {
paramMap.add(Constants.PARAM_CONTENT, theContent);
}
if (theNarrative != null) {
paramMap.add(Constants.PARAM_TEXT, theNarrative);
}
if (theTypes != null) {
paramMap.add(Constants.PARAM_TYPE, theTypes);
}
paramMap.setIncludes(Collections.singleton(IBaseResource.INCLUDE_ALL.asRecursive()));
paramMap.setEverythingMode(theId != null ? EverythingModeEnum.PATIENT_INSTANCE : EverythingModeEnum.PATIENT_TYPE);
paramMap.setSort(theSort);
paramMap.setLastUpdated(theLastUpdated);
if (theId != null) {
if (theRequest.getParameters().containsKey("_mdm")) {
String[] paramVal = theRequest.getParameters().get("_mdm");
if (Arrays.asList(paramVal).contains("true")) {
theId.getValuesAsQueryTokens().stream().forEach(param -> param.setMdmExpand(true));
}
}
paramMap.add("_id", theId);
}
if (!isPagingProviderDatabaseBacked(theRequest)) {
paramMap.setLoadSynchronous(true);
}
RequestPartitionId requestPartitionId = myPartitionHelperSvc.determineReadPartitionForRequestForSearchType(theRequest, getResourceName(), paramMap, null);
return mySearchCoordinatorSvc.registerSearch(this, paramMap, getResourceName(), new CacheControlDirective().parse(theRequest.getHeaders(Constants.HEADER_CACHE_CONTROL)), theRequest, requestPartitionId);
}
@Override
public IBundleProvider patientInstanceEverything(HttpServletRequest theServletRequest, RequestDetails theRequestDetails, PatientEverythingParameters theQueryParams, IIdType theId) {
TokenOrListParam id = new TokenOrListParam().add(new TokenParam(theId.getIdPart()));
return doEverythingOperation(id, theQueryParams.getCount(), theQueryParams.getOffset(), theQueryParams.getLastUpdated(), theQueryParams.getSort(), theQueryParams.getContent(), theQueryParams.getNarrative(), theQueryParams.getTypes(), theRequestDetails);
}
@Override
public IBundleProvider patientTypeEverything(HttpServletRequest theServletRequest, RequestDetails theRequestDetails, PatientEverythingParameters theQueryParams, TokenOrListParam theId) {
return doEverythingOperation(theId, theQueryParams.getCount(), theQueryParams.getOffset(), theQueryParams.getLastUpdated(), theQueryParams.getSort(), theQueryParams.getContent(), theQueryParams.getNarrative(), theQueryParams.getTypes(), theRequestDetails);
}
}

View File

@ -1,87 +0,0 @@
package ca.uhn.fhir.jpa.dao.r5;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao;
import org.hl7.fhir.r5.model.QuestionnaireResponse;
public class FhirResourceDaoQuestionnaireResponseR5 extends BaseHapiFhirResourceDao<QuestionnaireResponse> {
// @Override
// protected void validateResourceForStorage(QuestionnaireResponse theResource, ResourceTable theEntityToSave, RequestDetails theRequestDetails) {
// super.validateResourceForStorage(theResource, theEntityToSave, theRequestDetails);
// if (!myValidateResponses) {
// return;
// }
//
// if (theResource == null || theResource.getQuestionnaire() == null || theResource.getQuestionnaire().getReference() == null || theResource.getQuestionnaire().getReference().isEmpty()) {
// return;
// }
//
// FhirValidator val = getContext().newValidator();
// val.setValidateAgainstStandardSchema(false);
// val.setValidateAgainstStandardSchematron(false);
//
// val.registerValidatorModule(myQuestionnaireResponseValidatorR5);
//
// ValidationResult result = val.validateWithResult(getContext().newJsonParser().parseResource(getContext().newJsonParser().encodeResourceToString(theResource)));
// if (!result.isSuccessful()) {
// IBaseOperationOutcome oo = getContext().newJsonParser().parseResource(OperationOutcome.class, getContext().newJsonParser().encodeResourceToString(result.toOperationOutcome()));
// throw new UnprocessableEntityException(Msg.code(1123) + getContext(), oo);
// }
// }
//
// public class ResourceLoaderImpl implements IResourceLoader {
//
// private RequestDetails myRequestDetails;
//
// public ResourceLoaderImpl(RequestDetails theRequestDetails) {
// super();
// myRequestDetails = theRequestDetails;
// }
//
// @Override
// public <T extends IBaseResource> T load(Class<T> theType, IIdType theId) throws ResourceNotFoundException {
//
// /*
// * The QuestionnaireResponse validator uses RI structures, so for now we need to convert between that and HAPI
// * structures. This is a bit hackish, but hopefully it will go away at some point.
// */
// if ("ValueSet".equals(theType.getSimpleName())) {
// IFhirResourceDao<ValueSet> dao = getDao(ValueSet.class);
// ValueSet in = dao.read(theId, myRequestDetails);
// return (T) in;
// } else if ("Questionnaire".equals(theType.getSimpleName())) {
// IFhirResourceDao<Questionnaire> dao = getDao(Questionnaire.class);
// Questionnaire vs = dao.read(theId, myRequestDetails);
// return (T) vs;
// } else {
// // Should not happen, validator will only ask for these two
// throw new IllegalStateException(Msg.code(1124) + "Unexpected request to load resource of type " + theType);
// }
//
// }
//
// }
}

View File

@ -43,6 +43,7 @@ import org.springframework.retry.backoff.FixedBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy; import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate; import org.springframework.retry.support.RetryTemplate;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate; import org.springframework.transaction.support.TransactionTemplate;
import java.util.Collections; import java.util.Collections;
@ -54,21 +55,29 @@ import java.util.List;
* Specifically, this class spawns an inner transaction for each {@link DeleteConflictList}. This class is meant to handle any potential delete collisions (ex {@link ResourceGoneException} or {@link ResourceVersionConflictException}. In the former case, we swallow the Exception in the inner transaction then continue. In the latter case, we retry according to the RETRY_BACKOFF_PERIOD and RETRY_MAX_ATTEMPTS before giving up. * Specifically, this class spawns an inner transaction for each {@link DeleteConflictList}. This class is meant to handle any potential delete collisions (ex {@link ResourceGoneException} or {@link ResourceVersionConflictException}. In the former case, we swallow the Exception in the inner transaction then continue. In the latter case, we retry according to the RETRY_BACKOFF_PERIOD and RETRY_MAX_ATTEMPTS before giving up.
*/ */
public class ThreadSafeResourceDeleterSvc { public class ThreadSafeResourceDeleterSvc {
private static final String REQ_DET_KEY_IN_NEW_TRANSACTION = ThreadSafeResourceDeleterSvc.class.getName() + "REQ_DET_KEY_IN_NEW_TRANSACTION";
public static final long RETRY_BACKOFF_PERIOD = 100L; public static final long RETRY_BACKOFF_PERIOD = 100L;
public static final int RETRY_MAX_ATTEMPTS = 4; public static final int RETRY_MAX_ATTEMPTS = 4;
private static final Logger ourLog = LoggerFactory.getLogger(ThreadSafeResourceDeleterSvc.class); private static final Logger ourLog = LoggerFactory.getLogger(ThreadSafeResourceDeleterSvc.class);
private final DaoRegistry myDaoRegistry; private final DaoRegistry myDaoRegistry;
private final IInterceptorBroadcaster myInterceptorBroadcaster; private final IInterceptorBroadcaster myInterceptorBroadcaster;
private final TransactionTemplate myTxTemplate; private final TransactionTemplate myTxTemplateRequired;
private final TransactionTemplate myTxTemplateRequiresNew;
private final RetryTemplate myRetryTemplate = getRetryTemplate(); private final RetryTemplate myRetryTemplate = getRetryTemplate();
public ThreadSafeResourceDeleterSvc(DaoRegistry theDaoRegistry, IInterceptorBroadcaster theInterceptorBroadcaster, PlatformTransactionManager thePlatformTransactionManager) { public ThreadSafeResourceDeleterSvc(DaoRegistry theDaoRegistry, IInterceptorBroadcaster theInterceptorBroadcaster, PlatformTransactionManager thePlatformTransactionManager) {
myDaoRegistry = theDaoRegistry; myDaoRegistry = theDaoRegistry;
myInterceptorBroadcaster = theInterceptorBroadcaster; myInterceptorBroadcaster = theInterceptorBroadcaster;
myTxTemplate = new TransactionTemplate(thePlatformTransactionManager);
myTxTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRES_NEW); myTxTemplateRequired = new TransactionTemplate(thePlatformTransactionManager);
myTxTemplateRequired.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
myTxTemplateRequiresNew = new TransactionTemplate(thePlatformTransactionManager);
myTxTemplateRequiresNew.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
} }
/** /**
@ -99,15 +108,36 @@ public class ThreadSafeResourceDeleterSvc {
// We will retry deletes on any occurrence of ResourceVersionConflictException up to RETRY_MAX_ATTEMPTS // We will retry deletes on any occurrence of ResourceVersionConflictException up to RETRY_MAX_ATTEMPTS
return myRetryTemplate.execute(retryContext -> { return myRetryTemplate.execute(retryContext -> {
String previousNewTransactionValue = null;
if (theRequest != null) {
previousNewTransactionValue = (String) theRequest.getUserData().get(REQ_DET_KEY_IN_NEW_TRANSACTION);
}
try { try {
if (retryContext.getRetryCount() > 0) { if (retryContext.getRetryCount() > 0) {
ourLog.info("Retrying delete of {} - Attempt #{}", nextSourceId, retryContext.getRetryCount()); ourLog.info("Retrying delete of {} - Attempt #{}", nextSourceId, retryContext.getRetryCount());
} }
myTxTemplate.execute(s -> doDelete(theRequest, theConflictList, theTransactionDetails, nextSource, dao));
// Avoid nesting multiple new transactions deep. This can easily cause
// thread pools to get exhausted.
if (theRequest == null || previousNewTransactionValue != null) {
myTxTemplateRequired.execute(s -> doDelete(theRequest, theConflictList, theTransactionDetails, nextSource, dao));
} else {
theRequest.getUserData().put(REQ_DET_KEY_IN_NEW_TRANSACTION, REQ_DET_KEY_IN_NEW_TRANSACTION);
myTxTemplateRequiresNew.execute(s -> doDelete(theRequest, theConflictList, theTransactionDetails, nextSource, dao));
}
return 1; return 1;
} catch (ResourceGoneException exception) { } catch (ResourceGoneException exception) {
ourLog.info("{} is already deleted. Skipping cascade delete of this resource", nextSourceId); ourLog.info("{} is already deleted. Skipping cascade delete of this resource", nextSourceId);
} finally {
if (theRequest != null) {
theRequest.getUserData().put(REQ_DET_KEY_IN_NEW_TRANSACTION, previousNewTransactionValue);
}
} }
return 0; return 0;
}); });
} }

View File

@ -0,0 +1,179 @@
package ca.uhn.fhir.jpa.provider;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.context.support.ConceptValidationOptions;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.validation.JpaValidationSupportChain;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.common.hapi.validation.support.InMemoryTerminologyServerValidationSupport;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseCoding;
import org.hl7.fhir.instance.model.api.IBaseParameters;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
public abstract class BaseJpaResourceProviderCodeSystem<T extends IBaseResource> extends BaseJpaResourceProvider<T> {
@Autowired
private JpaValidationSupportChain myValidationSupportChain;
/**
* $lookup operation
*/
@SuppressWarnings("unchecked")
@Operation(name = JpaConstants.OPERATION_LOOKUP, idempotent = true, returnParameters = {
@OperationParam(name = "name", typeName = "string", min = 1),
@OperationParam(name = "version", typeName = "string", min = 0),
@OperationParam(name = "display", typeName = "string", min = 1),
@OperationParam(name = "abstract", typeName = "boolean", min = 1),
})
public IBaseParameters lookup(
HttpServletRequest theServletRequest,
@OperationParam(name = "code", min = 0, max = 1, typeName = "code") IPrimitiveType<String> theCode,
@OperationParam(name = "system", min = 0, max = 1, typeName = "uri") IPrimitiveType<String> theSystem,
@OperationParam(name = "coding", min = 0, max = 1, typeName = "Coding") IBaseCoding theCoding,
@OperationParam(name = "version", min = 0, max = 1, typeName = "string") IPrimitiveType<String> theVersion,
@OperationParam(name = "displayLanguage", min = 0, max = 1, typeName = "code") IPrimitiveType<String> theDisplayLanguage,
@OperationParam(name = "property", min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "code") List<IPrimitiveType<String>> theProperties,
RequestDetails theRequestDetails
) {
startRequest(theServletRequest);
try {
IFhirResourceDaoCodeSystem dao = (IFhirResourceDaoCodeSystem) getDao();
IValidationSupport.LookupCodeResult result;
applyVersionToSystem(theSystem, theVersion);
result = dao.lookupCode(theCode, theSystem, theCoding, theDisplayLanguage, theRequestDetails);
result.throwNotFoundIfAppropriate();
return result.toParameters(theRequestDetails.getFhirContext(), theProperties);
} finally {
endRequest(theServletRequest);
}
}
/**
* $subsumes operation
*/
@Operation(name = JpaConstants.OPERATION_SUBSUMES, idempotent = true, returnParameters = {
@OperationParam(name = "outcome", typeName = "code", min = 1),
})
public IBaseParameters subsumes(
HttpServletRequest theServletRequest,
@OperationParam(name = "codeA", min = 0, max = 1, typeName = "code") IPrimitiveType<String> theCodeA,
@OperationParam(name = "codeB", min = 0, max = 1, typeName = "code") IPrimitiveType<String> theCodeB,
@OperationParam(name = "system", min = 0, max = 1, typeName = "uri") IPrimitiveType<String> theSystem,
@OperationParam(name = "codingA", min = 0, max = 1, typeName = "Coding") IBaseCoding theCodingA,
@OperationParam(name = "codingB", min = 0, max = 1, typeName = "Coding") IBaseCoding theCodingB,
@OperationParam(name = "version", min = 0, max = 1, typeName = "string") IPrimitiveType<String> theVersion,
RequestDetails theRequestDetails
) {
startRequest(theServletRequest);
try {
IFhirResourceDaoCodeSystem dao = (IFhirResourceDaoCodeSystem) getDao();
IFhirResourceDaoCodeSystem.SubsumesResult result;
applyVersionToSystem(theSystem, theVersion);
result = dao.subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB, theRequestDetails);
return result.toParameters(theRequestDetails.getFhirContext());
} finally {
endRequest(theServletRequest);
}
}
private static void applyVersionToSystem(IPrimitiveType<String> theSystem, IPrimitiveType<String> theVersion) {
if (theVersion != null && isNotBlank(theVersion.getValueAsString()) && theSystem != null) {
theSystem.setValue(theSystem.getValueAsString() + "|" + theVersion.getValueAsString());
}
}
/**
* $validate-code operation
*/
@SuppressWarnings("unchecked")
@Operation(name = JpaConstants.OPERATION_VALIDATE_CODE, idempotent = true, returnParameters = {
@OperationParam(name = "result", typeName = "boolean", min = 1),
@OperationParam(name = "message", typeName = "string"),
@OperationParam(name = "display", typeName = "string")
})
public IBaseParameters validateCode(
HttpServletRequest theServletRequest,
@IdParam(optional = true) IIdType theId,
@OperationParam(name = "url", min = 0, max = 1, typeName = "uri") IPrimitiveType<String> theCodeSystemUrl,
@OperationParam(name = "version", min = 0, max = 1, typeName = "string") IPrimitiveType<String> theVersion,
@OperationParam(name = "code", min = 0, max = 1, typeName = "code") IPrimitiveType<String> theCode,
@OperationParam(name = "display", min = 0, max = 1, typeName = "string") IPrimitiveType<String> theDisplay,
@OperationParam(name = "coding", min = 0, max = 1, typeName = "Coding") IBaseCoding theCoding,
@OperationParam(name = "codeableConcept", min = 0, max = 1, typeName = "CodeableConcept") IBase theCodeableConcept,
RequestDetails theRequestDetails
) {
IValidationSupport.CodeValidationResult result = null;
startRequest(theServletRequest);
try {
// TODO: JA why not just always just the chain here? and we can then get rid of the corresponding DAO method entirely
// If a Remote Terminology Server has been configured, use it
if (myValidationSupportChain.isRemoteTerminologyServiceConfigured()) {
String codeSystemUrl = (theCodeSystemUrl != null && theCodeSystemUrl.hasValue()) ?
theCodeSystemUrl.getValueAsString() : null;
if (theCoding != null) {
if (isNotBlank(theCoding.getSystem())) {
if (codeSystemUrl != null && !codeSystemUrl.equalsIgnoreCase(theCoding.getSystem())) {
throw new InvalidRequestException(Msg.code(1160) + "Coding.system '" + theCoding.getSystem() + "' does not equal param url '" + theCodeSystemUrl + "'. Unable to validate-code.");
}
codeSystemUrl = theCoding.getSystem();
String code = theCoding.getCode();
String display = theCoding.getDisplay();
result = myValidationSupportChain.validateCode(
new ValidationSupportContext(myValidationSupportChain), new ConceptValidationOptions(),
codeSystemUrl, code, display, null);
}
}
} else {
// Otherwise, use the local DAO layer to validate the code
IFhirResourceDaoCodeSystem dao = (IFhirResourceDaoCodeSystem) getDao();
result = dao.validateCode(theId, theCodeSystemUrl, theVersion, theCode, theDisplay, theCoding, theCodeableConcept, theRequestDetails);
}
return BaseJpaResourceProviderValueSetDstu2.toValidateCodeResult(getContext(), result);
} finally {
endRequest(theServletRequest);
}
}
}

View File

@ -1,4 +1,4 @@
package ca.uhn.fhir.jpa.provider.r5; package ca.uhn.fhir.jpa.provider;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoComposition; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoComposition;
import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.model.util.JpaConstants;
@ -13,9 +13,10 @@ import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.param.DateRangeParam;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r5.model.Composition; import org.hl7.fhir.r5.model.Composition;
import org.hl7.fhir.r5.model.IdType;
import org.hl7.fhir.r5.model.UnsignedIntType;
/* /*
@ -38,36 +39,36 @@ import org.hl7.fhir.r5.model.UnsignedIntType;
* #L% * #L%
*/ */
public abstract class BaseJpaResourceProviderCompositionR5 extends JpaResourceProviderR5<Composition> { public abstract class BaseJpaResourceProviderComposition<T extends IBaseResource> extends BaseJpaResourceProvider<T> {
/** /**
* Composition/123/$document * Composition/123/$document
*/ */
@Operation(name = JpaConstants.OPERATION_DOCUMENT, idempotent = true, bundleType=BundleTypeEnum.DOCUMENT) @Operation(name = JpaConstants.OPERATION_DOCUMENT, idempotent = true, bundleType = BundleTypeEnum.DOCUMENT)
public IBundleProvider getDocumentForComposition( public IBundleProvider getDocumentForComposition(
javax.servlet.http.HttpServletRequest theServletRequest, javax.servlet.http.HttpServletRequest theServletRequest,
@IdParam @IdParam
IdType theId, IIdType theId,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.") @Description(formalDefinition = "Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT) @OperationParam(name = Constants.PARAM_COUNT, typeName = "unsignedInt")
UnsignedIntType theCount, IPrimitiveType<Integer> theCount,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.") @Description(formalDefinition = "Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
@OperationParam(name = Constants.PARAM_OFFSET) @OperationParam(name = Constants.PARAM_OFFSET, typeName = "unsignedInt")
UnsignedIntType theOffset, IPrimitiveType<Integer> theOffset,
@Description(shortDefinition="Only return resources which were last updated as specified by the given range") @Description(shortDefinition = "Only return resources which were last updated as specified by the given range")
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1) @OperationParam(name = Constants.PARAM_LASTUPDATED, min = 0, max = 1)
DateRangeParam theLastUpdated, DateRangeParam theLastUpdated,
@Sort @Sort
SortSpec theSortSpec, SortSpec theSortSpec,
RequestDetails theRequestDetails RequestDetails theRequestDetails
) { ) {
startRequest(theServletRequest); startRequest(theServletRequest);
try { try {

View File

@ -1,49 +0,0 @@
package ca.uhn.fhir.jpa.provider;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoComposition;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.model.dstu2.resource.Composition;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public abstract class BaseJpaResourceProviderCompositionDstu2 extends JpaResourceProviderDstu2<Composition> {
/**
* Composition/123/$document
*/
//@formatter:off
@Operation(name = JpaConstants.OPERATION_DOCUMENT, idempotent = true, bundleType=BundleTypeEnum.DOCUMENT)
public IBundleProvider getDocumentForComposition(
javax.servlet.http.HttpServletRequest theServletRequest) {
//@formatter:on
startRequest(theServletRequest);
try {
return ((IFhirResourceDaoComposition<Composition>)getDao()).getDocumentForComposition(theServletRequest, null, null, null, null, null, null);
} finally {
endRequest(theServletRequest);
}
}
}

View File

@ -0,0 +1,109 @@
package ca.uhn.fhir.jpa.provider;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoEncounter;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.Sort;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.DateRangeParam;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public abstract class BaseJpaResourceProviderEncounter<T extends IBaseResource> extends BaseJpaResourceProvider<T> {
/**
* Encounter/123/$everything
*/
@Operation(name = JpaConstants.OPERATION_EVERYTHING, idempotent = true, bundleType = BundleTypeEnum.SEARCHSET)
public IBundleProvider EncounterInstanceEverything(
javax.servlet.http.HttpServletRequest theServletRequest,
@IdParam
IIdType theId,
@Description(formalDefinition = "Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT, typeName = "unsignedInt")
IPrimitiveType<Integer> theCount,
@Description(formalDefinition = "Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
@OperationParam(name = Constants.PARAM_OFFSET, typeName = "unsignedInt")
IPrimitiveType<Integer> theOffset,
@Description(shortDefinition = "Only return resources which were last updated as specified by the given range")
@OperationParam(name = Constants.PARAM_LASTUPDATED, min = 0, max = 1)
DateRangeParam theLastUpdated,
@Sort
SortSpec theSortSpec
) {
startRequest(theServletRequest);
try {
return ((IFhirResourceDaoEncounter<?>) getDao()).encounterInstanceEverything(theServletRequest, theId, theCount, theOffset, theLastUpdated, theSortSpec);
} finally {
endRequest(theServletRequest);
}
}
/**
* /Encounter/$everything
*/
@Operation(name = JpaConstants.OPERATION_EVERYTHING, idempotent = true, bundleType = BundleTypeEnum.SEARCHSET)
public IBundleProvider EncounterTypeEverything(
javax.servlet.http.HttpServletRequest theServletRequest,
@Description(formalDefinition = "Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT, typeName = "unsignedInt")
IPrimitiveType<Integer> theCount,
@Description(formalDefinition = "Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
@OperationParam(name = Constants.PARAM_OFFSET, typeName = "unsignedInt")
IPrimitiveType<Integer> theOffset,
@Description(shortDefinition = "Only return resources which were last updated as specified by the given range")
@OperationParam(name = Constants.PARAM_LASTUPDATED, min = 0, max = 1)
DateRangeParam theLastUpdated,
@Sort
SortSpec theSortSpec
) {
startRequest(theServletRequest);
try {
return ((IFhirResourceDaoEncounter<?>) getDao()).encounterTypeEverything(theServletRequest, theCount, theOffset, theLastUpdated, theSortSpec);
} finally {
endRequest(theServletRequest);
}
}
}

View File

@ -1,27 +0,0 @@
package ca.uhn.fhir.jpa.provider;
import ca.uhn.fhir.model.dstu2.resource.MessageHeader;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public abstract class BaseJpaResourceProviderMessageHeaderDstu2 extends JpaResourceProviderDstu2<MessageHeader> {
// nothing now
}

View File

@ -1,4 +1,4 @@
package ca.uhn.fhir.jpa.provider.r5; package ca.uhn.fhir.jpa.provider;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoObservation; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoObservation;
import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.model.util.JpaConstants;
@ -13,9 +13,8 @@ import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.DateAndListParam; import ca.uhn.fhir.rest.param.DateAndListParam;
import ca.uhn.fhir.rest.param.ReferenceAndListParam; import ca.uhn.fhir.rest.param.ReferenceAndListParam;
import ca.uhn.fhir.rest.param.TokenAndListParam; import ca.uhn.fhir.rest.param.TokenAndListParam;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r5.model.Observation;
import org.hl7.fhir.r5.model.UnsignedIntType;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -40,7 +39,7 @@ import java.util.Map;
* #L% * #L%
*/ */
public abstract class BaseJpaResourceProviderObservationR5 extends JpaResourceProviderR5<Observation> { public abstract class BaseJpaResourceProviderObservation<T extends IBaseResource> extends BaseJpaResourceProvider<T> {
/** /**
* Observation/$lastn * Observation/$lastn
@ -54,8 +53,8 @@ public abstract class BaseJpaResourceProviderObservationR5 extends JpaResourcePr
ca.uhn.fhir.rest.api.server.RequestDetails theRequestDetails, ca.uhn.fhir.rest.api.server.RequestDetails theRequestDetails,
@Description(formalDefinition = "Results from this method are returned across multiple pages. This parameter controls the size of those pages.") @Description(formalDefinition = "Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT) @OperationParam(name = Constants.PARAM_COUNT, typeName = "unsignedInt")
UnsignedIntType theCount, IPrimitiveType<Integer> theCount,
@Description(shortDefinition="The classification of the type of observation") @Description(shortDefinition="The classification of the type of observation")
@OperationParam(name="category") @OperationParam(name="category")
@ -105,7 +104,7 @@ public abstract class BaseJpaResourceProviderObservationR5 extends JpaResourcePr
getDao().translateRawParameters(theAdditionalRawParams, paramMap); getDao().translateRawParameters(theAdditionalRawParams, paramMap);
return ((IFhirResourceDaoObservation<Observation>) getDao()).observationsLastN(paramMap, theRequestDetails, theServletResponse); return ((IFhirResourceDaoObservation<?>) getDao()).observationsLastN(paramMap, theRequestDetails, theServletResponse);
} finally { } finally {
endRequest(theServletRequest); endRequest(theServletRequest);
} }

View File

@ -1,9 +1,10 @@
package ca.uhn.fhir.jpa.provider.r5; package ca.uhn.fhir.jpa.provider;
import ca.uhn.fhir.jpa.api.dao.PatientEverythingParameters;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient;
import ca.uhn.fhir.jpa.api.dao.PatientEverythingParameters;
import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.model.api.annotation.Description; import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.IdParam; import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation; import ca.uhn.fhir.rest.annotation.Operation;
@ -19,10 +20,9 @@ import ca.uhn.fhir.rest.param.StringOrListParam;
import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.TokenOrListParam; import ca.uhn.fhir.rest.param.TokenOrListParam;
import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.TokenParam;
import org.hl7.fhir.r5.model.IdType; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r5.model.Patient; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r5.model.StringType; import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r5.model.UnsignedIntType;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -49,46 +49,46 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
* #L% * #L%
*/ */
public abstract class BaseJpaResourceProviderPatientR5 extends JpaResourceProviderR5<Patient> { public abstract class BaseJpaResourceProviderPatient<T extends IBaseResource> extends BaseJpaResourceProvider<T> {
/** /**
* Patient/123/$everything * Patient/123/$everything
*/ */
@Operation(name = JpaConstants.OPERATION_EVERYTHING, idempotent = true, bundleType = BundleTypeEnum.SEARCHSET) @Operation(name = JpaConstants.OPERATION_EVERYTHING, canonicalUrl = "http://hl7.org/fhir/OperationDefinition/Patient-everything", idempotent = true, bundleType = BundleTypeEnum.SEARCHSET)
public IBundleProvider patientInstanceEverything( public IBundleProvider patientInstanceEverything(
javax.servlet.http.HttpServletRequest theServletRequest, javax.servlet.http.HttpServletRequest theServletRequest,
@IdParam @IdParam
IdType theId, IIdType theId,
@Description(formalDefinition = "Results from this method are returned across multiple pages. This parameter controls the size of those pages.") @Description(shortDefinition = "Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT) @OperationParam(name = Constants.PARAM_COUNT, typeName = "unsignedInt")
UnsignedIntType theCount, IPrimitiveType<Integer> theCount,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.") @Description(shortDefinition = "Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
@OperationParam(name = Constants.PARAM_OFFSET) @OperationParam(name = Constants.PARAM_OFFSET, typeName = "unsignedInt")
UnsignedIntType theOffset, IPrimitiveType<Integer> theOffset,
@Description(shortDefinition = "Only return resources which were last updated as specified by the given range") @Description(shortDefinition = "Only return resources which were last updated as specified by the given range")
@OperationParam(name = Constants.PARAM_LASTUPDATED, min = 0, max = 1) @OperationParam(name = Constants.PARAM_LASTUPDATED, min = 0, max = 1)
DateRangeParam theLastUpdated, DateRangeParam theLastUpdated,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _content filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)") @Description(shortDefinition = "Filter the resources to return only resources matching the given _content filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_CONTENT, min = 0, max = OperationParam.MAX_UNLIMITED) @OperationParam(name = Constants.PARAM_CONTENT, min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "string")
List<StringType> theContent, List<IPrimitiveType<String>> theContent,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _text filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)") @Description(shortDefinition = "Filter the resources to return only resources matching the given _text filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_TEXT, min = 0, max = OperationParam.MAX_UNLIMITED) @OperationParam(name = Constants.PARAM_TEXT, min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "string")
List<StringType> theNarrative, List<IPrimitiveType<String>> theNarrative,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _filter filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)") @Description(shortDefinition = "Filter the resources to return only resources matching the given _filter filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED) @OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "string")
List<StringType> theFilter, List<IPrimitiveType<String>> theFilter,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _type filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)") @Description(shortDefinition = "Filter the resources to return only resources matching the given _type filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_TYPE, min = 0, max = OperationParam.MAX_UNLIMITED) @OperationParam(name = Constants.PARAM_TYPE, min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "string")
List<StringType> theTypes, List<IPrimitiveType<String>> theTypes,
@Sort @Sort
SortSpec theSortSpec, SortSpec theSortSpec,
@ -108,7 +108,7 @@ public abstract class BaseJpaResourceProviderPatientR5 extends JpaResourceProvid
everythingParams.setFilter(toStringAndList(theFilter)); everythingParams.setFilter(toStringAndList(theFilter));
everythingParams.setTypes(toStringAndList(theTypes)); everythingParams.setTypes(toStringAndList(theTypes));
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theRequestDetails, everythingParams, theId); return ((IFhirResourceDaoPatient<?>) getDao()).patientInstanceEverything(theServletRequest, theRequestDetails, everythingParams, theId);
} finally { } finally {
endRequest(theServletRequest); endRequest(theServletRequest);
} }
@ -117,43 +117,43 @@ public abstract class BaseJpaResourceProviderPatientR5 extends JpaResourceProvid
/** /**
* /Patient/$everything * /Patient/$everything
*/ */
@Operation(name = JpaConstants.OPERATION_EVERYTHING, idempotent = true, bundleType = BundleTypeEnum.SEARCHSET) @Operation(name = JpaConstants.OPERATION_EVERYTHING, canonicalUrl = "http://hl7.org/fhir/OperationDefinition/Patient-everything", idempotent = true, bundleType = BundleTypeEnum.SEARCHSET)
public IBundleProvider patientTypeEverything( public IBundleProvider patientTypeEverything(
javax.servlet.http.HttpServletRequest theServletRequest, javax.servlet.http.HttpServletRequest theServletRequest,
@Description(formalDefinition = "Results from this method are returned across multiple pages. This parameter controls the size of those pages.") @Description(shortDefinition = "Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT) @OperationParam(name = Constants.PARAM_COUNT, typeName = "unsignedInt")
UnsignedIntType theCount, IPrimitiveType<Integer> theCount,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.") @Description(shortDefinition = "Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
@OperationParam(name = Constants.PARAM_OFFSET) @OperationParam(name = Constants.PARAM_OFFSET, typeName = "unsignedInt")
UnsignedIntType theOffset, IPrimitiveType<Integer> theOffset,
@Description(shortDefinition = "Only return resources which were last updated as specified by the given range") @Description(shortDefinition = "Only return resources which were last updated as specified by the given range")
@OperationParam(name = Constants.PARAM_LASTUPDATED, min = 0, max = 1) @OperationParam(name = Constants.PARAM_LASTUPDATED, min = 0, max = 1)
DateRangeParam theLastUpdated, DateRangeParam theLastUpdated,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _content filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)") @Description(shortDefinition = "Filter the resources to return only resources matching the given _content filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_CONTENT, min = 0, max = OperationParam.MAX_UNLIMITED) @OperationParam(name = Constants.PARAM_CONTENT, min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "string")
List<StringType> theContent, List<IPrimitiveType<String>> theContent,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _text filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)") @Description(shortDefinition = "Filter the resources to return only resources matching the given _text filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_TEXT, min = 0, max = OperationParam.MAX_UNLIMITED) @OperationParam(name = Constants.PARAM_TEXT, min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "string")
List<StringType> theNarrative, List<IPrimitiveType<String>> theNarrative,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _filter filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)") @Description(shortDefinition = "Filter the resources to return only resources matching the given _filter filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED) @OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "string")
List<StringType> theFilter, List<IPrimitiveType<String>> theFilter,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _type filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)") @Description(shortDefinition = "Filter the resources to return only resources matching the given _type filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_TYPE, min = 0, max = OperationParam.MAX_UNLIMITED) @OperationParam(name = Constants.PARAM_TYPE, min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "string")
List<StringType> theTypes, List<IPrimitiveType<String>> theTypes,
@Description(shortDefinition = "Filter the resources to return based on the patient ids provided.") @Description(shortDefinition = "Filter the resources to return based on the patient ids provided.")
@OperationParam(name = Constants.PARAM_ID, min = 0, max = OperationParam.MAX_UNLIMITED) @OperationParam(name = Constants.PARAM_ID, min = 0, max = OperationParam.MAX_UNLIMITED, typeName = "id")
List<IdType> theId, List<IIdType> theId,
@Sort @Sort
SortSpec theSortSpec, SortSpec theSortSpec,
@ -173,7 +173,7 @@ public abstract class BaseJpaResourceProviderPatientR5 extends JpaResourceProvid
everythingParams.setFilter(toStringAndList(theFilter)); everythingParams.setFilter(toStringAndList(theFilter));
everythingParams.setTypes(toStringAndList(theTypes)); everythingParams.setTypes(toStringAndList(theTypes));
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theRequestDetails, everythingParams, toFlattenedPatientIdTokenParamList(theId)); return ((IFhirResourceDaoPatient<?>) getDao()).patientTypeEverything(theServletRequest, theRequestDetails, everythingParams, toFlattenedPatientIdTokenParamList(theId));
} finally { } finally {
endRequest(theServletRequest); endRequest(theServletRequest);
} }
@ -183,13 +183,13 @@ public abstract class BaseJpaResourceProviderPatientR5 extends JpaResourceProvid
/** /**
* Given a list of string types, return only the ID portions of any parameters passed in. * Given a list of string types, return only the ID portions of any parameters passed in.
*/ */
private TokenOrListParam toFlattenedPatientIdTokenParamList(List<IdType> theId) { private TokenOrListParam toFlattenedPatientIdTokenParamList(List<IIdType> theId) {
TokenOrListParam retVal = new TokenOrListParam(); TokenOrListParam retVal = new TokenOrListParam();
if (theId != null) { if (theId != null) {
for (IdType next: theId) { for (IIdType next : theId) {
if (isNotBlank(next.getValue())) { if (isNotBlank(next.getValue())) {
String[] split = next.getValueAsString().split(","); String[] split = next.getValueAsString().split(",");
Arrays.stream(split).map(IdType::new).forEach(id -> { Arrays.stream(split).map(IdDt::new).forEach(id -> {
retVal.addOr(new TokenParam(id.getIdPart())); retVal.addOr(new TokenParam(id.getIdPart()));
}); });
} }
@ -199,10 +199,10 @@ public abstract class BaseJpaResourceProviderPatientR5 extends JpaResourceProvid
return retVal.getValuesAsQueryTokens().isEmpty() ? null: retVal; return retVal.getValuesAsQueryTokens().isEmpty() ? null: retVal;
} }
private StringAndListParam toStringAndList(List<StringType> theNarrative) { private StringAndListParam toStringAndList(List<IPrimitiveType<String>> theNarrative) {
StringAndListParam retVal = new StringAndListParam(); StringAndListParam retVal = new StringAndListParam();
if (theNarrative != null) { if (theNarrative != null) {
for (StringType next : theNarrative) { for (IPrimitiveType<String> next : theNarrative) {
if (isNotBlank(next.getValue())) { if (isNotBlank(next.getValue())) {
retVal.addAnd(new StringOrListParam().addOr(new StringParam(next.getValue()))); retVal.addAnd(new StringOrListParam().addOr(new StringParam(next.getValue())));
} }

View File

@ -1,214 +0,0 @@
package ca.uhn.fhir.jpa.provider;
import ca.uhn.fhir.jpa.api.dao.PatientEverythingParameters;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.Sort;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.StringAndListParam;
import ca.uhn.fhir.rest.param.StringOrListParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.TokenOrListParam;
import ca.uhn.fhir.rest.param.TokenParam;
import java.util.Arrays;
import java.util.List;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public abstract class BaseJpaResourceProviderPatientDstu2 extends JpaResourceProviderDstu2<Patient> {
/**
* Patient/123/$everything
*/
@Operation(name = JpaConstants.OPERATION_EVERYTHING, idempotent = true, bundleType=BundleTypeEnum.SEARCHSET)
public IBundleProvider patientInstanceEverything(
javax.servlet.http.HttpServletRequest theServletRequest,
@IdParam
ca.uhn.fhir.model.primitive.IdDt theId,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT)
ca.uhn.fhir.model.primitive.UnsignedIntDt theCount,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
@OperationParam(name = Constants.PARAM_OFFSET)
ca.uhn.fhir.model.primitive.UnsignedIntDt theOffset,
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
DateRangeParam theLastUpdated,
@Description(shortDefinition="Filter the resources to return only resources matching the given _content filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_CONTENT, min=0, max=OperationParam.MAX_UNLIMITED)
List<StringDt> theContent,
@Description(shortDefinition="Filter the resources to return only resources matching the given _text filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_TEXT, min=0, max=OperationParam.MAX_UNLIMITED)
List<StringDt> theNarrative,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _filter filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringDt> theFilter,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _type filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_TYPE, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringDt> theTypes,
@Sort
SortSpec theSortSpec,
RequestDetails theRequestDetails
) {
startRequest(theServletRequest);
try {
PatientEverythingParameters everythingParams = new PatientEverythingParameters();
everythingParams.setCount(theCount);
everythingParams.setOffset(theOffset);
everythingParams.setLastUpdated(theLastUpdated);
everythingParams.setSort(theSortSpec);
everythingParams.setContent(toStringAndList(theContent));
everythingParams.setNarrative(toStringAndList(theNarrative));
everythingParams.setFilter(toStringAndList(theFilter));
everythingParams.setTypes(toStringAndList(theTypes));
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theRequestDetails, everythingParams, theId);
} finally {
endRequest(theServletRequest);
}
}
/**
* /Patient/$everything
*/
@Operation(name = JpaConstants.OPERATION_EVERYTHING, idempotent = true, bundleType=BundleTypeEnum.SEARCHSET)
public IBundleProvider patientTypeEverything(
javax.servlet.http.HttpServletRequest theServletRequest,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT)
ca.uhn.fhir.model.primitive.UnsignedIntDt theCount,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
@OperationParam(name = Constants.PARAM_OFFSET)
ca.uhn.fhir.model.primitive.UnsignedIntDt theOffset,
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
DateRangeParam theLastUpdated,
@Description(shortDefinition="Filter the resources to return only resources matching the given _content filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_CONTENT, min=0, max=OperationParam.MAX_UNLIMITED)
List<StringDt> theContent,
@Description(shortDefinition="Filter the resources to return only resources matching the given _text filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_TEXT, min=0, max=OperationParam.MAX_UNLIMITED)
List<StringDt> theNarrative,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _filter filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringDt> theFilter,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _type filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_TYPE, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringDt> theTypes,
@Description(shortDefinition = "Filter the resources to return based on the patient ids provided.")
@OperationParam(name = Constants.PARAM_ID, min = 0, max = OperationParam.MAX_UNLIMITED)
List<IdDt> theId,
@Sort
SortSpec theSortSpec,
RequestDetails theRequestDetails
) {
startRequest(theServletRequest);
try {
PatientEverythingParameters everythingParams = new PatientEverythingParameters();
everythingParams.setCount(theCount);
everythingParams.setOffset(theOffset);
everythingParams.setLastUpdated(theLastUpdated);
everythingParams.setSort(theSortSpec);
everythingParams.setContent(toStringAndList(theContent));
everythingParams.setNarrative(toStringAndList(theNarrative));
everythingParams.setFilter(toStringAndList(theFilter));
everythingParams.setTypes(toStringAndList(theTypes));
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theRequestDetails, everythingParams, toFlattenedPatientIdTokenParamList(theId));
} finally {
endRequest(theServletRequest);
}
}
/**
* Given a list of string types, return only the ID portions of any parameters passed in.
*/
private TokenOrListParam toFlattenedPatientIdTokenParamList(List<IdDt> theId) {
TokenOrListParam retVal = new TokenOrListParam();
if (theId != null) {
for (IdDt next : theId) {
if (isNotBlank(next.getValue())) {
String[] split = next.getValueAsString().split(",");
Arrays.stream(split).map(IdDt::new).forEach(id -> {
retVal.addOr(new TokenParam(id.getIdPart()));
});
}
}
}
return retVal.getValuesAsQueryTokens().isEmpty() ? null: retVal;
}
private StringAndListParam toStringAndList(List<StringDt> theNarrative) {
StringAndListParam retVal = new StringAndListParam();
if (theNarrative != null) {
for (StringDt next : theNarrative) {
if (isNotBlank(next.getValue())) {
retVal.addAnd(new StringOrListParam().addOr(new StringParam(next.getValue())));
}
}
}
if (retVal.getValuesAsQueryTokens().isEmpty()) {
return null;
}
return retVal;
}
}

View File

@ -1,4 +1,4 @@
package ca.uhn.fhir.jpa.provider.r5; package ca.uhn.fhir.jpa.provider;
import ca.uhn.fhir.i18n.Msg; import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoStructureDefinition; import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoStructureDefinition;
@ -12,9 +12,9 @@ import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.UriParam; import ca.uhn.fhir.rest.param.UriParam;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.util.ValidateUtil; import ca.uhn.fhir.util.ValidateUtil;
import org.hl7.fhir.r5.model.IdType; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r5.model.StringType; import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r5.model.StructureDefinition; import org.hl7.fhir.instance.model.api.IPrimitiveType;
/* /*
* #%L * #%L
@ -36,16 +36,16 @@ import org.hl7.fhir.r5.model.StructureDefinition;
* #L% * #L%
*/ */
public abstract class BaseJpaResourceProviderStructureDefinitionR5 extends JpaResourceProviderR5<StructureDefinition> { public abstract class BaseJpaResourceProviderStructureDefinition<T extends IBaseResource> extends BaseJpaResourceProvider<T> {
/** /**
* <code>$snapshot</code> operation * <code>$snapshot</code> operation
*/ */
@Operation(name=JpaConstants.OPERATION_SNAPSHOT, idempotent = true) @Operation(name=JpaConstants.OPERATION_SNAPSHOT, idempotent = true)
public StructureDefinition snapshot( public IBaseResource snapshot(
@IdParam(optional = true) IdType theId, @IdParam(optional = true) IIdType theId,
@OperationParam(name = "definition") StructureDefinition theStructureDefinition, @OperationParam(name = "definition", typeName = "StructureDefinition") IBaseResource theStructureDefinition,
@OperationParam(name = "url") StringType theUrl, @OperationParam(name = "url", typeName = "string") IPrimitiveType<String> theUrl,
RequestDetails theRequestDetails) { RequestDetails theRequestDetails) {
ValidateUtil.exactlyOneNotNullOrThrowInvalidRequestException( ValidateUtil.exactlyOneNotNullOrThrowInvalidRequestException(
@ -53,30 +53,31 @@ public abstract class BaseJpaResourceProviderStructureDefinitionR5 extends JpaRe
"Must supply either an ID or a StructureDefinition or a URL (but not more than one of these things)" "Must supply either an ID or a StructureDefinition or a URL (but not more than one of these things)"
); );
StructureDefinition sd; IBaseResource sd;
IFhirResourceDaoStructureDefinition dao = getDao();
if (theId == null && theStructureDefinition != null && theUrl == null) { if (theId == null && theStructureDefinition != null && theUrl == null) {
sd = theStructureDefinition; sd = theStructureDefinition;
} else if (theId != null && theStructureDefinition == null) { } else if (theId != null && theStructureDefinition == null) {
sd = getDao().read(theId, theRequestDetails); sd = dao.read(theId, theRequestDetails);
} else { } else {
SearchParameterMap map = new SearchParameterMap(); SearchParameterMap map = new SearchParameterMap();
map.setLoadSynchronousUpTo(2); map.setLoadSynchronousUpTo(2);
map.add(org.hl7.fhir.r4.model.StructureDefinition.SP_URL, new UriParam(theUrl.getValue())); map.add(org.hl7.fhir.r4.model.StructureDefinition.SP_URL, new UriParam(theUrl.getValue()));
IBundleProvider outcome = getDao().search(map, theRequestDetails); IBundleProvider outcome = dao.search(map, theRequestDetails);
Integer numResults = outcome.size(); Integer numResults = outcome.size();
assert numResults != null; assert numResults != null;
if (numResults == 0) { if (numResults == 0) {
throw new ResourceNotFoundException(Msg.code(1162) + "No StructureDefiniton found with url = '" + theUrl.getValue() + "'"); throw new ResourceNotFoundException(Msg.code(1162) + "No StructureDefiniton found with url = '" + theUrl.getValue() + "'");
} }
sd = (StructureDefinition) outcome.getResources(0, 1).get(0); sd = outcome.getResources(0, 1).get(0);
} }
return getDao().generateSnapshot(sd, null, null, null); return dao.generateSnapshot(sd, null, null, null);
} }
@Override @Override
public IFhirResourceDaoStructureDefinition<StructureDefinition> getDao() { public IFhirResourceDaoStructureDefinition<T> getDao() {
return (IFhirResourceDaoStructureDefinition<StructureDefinition>) super.getDao(); return (IFhirResourceDaoStructureDefinition<T>) super.getDao();
} }
} }

View File

@ -21,23 +21,33 @@ package ca.uhn.fhir.jpa.provider;
*/ */
import ca.uhn.fhir.batch2.jobs.reindex.ReindexProvider; import ca.uhn.fhir.batch2.jobs.reindex.ReindexProvider;
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.model.api.annotation.Description; import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.rest.annotation.Operation; 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.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.util.ParametersUtil; import ca.uhn.fhir.util.ParametersUtil;
import org.hl7.fhir.instance.model.api.IBaseBundle; import org.hl7.fhir.instance.model.api.IBaseBundle;
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.IPrimitiveType; import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.Meta;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
public abstract class BaseJpaSystemProviderDstu2Plus<T, MT> extends BaseJpaSystemProvider<T, MT> { public final class JpaSystemProvider<T, MT> extends BaseJpaSystemProvider<T, MT> {
@Description("Marks all currently existing resources of a given type, or all resources of all types, for reindexing.") @Description("Marks all currently existing resources of a given type, or all resources of all types, for reindexing.")
@ -50,7 +60,7 @@ public abstract class BaseJpaSystemProviderDstu2Plus<T, MT> extends BaseJpaSyste
*/ */
@Deprecated @Deprecated
public IBaseResource markAllResourcesForReindexing( public IBaseResource markAllResourcesForReindexing(
@OperationParam(name="type", min = 0, max = 1, typeName = "code") IPrimitiveType<String> theType @OperationParam(name = "type", min = 0, max = 1, typeName = "code") IPrimitiveType<String> theType
) { ) {
if (theType != null && isNotBlank(theType.getValueAsString())) { if (theType != null && isNotBlank(theType.getValueAsString())) {
@ -103,7 +113,7 @@ public abstract class BaseJpaSystemProviderDstu2Plus<T, MT> extends BaseJpaSyste
@OperationParam(name = "content", min = 1, max = 1, typeName = "Bundle") @OperationParam(name = "content", min = 1, max = 1, typeName = "Bundle")
@Description(formalDefinition = "The message to process (or, if using asynchronous messaging, it may be a response message to accept)") @Description(formalDefinition = "The message to process (or, if using asynchronous messaging, it may be a response message to accept)")
IBaseBundle theMessageToProcess IBaseBundle theMessageToProcess
) { ) {
startRequest(theServletRequest); startRequest(theServletRequest);
@ -115,5 +125,41 @@ public abstract class BaseJpaSystemProviderDstu2Plus<T, MT> extends BaseJpaSyste
} }
@Operation(name = JpaConstants.OPERATION_GET_RESOURCE_COUNTS, idempotent = true)
@Description(shortDefinition = "Provides the number of resources currently stored on the server, broken down by resource type")
public IBaseParameters getResourceCounts() {
IBaseParameters retVal = ParametersUtil.newInstance(getContext());
Map<String, Long> counts = getDao().getResourceCountsFromCache();
counts = defaultIfNull(counts, Collections.emptyMap());
counts = new TreeMap<>(counts);
for (Map.Entry<String, Long> nextEntry : counts.entrySet()) {
ParametersUtil.addParameterToParametersInteger(getContext(), retVal, nextEntry.getKey(), nextEntry.getValue().intValue());
}
return retVal;
}
@Operation(name = ProviderConstants.OPERATION_META, idempotent = true, returnParameters = {
@OperationParam(name = "return", typeName = "Meta")
})
public IBaseParameters meta(RequestDetails theRequestDetails) {
IBaseParameters retVal = ParametersUtil.newInstance(getContext());
ParametersUtil.addParameterToParameters(getContext(), retVal, "return", getDao().metaGetOperation(theRequestDetails));
return retVal;
}
@SuppressWarnings("unchecked")
@Transaction
public IBaseBundle transaction(RequestDetails theRequestDetails, @TransactionParam IBaseBundle theResources) {
startRequest(((ServletRequestDetails) theRequestDetails).getServletRequest());
try {
IFhirSystemDao<T, MT> dao = getDao();
return (IBaseBundle) dao.transaction(theRequestDetails, (T) theResources);
} finally {
endRequest(((ServletRequestDetails) theRequestDetails).getServletRequest());
}
}
} }

View File

@ -1,192 +0,0 @@
package ca.uhn.fhir.jpa.provider;
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Parameters;
import ca.uhn.fhir.model.dstu2.resource.Parameters.Parameter;
import ca.uhn.fhir.model.primitive.IntegerDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import org.hl7.fhir.r4.model.IntegerType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public class JpaSystemProviderDstu2 extends BaseJpaSystemProviderDstu2Plus<Bundle, MetaDt> {
@Autowired()
@Qualifier("mySystemDaoDstu2")
private IFhirSystemDao<Bundle, MetaDt> mySystemDao;
//@formatter:off
// This is generated by hand:
// ls hapi-fhir-structures-dstu2/target/generated-sources/tinder/ca/uhn/fhir/model/dstu2/resource/ | sort | sed "s/.java//" | sed "s/^/@OperationParam(name=\"/" | sed "s/$/\", type=IntegerDt.class, min=0, max=1),/"
@Operation(name = JpaConstants.OPERATION_GET_RESOURCE_COUNTS, idempotent = true, returnParameters = {
@OperationParam(name = "AllergyIntolerance", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Appointment", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "AppointmentResponse", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "AuditEvent", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Basic", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Binary", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "BodySite", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Bundle", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "CarePlan", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "CarePlan2", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Claim", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ClaimResponse", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ClinicalImpression", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Communication", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "CommunicationRequest", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Composition", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ConceptMap", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Condition", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Conformance", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Contract", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Contraindication", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Coverage", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "DataElement", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Device", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "DeviceComponent", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "DeviceMetric", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "DeviceUseRequest", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "DeviceUseStatement", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "DiagnosticOrder", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "DiagnosticReport", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "DocumentManifest", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "DocumentReference", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "EligibilityRequest", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "EligibilityResponse", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Encounter", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "EnrollmentRequest", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "EnrollmentResponse", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "EpisodeOfCare", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ExplanationOfBenefit", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "FamilyMemberHistory", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Flag", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Goal", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Group", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "HealthcareService", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ImagingObjectSelection", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ImagingStudy", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Immunization", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ImmunizationRecommendation", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ListResource", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Location", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Media", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Medication", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "MedicationAdministration", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "MedicationDispense", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "MedicationPrescription", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "MedicationStatement", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "MessageHeader", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "NamingSystem", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "NutritionOrder", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Observation", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "OperationDefinition", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "OperationOutcome", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Order", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "OrderResponse", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Organization", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Parameters", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Patient", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "PaymentNotice", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "PaymentReconciliation", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Person", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Practitioner", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Procedure", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ProcedureRequest", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ProcessRequest", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ProcessResponse", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Provenance", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Questionnaire", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "QuestionnaireAnswers", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ReferralRequest", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "RelatedPerson", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "RiskAssessment", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Schedule", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "SearchParameter", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Slot", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Specimen", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "StructureDefinition", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Subscription", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Substance", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "Supply", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "ValueSet", type = IntegerDt.class, min = 0, max = 1),
@OperationParam(name = "VisionPrescription", type = IntegerDt.class, min = 0, max = 1)
})
@Description(shortDefinition = "Provides the number of resources currently stored on the server, broken down by resource type")
//@formatter:on
public Parameters getResourceCounts() {
Parameters retVal = new Parameters();
Map<String, Long> counts = mySystemDao.getResourceCountsFromCache();
counts = defaultIfNull(counts, Collections.emptyMap());
counts = new TreeMap<>(counts);
for (Entry<String, Long> nextEntry : counts.entrySet()) {
retVal.addParameter().setName(new StringDt(nextEntry.getKey())).setValue(new IntegerDt(nextEntry.getValue().intValue()));
}
return retVal;
}
@Operation(name = ProviderConstants.OPERATION_META, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = MetaDt.class)
})
public Parameters meta(RequestDetails theRequestDetails) {
Parameters parameters = new Parameters();
parameters.addParameter().setName("return").setValue(getDao().metaGetOperation(theRequestDetails));
return parameters;
}
@Transaction
public Bundle transaction(RequestDetails theRequestDetails, @TransactionParam Bundle theResources) {
startRequest(((ServletRequestDetails) theRequestDetails).getServletRequest());
try {
return getDao().transaction(theRequestDetails, theResources);
} finally {
endRequest(((ServletRequestDetails) theRequestDetails).getServletRequest());
}
}
public static Parameters toExpungeResponse(org.hl7.fhir.r4.model.Parameters theRetVal) {
Integer count = ((IntegerType) theRetVal.getParameterFirstRep().getValue()).getValue();
return new Parameters()
.addParameter(new Parameter().setName("count").setValue(new IntegerDt(count)));
}
}

View File

@ -1,113 +0,0 @@
package ca.uhn.fhir.jpa.provider.dstu3;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
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.CodeableConcept;
import org.hl7.fhir.dstu3.model.Coding;
import org.hl7.fhir.dstu3.model.Parameters;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.dstu3.model.UriType;
import org.hl7.fhir.exceptions.FHIRException;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
public abstract class BaseJpaResourceProviderCodeSystemDstu3 extends JpaResourceProviderDstu3<CodeSystem> {
@Operation(name = JpaConstants.OPERATION_LOOKUP, idempotent = true, returnParameters = {
@OperationParam(name = "name", type = StringType.class, min = 1),
@OperationParam(name = "version", type = StringType.class, min = 0),
@OperationParam(name = "display", type = StringType.class, min = 1),
@OperationParam(name = "abstract", type = BooleanType.class, min = 1),
})
public Parameters lookup(
HttpServletRequest theServletRequest,
@OperationParam(name = "code", min = 0, max = 1) CodeType theCode,
@OperationParam(name = "system", min = 0, max = 1) UriType theSystem,
@OperationParam(name = "coding", min = 0, max = 1) Coding theCoding,
@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,
RequestDetails theRequestDetails
) {
startRequest(theServletRequest);
try {
IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> dao = (IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept>) getDao();
IValidationSupport.LookupCodeResult result;
if (theVersion != null) {
result = dao.lookupCode(theCode, new UriType(theSystem.getValue() + "|" + theVersion), theCoding, theDisplayLanguage, theRequestDetails);
} else {
result = dao.lookupCode(theCode, theSystem, theCoding, theDisplayLanguage, theRequestDetails);
}
result.throwNotFoundIfAppropriate();
return (Parameters) result.toParameters(theRequestDetails.getFhirContext(), theProperties);
} catch (FHIRException e) {
throw new InternalErrorException(Msg.code(1153) + e);
} finally {
endRequest(theServletRequest);
}
}
/**
* $subsumes operation
*/
@Operation(name = JpaConstants.OPERATION_SUBSUMES, idempotent = true, returnParameters = {
@OperationParam(name = "outcome", type = CodeType.class, min = 1),
})
public Parameters subsumes(
HttpServletRequest theServletRequest,
@OperationParam(name = "codeA", min = 0, max = 1) CodeType theCodeA,
@OperationParam(name = "codeB", min = 0, max = 1) CodeType theCodeB,
@OperationParam(name = "system", min = 0, max = 1) UriType theSystem,
@OperationParam(name = "codingA", min = 0, max = 1) Coding theCodingA,
@OperationParam(name = "codingB", min = 0, max = 1) Coding theCodingB,
@OperationParam(name = "version", min = 0, max = 1) StringType theVersion,
RequestDetails theRequestDetails
) {
startRequest(theServletRequest);
try {
IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> dao = (IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept>) getDao();
IFhirResourceDaoCodeSystem.SubsumesResult result;
if (theVersion != null) {
theSystem = new UriType(theSystem.asStringValue() + "|" + theVersion.toString());
}
result = dao.subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB, theRequestDetails);
return (Parameters) result.toParameters(theRequestDetails.getFhirContext());
} finally {
endRequest(theServletRequest);
}
}
}

View File

@ -1,83 +0,0 @@
package ca.uhn.fhir.jpa.provider.dstu3;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoComposition;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.Sort;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.DateRangeParam;
import org.hl7.fhir.dstu3.model.Composition;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.UnsignedIntType;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public abstract class BaseJpaResourceProviderCompositionDstu3 extends JpaResourceProviderDstu3<Composition> {
/**
* Composition/123/$document
*
* @param theRequestDetails
*/
//@formatter:off
@Operation(name = JpaConstants.OPERATION_DOCUMENT, idempotent = true, bundleType=BundleTypeEnum.DOCUMENT)
public IBundleProvider getDocumentForComposition(
javax.servlet.http.HttpServletRequest theServletRequest,
@IdParam
IdType theId,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT)
UnsignedIntType theCount,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
@OperationParam(name = Constants.PARAM_OFFSET)
UnsignedIntType theOffset,
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
DateRangeParam theLastUpdated,
@Sort
SortSpec theSortSpec,
RequestDetails theRequestDetails
) {
//@formatter:on
startRequest(theServletRequest);
try {
IBundleProvider bundleProvider = ((IFhirResourceDaoComposition<Composition>) getDao()).getDocumentForComposition(theServletRequest, theId, theCount, theOffset, theLastUpdated, theSortSpec, theRequestDetails);
return bundleProvider;
} finally {
endRequest(theServletRequest);
}
}
}

View File

@ -25,6 +25,7 @@ import ca.uhn.fhir.i18n.Msg;
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.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider;
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;
import ca.uhn.fhir.rest.annotation.Operation; import ca.uhn.fhir.rest.annotation.Operation;
@ -47,7 +48,7 @@ import org.hl7.fhir.exceptions.FHIRException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
public abstract class BaseJpaResourceProviderConceptMapDstu3 extends JpaResourceProviderDstu3<ConceptMap> { public abstract class BaseJpaResourceProviderConceptMapDstu3 extends BaseJpaResourceProvider<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),
@OperationParam(name = "message", type = StringType.class, min = 0, max = 1), @OperationParam(name = "message", type = StringType.class, min = 0, max = 1),

View File

@ -1,108 +0,0 @@
package ca.uhn.fhir.jpa.provider.dstu3;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoEncounter;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.Sort;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.DateRangeParam;
import org.hl7.fhir.dstu3.model.Encounter;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.UnsignedIntType;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public abstract class BaseJpaResourceProviderEncounterDstu3 extends JpaResourceProviderDstu3<Encounter> {
/**
* Encounter/123/$everything
*/
@Operation(name = JpaConstants.OPERATION_EVERYTHING, idempotent = true, bundleType=BundleTypeEnum.SEARCHSET)
public IBundleProvider EncounterInstanceEverything(
javax.servlet.http.HttpServletRequest theServletRequest,
@IdParam
IdType theId,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT)
UnsignedIntType theCount,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
@OperationParam(name = Constants.PARAM_OFFSET)
UnsignedIntType theOffset,
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
DateRangeParam theLastUpdated,
@Sort
SortSpec theSortSpec
) {
startRequest(theServletRequest);
try {
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterInstanceEverything(theServletRequest, theId, theCount, theOffset,theLastUpdated, theSortSpec);
} finally {
endRequest(theServletRequest);
}}
/**
* /Encounter/$everything
*/
@Operation(name = JpaConstants.OPERATION_EVERYTHING, idempotent = true, bundleType=BundleTypeEnum.SEARCHSET)
public IBundleProvider EncounterTypeEverything(
javax.servlet.http.HttpServletRequest theServletRequest,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT)
UnsignedIntType theCount,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
@OperationParam(name = Constants.PARAM_OFFSET)
UnsignedIntType theOffset,
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
DateRangeParam theLastUpdated,
@Sort
SortSpec theSortSpec
) {
startRequest(theServletRequest);
try {
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterTypeEverything(theServletRequest, theCount, theOffset, theLastUpdated, theSortSpec);
} finally {
endRequest(theServletRequest);
}
}
}

View File

@ -1,114 +0,0 @@
package ca.uhn.fhir.jpa.provider.dstu3;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoObservation;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.RawParam;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.DateAndListParam;
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
import ca.uhn.fhir.rest.param.TokenAndListParam;
import org.hl7.fhir.dstu3.model.Observation;
import org.hl7.fhir.dstu3.model.UnsignedIntType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import java.util.List;
import java.util.Map;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public abstract class BaseJpaResourceProviderObservationDstu3 extends JpaResourceProviderDstu3<Observation> {
/**
* Observation/$lastn
*/
@Operation(name = JpaConstants.OPERATION_LASTN, idempotent = true, bundleType = BundleTypeEnum.SEARCHSET)
public IBundleProvider observationLastN(
javax.servlet.http.HttpServletRequest theServletRequest,
javax.servlet.http.HttpServletResponse theServletResponse,
ca.uhn.fhir.rest.api.server.RequestDetails theRequestDetails,
@Description(formalDefinition = "Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT)
UnsignedIntType theCount,
@Description(shortDefinition="The classification of the type of observation")
@OperationParam(name="category")
TokenAndListParam theCategory,
@Description(shortDefinition="The code of the observation type")
@OperationParam(name="code")
TokenAndListParam theCode,
@Description(shortDefinition="The effective date of the observation")
@OperationParam(name="date")
DateAndListParam theDate,
@Description(shortDefinition="The subject that the observation is about (if patient)")
@OperationParam(name="patient")
ReferenceAndListParam thePatient,
@Description(shortDefinition="The subject that the observation is about")
@OperationParam(name="subject" )
ReferenceAndListParam theSubject,
@Description(shortDefinition="The maximum number of observations to return for each observation code")
@OperationParam(name = "max", typeName = "integer", min = 0, max = 1)
IPrimitiveType<Integer> theMax,
@RawParam
Map<String, List<String>> theAdditionalRawParams
) {
startRequest(theServletRequest);
try {
SearchParameterMap paramMap = new SearchParameterMap();
paramMap.add(Observation.SP_CATEGORY, theCategory);
paramMap.add(Observation.SP_CODE, theCode);
paramMap.add(Observation.SP_DATE, theDate);
if (thePatient != null) {
paramMap.add(Observation.SP_PATIENT, thePatient);
}
if (theSubject != null) {
paramMap.add(Observation.SP_SUBJECT, theSubject);
}
if (theMax != null) {
paramMap.setLastNMax(theMax.getValue());
}
if (theCount != null) {
paramMap.setCount(theCount.getValue());
}
getDao().translateRawParameters(theAdditionalRawParams, paramMap);
return ((IFhirResourceDaoObservation<Observation>) getDao()).observationsLastN(paramMap, theRequestDetails, theServletResponse);
} finally {
endRequest(theServletRequest);
}
}
}

View File

@ -1,214 +0,0 @@
package ca.uhn.fhir.jpa.provider.dstu3;
import ca.uhn.fhir.jpa.api.dao.PatientEverythingParameters;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.Sort;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.StringAndListParam;
import ca.uhn.fhir.rest.param.StringOrListParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.TokenOrListParam;
import ca.uhn.fhir.rest.param.TokenParam;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.Patient;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.dstu3.model.UnsignedIntType;
import java.util.Arrays;
import java.util.List;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public abstract class BaseJpaResourceProviderPatientDstu3 extends JpaResourceProviderDstu3<Patient> {
/**
* Patient/123/$everything
*/
@Operation(name = JpaConstants.OPERATION_EVERYTHING, idempotent = true, bundleType = BundleTypeEnum.SEARCHSET)
public IBundleProvider patientInstanceEverything(
javax.servlet.http.HttpServletRequest theServletRequest,
@IdParam
IdType theId,
@Description(formalDefinition = "Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT)
UnsignedIntType theCount,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
@OperationParam(name = Constants.PARAM_OFFSET)
UnsignedIntType theOffset,
@Description(shortDefinition = "Only return resources which were last updated as specified by the given range")
@OperationParam(name = Constants.PARAM_LASTUPDATED, min = 0, max = 1)
DateRangeParam theLastUpdated,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _content filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_CONTENT, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringType> theContent,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _text filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_TEXT, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringType> theNarrative,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _filter filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringType> theFilter,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _type filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_TYPE, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringType> theTypes,
@Sort
SortSpec theSortSpec,
RequestDetails theRequestDetails
) {
startRequest(theServletRequest);
try {
PatientEverythingParameters everythingParams = new PatientEverythingParameters();
everythingParams.setCount(theCount);
everythingParams.setOffset(theOffset);
everythingParams.setLastUpdated(theLastUpdated);
everythingParams.setSort(theSortSpec);
everythingParams.setContent(toStringAndList(theContent));
everythingParams.setNarrative(toStringAndList(theNarrative));
everythingParams.setFilter(toStringAndList(theFilter));
everythingParams.setTypes(toStringAndList(theTypes));
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theRequestDetails, everythingParams, theId);
} finally {
endRequest(theServletRequest);
}
}
/**
* /Patient/$everything
*/
@Operation(name = JpaConstants.OPERATION_EVERYTHING, idempotent = true, bundleType = BundleTypeEnum.SEARCHSET)
public IBundleProvider patientTypeEverything(
javax.servlet.http.HttpServletRequest theServletRequest,
@Description(formalDefinition = "Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT)
UnsignedIntType theCount,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
@OperationParam(name = Constants.PARAM_OFFSET)
UnsignedIntType theOffset,
@Description(shortDefinition = "Only return resources which were last updated as specified by the given range")
@OperationParam(name = Constants.PARAM_LASTUPDATED, min = 0, max = 1)
DateRangeParam theLastUpdated,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _content filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_CONTENT, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringType> theContent,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _text filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_TEXT, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringType> theNarrative,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _filter filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringType> theFilter,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _type filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_TYPE, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringType> theTypes,
@Description(shortDefinition = "Filter the resources to return based on the patient ids provided.")
@OperationParam(name = Constants.PARAM_ID, min = 0, max = OperationParam.MAX_UNLIMITED)
List<IdType> theId,
@Sort
SortSpec theSortSpec,
RequestDetails theRequestDetails
) {
startRequest(theServletRequest);
try {
PatientEverythingParameters everythingParams = new PatientEverythingParameters();
everythingParams.setCount(theCount);
everythingParams.setOffset(theOffset);
everythingParams.setLastUpdated(theLastUpdated);
everythingParams.setSort(theSortSpec);
everythingParams.setContent(toStringAndList(theContent));
everythingParams.setNarrative(toStringAndList(theNarrative));
everythingParams.setFilter(toStringAndList(theFilter));
everythingParams.setTypes(toStringAndList(theTypes));
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theRequestDetails, everythingParams, toFlattenedPatientIdTokenParamList(theId));
} finally {
endRequest(theServletRequest);
}
}
/**
* Given a list of string types, return only the ID portions of any parameters passed in.
*/
private TokenOrListParam toFlattenedPatientIdTokenParamList(List<IdType> theId) {
TokenOrListParam retVal = new TokenOrListParam();
if (theId != null) {
for (IdType next: theId) {
if (isNotBlank(next.getValue())) {
String[] split = next.getValueAsString().split(",");
Arrays.stream(split).map(IdType::new).forEach(id -> {
retVal.addOr(new TokenParam(id.getIdPart()));
});
}
}
}
return retVal.getValuesAsQueryTokens().isEmpty() ? null: retVal;
}
private StringAndListParam toStringAndList(List<StringType> theNarrative) {
StringAndListParam retVal = new StringAndListParam();
if (theNarrative != null) {
for (StringType next : theNarrative) {
if (isNotBlank(next.getValue())) {
retVal.addAnd(new StringOrListParam().addOr(new StringParam(next.getValue())));
}
}
}
if (retVal.getValuesAsQueryTokens().isEmpty()) {
return null;
}
return retVal;
}
}

View File

@ -1,80 +0,0 @@
package ca.uhn.fhir.jpa.provider.dstu3;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoStructureDefinition;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.UriParam;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.util.ValidateUtil;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.dstu3.model.StructureDefinition;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public abstract class BaseJpaResourceProviderStructureDefinitionDstu3 extends JpaResourceProviderDstu3<StructureDefinition> {
/**
* <code>$snapshot</code> operation
*/
@Operation(name=JpaConstants.OPERATION_SNAPSHOT, idempotent = true)
public StructureDefinition snapshot(
@IdParam(optional = true) IdType theId,
@OperationParam(name = "definition") StructureDefinition theStructureDefinition,
@OperationParam(name = "url") StringType theUrl,
RequestDetails theRequestDetails) {
ValidateUtil.exactlyOneNotNullOrThrowInvalidRequestException(
new Object[]{ theId, theStructureDefinition, theUrl },
"Must supply either an ID or a StructureDefinition or a URL (but not more than one of these things)"
);
StructureDefinition sd;
if (theId == null && theStructureDefinition != null && theUrl == null) {
sd = theStructureDefinition;
} else if (theId != null && theStructureDefinition == null) {
sd = getDao().read(theId, theRequestDetails);
} else {
SearchParameterMap map = new SearchParameterMap();
map.setLoadSynchronousUpTo(2);
map.add(StructureDefinition.SP_URL, new UriParam(theUrl.getValue()));
IBundleProvider outcome = getDao().search(map, theRequestDetails);
if (outcome.size() == 0) {
throw new ResourceNotFoundException(Msg.code(1152) + "No StructureDefiniton found with url = '" + theUrl.getValue() + "'");
}
sd = (StructureDefinition) outcome.getResources(0, 1).get(0);
}
return getDao().generateSnapshot(sd, null, null, null);
}
@Override
public IFhirResourceDaoStructureDefinition<StructureDefinition> getDao() {
return (IFhirResourceDaoStructureDefinition<StructureDefinition>) super.getDao();
}
}

View File

@ -20,8 +20,9 @@ package ca.uhn.fhir.jpa.provider.dstu3;
* #L% * #L%
*/ */
import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider;
import org.hl7.fhir.dstu3.model.ValueSet; import org.hl7.fhir.dstu3.model.ValueSet;
public abstract class BaseJpaResourceProviderValueSetDstu3 extends JpaResourceProviderDstu3<ValueSet> { public abstract class BaseJpaResourceProviderValueSetDstu3 extends BaseJpaResourceProvider<ValueSet> {
} }

View File

@ -1,37 +0,0 @@
package ca.uhn.fhir.jpa.provider.dstu3;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDao;
import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider;
import org.hl7.fhir.instance.model.api.IAnyResource;
public class JpaResourceProviderDstu3<T extends IAnyResource> extends BaseJpaResourceProvider<T> {
public JpaResourceProviderDstu3() {
// nothing
}
public JpaResourceProviderDstu3(IFhirResourceDao<T> theDao) {
super(theDao);
}
}

View File

@ -1,182 +0,0 @@
package ca.uhn.fhir.jpa.provider.dstu3;
import ca.uhn.fhir.jpa.api.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.BaseJpaSystemProviderDstu2Plus;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.IntegerType;
import org.hl7.fhir.dstu3.model.Meta;
import org.hl7.fhir.dstu3.model.Parameters;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public class JpaSystemProviderDstu3 extends BaseJpaSystemProviderDstu2Plus<Bundle, Meta> {
@Autowired()
@Qualifier("mySystemDaoDstu3")
private IFhirSystemDao<Bundle, Meta> mySystemDao;
// This is generated by hand:
// ls hapi-fhir-structures-dstu2/target/generated-sources/tinder/ca/uhn/fhir/model/dstu2/resource/ | sort | sed "s/.java//" | sed "s/^/@OperationParam(name=\"/" | sed "s/$/\", type=IntegerType.class, min=0, max=1),/"
@Operation(name = JpaConstants.OPERATION_GET_RESOURCE_COUNTS, idempotent = true, returnParameters = {
@OperationParam(name = "AllergyIntolerance", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Appointment", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "AppointmentResponse", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "AuditEvent", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Basic", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Binary", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "BodySite", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Bundle", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "CarePlan", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "CarePlan2", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Claim", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ClaimResponse", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ClinicalImpression", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Communication", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "CommunicationRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Composition", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ConceptMap", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Condition", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Conformance", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Contract", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Contraindication", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Coverage", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DataElement", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Device", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DeviceComponent", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DeviceMetric", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DeviceUseRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DeviceUseStatement", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DiagnosticOrder", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DiagnosticReport", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DocumentManifest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "DocumentReference", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "EligibilityRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "EligibilityResponse", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Encounter", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "EnrollmentRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "EnrollmentResponse", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "EpisodeOfCare", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ExplanationOfBenefit", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "FamilyMemberHistory", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Flag", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Goal", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Group", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "HealthcareService", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ImagingObjectSelection", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ImagingStudy", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Immunization", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ImmunizationRecommendation", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ListResource", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Location", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Media", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Medication", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "MedicationAdministration", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "MedicationDispense", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "MedicationPrescription", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "MedicationStatement", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "MessageHeader", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "NamingSystem", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "NutritionOrder", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Observation", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "OperationDefinition", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "OperationOutcome", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Order", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "OrderResponse", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Organization", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Parameters", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Patient", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "PaymentNotice", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "PaymentReconciliation", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Person", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Practitioner", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Procedure", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ProcedureRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ProcessRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ProcessResponse", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Provenance", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Questionnaire", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "QuestionnaireAnswers", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ReferralRequest", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "RelatedPerson", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "RiskAssessment", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Schedule", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "SearchParameter", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Slot", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Specimen", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "StructureDefinition", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Subscription", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Substance", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "Supply", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "ValueSet", type = IntegerType.class, min = 0, max = 1),
@OperationParam(name = "VisionPrescription", type = IntegerType.class, min = 0, max = 1)
})
@Description(shortDefinition = "Provides the number of resources currently stored on the server, broken down by resource type")
public Parameters getResourceCounts() {
Parameters retVal = new Parameters();
Map<String, Long> counts = mySystemDao.getResourceCountsFromCache();
counts = defaultIfNull(counts, Collections.emptyMap());
counts = new TreeMap<>(counts);
for (Entry<String, Long> nextEntry : counts.entrySet()) {
retVal.addParameter().setName((nextEntry.getKey())).setValue(new IntegerType(nextEntry.getValue().intValue()));
}
return retVal;
}
@Operation(name = ProviderConstants.OPERATION_META, idempotent = true, returnParameters = {
@OperationParam(name = "return", type = Meta.class)
})
public Parameters meta(RequestDetails theRequestDetails) {
Parameters parameters = new Parameters();
parameters.addParameter().setName("return").setValue(getDao().metaGetOperation(theRequestDetails));
return parameters;
}
@Transaction
public Bundle transaction(RequestDetails theRequestDetails, @TransactionParam Bundle theResources) {
startRequest(((ServletRequestDetails) theRequestDetails).getServletRequest());
try {
return getDao().transaction(theRequestDetails, theResources);
} finally {
endRequest(((ServletRequestDetails) theRequestDetails).getServletRequest());
}
}
}

View File

@ -1,186 +0,0 @@
package ca.uhn.fhir.jpa.provider.r4;
import ca.uhn.fhir.context.support.ConceptValidationOptions;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.ValidationSupportContext;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoCodeSystem;
import ca.uhn.fhir.jpa.config.JpaConfig;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.BaseJpaResourceProviderValueSetDstu2;
import ca.uhn.fhir.jpa.term.api.ITermReadSvcR4;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import org.hl7.fhir.common.hapi.validation.support.ValidationSupportChain;
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.CodeableConcept;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.StringType;
import org.hl7.fhir.r4.model.UriType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public abstract class BaseJpaResourceProviderCodeSystemR4 extends JpaResourceProviderR4<CodeSystem> {
@Autowired
@Qualifier(JpaConfig.JPA_VALIDATION_SUPPORT_CHAIN)
private ValidationSupportChain myValidationSupportChain;
@Autowired
protected ITermReadSvcR4 myTermSvc;
/**
* $lookup operation
*/
@SuppressWarnings("unchecked")
@Operation(name = JpaConstants.OPERATION_LOOKUP, idempotent = true, returnParameters= {
@OperationParam(name="name", type=StringType.class, min=1),
@OperationParam(name="version", type=StringType.class, min=0),
@OperationParam(name="display", type=StringType.class, min=1),
@OperationParam(name="abstract", type=BooleanType.class, min=1),
})
public Parameters lookup(
HttpServletRequest theServletRequest,
@OperationParam(name="code", min=0, max=1) CodeType theCode,
@OperationParam(name="system", min=0, max=1) UriType theSystem,
@OperationParam(name="coding", min=0, max=1) Coding theCoding,
@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,
RequestDetails theRequestDetails
) {
startRequest(theServletRequest);
try {
IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> dao = (IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept>) getDao();
IValidationSupport.LookupCodeResult result;
if (theVersion != null) {
result = dao.lookupCode(theCode, new UriType(theSystem.getValue() + "|" + theVersion), theCoding, theDisplayLanguage, theRequestDetails);
} else {
result = dao.lookupCode(theCode, theSystem, theCoding, theDisplayLanguage, theRequestDetails);
}
result.throwNotFoundIfAppropriate();
return (Parameters) result.toParameters(theRequestDetails.getFhirContext(), theProperties);
} finally {
endRequest(theServletRequest);
}
}
/**
* $subsumes operation
*/
@Operation(name = JpaConstants.OPERATION_SUBSUMES, idempotent = true, returnParameters= {
@OperationParam(name="outcome", type=CodeType.class, min=1),
})
public Parameters subsumes(
HttpServletRequest theServletRequest,
@OperationParam(name="codeA", min=0, max=1) CodeType theCodeA,
@OperationParam(name="codeB", min=0, max=1) CodeType theCodeB,
@OperationParam(name="system", min=0, max=1) UriType theSystem,
@OperationParam(name="codingA", min=0, max=1) Coding theCodingA,
@OperationParam(name="codingB", min=0, max=1) Coding theCodingB,
@OperationParam(name="version", min=0, max=1) StringType theVersion,
RequestDetails theRequestDetails
) {
startRequest(theServletRequest);
try {
IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> dao = (IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept>) getDao();
IFhirResourceDaoCodeSystem.SubsumesResult result;
if (theVersion != null) {
theSystem = new UriType(theSystem.asStringValue() + "|" + theVersion.toString());
}
result = dao.subsumes(theCodeA, theCodeB, theSystem, theCodingA, theCodingB, theRequestDetails);
return (Parameters) result.toParameters(theRequestDetails.getFhirContext());
} finally {
endRequest(theServletRequest);
}
}
/**
* $validate-code operation
*/
@SuppressWarnings("unchecked")
@Operation(name = JpaConstants.OPERATION_VALIDATE_CODE, idempotent = true, returnParameters = {
@OperationParam(name = "result", type = BooleanType.class, min = 1),
@OperationParam(name = "message", type = StringType.class),
@OperationParam(name = "display", type = StringType.class)
})
public Parameters validateCode(
HttpServletRequest theServletRequest,
@IdParam(optional = true) IdType theId,
@OperationParam(name = "url", min = 0, max = 1) UriType theCodeSystemUrl,
@OperationParam(name = "version", min = 0, max = 1) StringType theVersion,
@OperationParam(name = "code", min = 0, max = 1) CodeType theCode,
@OperationParam(name = "display", min = 0, max = 1) StringType theDisplay,
@OperationParam(name = "coding", min = 0, max = 1) Coding theCoding,
@OperationParam(name = "codeableConcept", min = 0, max = 1) CodeableConcept theCodeableConcept,
RequestDetails theRequestDetails
) {
IValidationSupport.CodeValidationResult result = null;
startRequest(theServletRequest);
try {
// If a Remote Terminology Server has been configured, use it
if (myValidationSupportChain.isRemoteTerminologyServiceConfigured()) {
String codeSystemUrl = (theCodeSystemUrl != null && theCodeSystemUrl.hasValue()) ?
theCodeSystemUrl.asStringValue() : null;
String code = (theCode != null && theCode.hasValue()) ? theCode.asStringValue() : null;
String display = (theDisplay != null && theDisplay.hasValue()) ? theDisplay.asStringValue() : null;
if (theCoding != null) {
if (theCoding.hasSystem()) {
if (codeSystemUrl != null && !codeSystemUrl.equalsIgnoreCase(theCoding.getSystem())) {
throw new InvalidRequestException(Msg.code(1160) + "Coding.system '" + theCoding.getSystem() + "' does not equal param url '" + theCodeSystemUrl + "'. Unable to validate-code.");
}
codeSystemUrl = theCoding.getSystem();
code = theCoding.getCode();
display = theCoding.getDisplay();
result = myValidationSupportChain.validateCode(
new ValidationSupportContext(myValidationSupportChain), new ConceptValidationOptions(),
codeSystemUrl, code, display, null);
}
}
} else {
// Otherwise, use the local DAO layer to validate the code
IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept> dao = (IFhirResourceDaoCodeSystem<CodeSystem, Coding, CodeableConcept>) getDao();
result = dao.validateCode(theId, theCodeSystemUrl, theVersion, theCode, theDisplay, theCoding, theCodeableConcept, theRequestDetails);
}
return (Parameters) BaseJpaResourceProviderValueSetDstu2.toValidateCodeResult(getContext(), result);
} finally {
endRequest(theServletRequest);
}
}
}

View File

@ -1,81 +0,0 @@
package ca.uhn.fhir.jpa.provider.r4;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoComposition;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.Sort;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.DateRangeParam;
import org.hl7.fhir.r4.model.Composition;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.UnsignedIntType;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public abstract class BaseJpaResourceProviderCompositionR4 extends JpaResourceProviderR4<Composition> {
/**
* Composition/123/$document
*/
@Operation(name = JpaConstants.OPERATION_DOCUMENT, idempotent = true, bundleType=BundleTypeEnum.DOCUMENT)
// public IBaseBundle getDocumentForComposition(
public IBundleProvider getDocumentForComposition(
javax.servlet.http.HttpServletRequest theServletRequest,
@IdParam
IdType theId,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT)
UnsignedIntType theCount,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
@OperationParam(name = Constants.PARAM_OFFSET)
UnsignedIntType theOffset,
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
DateRangeParam theLastUpdated,
@Sort
SortSpec theSortSpec,
RequestDetails theRequestDetails
) {
startRequest(theServletRequest);
try {
IBundleProvider bundleProvider = ((IFhirResourceDaoComposition<Composition>) getDao()).getDocumentForComposition(theServletRequest, theId, theCount, theOffset, theLastUpdated, theSortSpec, theRequestDetails);
return bundleProvider;
} finally {
endRequest(theServletRequest);
}
}
}

View File

@ -25,6 +25,7 @@ import ca.uhn.fhir.i18n.Msg;
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.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.provider.BaseJpaResourceProvider;
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;
import ca.uhn.fhir.rest.annotation.Operation; import ca.uhn.fhir.rest.annotation.Operation;
@ -43,7 +44,7 @@ import org.hl7.fhir.r4.model.UriType;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
public abstract class BaseJpaResourceProviderConceptMapR4 extends JpaResourceProviderR4<ConceptMap> { public abstract class BaseJpaResourceProviderConceptMapR4 extends BaseJpaResourceProvider<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),
@OperationParam(name = "message", type = StringType.class, min = 0, max = 1), @OperationParam(name = "message", type = StringType.class, min = 0, max = 1),

View File

@ -1,108 +0,0 @@
package ca.uhn.fhir.jpa.provider.r4;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoEncounter;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.Sort;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.DateRangeParam;
import org.hl7.fhir.r4.model.Encounter;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.UnsignedIntType;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public abstract class BaseJpaResourceProviderEncounterR4 extends JpaResourceProviderR4<Encounter> {
/**
* Encounter/123/$everything
*/
@Operation(name = JpaConstants.OPERATION_EVERYTHING, idempotent = true, bundleType=BundleTypeEnum.SEARCHSET)
public IBundleProvider EncounterInstanceEverything(
javax.servlet.http.HttpServletRequest theServletRequest,
@IdParam
IdType theId,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT)
UnsignedIntType theCount,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
@OperationParam(name = Constants.PARAM_OFFSET)
UnsignedIntType theOffset,
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
DateRangeParam theLastUpdated,
@Sort
SortSpec theSortSpec
) {
startRequest(theServletRequest);
try {
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterInstanceEverything(theServletRequest, theId, theCount, theOffset, theLastUpdated, theSortSpec);
} finally {
endRequest(theServletRequest);
}}
/**
* /Encounter/$everything
*/
@Operation(name = JpaConstants.OPERATION_EVERYTHING, idempotent = true, bundleType=BundleTypeEnum.SEARCHSET)
public IBundleProvider EncounterTypeEverything(
javax.servlet.http.HttpServletRequest theServletRequest,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT)
UnsignedIntType theCount,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
@OperationParam(name = Constants.PARAM_OFFSET)
UnsignedIntType theOffset,
@Description(shortDefinition="Only return resources which were last updated as specified by the given range")
@OperationParam(name = Constants.PARAM_LASTUPDATED, min=0, max=1)
DateRangeParam theLastUpdated,
@Sort
SortSpec theSortSpec
) {
startRequest(theServletRequest);
try {
return ((IFhirResourceDaoEncounter<Encounter>)getDao()).encounterTypeEverything(theServletRequest, theCount, theOffset, theLastUpdated, theSortSpec);
} finally {
endRequest(theServletRequest);
}
}
}

View File

@ -1,27 +0,0 @@
package ca.uhn.fhir.jpa.provider.r4;
import org.hl7.fhir.r4.model.MessageHeader;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public abstract class BaseJpaResourceProviderMessageHeaderR4 extends JpaResourceProviderR4<MessageHeader> {
// nothing right now
}

View File

@ -1,115 +0,0 @@
package ca.uhn.fhir.jpa.provider.r4;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoObservation;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.RawParam;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.DateAndListParam;
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
import ca.uhn.fhir.rest.param.TokenAndListParam;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import org.hl7.fhir.r4.model.Observation;
import org.hl7.fhir.r4.model.UnsignedIntType;
import java.util.List;
import java.util.Map;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public abstract class BaseJpaResourceProviderObservationR4 extends JpaResourceProviderR4<Observation> {
/**
* Observation/$lastn
*/
@Operation(name = JpaConstants.OPERATION_LASTN, idempotent = true, bundleType = BundleTypeEnum.SEARCHSET)
public IBundleProvider observationLastN(
javax.servlet.http.HttpServletRequest theServletRequest,
javax.servlet.http.HttpServletResponse theServletResponse,
ca.uhn.fhir.rest.api.server.RequestDetails theRequestDetails,
@Description(formalDefinition = "Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT)
UnsignedIntType theCount,
@Description(shortDefinition="The classification of the type of observation")
@OperationParam(name="category")
TokenAndListParam theCategory,
@Description(shortDefinition="The code of the observation type")
@OperationParam(name="code")
TokenAndListParam theCode,
@Description(shortDefinition="The effective date of the observation")
@OperationParam(name="date")
DateAndListParam theDate,
@Description(shortDefinition="The subject that the observation is about (if patient)")
@OperationParam(name="patient")
ReferenceAndListParam thePatient,
@Description(shortDefinition="The subject that the observation is about")
@OperationParam(name="subject" )
ReferenceAndListParam theSubject,
@Description(shortDefinition="The maximum number of observations to return for each observation code")
@OperationParam(name = "max", typeName = "integer", min = 0, max = 1)
IPrimitiveType<Integer> theMax,
@RawParam
Map<String, List<String>> theAdditionalRawParams
) {
startRequest(theServletRequest);
try {
SearchParameterMap paramMap = new SearchParameterMap();
paramMap.add(Observation.SP_CATEGORY, theCategory);
paramMap.add(Observation.SP_CODE, theCode);
paramMap.add(Observation.SP_DATE, theDate);
if (thePatient != null) {
paramMap.add(Observation.SP_PATIENT, thePatient);
}
if (theSubject != null) {
paramMap.add(Observation.SP_SUBJECT, theSubject);
}
if(theMax != null) {
paramMap.setLastNMax(theMax.getValue());
}
if (theCount != null) {
paramMap.setCount(theCount.getValue());
}
getDao().translateRawParameters(theAdditionalRawParams, paramMap);
return ((IFhirResourceDaoObservation<Observation>) getDao()).observationsLastN(paramMap, theRequestDetails, theServletResponse);
} finally {
endRequest(theServletRequest);
}
}
}

View File

@ -1,320 +0,0 @@
package ca.uhn.fhir.jpa.provider.r4;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.dao.PatientEverythingParameters;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.annotation.Sort;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.StringAndListParam;
import ca.uhn.fhir.rest.param.StringOrListParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.TokenOrListParam;
import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.rest.server.provider.ProviderConstants;
import org.hl7.fhir.r4.model.Coverage;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.Patient;
import org.hl7.fhir.r4.model.StringType;
import org.hl7.fhir.r4.model.UnsignedIntType;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public abstract class BaseJpaResourceProviderPatientR4 extends JpaResourceProviderR4<Patient> {
@Autowired
private MemberMatcherR4Helper myMemberMatcherR4Helper;
/**
* Patient/123/$everything
*/
@Operation(name = JpaConstants.OPERATION_EVERYTHING, canonicalUrl = "http://hl7.org/fhir/OperationDefinition/Patient-everything", idempotent = true, bundleType = BundleTypeEnum.SEARCHSET)
public IBundleProvider patientInstanceEverything(
javax.servlet.http.HttpServletRequest theServletRequest,
@IdParam
IdType theId,
@Description(formalDefinition = "Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT)
UnsignedIntType theCount,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
@OperationParam(name = Constants.PARAM_OFFSET)
UnsignedIntType theOffset,
@Description(shortDefinition = "Only return resources which were last updated as specified by the given range")
@OperationParam(name = Constants.PARAM_LASTUPDATED, min = 0, max = 1)
DateRangeParam theLastUpdated,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _content filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_CONTENT, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringType> theContent,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _text filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_TEXT, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringType> theNarrative,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _filter filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringType> theFilter,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _type filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_TYPE, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringType> theTypes,
@Sort
SortSpec theSortSpec,
RequestDetails theRequestDetails
) {
startRequest(theServletRequest);
try {
PatientEverythingParameters everythingParams = new PatientEverythingParameters();
everythingParams.setCount(theCount);
everythingParams.setOffset(theOffset);
everythingParams.setLastUpdated(theLastUpdated);
everythingParams.setSort(theSortSpec);
everythingParams.setContent(toStringAndList(theContent));
everythingParams.setNarrative(toStringAndList(theNarrative));
everythingParams.setFilter(toStringAndList(theFilter));
everythingParams.setTypes(toStringAndList(theTypes));
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theRequestDetails, everythingParams, theId);
} finally {
endRequest(theServletRequest);
}
}
/**
* /Patient/$everything
*/
@Operation(name = JpaConstants.OPERATION_EVERYTHING, canonicalUrl = "http://hl7.org/fhir/OperationDefinition/Patient-everything", idempotent = true, bundleType = BundleTypeEnum.SEARCHSET)
public IBundleProvider patientTypeEverything(
javax.servlet.http.HttpServletRequest theServletRequest,
@Description(formalDefinition = "Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
@OperationParam(name = Constants.PARAM_COUNT)
UnsignedIntType theCount,
@Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
@OperationParam(name = Constants.PARAM_OFFSET)
UnsignedIntType theOffset,
@Description(shortDefinition = "Only return resources which were last updated as specified by the given range")
@OperationParam(name = Constants.PARAM_LASTUPDATED, min = 0, max = 1)
DateRangeParam theLastUpdated,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _content filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_CONTENT, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringType> theContent,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _text filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_TEXT, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringType> theNarrative,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _filter filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringType> theFilter,
@Description(shortDefinition = "Filter the resources to return only resources matching the given _type filter (note that this filter is applied only to results which link to the given patient, not to the patient itself or to supporting resources linked to by the matched resources)")
@OperationParam(name = Constants.PARAM_TYPE, min = 0, max = OperationParam.MAX_UNLIMITED)
List<StringType> theTypes,
@Description(shortDefinition = "Filter the resources to return based on the patient ids provided.")
@OperationParam(name = Constants.PARAM_ID, min = 0, max = OperationParam.MAX_UNLIMITED)
List<IdType> theId,
@Sort
SortSpec theSortSpec,
RequestDetails theRequestDetails
) {
startRequest(theServletRequest);
try {
PatientEverythingParameters everythingParams = new PatientEverythingParameters();
everythingParams.setCount(theCount);
everythingParams.setOffset(theOffset);
everythingParams.setLastUpdated(theLastUpdated);
everythingParams.setSort(theSortSpec);
everythingParams.setContent(toStringAndList(theContent));
everythingParams.setNarrative(toStringAndList(theNarrative));
everythingParams.setFilter(toStringAndList(theFilter));
everythingParams.setTypes(toStringAndList(theTypes));
return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theRequestDetails, everythingParams, toFlattenedPatientIdTokenParamList(theId));
} finally {
endRequest(theServletRequest);
}
}
/**
* /Patient/$member-match operation
* Basic implementation matching by coverage id or by coverage identifier. Matching by
* Beneficiary (Patient) demographics on family name and birthdate in this version
*/
@Operation(name = ProviderConstants.OPERATION_MEMBER_MATCH, canonicalUrl = "http://hl7.org/fhir/us/davinci-hrex/OperationDefinition/member-match", idempotent = false, returnParameters = {
@OperationParam(name = "MemberIdentifier", typeName = "string")
})
public Parameters patientMemberMatch(
javax.servlet.http.HttpServletRequest theServletRequest,
@Description(shortDefinition = "The target of the operation. Will be returned with Identifier for matched coverage added.")
@OperationParam(name = Constants.PARAM_MEMBER_PATIENT, min = 1, max = 1)
Patient theMemberPatient,
@Description(shortDefinition = "Old coverage information as extracted from beneficiary's card.")
@OperationParam(name = Constants.PARAM_OLD_COVERAGE, min = 1, max = 1)
Coverage oldCoverage,
@Description(shortDefinition = "New Coverage information. Provided as a reference. Optionally returned unmodified.")
@OperationParam(name = Constants.PARAM_NEW_COVERAGE, min = 1, max = 1)
Coverage newCoverage,
RequestDetails theRequestDetails
) {
return doMemberMatchOperation(theServletRequest, theMemberPatient, oldCoverage, newCoverage, theRequestDetails);
}
private Parameters doMemberMatchOperation(HttpServletRequest theServletRequest, Patient theMemberPatient,
Coverage theCoverageToMatch, Coverage theCoverageToLink, RequestDetails theRequestDetails) {
validateParams(theMemberPatient, theCoverageToMatch, theCoverageToLink);
Optional<Coverage> coverageOpt = myMemberMatcherR4Helper.findMatchingCoverage(theCoverageToMatch);
if ( ! coverageOpt.isPresent()) {
String i18nMessage = getContext().getLocalizer().getMessage(
"operation.member.match.error.coverage.not.found");
throw new UnprocessableEntityException(Msg.code(1155) + i18nMessage);
}
Coverage coverage = coverageOpt.get();
Optional<Patient> patientOpt = myMemberMatcherR4Helper.getBeneficiaryPatient(coverage);
if (! patientOpt.isPresent()) {
String i18nMessage = getContext().getLocalizer().getMessage(
"operation.member.match.error.beneficiary.not.found");
throw new UnprocessableEntityException(Msg.code(1156) + i18nMessage);
}
Patient patient = patientOpt.get();
if (!myMemberMatcherR4Helper.validPatientMember(patient, theMemberPatient)) {
String i18nMessage = getContext().getLocalizer().getMessage(
"operation.member.match.error.patient.not.found");
throw new UnprocessableEntityException(Msg.code(2146) + i18nMessage);
}
if (patient.getIdentifier().isEmpty()) {
String i18nMessage = getContext().getLocalizer().getMessage(
"operation.member.match.error.beneficiary.without.identifier");
throw new UnprocessableEntityException(Msg.code(1157) + i18nMessage);
}
myMemberMatcherR4Helper.addMemberIdentifierToMemberPatient(theMemberPatient, patient.getIdentifierFirstRep());
return myMemberMatcherR4Helper.buildSuccessReturnParameters(theMemberPatient, theCoverageToLink);
}
private void validateParams(Patient theMemberPatient, Coverage theOldCoverage, Coverage theNewCoverage) {
validateParam(theMemberPatient, Constants.PARAM_MEMBER_PATIENT);
validateParam(theOldCoverage, Constants.PARAM_OLD_COVERAGE);
validateParam(theNewCoverage, Constants.PARAM_NEW_COVERAGE);
validateMemberPatientParam(theMemberPatient);
}
private void validateParam(Object theParam, String theParamName) {
if (theParam == null) {
String i18nMessage = getContext().getLocalizer().getMessage(
"operation.member.match.error.missing.parameter", theParamName);
throw new UnprocessableEntityException(Msg.code(1158) + i18nMessage);
}
}
private void validateMemberPatientParam(Patient theMemberPatient) {
if (theMemberPatient.getName().isEmpty()) {
validateParam(null, Constants.PARAM_MEMBER_PATIENT_NAME);
}
validateParam(theMemberPatient.getName().get(0).getFamily(), Constants.PARAM_MEMBER_PATIENT_NAME);
validateParam(theMemberPatient.getBirthDate(), Constants.PARAM_MEMBER_PATIENT_BIRTHDATE);
}
/**
* Given a list of string types, return only the ID portions of any parameters passed in.
*/
private TokenOrListParam toFlattenedPatientIdTokenParamList(List<IdType> theId) {
TokenOrListParam retVal = new TokenOrListParam();
if (theId != null) {
for (IdType next: theId) {
if (isNotBlank(next.getValue())) {
String[] split = next.getValueAsString().split(",");
Arrays.stream(split).map(IdType::new).forEach(id -> {
retVal.addOr(new TokenParam(id.getIdPart()));
});
}
}
}
return retVal.getValuesAsQueryTokens().isEmpty() ? null: retVal;
}
private StringAndListParam toStringAndList(List<StringType> theNarrative) {
StringAndListParam retVal = new StringAndListParam();
if (theNarrative != null) {
for (StringType next : theNarrative) {
if (isNotBlank(next.getValue())) {
retVal.addAnd(new StringOrListParam().addOr(new StringParam(next.getValue())));
}
}
}
if (retVal.getValuesAsQueryTokens().isEmpty()) {
return null;
}
return retVal;
}
}

View File

@ -1,82 +0,0 @@
package ca.uhn.fhir.jpa.provider.r4;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoStructureDefinition;
import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.UriParam;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.util.ValidateUtil;
import org.hl7.fhir.r4.model.IdType;
import org.hl7.fhir.r4.model.StringType;
import org.hl7.fhir.r4.model.StructureDefinition;
/*
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2022 Smile CDR, Inc.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
public abstract class BaseJpaResourceProviderStructureDefinitionR4 extends JpaResourceProviderR4<StructureDefinition> {
/**
* <code>$snapshot</code> operation
*/
@Operation(name=JpaConstants.OPERATION_SNAPSHOT, idempotent = true)
public StructureDefinition snapshot(
@IdParam(optional = true) IdType theId,
@OperationParam(name = "definition") StructureDefinition theStructureDefinition,
@OperationParam(name = "url") StringType theUrl,
RequestDetails theRequestDetails) {
ValidateUtil.exactlyOneNotNullOrThrowInvalidRequestException(
new Object[]{ theId, theStructureDefinition, theUrl },
"Must supply either an ID or a StructureDefinition or a URL (but not more than one of these things)"
);
StructureDefinition sd;
if (theId == null && theStructureDefinition != null && theUrl == null) {
sd = theStructureDefinition;
} else if (theId != null && theStructureDefinition == null) {
sd = getDao().read(theId, theRequestDetails);
} else {
SearchParameterMap map = new SearchParameterMap();
map.setLoadSynchronousUpTo(2);
map.add(StructureDefinition.SP_URL, new UriParam(theUrl.getValue()));
IBundleProvider outcome = getDao().search(map, theRequestDetails);
Integer numResults = outcome.size();
assert numResults != null;
if (numResults == 0) {
throw new ResourceNotFoundException(Msg.code(1159) + "No StructureDefiniton found with url = '" + theUrl.getValue() + "'");
}
sd = (StructureDefinition) outcome.getResources(0, 1).get(0);
}
return getDao().generateSnapshot(sd, null, null, null);
}
@Override
public IFhirResourceDaoStructureDefinition<StructureDefinition> getDao() {
return (IFhirResourceDaoStructureDefinition<StructureDefinition>) super.getDao();
}
}

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