diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 7874bf40a3b..44fed4bfde0 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -25,7 +25,7 @@ jobs:
if: ${{ github.event_name == 'pull_request' }}
- name: Setup java
- uses: actions/setup-java@v2
+ uses: actions/setup-java@v3
with:
distribution: zulu
java-version: 17
diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java
index b901097f2db..7881deef30b 100644
--- a/.mvn/wrapper/MavenWrapperDownloader.java
+++ b/.mvn/wrapper/MavenWrapperDownloader.java
@@ -13,9 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import java.net.*;
-import java.io.*;
-import java.nio.channels.*;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.Authenticator;
+import java.net.PasswordAuthentication;
+import java.net.URL;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
import java.util.Properties;
public class MavenWrapperDownloader {
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 4823ea9b222..8f0a48f0f3a 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -4,7 +4,7 @@
repos:
- repo: https://github.com/ejba/pre-commit-maven
- rev: v0.3.3
+ rev: v0.3.4
hooks:
- id: maven-spotless-apply
stages: [pre-push]
diff --git a/hapi-deployable-pom/pom.xml b/hapi-deployable-pom/pom.xml
index 5e53eca724d..e0fdc9defbd 100644
--- a/hapi-deployable-pom/pom.xml
+++ b/hapi-deployable-pom/pom.xml
@@ -5,7 +5,7 @@
null
.
+ * @param theDisplayLanguage Used to filter out the designation by the display language. To return all designation, set this value to null
.
*/
+ @Deprecated
@Nullable
default LookupCodeResult lookupCode(
ValidationSupportContext theValidationSupportContext,
@@ -347,12 +350,14 @@ public interface IValidationSupport {
/**
* Look up a code using the system and code value
+ * @deprecated This method has been deprecated in HAPI FHIR 7.0.0. Use {@link IValidationSupport#lookupCode(ValidationSupportContext, LookupCodeRequest)} instead.
*
* @param theValidationSupportContext The validation support module will be passed in to this method. This is convenient in cases where the operation needs to make calls to
* other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter.
* @param theSystem The CodeSystem URL
* @param theCode The code
*/
+ @Deprecated
@Nullable
default LookupCodeResult lookupCode(
ValidationSupportContext theValidationSupportContext, String theSystem, String theCode) {
@@ -360,7 +365,26 @@ public interface IValidationSupport {
}
/**
- * Returns true
if the given valueset can be validated by the given
+ * Look up a code using the system, code and other parameters captured in {@link LookupCodeRequest}.
+ * @since 7.0.0
+ *
+ * @param theValidationSupportContext The validation support module will be passed in to this method. This is convenient in cases where the operation needs to make calls to
+ * other method in the support chain, so that they can be passed through the entire chain. Implementations of this interface may always safely ignore this parameter.
+ * @param theLookupCodeRequest The parameters used to perform the lookup, including system and code.
+ */
+ @Nullable
+ default LookupCodeResult lookupCode(
+ ValidationSupportContext theValidationSupportContext, @Nonnull LookupCodeRequest theLookupCodeRequest) {
+ // TODO: can change to return null once the deprecated methods are removed
+ return lookupCode(
+ theValidationSupportContext,
+ theLookupCodeRequest.getSystem(),
+ theLookupCodeRequest.getCode(),
+ theLookupCodeRequest.getDisplayLanguage());
+ }
+
+ /**
+ * Returns true
if the given ValueSet can be validated by the given
* validation support module
*
* @param theValidationSupportContext The validation support module will be passed in to this method. This is convenient in cases where the operation needs to make calls to
@@ -409,6 +433,13 @@ public interface IValidationSupport {
return null;
}
+ /**
+ * This field is used by the Terminology Troubleshooting Log to log which validation support module was used for the operation being logged.
+ */
+ default String getName() {
+ return "Unknown " + getFhirContext().getVersion().getVersion() + " Validation Support";
+ }
+
enum IssueSeverity {
/**
* The issue caused the action to fail, and no further checking could be performed.
@@ -495,8 +526,13 @@ public interface IValidationSupport {
public String getPropertyName() {
return myPropertyName;
}
+
+ public abstract String getType();
}
+ String TYPE_STRING = "string";
+ String TYPE_CODING = "Coding";
+
class StringConceptProperty extends BaseConceptProperty {
private final String myValue;
@@ -513,6 +549,10 @@ public interface IValidationSupport {
public String getValue() {
return myValue;
}
+
+ public String getType() {
+ return TYPE_STRING;
+ }
}
class CodingConceptProperty extends BaseConceptProperty {
@@ -543,9 +583,18 @@ public interface IValidationSupport {
public String getDisplay() {
return myDisplay;
}
+
+ public String getType() {
+ return TYPE_CODING;
+ }
}
class CodeValidationResult {
+ public static final String SOURCE_DETAILS = "sourceDetails";
+ public static final String RESULT = "result";
+ public static final String MESSAGE = "message";
+ public static final String DISPLAY = "display";
+
private String myCode;
private String myMessage;
private IssueSeverity mySeverity;
@@ -674,6 +723,23 @@ public interface IValidationSupport {
setSeverity(IssueSeverity.valueOf(theIssueSeverity.toUpperCase()));
return this;
}
+
+ public IBaseParameters toParameters(FhirContext theContext) {
+ IBaseParameters retVal = ParametersUtil.newInstance(theContext);
+
+ ParametersUtil.addParameterToParametersBoolean(theContext, retVal, RESULT, isOk());
+ if (isNotBlank(getMessage())) {
+ ParametersUtil.addParameterToParametersString(theContext, retVal, MESSAGE, getMessage());
+ }
+ if (isNotBlank(getDisplay())) {
+ ParametersUtil.addParameterToParametersString(theContext, retVal, DISPLAY, getDisplay());
+ }
+ if (isNotBlank(getSourceDetails())) {
+ ParametersUtil.addParameterToParametersString(theContext, retVal, SOURCE_DETAILS, getSourceDetails());
+ }
+
+ return retVal;
+ }
}
class ValueSetExpansionOutcome {
@@ -806,7 +872,7 @@ public interface IValidationSupport {
}
public IBaseParameters toParameters(
- FhirContext theContext, List extends IPrimitiveTypenull
.
+ * @param thePropertyNames The collection of properties to be returned in the output. If no properties are specified, the implementor chooses what to return.
+ */
+ public LookupCodeRequest(
+ String theSystem, String theCode, String theDisplayLanguage, Collection
void
.
@@ -101,7 +105,8 @@ public enum Pointcut implements IPointcut {
void.class,
"ca.uhn.fhir.rest.client.api.IHttpRequest",
"ca.uhn.fhir.rest.client.api.IHttpResponse",
- "ca.uhn.fhir.rest.client.api.IRestfulClient"),
+ "ca.uhn.fhir.rest.client.api.IRestfulClient",
+ "ca.uhn.fhir.rest.client.api.ClientResponseContext"),
/**
* Server Hook:
@@ -153,10 +158,10 @@ public enum Pointcut implements IPointcut {
* Hooks may accept the following parameters:
* @@ -263,8 +268,8 @@ public enum Pointcut implements IPointcut { boolean.class, "ca.uhn.fhir.rest.api.server.RequestDetails", "ca.uhn.fhir.rest.server.servlet.ServletRequestDetails", - "javax.servlet.http.HttpServletRequest", - "javax.servlet.http.HttpServletResponse"), + "jakarta.servlet.http.HttpServletRequest", + "jakarta.servlet.http.HttpServletResponse"), /** * Server Hook: @@ -286,10 +291,10 @@ public enum Pointcut implements IPointcut { * only be populated when operating in a RestfulServer implementation. It is provided as a convenience. * *
@@ -308,8 +313,8 @@ public enum Pointcut implements IPointcut { boolean.class, "ca.uhn.fhir.rest.api.server.RequestDetails", "ca.uhn.fhir.rest.server.servlet.ServletRequestDetails", - "javax.servlet.http.HttpServletRequest", - "javax.servlet.http.HttpServletResponse"), + "jakarta.servlet.http.HttpServletRequest", + "jakarta.servlet.http.HttpServletResponse"), /** * Server Hook: @@ -411,10 +416,10 @@ public enum Pointcut implements IPointcut { * {@link NullPointerException} in the case of a bug being triggered. * *
@@ -429,8 +434,8 @@ public enum Pointcut implements IPointcut { "ca.uhn.fhir.rest.api.server.RequestDetails", "ca.uhn.fhir.rest.server.servlet.ServletRequestDetails", "java.lang.Throwable", - "javax.servlet.http.HttpServletRequest", - "javax.servlet.http.HttpServletResponse"), + "jakarta.servlet.http.HttpServletRequest", + "jakarta.servlet.http.HttpServletResponse"), /** * Server Hook: @@ -458,10 +463,10 @@ public enum Pointcut implements IPointcut { * ca.uhn.fhir.rest.api.server.ResponseDetails - This object contains details about the response, including the contents. Hook methods may modify this object to change or replace the response. * *
+ * Hooks will have access to the content of the job being created + * and may choose to make modifications to it. These changes will be + * reflected in permanent storage. + *
+ * Hooks may accept the following parameters: + *
+ * Hooks should return void
.
+ *
- * { - * "key": "value" - * } - *- * in order to be consistent with Gson behaviour, instead of the jackson default - *
- * { - * "key" : "value" - * } - *- */ - @Override - public DefaultPrettyPrinter withSeparators(Separators separators) { - _separators = separators; - _objectFieldValueSeparatorWithSpaces = separators.getObjectFieldValueSeparator() + " "; - return this; - } - }; + DefaultPrettyPrinter prettyPrinter = new DefaultPrettyPrinter() + .withSeparators(new Separators( + Separators.DEFAULT_ROOT_VALUE_SEPARATOR, + ':', + Separators.Spacing.AFTER, + ',', + Separators.Spacing.NONE, + ',', + Separators.Spacing.NONE)); prettyPrinter = prettyPrinter.withObjectIndenter(new DefaultIndenter(" ", "\n")); myJsonGenerator.setPrettyPrinter(prettyPrinter); diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/annotation/Operation.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/annotation/Operation.java index 83907544fc5..69a521a77ec 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/annotation/Operation.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/annotation/Operation.java @@ -118,7 +118,7 @@ public @interface Operation { * always the right choice), the framework will not attempt to generate a response to * this method. *
- * This is useful if you want to include an {@link javax.servlet.http.HttpServletResponse}
+ * This is useful if you want to include an {@link jakarta.servlet.http.HttpServletResponse}
* in your method parameters and create a response yourself directly from your
* @Operation
method.
*
@Operation
method.
* - * This is useful if you want to include an {@link javax.servlet.http.HttpServletRequest} + * This is useful if you want to include an {@link jakarta.servlet.http.HttpServletRequest} * in your method parameters and parse the request yourself. *
*/ diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/annotation/Read.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/annotation/Read.java index 4276229f630..aedd0656b36 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/annotation/Read.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/annotation/Read.java @@ -23,7 +23,10 @@ import ca.uhn.fhir.rest.client.api.IBasicClient; import ca.uhn.fhir.rest.client.api.IRestfulClient; import org.hl7.fhir.instance.model.api.IBaseResource; -import java.lang.annotation.*; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * RESTful method annotation to be used for the FHIR read and transaction method. diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/annotation/TransactionParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/annotation/TransactionParam.java index 8e50b13c9bb..51539b5d384 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/annotation/TransactionParam.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/annotation/TransactionParam.java @@ -19,7 +19,10 @@ */ package ca.uhn.fhir.rest.annotation; -import java.lang.annotation.*; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import java.util.List; /** diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/annotation/Validate.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/annotation/Validate.java index 7826df8daee..2ece6309e97 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/annotation/Validate.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/annotation/Validate.java @@ -22,7 +22,10 @@ package ca.uhn.fhir.rest.annotation; import ca.uhn.fhir.rest.api.ValidationModeEnum; import org.hl7.fhir.instance.model.api.IBaseResource; -import java.lang.annotation.*; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * RESTful method annotation to be used for the FHIR diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/Constants.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/Constants.java index ab3faa6862d..00d0b90799d 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/Constants.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/Constants.java @@ -199,6 +199,8 @@ public class Constants { public static final String PARAM_PRETTY_VALUE_FALSE = "false"; public static final String PARAM_PRETTY_VALUE_TRUE = "true"; public static final String PARAM_PROFILE = "_profile"; + public static final String PARAM_PID = "_pid"; + public static final String PARAM_QUERY = "_query"; public static final String PARAM_RESPONSE_URL = "response-url"; // Used in messaging public static final String PARAM_REVINCLUDE = "_revinclude"; @@ -218,21 +220,6 @@ public class Constants { public static final String PARAM_TEXT = "_text"; public static final String PARAM_VALIDATE = "_validate"; - /** - * $member-match operation - */ - public static final String PARAM_MEMBER_PATIENT = "MemberPatient"; - - public static final String PARAM_MEMBER_IDENTIFIER = "MemberIdentifier"; - - public static final String PARAM_OLD_COVERAGE = "OldCoverage"; - public static final String PARAM_NEW_COVERAGE = "NewCoverage"; - public static final String PARAM_CONSENT = "Consent"; - public static final String PARAM_MEMBER_PATIENT_NAME = PARAM_MEMBER_PATIENT + " Name"; - public static final String PARAM_MEMBER_PATIENT_BIRTHDATE = PARAM_MEMBER_PATIENT + " Birthdate"; - public static final String PARAM_CONSENT_PATIENT_REFERENCE = PARAM_CONSENT + "'s Patient Reference"; - public static final String PARAM_CONSENT_PERFORMER_REFERENCE = PARAM_CONSENT + "'s Performer Reference"; - public static final String PARAMQUALIFIER_MISSING = ":missing"; public static final String PARAMQUALIFIER_MISSING_FALSE = "false"; public static final String PARAMQUALIFIER_MISSING_TRUE = "true"; @@ -331,6 +318,9 @@ public class Constants { */ public static final int UUID_LENGTH = 36; + public static final String BULK_DATA_ACCESS_IG_URL = + "http://hl7.org/fhir/uv/bulkdata/CapabilityStatement/bulk-data"; + /** * Application configuration key used to enable or disable Hibernate Envers. */ diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/IVersionSpecificBundleFactory.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/IVersionSpecificBundleFactory.java index 946c8943fbf..8027b1e11bc 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/IVersionSpecificBundleFactory.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/IVersionSpecificBundleFactory.java @@ -22,6 +22,8 @@ package ca.uhn.fhir.rest.api; import ca.uhn.fhir.context.api.BundleInclusionRule; import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.valueset.BundleTypeEnum; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IPrimitiveType; @@ -29,8 +31,6 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Set; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; /** * This interface should be considered experimental and will likely change in future releases of HAPI. Use with caution! diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/PatchTypeEnum.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/PatchTypeEnum.java index ea4c764e044..b8383671d80 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/PatchTypeEnum.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/PatchTypeEnum.java @@ -23,10 +23,10 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.i18n.Msg; import ca.uhn.fhir.rest.annotation.Patch; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; +import jakarta.annotation.Nonnull; import java.util.HashMap; import java.util.Map; -import javax.annotation.Nonnull; import static org.apache.commons.lang3.StringUtils.defaultString; import static org.apache.commons.lang3.StringUtils.isBlank; diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/PreferHeader.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/PreferHeader.java index 09d42fdce25..03f9a115215 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/PreferHeader.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/PreferHeader.java @@ -19,7 +19,7 @@ */ package ca.uhn.fhir.rest.api; -import javax.annotation.Nullable; +import jakarta.annotation.Nullable; public class PreferHeader { diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/PreferReturnEnum.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/PreferReturnEnum.java index 07ab10f62c0..09a945ca651 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/PreferReturnEnum.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/PreferReturnEnum.java @@ -19,8 +19,9 @@ */ package ca.uhn.fhir.rest.api; +import jakarta.annotation.Nullable; + import java.util.HashMap; -import javax.annotation.Nullable; /** * Represents values for "return" value as provided in the the HTTP Prefer header. diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestOperationTypeEnum.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestOperationTypeEnum.java index 9a37ca86aa2..cd864314b82 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestOperationTypeEnum.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestOperationTypeEnum.java @@ -20,11 +20,11 @@ package ca.uhn.fhir.rest.api; import ca.uhn.fhir.util.CoverageIgnore; +import jakarta.annotation.Nonnull; import org.apache.commons.lang3.Validate; import java.util.HashMap; import java.util.Map; -import javax.annotation.Nonnull; @CoverageIgnore public enum RestOperationTypeEnum { diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/api/ClientResponseContext.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/api/ClientResponseContext.java new file mode 100644 index 00000000000..b0748bf2ab7 --- /dev/null +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/api/ClientResponseContext.java @@ -0,0 +1,103 @@ +/*- + * #%L + * HAPI FHIR - Core Library + * %% + * Copyright (C) 2014 - 2023 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% + */ +package ca.uhn.fhir.rest.client.api; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.interceptor.api.Pointcut; +import org.hl7.fhir.instance.model.api.IBaseResource; + +import java.util.Objects; +import java.util.StringJoiner; + +/** + * Used to pass context to {@link Pointcut#CLIENT_RESPONSE}, including a mutable {@link IHttpResponse} + */ +public class ClientResponseContext { + private final IHttpRequest myHttpRequest; + private IHttpResponse myHttpResponse; + private final IRestfulClient myRestfulClient; + private final FhirContext myFhirContext; + private final Class extends IBaseResource> myReturnType; + + public ClientResponseContext( + IHttpRequest myHttpRequest, + IHttpResponse theHttpResponse, + IRestfulClient myRestfulClient, + FhirContext theFhirContext, + Class extends IBaseResource> theReturnType) { + this.myHttpRequest = myHttpRequest; + this.myHttpResponse = theHttpResponse; + this.myRestfulClient = myRestfulClient; + this.myFhirContext = theFhirContext; + this.myReturnType = theReturnType; + } + + public IHttpRequest getHttpRequest() { + return myHttpRequest; + } + + public IHttpResponse getHttpResponse() { + return myHttpResponse; + } + + public IRestfulClient getRestfulClient() { + return myRestfulClient; + } + + public FhirContext getFhirContext() { + return myFhirContext; + } + + public Class extends IBaseResource> getReturnType() { + return myReturnType; + } + + public void setHttpResponse(IHttpResponse theHttpResponse) { + this.myHttpResponse = theHttpResponse; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + ClientResponseContext that = (ClientResponseContext) o; + return Objects.equals(myHttpRequest, that.myHttpRequest) + && Objects.equals(myHttpResponse, that.myHttpResponse) + && Objects.equals(myRestfulClient, that.myRestfulClient) + && Objects.equals(myFhirContext, that.myFhirContext) + && Objects.equals(myReturnType, that.myReturnType); + } + + @Override + public int hashCode() { + return Objects.hash(myHttpRequest, myHttpResponse, myRestfulClient, myFhirContext, myReturnType); + } + + @Override + public String toString() { + return new StringJoiner(", ", ClientResponseContext.class.getSimpleName() + "[", "]") + .add("myHttpRequest=" + myHttpRequest) + .add("myHttpResponse=" + myHttpResponse) + .add("myRestfulClient=" + myRestfulClient) + .add("myFhirContext=" + myFhirContext) + .add("myReturnType=" + myReturnType) + .toString(); + } +} diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/api/IRestfulClient.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/api/IRestfulClient.java index daec727f9f8..2f49f863fda 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/api/IRestfulClient.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/api/IRestfulClient.java @@ -24,10 +24,9 @@ import ca.uhn.fhir.interceptor.api.IInterceptorService; import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.RequestFormatParamStyleEnum; import ca.uhn.fhir.rest.api.SummaryEnum; +import jakarta.annotation.Nonnull; import org.hl7.fhir.instance.model.api.IBaseResource; -import javax.annotation.Nonnull; - public interface IRestfulClient { /** diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/TokenClientParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/TokenClientParam.java index 2f8a91f22f4..d51b427f271 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/TokenClientParam.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/gclient/TokenClientParam.java @@ -23,7 +23,9 @@ import ca.uhn.fhir.model.base.composite.BaseIdentifierDt; import org.apache.commons.lang3.ObjectUtils; import org.hl7.fhir.instance.model.api.IBaseCoding; -import java.util.*; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; import static org.apache.commons.lang3.StringUtils.defaultString; diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java index c1192fe5f70..ce6c7c51776 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/DateRangeParam.java @@ -27,6 +27,7 @@ import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.rest.api.QualifiedParamList; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.util.DateUtils; +import jakarta.annotation.Nonnull; import org.apache.commons.lang3.Validate; import org.hl7.fhir.instance.model.api.IPrimitiveType; @@ -34,7 +35,6 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Objects; -import javax.annotation.Nonnull; import static ca.uhn.fhir.rest.param.ParamPrefixEnum.EQUAL; import static ca.uhn.fhir.rest.param.ParamPrefixEnum.GREATERTHAN_OR_EQUALS; diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ParamPrefixEnum.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ParamPrefixEnum.java index 3763c5292ae..56910ea563b 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ParamPrefixEnum.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ParamPrefixEnum.java @@ -19,7 +19,9 @@ */ package ca.uhn.fhir.rest.param; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; /** * Comparator/qualifier for values used in REST params, such as {@link DateParam}, {@link NumberParam}, and diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/AttachmentUtil.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/AttachmentUtil.java index 9e7d82dd51d..cbb1adceb58 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/AttachmentUtil.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/AttachmentUtil.java @@ -19,7 +19,11 @@ */ package ca.uhn.fhir.util; -import ca.uhn.fhir.context.*; +import ca.uhn.fhir.context.BaseRuntimeChildDefinition; +import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition; +import ca.uhn.fhir.context.BaseRuntimeElementDefinition; +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.context.FhirVersionEnum; import org.apache.commons.lang3.Validate; import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.ICompositeType; diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/BundleBuilder.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/BundleBuilder.java index 4c2bd44fb72..a073f2a0dcf 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/BundleBuilder.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/BundleBuilder.java @@ -25,6 +25,8 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.model.primitive.IdDt; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; import org.apache.commons.lang3.Validate; import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBaseBackboneElement; @@ -36,8 +38,6 @@ import org.hl7.fhir.instance.model.api.IPrimitiveType; import java.util.Date; import java.util.Objects; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; /** * This class can be used to build a Bundle resource to be used as a FHIR transaction. Convenience methods provide @@ -196,11 +196,7 @@ public class BundleBuilder { public UpdateBuilder addTransactionUpdateEntry(IBaseResource theResource) { Validate.notNull(theResource, "theResource must not be null"); - IIdType id = theResource.getIdElement(); - if (id.hasIdPart() && !id.hasResourceType()) { - String resourceType = myContext.getResourceType(theResource); - id = id.withResourceType(resourceType); - } + IIdType id = getIdTypeForUpdate(theResource); String requestUrl = id.toUnqualifiedVersionless().getValue(); String fullUrl = id.getValue(); @@ -225,13 +221,29 @@ public class BundleBuilder { myEntryRequestUrlChild.getMutator().setValue(request, url); // Bundle.entry.request.method - IPrimitiveType> method = (IPrimitiveType>) - myEntryRequestMethodDef.newInstance(myEntryRequestMethodChild.getInstanceConstructorArguments()); - method.setValueAsString(theHttpVerb); - myEntryRequestMethodChild.getMutator().setValue(request, method); + addRequestMethod(request, theHttpVerb); return url; } + /** + * Adds an entry containing an update (UPDATE) request without the body of the resource. + * Also sets the Bundle.type value to "transaction" if it is not already set. + * + * @param theResource The resource to update. + */ + public void addTransactionUpdateIdOnlyEntry(IBaseResource theResource) { + setBundleField("type", "transaction"); + + Validate.notNull(theResource, "theResource must not be null"); + + IIdType id = getIdTypeForUpdate(theResource); + String requestUrl = id.toUnqualifiedVersionless().getValue(); + String fullUrl = id.getValue(); + String httpMethod = "PUT"; + + addIdOnlyEntry(requestUrl, httpMethod, fullUrl); + } + /** * Adds an entry containing an create (POST) request. * Also sets the Bundle.type value to "transaction" if it is not already set. @@ -247,20 +259,47 @@ public class BundleBuilder { String resourceType = myContext.getResourceType(theResource); // Bundle.entry.request.url - IPrimitiveType> url = - (IPrimitiveType>) myContext.getElementDefinition("uri").newInstance(); - url.setValueAsString(resourceType); - myEntryRequestUrlChild.getMutator().setValue(request, url); + addRequestUrl(request, resourceType); - // Bundle.entry.request.url - IPrimitiveType> method = (IPrimitiveType>) - myEntryRequestMethodDef.newInstance(myEntryRequestMethodChild.getInstanceConstructorArguments()); - method.setValueAsString("POST"); - myEntryRequestMethodChild.getMutator().setValue(request, method); + // Bundle.entry.request.method + addRequestMethod(request, "POST"); return new CreateBuilder(request); } + /** + * Adds an entry containing a create (POST) request without the body of the resource. + * Also sets the Bundle.type value to "transaction" if it is not already set. + * + * @param theResource The resource to create + */ + public void addTransactionCreateEntryIdOnly(IBaseResource theResource) { + setBundleField("type", "transaction"); + + String requestUrl = myContext.getResourceType(theResource); + String fullUrl = theResource.getIdElement().getValue(); + String httpMethod = "POST"; + + addIdOnlyEntry(requestUrl, httpMethod, fullUrl); + } + + private void addIdOnlyEntry(String theRequestUrl, String theHttpMethod, String theFullUrl) { + IBase entry = addEntry(); + + // Bundle.entry.request + IBase request = myEntryRequestDef.newInstance(); + myEntryRequestChild.getMutator().setValue(entry, request); + + // Bundle.entry.request.url + addRequestUrl(request, theRequestUrl); + + // Bundle.entry.request.method + addRequestMethod(request, theHttpMethod); + + // Bundle.entry.fullUrl + addFullUrl(entry, theFullUrl); + } + /** * Adds an entry containing a delete (DELETE) request. * Also sets the Bundle.type value to "transaction" if it is not already set. @@ -341,20 +380,44 @@ public class BundleBuilder { IBase request = addEntryAndReturnRequest(); // Bundle.entry.request.url - IPrimitiveType> url = - (IPrimitiveType>) myContext.getElementDefinition("uri").newInstance(); - url.setValueAsString(theDeleteUrl); - myEntryRequestUrlChild.getMutator().setValue(request, url); + addRequestUrl(request, theDeleteUrl); // Bundle.entry.request.method - IPrimitiveType> method = (IPrimitiveType>) - myEntryRequestMethodDef.newInstance(myEntryRequestMethodChild.getInstanceConstructorArguments()); - method.setValueAsString("DELETE"); - myEntryRequestMethodChild.getMutator().setValue(request, method); + addRequestMethod(request, "DELETE"); return new DeleteBuilder(); } + private IIdType getIdTypeForUpdate(IBaseResource theResource) { + IIdType id = theResource.getIdElement(); + if (id.hasIdPart() && !id.hasResourceType()) { + String resourceType = myContext.getResourceType(theResource); + id = id.withResourceType(resourceType); + } + return id; + } + + private void addFullUrl(IBase theEntry, String theFullUrl) { + IPrimitiveType> fullUrl = + (IPrimitiveType>) myContext.getElementDefinition("uri").newInstance(); + fullUrl.setValueAsString(theFullUrl); + myEntryFullUrlChild.getMutator().setValue(theEntry, fullUrl); + } + + private void addRequestUrl(IBase request, String theRequestUrl) { + IPrimitiveType> url = + (IPrimitiveType>) myContext.getElementDefinition("uri").newInstance(); + url.setValueAsString(theRequestUrl); + myEntryRequestUrlChild.getMutator().setValue(request, url); + } + + private void addRequestMethod(IBase theRequest, String theMethod) { + IPrimitiveType> method = (IPrimitiveType>) + myEntryRequestMethodDef.newInstance(myEntryRequestMethodChild.getInstanceConstructorArguments()); + method.setValueAsString(theMethod); + myEntryRequestMethodChild.getMutator().setValue(theRequest, method); + } + /** * Adds an entry for a Collection bundle type */ @@ -406,10 +469,7 @@ public class BundleBuilder { IBase entry = addEntry(); // Bundle.entry.fullUrl - IPrimitiveType> fullUrl = - (IPrimitiveType>) myContext.getElementDefinition("uri").newInstance(); - fullUrl.setValueAsString(theFullUrl); - myEntryFullUrlChild.getMutator().setValue(entry, fullUrl); + addFullUrl(entry, theFullUrl); // Bundle.entry.resource myEntryResourceChild.getMutator().setValue(entry, theResource); diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/BundleUtil.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/BundleUtil.java index 2ed1a3b47af..98fc0bfac63 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/BundleUtil.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/BundleUtil.java @@ -35,10 +35,12 @@ import ca.uhn.fhir.util.bundle.EntryListAccumulator; import ca.uhn.fhir.util.bundle.ModifiableBundleEntry; import ca.uhn.fhir.util.bundle.SearchBundleEntryParts; import com.google.common.collect.Sets; +import jakarta.annotation.Nonnull; import org.apache.commons.lang3.tuple.Pair; import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBaseBinary; import org.hl7.fhir.instance.model.api.IBaseBundle; +import org.hl7.fhir.instance.model.api.IBaseReference; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IPrimitiveType; import org.slf4j.Logger; @@ -693,6 +695,25 @@ public class BundleUtil { return bundleEntry; } + /** + * Get resource from bundle by resource type and reference + * @param theContext FhirContext + * @param theBundle IBaseBundle + * @param theReference IBaseReference + * @return IBaseResource if found and null if not found. + */ + @Nonnull + public static IBaseResource getResourceByReferenceAndResourceType( + @Nonnull FhirContext theContext, @Nonnull IBaseBundle theBundle, @Nonnull IBaseReference theReference) { + return toListOfResources(theContext, theBundle).stream() + .filter(theResource -> theReference + .getReferenceElement() + .getIdPart() + .equals(theResource.getIdElement().getIdPart())) + .findFirst() + .orElse(null); + } + private static class SortLegality { private boolean myIsLegal; diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ClasspathUtil.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ClasspathUtil.java index f22e114484e..03a81448288 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ClasspathUtil.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ClasspathUtil.java @@ -24,6 +24,7 @@ import ca.uhn.fhir.i18n.Msg; import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import com.google.common.base.Charsets; +import jakarta.annotation.Nonnull; import org.apache.commons.io.IOUtils; import org.apache.commons.io.input.BOMInputStream; import org.hl7.fhir.instance.model.api.IBaseResource; @@ -37,7 +38,6 @@ import java.io.Reader; import java.nio.charset.StandardCharsets; import java.util.function.Function; import java.util.zip.GZIPInputStream; -import javax.annotation.Nonnull; /** * Use this API with caution, it may change! diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/CompositionBuilder.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/CompositionBuilder.java index 2cd02c96e09..a20c383a2be 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/CompositionBuilder.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/CompositionBuilder.java @@ -21,6 +21,7 @@ package ca.uhn.fhir.util; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.RuntimeResourceDefinition; +import jakarta.annotation.Nonnull; import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBaseCoding; import org.hl7.fhir.instance.model.api.IBaseReference; @@ -29,7 +30,6 @@ import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.instance.model.api.IPrimitiveType; import java.util.Date; -import javax.annotation.Nonnull; /** * This class can be used to generateComposition
resources in
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/DateRangeUtil.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/DateRangeUtil.java
index 6e488c39a2d..6204c5d1897 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/DateRangeUtil.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/DateRangeUtil.java
@@ -20,10 +20,10 @@
package ca.uhn.fhir.util;
import ca.uhn.fhir.rest.param.DateRangeParam;
+import jakarta.annotation.Nonnull;
+import jakarta.annotation.Nullable;
import java.util.Date;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
public class DateRangeUtil {
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ExtensionUtil.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ExtensionUtil.java
index 074fbac22f3..9b100ec1309 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ExtensionUtil.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ExtensionUtil.java
@@ -21,6 +21,7 @@ package ca.uhn.fhir.util;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.i18n.Msg;
+import jakarta.annotation.Nonnull;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBase;
@@ -33,7 +34,6 @@ import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;
-import javax.annotation.Nonnull;
/**
* Utility for modifying with extensions in a FHIR version-independent approach.
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/FhirTerser.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/FhirTerser.java
index 4e4319076c3..9b812de7198 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/FhirTerser.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/FhirTerser.java
@@ -42,6 +42,8 @@ import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.parser.DataFormatException;
import com.google.common.collect.Lists;
+import jakarta.annotation.Nonnull;
+import jakarta.annotation.Nullable;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBase;
@@ -71,8 +73,6 @@ import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isBlank;
@@ -287,9 +287,33 @@ public class FhirTerser {
return retVal;
}
+ /**
+ * Extracts all outbound references from a resource
+ *
+ * @param theResource the resource to be analyzed
+ * @return a list of references to other resources
+ */
public ListHASH_IDENTITY | ++ | Long | ++ | + A hash of SP_NAME and RES_TYPE. Used to narrow the table to a specific SearchParameter during sorting, and some queries. + | +||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SP_UPDATED | @@ -550,12 +564,13 @@ The following columns are common to **all HFJ_SPIDX_xxx tables**. # HFJ_SPIDX_DATE: Date Search Parameters -For any FHIR Search Parameter of type *date* that generates a database index, a row in the *HFJ_SPIDX_DATE* table will be created. +For any FHIR Search Parameter of type [*date*](https://www.hl7.org/fhir/search.html#date) that generates a database index, a row in the `HFJ_SPIDX_DATE` table will be created. +Range queries with Date parameters (e.g. `Observation?date=ge2020-01-01`) will query the HASH_IDENTITY, SP_VALUE_LOW_DATE_ORDINAL and/or SP_VALUE_HIGH_DATE_ORDINAL columns. +Range queries with DateTime parameters (e.g. `Observation?date=ge2021-01-01T10:30:00`) will query the HASH_IDENTITY, SP_VALUE_LOW and/or SP_VALUE_HIGH columns. +Sorting is done by the SP_VALUE_LOW column. ## Columns -The following columns are common to **all HFJ_SPIDX_xxx tables**. - |
Name | +Relationships | +Datatype | +Nullable | +Description | +
---|---|---|---|---|
SP_VALUE | ++ | Double | +Not nullable | ++ This is the value extracted by the SearchParameter expression. + | +
Name | +Relationships | +Datatype | +Nullable | +Description | +
---|---|---|---|---|
HASH_IDENTITY_AND_UNITS | ++ | Long | ++ | + A hash like HASH_IDENTITY that also includes the SP_UNITS column. + | +
HASH_IDENTITY_SYS_UNITS | ++ | Long | ++ | + A hash like HASH_IDENTITY that also includes the SP_SYSTEM and SP_UNITS columns. + | +
SP_SYSTEM | ++ | String | ++ | + The system of the quantity units. e.g. "http://unitsofmeasure.org". + | +
SP_UNITS | ++ | String | ++ | + The units of the quantity. E.g. "mg". + | +
SP_VALUE | ++ | Double | ++ | + This is the value extracted by the SearchParameter expression. + | +
Name | +Relationships | +Datatype | +Nullable | +Description | +
---|---|---|---|---|
HASH_EXACT | ++ | Long | ++ | + A hash like HASH_IDENTITY that also includes the SP_VALUE_EXACT column. + | +
SP_VALUE_NORMALIZED | ++ | String | ++ | + An UPPERCASE string with accents removed. + | +
SP_VALUE_EXACT | ++ | String | ++ | + The extracted string unchanged. + | +
Name | +Relationships | +Datatype | +Nullable | +Description | +
---|---|---|---|---|
HASH_VALUE | ++ | Long | ++ | + A hash like HASH_IDENTITY that also includes the SP_VALUE column. + | +
HASH_SYS_AND_VALUE | ++ | Long | ++ | + A hash like HASH_IDENTITY that also includes the SP_SYSTEM and SP_VALUE columns. + | +
HASH_SYS | ++ | Long | ++ | + A hash like HASH_IDENTITY that also includes the SP_SYSTEM column. + | +
SP_SYSTEM | ++ | String | ++ | + The system of the code. + | +
SP_VALUE | ++ | String | ++ | + This is the bare code value. + | +
Name | +Relationships | +Datatype | +Nullable | +Description | +
---|---|---|---|---|
HASH_URI | ++ | Long | ++ | + A hash like HASH_IDENTITY that also includes the SP_URI column. + | +
SP_URI | ++ | String | ++ | + The uri string extracted by the SearchParameter. + | +
[baseUrl]?_getpages=foo
request, which is a request to the
diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java
index 6d3e3b17cd2..b297ee90daa 100644
--- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java
+++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsProvider.java
@@ -29,16 +29,16 @@ import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest.Builder;
import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
import ca.uhn.fhir.rest.server.*;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.UriInfo;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.util.Map.Entry;
import java.util.*;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
/**
* This is the abstract superclass for all jaxrs providers. It contains some defaults implementing
@@ -103,7 +103,7 @@ public abstract class AbstractJaxRsProvider implements IRestfulServerDefaults {
/**
* This method returns the server base, independent of the request or resource.
*
- * @see javax.ws.rs.core.UriInfo#getBaseUri()
+ * @see jakarta.ws.rs.core.UriInfo#getBaseUri()
* @return the ascii string for the server base
*/
public String getBaseForServer() {
diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProvider.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProvider.java
index ebb634294af..5feb325154e 100644
--- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProvider.java
+++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/AbstractJaxRsResourceProvider.java
@@ -30,14 +30,21 @@ import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.server.IPagingProvider;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.method.BaseMethodBinding;
+import jakarta.interceptor.Interceptors;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.DELETE;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.PUT;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
import org.hl7.fhir.instance.model.api.IBaseResource;
import java.io.IOException;
import java.net.URL;
-import javax.interceptor.Interceptors;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.*;
/**
* This server is the abstract superclass for all resource providers. It exposes
diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/interceptor/JaxRsExceptionInterceptor.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/interceptor/JaxRsExceptionInterceptor.java
index 19b046cf2d9..f58be619bec 100644
--- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/interceptor/JaxRsExceptionInterceptor.java
+++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/interceptor/JaxRsExceptionInterceptor.java
@@ -24,12 +24,12 @@ import ca.uhn.fhir.jaxrs.server.util.JaxRsRequest;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.interceptor.ExceptionHandlingInterceptor;
+import jakarta.interceptor.AroundInvoke;
+import jakarta.interceptor.InvocationContext;
+import jakarta.servlet.ServletException;
+import jakarta.ws.rs.core.Response;
import java.io.IOException;
-import javax.interceptor.AroundInvoke;
-import javax.interceptor.InvocationContext;
-import javax.servlet.ServletException;
-import javax.ws.rs.core.Response;
/**
* An interceptor that catches the jax-rs exceptions
diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/interceptor/JaxRsResponseException.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/interceptor/JaxRsResponseException.java
index 8b14284e530..14100369b86 100644
--- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/interceptor/JaxRsResponseException.java
+++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/interceptor/JaxRsResponseException.java
@@ -20,8 +20,7 @@
package ca.uhn.fhir.jaxrs.server.interceptor;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
-
-import javax.ejb.ApplicationException;
+import jakarta.ejb.ApplicationException;
/**
* A JEE wrapper exception that will not force a rollback.
diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/util/JaxRsRequest.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/util/JaxRsRequest.java
index 3fd75c52e6f..52a9177ffd5 100644
--- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/util/JaxRsRequest.java
+++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/util/JaxRsRequest.java
@@ -32,6 +32,8 @@ import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.method.ResourceParameter;
import ca.uhn.fhir.util.UrlUtil;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.MediaType;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
@@ -42,8 +44,6 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
/**
* The JaxRsRequest is a jax-rs specific implementation of the RequestDetails.
diff --git a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/util/JaxRsResponse.java b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/util/JaxRsResponse.java
index 5d08b17f87e..1de1682f63d 100644
--- a/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/util/JaxRsResponse.java
+++ b/hapi-fhir-jaxrsserver-base/src/main/java/ca/uhn/fhir/jaxrs/server/util/JaxRsResponse.java
@@ -22,6 +22,9 @@ package ca.uhn.fhir.jaxrs.server.util;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.server.BaseRestfulResponse;
import ca.uhn.fhir.util.IoUtil;
+import jakarta.annotation.Nonnull;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.ResponseBuilder;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
@@ -32,9 +35,6 @@ import java.io.StringWriter;
import java.io.Writer;
import java.util.List;
import java.util.Map.Entry;
-import javax.annotation.Nonnull;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.ResponseBuilder;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
diff --git a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/client/GenericJaxRsClientDstu2Test.java b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/client/GenericJaxRsClientDstu2Test.java
index 4392426bc20..725c8268525 100644
--- a/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/client/GenericJaxRsClientDstu2Test.java
+++ b/hapi-fhir-jaxrsserver-base/src/test/java/ca/uhn/fhir/jaxrs/client/GenericJaxRsClientDstu2Test.java
@@ -27,38 +27,26 @@ import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.PreferReturnEnum;
import ca.uhn.fhir.rest.api.SearchStyleEnum;
import ca.uhn.fhir.rest.api.SummaryEnum;
-import ca.uhn.fhir.rest.client.api.Header;
import ca.uhn.fhir.rest.client.api.IGenericClient;
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
import ca.uhn.fhir.rest.client.exceptions.InvalidResponseException;
import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
import ca.uhn.fhir.rest.param.DateRangeParam;
-import ca.uhn.fhir.test.utilities.JettyUtil;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import org.apache.commons.io.Charsets;
+import ca.uhn.fhir.test.utilities.server.HttpServletExtension;
+import ca.uhn.fhir.test.utilities.server.RequestCaptureServlet;
import org.apache.commons.io.IOUtils;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.AbstractHandler;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseResource;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
import java.util.ArrayList;
import java.util.Date;
-import java.util.Enumeration;
import java.util.List;
-import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
@@ -73,23 +61,15 @@ import static org.junit.jupiter.api.Assertions.fail;
public class GenericJaxRsClientDstu2Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(GenericJaxRsClientDstu2Test.class);
- private static FhirContext ourCtx;
- private static int ourPort;
- private static Server ourServer;
- private static int ourResponseCount = 0;
- private static String[] ourResponseBodies;
- private static String ourResponseBody;
- private static String ourResponseContentType;
- private static int ourResponseStatus;
- private static String ourRequestUri;
- private static ListResourceTable#getFhirVersion()
+ * would look like:
+ * + * RES_VERSION varchar(7) check (RES_VERSION in ('DSTU2','DSTU2_HL7ORG','DSTU2_1','DSTU3','R4','R4B','R5')), + *+ *
+ * This is a nice addition since it enforces the values that the Enum allows, but it's problematic for us because these + * constraints are invisible to the JDBC metadata API on most databases, which means that our schema migration + * checker isn't able to catch problems if we add a value to an Enum and don't add a corresponding database + * migration. Rather than risk having inconsistent behaviour between annotated and migrated schemas, we just + * disable these checks on all of our dialects. + *
+ * See this discussion from the author of SchemaCrawler discussing this limitation: + * https://stackoverflow.com/questions/63346650/schemacrawler-java-api-retrieve-check-column-constraints. + * With this change in place, the definition above becomes simply: + *
+ * RES_VERSION varchar(7), + *+ * + */ + @Override + public boolean supportsColumnCheck() { + return false; + } +} diff --git a/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirMariaDBDialect.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirMariaDBDialect.java new file mode 100644 index 00000000000..0a121b8f3f5 --- /dev/null +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirMariaDBDialect.java @@ -0,0 +1,42 @@ +/*- + * #%L + * HAPI FHIR JPA Model + * %% + * Copyright (C) 2014 - 2023 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% + */ +package ca.uhn.fhir.jpa.model.dialect; + +import org.hibernate.dialect.DatabaseVersion; +import org.hibernate.dialect.MariaDBDialect; + +/** + * Dialect for MySQL database. + * Minimum version: 10.11.5 + */ +public class HapiFhirMariaDBDialect extends MariaDBDialect { + + public HapiFhirMariaDBDialect() { + super(DatabaseVersion.make(10, 11, 5)); + } + + /** + * @see HapiFhirH2Dialect#supportsColumnCheck() for an explanation of why we disable this + */ + @Override + public boolean supportsColumnCheck() { + return false; + } +} diff --git a/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirMySQLDialect.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirMySQLDialect.java new file mode 100644 index 00000000000..8bdbf26ba4c --- /dev/null +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirMySQLDialect.java @@ -0,0 +1,42 @@ +/*- + * #%L + * HAPI FHIR JPA Model + * %% + * Copyright (C) 2014 - 2023 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% + */ +package ca.uhn.fhir.jpa.model.dialect; + +import org.hibernate.dialect.DatabaseVersion; +import org.hibernate.dialect.MySQLDialect; + +/** + * Dialect for MySQL database. + * Minimum version: 5.7 + */ +public class HapiFhirMySQLDialect extends MySQLDialect { + + public HapiFhirMySQLDialect() { + super(DatabaseVersion.make(5, 7)); + } + + /** + * @see HapiFhirH2Dialect#supportsColumnCheck() for an explanation of why we disable this + */ + @Override + public boolean supportsColumnCheck() { + return false; + } +} diff --git a/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirOracleDialect.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirOracleDialect.java new file mode 100644 index 00000000000..ec1095e3765 --- /dev/null +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirOracleDialect.java @@ -0,0 +1,42 @@ +/*- + * #%L + * HAPI FHIR JPA Model + * %% + * Copyright (C) 2014 - 2023 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% + */ +package ca.uhn.fhir.jpa.model.dialect; + +import org.hibernate.dialect.DatabaseVersion; +import org.hibernate.dialect.OracleDialect; + +/** + * Dialect for Oracle database. + * Minimum version: 12.2 (Oracle 12c R2) + */ +public class HapiFhirOracleDialect extends OracleDialect { + + public HapiFhirOracleDialect() { + super(DatabaseVersion.make(12, 2)); + } + + /** + * @see HapiFhirH2Dialect#supportsColumnCheck() for an explanation of why we disable this + */ + @Override + public boolean supportsColumnCheck() { + return false; + } +} diff --git a/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirPostgres94Dialect.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirPostgres94Dialect.java new file mode 100644 index 00000000000..da3a48025ad --- /dev/null +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirPostgres94Dialect.java @@ -0,0 +1,39 @@ +/*- + * #%L + * HAPI FHIR JPA Model + * %% + * Copyright (C) 2014 - 2023 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% + */ +package ca.uhn.fhir.jpa.model.dialect; + +import org.hibernate.dialect.PostgreSQLDialect; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This dialect is recommended when using HAPI FHIR JPA on Postgresql database. + * + * @deprecated Use {@link HapiFhirPostgresDialect} instead + */ +public class HapiFhirPostgres94Dialect extends PostgreSQLDialect { + private static final Logger ourLog = LoggerFactory.getLogger(HapiFhirPostgres94Dialect.class); + + public HapiFhirPostgres94Dialect() { + super(); + ourLog.warn("The " + getClass() + " dialect is deprecated and will be removed in a future release. Use " + + HapiFhirPostgresDialect.class.getName() + " instead"); + } +} diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirPostgres94Dialect.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirPostgresDialect.java similarity index 63% rename from hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirPostgres94Dialect.java rename to hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirPostgresDialect.java index 57f42b5322a..c0a3435b7a1 100644 --- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirPostgres94Dialect.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirPostgresDialect.java @@ -19,17 +19,20 @@ */ package ca.uhn.fhir.jpa.model.dialect; -import org.hibernate.dialect.PostgreSQL94Dialect; +import org.hibernate.dialect.DatabaseVersion; +import org.hibernate.dialect.PostgreSQLDialect; -import java.sql.Types; +public class HapiFhirPostgresDialect extends PostgreSQLDialect { -/** - * This dialect is recommended when using HAPI FHIR JPA on Postgresql database. - */ -public class HapiFhirPostgres94Dialect extends PostgreSQL94Dialect { + public HapiFhirPostgresDialect() { + super(DatabaseVersion.make(10, 0, 0)); + } - public HapiFhirPostgres94Dialect() { - super(); - registerColumnType(Types.CLOB, "oid"); + /** + * @see HapiFhirH2Dialect#supportsColumnCheck() for an explanation of why we disable this + */ + @Override + public boolean supportsColumnCheck() { + return false; } } diff --git a/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirSQLServerDialect.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirSQLServerDialect.java new file mode 100644 index 00000000000..606d91b4dea --- /dev/null +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/model/dialect/HapiFhirSQLServerDialect.java @@ -0,0 +1,42 @@ +/*- + * #%L + * HAPI FHIR JPA Model + * %% + * Copyright (C) 2014 - 2023 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% + */ +package ca.uhn.fhir.jpa.model.dialect; + +import org.hibernate.dialect.DatabaseVersion; +import org.hibernate.dialect.SQLServerDialect; + +/** + * Dialect for MS SQL Server database. + * Minimum version: 12.0 (SQL Server 2014 and Azure SQL Database) + */ +public class HapiFhirSQLServerDialect extends SQLServerDialect { + + public HapiFhirSQLServerDialect() { + super(DatabaseVersion.make(11)); + } + + /** + * @see HapiFhirH2Dialect#supportsColumnCheck() for an explanation of why we disable this + */ + @Override + public boolean supportsColumnCheck() { + return false; + } +} diff --git a/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/nickname/NicknameMap.java b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/nickname/NicknameMap.java index 5399355c6f6..7920c60b997 100644 --- a/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/nickname/NicknameMap.java +++ b/hapi-fhir-jpa/src/main/java/ca/uhn/fhir/jpa/nickname/NicknameMap.java @@ -19,6 +19,8 @@ */ package ca.uhn.fhir.jpa.nickname; +import jakarta.annotation.Nonnull; + import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; @@ -27,7 +29,6 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import javax.annotation.Nonnull; class NicknameMap { private final Map
+ * In Hibernate 5 we didn't need to do this, since we could just register
+ * the service with Spring and Hibernate would ask Spring for it. This no longer
+ * seems to work in Hibernate 6, so we now have to manually register it.
+ */
+ private class MyEntityManagerFactoryBuilderImpl extends EntityManagerFactoryBuilderImpl {
+ public MyEntityManagerFactoryBuilderImpl(PersistenceUnitInfo theInfo, Map, ?> theIntegration) {
+ super(new PersistenceUnitInfoDescriptor(theInfo), (Map) theIntegration);
+ }
+
+ @Override
+ protected StandardServiceRegistryBuilder getStandardServiceRegistryBuilder(BootstrapServiceRegistry bsr) {
+ StandardServiceRegistryBuilder retVal = super.getStandardServiceRegistryBuilder(bsr);
+ ISequenceValueMassager sequenceValueMassager =
+ ReflectionUtil.newInstance(myStorageSettings.getSequenceValueMassagerClass());
+ retVal.addService(ISequenceValueMassager.class, sequenceValueMassager);
+ return retVal;
+ }
+ }
}
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java
index 13dfc7b25f0..90ac47f982d 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java
@@ -107,6 +107,18 @@ import com.google.common.collect.Sets;
import com.google.common.hash.HashCode;
import com.google.common.hash.HashFunction;
import com.google.common.hash.Hashing;
+import jakarta.annotation.Nonnull;
+import jakarta.annotation.Nullable;
+import jakarta.annotation.PostConstruct;
+import jakarta.persistence.EntityManager;
+import jakarta.persistence.NoResultException;
+import jakarta.persistence.PersistenceContext;
+import jakarta.persistence.PersistenceContextType;
+import jakarta.persistence.TypedQuery;
+import jakarta.persistence.criteria.CriteriaBuilder;
+import jakarta.persistence.criteria.CriteriaQuery;
+import jakarta.persistence.criteria.Predicate;
+import jakarta.persistence.criteria.Root;
import org.apache.commons.lang3.NotImplementedException;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
@@ -136,9 +148,7 @@ import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionTemplate;
-import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
@@ -149,18 +159,6 @@ import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.stream.Collectors;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.annotation.PostConstruct;
-import javax.persistence.EntityManager;
-import javax.persistence.NoResultException;
-import javax.persistence.PersistenceContext;
-import javax.persistence.PersistenceContextType;
-import javax.persistence.TypedQuery;
-import javax.persistence.criteria.CriteriaBuilder;
-import javax.persistence.criteria.CriteriaQuery;
-import javax.persistence.criteria.Predicate;
-import javax.persistence.criteria.Root;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.XMLEvent;
@@ -645,7 +643,6 @@ public abstract class BaseHapiFhirDaoRES_TEXT
column, which is where data may have
+ * been stored by versions of HAPI FHIR prior to 7.0.0
+ *
+ * @since 7.0.0
+ */
+ @Modifying
+ @Query(
+ "UPDATE ResourceHistoryTable r SET r.myResourceTextVc = null, r.myResource = :text, r.myEncoding = 'JSONC' WHERE r.myId = :pid")
+ void updateNonInlinedContents(@Param("text") byte[] theText, @Param("pid") long thePid);
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceTableDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceTableDao.java
index 3696314341e..c1263047940 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceTableDao.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceTableDao.java
@@ -19,6 +19,7 @@
*/
package ca.uhn.fhir.jpa.dao.data;
+import ca.uhn.fhir.jpa.dao.data.custom.IForcedIdQueries;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
@@ -34,9 +35,11 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.stream.Stream;
@Transactional(propagation = Propagation.MANDATORY)
-public interface IResourceTableDao extends JpaRepository