001package ca.uhn.fhir.jpa.provider.r4;
002
003import ca.uhn.fhir.jpa.api.dao.IFhirResourceDaoPatient;
004import ca.uhn.fhir.jpa.model.util.JpaConstants;
005import ca.uhn.fhir.model.api.annotation.Description;
006import ca.uhn.fhir.model.valueset.BundleTypeEnum;
007import ca.uhn.fhir.rest.annotation.IdParam;
008import ca.uhn.fhir.rest.annotation.Operation;
009import ca.uhn.fhir.rest.annotation.OperationParam;
010import ca.uhn.fhir.rest.annotation.Sort;
011import ca.uhn.fhir.rest.api.Constants;
012import ca.uhn.fhir.rest.api.SortSpec;
013import ca.uhn.fhir.rest.api.server.IBundleProvider;
014import ca.uhn.fhir.rest.api.server.RequestDetails;
015import ca.uhn.fhir.rest.param.DateRangeParam;
016import ca.uhn.fhir.rest.param.StringAndListParam;
017import ca.uhn.fhir.rest.param.StringOrListParam;
018import ca.uhn.fhir.rest.param.StringParam;
019import ca.uhn.fhir.rest.param.TokenOrListParam;
020import ca.uhn.fhir.rest.param.TokenParam;
021import org.hl7.fhir.r4.model.IdType;
022import org.hl7.fhir.r4.model.Patient;
023import org.hl7.fhir.r4.model.StringType;
024import org.hl7.fhir.r4.model.UnsignedIntType;
025
026import java.util.Arrays;
027import java.util.List;
028
029import static org.apache.commons.lang3.StringUtils.isNotBlank;
030
031/*
032 * #%L
033 * HAPI FHIR JPA Server
034 * %%
035 * Copyright (C) 2014 - 2021 Smile CDR, Inc.
036 * %%
037 * Licensed under the Apache License, Version 2.0 (the "License");
038 * you may not use this file except in compliance with the License.
039 * You may obtain a copy of the License at
040 *
041 *      http://www.apache.org/licenses/LICENSE-2.0
042 *
043 * Unless required by applicable law or agreed to in writing, software
044 * distributed under the License is distributed on an "AS IS" BASIS,
045 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
046 * See the License for the specific language governing permissions and
047 * limitations under the License.
048 * #L%
049 */
050
051public class BaseJpaResourceProviderPatientR4 extends JpaResourceProviderR4<Patient> {
052
053        /**
054         * Patient/123/$everything
055         */
056        @Operation(name = JpaConstants.OPERATION_EVERYTHING, idempotent = true, bundleType = BundleTypeEnum.SEARCHSET)
057        public IBundleProvider patientInstanceEverything(
058
059                javax.servlet.http.HttpServletRequest theServletRequest,
060
061                @IdParam
062                        IdType theId,
063
064                @Description(formalDefinition = "Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
065                @OperationParam(name = Constants.PARAM_COUNT)
066                        UnsignedIntType theCount,
067
068                @Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
069                @OperationParam(name = Constants.PARAM_OFFSET)
070                        UnsignedIntType theOffset,
071
072                @Description(shortDefinition = "Only return resources which were last updated as specified by the given range")
073                @OperationParam(name = Constants.PARAM_LASTUPDATED, min = 0, max = 1)
074                        DateRangeParam theLastUpdated,
075
076                @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)")
077                @OperationParam(name = Constants.PARAM_CONTENT, min = 0, max = OperationParam.MAX_UNLIMITED)
078                        List<StringType> theContent,
079
080                @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)")
081                @OperationParam(name = Constants.PARAM_TEXT, min = 0, max = OperationParam.MAX_UNLIMITED)
082                        List<StringType> theNarrative,
083
084                @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)")
085                @OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED)
086                        List<StringType> theFilter,
087
088                @Sort
089                        SortSpec theSortSpec,
090
091                RequestDetails theRequestDetails
092        ) {
093
094                startRequest(theServletRequest);
095                try {
096                        return ((IFhirResourceDaoPatient<Patient>) getDao()).patientInstanceEverything(theServletRequest, theId, theCount, theOffset, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails);
097                } finally {
098                        endRequest(theServletRequest);
099                }
100        }
101
102        /**
103         * /Patient/$everything
104         */
105        @Operation(name = JpaConstants.OPERATION_EVERYTHING, idempotent = true, bundleType = BundleTypeEnum.SEARCHSET)
106        public IBundleProvider patientTypeEverything(
107
108                javax.servlet.http.HttpServletRequest theServletRequest,
109
110                @Description(formalDefinition = "Results from this method are returned across multiple pages. This parameter controls the size of those pages.")
111                @OperationParam(name = Constants.PARAM_COUNT)
112                        UnsignedIntType theCount,
113
114                @Description(formalDefinition="Results from this method are returned across multiple pages. This parameter controls the offset when fetching a page.")
115                @OperationParam(name = Constants.PARAM_OFFSET)
116                        UnsignedIntType theOffset,
117
118                @Description(shortDefinition = "Only return resources which were last updated as specified by the given range")
119                @OperationParam(name = Constants.PARAM_LASTUPDATED, min = 0, max = 1)
120                        DateRangeParam theLastUpdated,
121
122                @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)")
123                @OperationParam(name = Constants.PARAM_CONTENT, min = 0, max = OperationParam.MAX_UNLIMITED)
124                        List<StringType> theContent,
125
126                @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)")
127                @OperationParam(name = Constants.PARAM_TEXT, min = 0, max = OperationParam.MAX_UNLIMITED)
128                        List<StringType> theNarrative,
129
130                @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)")
131                @OperationParam(name = Constants.PARAM_FILTER, min = 0, max = OperationParam.MAX_UNLIMITED)
132                        List<StringType> theFilter,
133
134                @Description(shortDefinition = "Filter the resources to return based on the patient ids provided.")
135                @OperationParam(name = Constants.PARAM_ID, min = 0, max = OperationParam.MAX_UNLIMITED)
136                        List<IdType> theId,
137
138                @Sort
139                        SortSpec theSortSpec,
140
141                RequestDetails theRequestDetails
142        ) {
143
144                startRequest(theServletRequest);
145                try {
146                        return ((IFhirResourceDaoPatient<Patient>) getDao()).patientTypeEverything(theServletRequest, theCount, theOffset, theLastUpdated, theSortSpec, toStringAndList(theContent), toStringAndList(theNarrative), toStringAndList(theFilter), theRequestDetails, toFlattenedPatientIdTokenParamList(theId));
147                } finally {
148                        endRequest(theServletRequest);
149                }
150
151        }
152
153        /**
154         * Given a list of string types, return only the ID portions of any parameters passed in.
155         */
156        private TokenOrListParam toFlattenedPatientIdTokenParamList(List<IdType> theId) {
157                TokenOrListParam retVal = new TokenOrListParam();
158                if (theId != null) {
159                        for (IdType next: theId) {
160                                if (isNotBlank(next.getValue())) {
161                                        String[] split = next.getValueAsString().split(",");
162                                        Arrays.stream(split).map(IdType::new).forEach(id -> {
163                                                retVal.addOr(new TokenParam(id.getIdPart()));
164                                        });
165                                }
166                        }
167                }
168                return retVal.getValuesAsQueryTokens().isEmpty() ? null: retVal;
169        }
170
171        private StringAndListParam toStringAndList(List<StringType> theNarrative) {
172                StringAndListParam retVal = new StringAndListParam();
173                if (theNarrative != null) {
174                        for (StringType next : theNarrative) {
175                                if (isNotBlank(next.getValue())) {
176                                        retVal.addAnd(new StringOrListParam().addOr(new StringParam(next.getValue())));
177                                }
178                        }
179                }
180                if (retVal.getValuesAsQueryTokens().isEmpty()) {
181                        return null;
182                }
183                return retVal;
184        }
185
186}