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.api;
021
022import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemDao;
023import ca.uhn.fhir.jpa.dao.data.ITermCodeSystemVersionDao;
024import ca.uhn.fhir.jpa.dao.data.ITermConceptDao;
025import ca.uhn.fhir.jpa.dao.data.ITermConceptDesignationDao;
026import ca.uhn.fhir.jpa.dao.data.ITermConceptParentChildLinkDao;
027import ca.uhn.fhir.jpa.dao.data.ITermConceptPropertyDao;
028import ca.uhn.fhir.jpa.entity.TermCodeSystem;
029import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
030import ca.uhn.fhir.jpa.term.models.CodeSystemConceptsDeleteResult;
031import com.fasterxml.jackson.databind.util.ArrayIterator;
032import org.slf4j.Logger;
033import org.slf4j.LoggerFactory;
034import org.springframework.beans.factory.annotation.Autowired;
035import org.springframework.transaction.annotation.Transactional;
036
037import java.text.DecimalFormat;
038import java.util.Iterator;
039import java.util.List;
040import java.util.Optional;
041
042@Transactional
043public class TermCodeSystemDeleteJobSvc implements ITermCodeSystemDeleteJobSvc {
044        private static final Logger ourLog = LoggerFactory.getLogger(TermCodeSystemDeleteJobSvc.class);
045
046        private static final DecimalFormat ourDecimalFormat = new DecimalFormat("#,###");
047
048        @Autowired
049        private ITermConceptDao myConceptDao;
050
051        @Autowired
052        private ITermCodeSystemDao myCodeSystemDao;
053
054        @Autowired
055        private ITermCodeSystemVersionDao myTermCodeSystemVersionDao;
056
057        @Autowired
058        private ITermConceptParentChildLinkDao myConceptParentChildLinkDao;
059
060        @Autowired
061        private ITermConceptPropertyDao myConceptPropertyDao;
062
063        @Autowired
064        private ITermConceptDesignationDao myConceptDesignationDao;
065
066        @Autowired
067        private ITermCodeSystemDao myTermCodeSystemDao;
068
069        @Autowired
070        private ITermDeferredStorageSvc myDeferredStorageSvc;
071
072        @Override
073        public Iterator<Long> getAllCodeSystemVersionForCodeSystemPid(long thePid) {
074                // TODO - make this a pageable iterator
075                List<Long> pids = myTermCodeSystemVersionDao.findSortedPidsByCodeSystemPid(thePid);
076
077                if (pids == null) {
078                        return new ArrayIterator<>(new Long[0]);
079                }
080
081                return pids.iterator();
082        }
083
084        @Override
085        public CodeSystemConceptsDeleteResult deleteCodeSystemConceptsByCodeSystemVersionPid(long theCodeSystemVersionPid) {
086                CodeSystemConceptsDeleteResult result = new CodeSystemConceptsDeleteResult();
087
088                // code system links delete
089                ourLog.info("Deleting term code links");
090                int deletedLinks = myConceptParentChildLinkDao.deleteByCodeSystemVersion(theCodeSystemVersionPid);
091                ourLog.info("Deleted {} term code links", ourDecimalFormat.format(deletedLinks));
092                result.setDeletedLinks(deletedLinks);
093
094                // code system concept properties
095                ourLog.info("Deleting term code properties");
096                int deletedProperties = myConceptPropertyDao.deleteByCodeSystemVersion(theCodeSystemVersionPid);
097                ourLog.info("Deleted {} term code properties", ourDecimalFormat.format(deletedProperties));
098                result.setDeletedProperties(deletedProperties);
099
100                // code system concept designations
101                ourLog.info("Deleting concept designations");
102                int deletedDesignations = myConceptDesignationDao.deleteByCodeSystemVersion(theCodeSystemVersionPid);
103                ourLog.info("Deleted {} concept designations", ourDecimalFormat.format(deletedDesignations));
104                result.setDeletedDesignations(deletedDesignations);
105
106                // code system concept
107                ourLog.info("Deleting concepts");
108                int deletedConcepts = myConceptDao.deleteByCodeSystemVersion(theCodeSystemVersionPid);
109                ourLog.info("Deleted {} concepts", ourDecimalFormat.format(deletedConcepts));
110                result.setCodeSystemConceptDelete(deletedConcepts);
111
112                return result;
113        }
114
115        @Override
116        public void deleteCodeSystemVersion(long theVersionPid) {
117                ourLog.debug("Executing for codeSystemVersionId: {}", theVersionPid);
118
119                // if TermCodeSystemVersion being deleted is current, disconnect it form TermCodeSystem
120                Optional<TermCodeSystem> codeSystemOpt =
121                                myCodeSystemDao.findWithCodeSystemVersionAsCurrentVersion(theVersionPid);
122                if (codeSystemOpt.isPresent()) {
123                        TermCodeSystem codeSystem = codeSystemOpt.get();
124                        ourLog.info(
125                                        "Removing code system version: {} as current version of code system: {}",
126                                        theVersionPid,
127                                        codeSystem.getPid());
128                        codeSystem.setCurrentVersion(null);
129                        myCodeSystemDao.save(codeSystem);
130                }
131
132                ourLog.info("Deleting code system version: {}", theVersionPid);
133                Optional<TermCodeSystemVersion> csv = myTermCodeSystemVersionDao.findById(theVersionPid);
134                csv.ifPresent(theTermCodeSystemVersion -> {
135                        myTermCodeSystemVersionDao.delete(theTermCodeSystemVersion);
136                        ourLog.info("Code system version: {} deleted", theVersionPid);
137                });
138        }
139
140        @Override
141        public void deleteCodeSystem(long thePid) {
142                ourLog.info("Deleting code system by id : {}", thePid);
143
144                Optional<TermCodeSystem> csop = myTermCodeSystemDao.findById(thePid);
145                if (csop.isPresent()) {
146                        TermCodeSystem cs = csop.get();
147
148                        ourLog.info("Deleting code system {} / {}", thePid, cs.getCodeSystemUri());
149
150                        myTermCodeSystemDao.deleteById(thePid);
151
152                        ourLog.info("Code system {} deleted", thePid);
153                }
154        }
155
156        @Override
157        public void notifyJobComplete(String theJobId) {
158                myDeferredStorageSvc.notifyJobEnded(theJobId);
159        }
160}