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.term;
021
022import ca.uhn.fhir.jpa.entity.TermConcept;
023import ca.uhn.fhir.jpa.entity.TermConceptDesignation;
024import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
025import ca.uhn.fhir.jpa.entity.TermConceptProperty;
026import ca.uhn.fhir.jpa.model.entity.EntityIndexStatusEnum;
027import jakarta.persistence.EntityManager;
028import org.slf4j.Logger;
029import org.slf4j.LoggerFactory;
030import org.springframework.beans.factory.annotation.Autowired;
031
032import java.util.Collection;
033import java.util.Date;
034
035public class TermConceptDaoSvc {
036        private static final Logger ourLog = LoggerFactory.getLogger(TermConceptDaoSvc.class);
037
038        @Autowired
039        private EntityManager myEntityManager;
040
041        private boolean mySupportLegacyLob = false;
042
043        public int saveConcept(TermConcept theConcept) {
044                int retVal = 0;
045
046                /*
047                 * If the concept has an ID, we're reindexing, so there's no need to
048                 * save parent concepts first (it's way too slow to do that)
049                 */
050                if (theConcept.getId() == null) {
051                        boolean needToSaveParents = false;
052                        for (TermConceptParentChildLink next : theConcept.getParents()) {
053                                if (next.getParent().getId() == null) {
054                                        needToSaveParents = true;
055                                        break;
056                                }
057                        }
058                        if (needToSaveParents) {
059                                retVal += ensureParentsSaved(theConcept.getParents());
060                        }
061                }
062
063                if (theConcept.getId() == null || theConcept.getIndexStatus() == null) {
064                        retVal++;
065                        theConcept.setIndexStatus(EntityIndexStatusEnum.INDEXED_ALL);
066                        theConcept.setUpdated(new Date());
067                        theConcept.flagForLegacyLobSupport(mySupportLegacyLob);
068                        myEntityManager.persist(theConcept);
069
070                        for (TermConceptProperty next : theConcept.getProperties()) {
071                                next.performLegacyLobSupport(mySupportLegacyLob);
072                                myEntityManager.persist(next);
073                        }
074
075                        for (TermConceptDesignation next : theConcept.getDesignations()) {
076                                myEntityManager.persist(next);
077                        }
078                }
079
080                ourLog.trace("Saved {} and got PID {}", theConcept.getCode(), theConcept.getId());
081                return retVal;
082        }
083
084        public TermConceptDaoSvc setSupportLegacyLob(boolean theSupportLegacyLob) {
085                mySupportLegacyLob = theSupportLegacyLob;
086                return this;
087        }
088
089        private int ensureParentsSaved(Collection<TermConceptParentChildLink> theParents) {
090                ourLog.trace("Checking {} parents", theParents.size());
091                int retVal = 0;
092
093                for (TermConceptParentChildLink nextLink : theParents) {
094                        if (nextLink.getRelationshipType() == TermConceptParentChildLink.RelationshipTypeEnum.ISA) {
095                                TermConcept nextParent = nextLink.getParent();
096                                retVal += ensureParentsSaved(nextParent.getParents());
097                                if (nextParent.getId() == null) {
098                                        nextParent.setUpdated(new Date());
099                                        nextParent.flagForLegacyLobSupport(mySupportLegacyLob);
100                                        myEntityManager.persist(nextParent);
101                                        retVal++;
102                                        ourLog.debug("Saved parent code {} and got id {}", nextParent.getCode(), nextParent.getId());
103                                }
104                        }
105                }
106
107                return retVal;
108        }
109}