001/*-
002 * #%L
003 * HAPI FHIR JPA Server
004 * %%
005 * Copyright (C) 2014 - 2023 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        public int saveConcept(TermConcept theConcept) {
050                int retVal = 0;
051
052                /*
053                 * If the concept has an ID, we're reindexing, so there's no need to
054                 * save parent concepts first (it's way too slow to do that)
055                 */
056                if (theConcept.getId() == null) {
057                        boolean needToSaveParents = false;
058                        for (TermConceptParentChildLink next : theConcept.getParents()) {
059                                if (next.getParent().getId() == null) {
060                                        needToSaveParents = true;
061                                        break;
062                                }
063                        }
064                        if (needToSaveParents) {
065                                retVal += ensureParentsSaved(theConcept.getParents());
066                        }
067                }
068
069                if (theConcept.getId() == null || theConcept.getIndexStatus() == null) {
070                        retVal++;
071                        theConcept.setIndexStatus(BaseHapiFhirDao.INDEX_STATUS_INDEXED);
072                        theConcept.setUpdated(new Date());
073                        myConceptDao.save(theConcept);
074
075                        for (TermConceptProperty next : theConcept.getProperties()) {
076                                myConceptPropertyDao.save(next);
077                        }
078
079                        for (TermConceptDesignation next : theConcept.getDesignations()) {
080                                myConceptDesignationDao.save(next);
081                        }
082                }
083
084                ourLog.trace("Saved {} and got PID {}", theConcept.getCode(), theConcept.getId());
085                return retVal;
086        }
087
088        private int ensureParentsSaved(Collection<TermConceptParentChildLink> theParents) {
089                ourLog.trace("Checking {} parents", theParents.size());
090                int retVal = 0;
091
092                for (TermConceptParentChildLink nextLink : theParents) {
093                        if (nextLink.getRelationshipType() == TermConceptParentChildLink.RelationshipTypeEnum.ISA) {
094                                TermConcept nextParent = nextLink.getParent();
095                                retVal += ensureParentsSaved(nextParent.getParents());
096                                if (nextParent.getId() == null) {
097                                        nextParent.setUpdated(new Date());
098                                        myConceptDao.saveAndFlush(nextParent);
099                                        retVal++;
100                                        ourLog.debug("Saved parent code {} and got id {}", nextParent.getCode(), nextParent.getId());
101                                }
102                        }
103                }
104
105                return retVal;
106        }
107}