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