001/*-
002 * #%L
003 * HAPI FHIR JPA Server
004 * %%
005 * Copyright (C) 2014 - 2025 Smile CDR, Inc.
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package ca.uhn.fhir.jpa.provider.merge;
021
022import ca.uhn.fhir.batch2.jobs.chunk.FhirIdJson;
023import ca.uhn.fhir.batch2.jobs.merge.MergeJobParameters;
024import ca.uhn.fhir.batch2.jobs.replacereferences.ProvenanceAgentJson;
025import ca.uhn.fhir.context.FhirContext;
026import ca.uhn.fhir.interceptor.model.RequestPartitionId;
027import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
028import ca.uhn.fhir.model.api.IProvenanceAgent;
029import ca.uhn.fhir.util.CanonicalIdentifier;
030import org.hl7.fhir.instance.model.api.IBaseReference;
031import org.hl7.fhir.instance.model.api.IBaseResource;
032import org.hl7.fhir.r4.model.Patient;
033
034import java.util.List;
035
036/**
037 * See <a href="https://build.fhir.org/patient-operation-merge.html">Patient $merge spec</a>
038 */
039public abstract class BaseMergeOperationInputParameters {
040
041        private List<CanonicalIdentifier> mySourceResourceIdentifiers;
042        private List<CanonicalIdentifier> myTargetResourceIdentifiers;
043        private IBaseReference mySourceResource;
044        private IBaseReference myTargetResource;
045        private boolean myPreview;
046        private boolean myDeleteSource;
047        private IBaseResource myResultResource;
048        private final int myResourceLimit;
049        private List<IProvenanceAgent> myProvenanceAgents;
050        private boolean myCreateProvenance = true;
051
052        protected BaseMergeOperationInputParameters(int theResourceLimit) {
053                myResourceLimit = theResourceLimit;
054        }
055
056        public abstract String getSourceResourceParameterName();
057
058        public abstract String getTargetResourceParameterName();
059
060        public abstract String getSourceIdentifiersParameterName();
061
062        public abstract String getTargetIdentifiersParameterName();
063
064        public abstract String getResultResourceParameterName();
065
066        public List<CanonicalIdentifier> getSourceIdentifiers() {
067                return mySourceResourceIdentifiers;
068        }
069
070        public boolean hasAtLeastOneSourceIdentifier() {
071                return mySourceResourceIdentifiers != null && !mySourceResourceIdentifiers.isEmpty();
072        }
073
074        public void setSourceResourceIdentifiers(List<CanonicalIdentifier> theSourceIdentifiers) {
075                this.mySourceResourceIdentifiers = theSourceIdentifiers;
076        }
077
078        public List<CanonicalIdentifier> getTargetIdentifiers() {
079                return myTargetResourceIdentifiers;
080        }
081
082        public boolean hasAtLeastOneTargetIdentifier() {
083                return myTargetResourceIdentifiers != null && !myTargetResourceIdentifiers.isEmpty();
084        }
085
086        public void setTargetResourceIdentifiers(List<CanonicalIdentifier> theTargetIdentifiers) {
087                this.myTargetResourceIdentifiers = theTargetIdentifiers;
088        }
089
090        public boolean getPreview() {
091                return myPreview;
092        }
093
094        public void setPreview(boolean thePreview) {
095                this.myPreview = thePreview;
096        }
097
098        public boolean getDeleteSource() {
099                return myDeleteSource;
100        }
101
102        public void setDeleteSource(boolean theDeleteSource) {
103                this.myDeleteSource = theDeleteSource;
104        }
105
106        public IBaseResource getResultResource() {
107                return myResultResource;
108        }
109
110        public void setResultResource(IBaseResource theResultResource) {
111                this.myResultResource = theResultResource;
112        }
113
114        public IBaseReference getSourceResource() {
115                return mySourceResource;
116        }
117
118        public void setSourceResource(IBaseReference theSourceResource) {
119                this.mySourceResource = theSourceResource;
120        }
121
122        public IBaseReference getTargetResource() {
123                return myTargetResource;
124        }
125
126        public void setTargetResource(IBaseReference theTargetResource) {
127                this.myTargetResource = theTargetResource;
128        }
129
130        public int getResourceLimit() {
131                return myResourceLimit;
132        }
133
134        public boolean getCreateProvenance() {
135                return myCreateProvenance;
136        }
137
138        public void setCreateProvenance(boolean theCreateProvenance) {
139                this.myCreateProvenance = theCreateProvenance;
140        }
141
142        public List<IProvenanceAgent> getProvenanceAgents() {
143                return myProvenanceAgents;
144        }
145
146        public void setProvenanceAgents(List<IProvenanceAgent> theProvenanceAgents) {
147                this.myProvenanceAgents = theProvenanceAgents;
148        }
149
150        public MergeJobParameters asMergeJobParameters(
151                        FhirContext theFhirContext,
152                        JpaStorageSettings theStorageSettings,
153                        Patient theSourceResource,
154                        Patient theTargetResource,
155                        RequestPartitionId thePartitionId) {
156                MergeJobParameters retval = new MergeJobParameters();
157                if (getResultResource() != null) {
158                        retval.setResultResource(theFhirContext.newJsonParser().encodeResourceToString(getResultResource()));
159                }
160                retval.setDeleteSource(getDeleteSource());
161                retval.setBatchSize(theStorageSettings.getDefaultTransactionEntriesForWrite());
162                retval.setSourceId(new FhirIdJson(theSourceResource.getIdElement().toVersionless()));
163                retval.setTargetId(new FhirIdJson(theTargetResource.getIdElement().toVersionless()));
164                retval.setPartitionId(thePartitionId);
165                retval.setProvenanceAgents(ProvenanceAgentJson.from(myProvenanceAgents, theFhirContext));
166                retval.setCreateProvenance(myCreateProvenance);
167                return retval;
168        }
169}