001/*
002 * #%L
003 * HAPI FHIR Storage api
004 * %%
005 * Copyright (C) 2014 - 2024 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.api.model;
021
022import ca.uhn.fhir.jpa.model.cross.IBasePersistedResource;
023import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
024import org.hl7.fhir.instance.model.api.IBaseResource;
025import org.hl7.fhir.instance.model.api.IIdType;
026
027import java.util.function.Supplier;
028
029public class LazyDaoMethodOutcome extends DaoMethodOutcome {
030
031        private Supplier<EntityAndResource> myEntitySupplier;
032        private Supplier<IIdType> myIdSupplier;
033        private Runnable myEntitySupplierUseCallback;
034
035        /**
036         * Constructor
037         */
038        public LazyDaoMethodOutcome(IResourcePersistentId theResourcePersistentId) {
039                setPersistentId(theResourcePersistentId);
040        }
041
042        @Override
043        public IBasePersistedResource getEntity() {
044                IBasePersistedResource retVal = super.getEntity();
045                if (retVal == null) {
046                        tryToRunSupplier();
047                        retVal = super.getEntity();
048                }
049                return retVal;
050        }
051
052        private void tryToRunSupplier() {
053                if (myEntitySupplier != null) {
054                        EntityAndResource entityAndResource = myEntitySupplier.get();
055                        setEntity(entityAndResource.getEntity());
056                        setResource(entityAndResource.getResource());
057                        setId(entityAndResource.getResource().getIdElement());
058                        myEntitySupplierUseCallback.run();
059                }
060        }
061
062        @Override
063        public IIdType getId() {
064                IIdType retVal = super.getId();
065                if (retVal == null) {
066                        if (super.hasResource()) {
067                                retVal = getResource().getIdElement();
068                                setId(retVal);
069                        } else {
070                                if (myIdSupplier != null) {
071                                        retVal = myIdSupplier.get();
072                                        setId(retVal);
073                                }
074                        }
075                }
076                return retVal;
077        }
078
079        @Override
080        public IBaseResource getResource() {
081                IBaseResource retVal = super.getResource();
082                if (retVal == null) {
083                        tryToRunSupplier();
084                        retVal = super.getResource();
085                }
086                return retVal;
087        }
088
089        public void setEntitySupplier(Supplier<EntityAndResource> theEntitySupplier) {
090                myEntitySupplier = theEntitySupplier;
091        }
092
093        public void setEntitySupplierUseCallback(Runnable theEntitySupplierUseCallback) {
094                myEntitySupplierUseCallback = theEntitySupplierUseCallback;
095        }
096
097        public void setIdSupplier(Supplier<IIdType> theIdSupplier) {
098                myIdSupplier = theIdSupplier;
099        }
100
101        public static class EntityAndResource {
102                private final IBasePersistedResource myEntity;
103                private final IBaseResource myResource;
104
105                public EntityAndResource(IBasePersistedResource theEntity, IBaseResource theResource) {
106                        myEntity = theEntity;
107                        myResource = theResource;
108                }
109
110                public IBasePersistedResource getEntity() {
111                        return myEntity;
112                }
113
114                public IBaseResource getResource() {
115                        return myResource;
116                }
117        }
118}