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.snomedct;
021
022import ca.uhn.fhir.jpa.entity.TermCodeSystemVersion;
023import ca.uhn.fhir.jpa.entity.TermConcept;
024import ca.uhn.fhir.jpa.entity.TermConceptParentChildLink;
025import ca.uhn.fhir.jpa.term.IZipContentsHandlerCsv;
026import org.apache.commons.csv.CSVRecord;
027
028import java.util.ArrayList;
029import java.util.HashMap;
030import java.util.HashSet;
031import java.util.Map;
032import java.util.Set;
033
034public final class SctHandlerRelationship implements IZipContentsHandlerCsv {
035        private final Map<String, TermConcept> myCode2concept;
036        private final TermCodeSystemVersion myCodeSystemVersion;
037        private final Map<String, TermConcept> myRootConcepts;
038
039        public SctHandlerRelationship(
040                        TermCodeSystemVersion theCodeSystemVersion,
041                        HashMap<String, TermConcept> theRootConcepts,
042                        Map<String, TermConcept> theCode2concept) {
043                myCodeSystemVersion = theCodeSystemVersion;
044                myRootConcepts = theRootConcepts;
045                myCode2concept = theCode2concept;
046        }
047
048        @Override
049        public void accept(CSVRecord theRecord) {
050                Set<String> ignoredTypes = new HashSet<String>();
051                ignoredTypes.add("Method (attribute)");
052                ignoredTypes.add("Direct device (attribute)");
053                ignoredTypes.add("Has focus (attribute)");
054                ignoredTypes.add("Access instrument");
055                ignoredTypes.add("Procedure site (attribute)");
056                ignoredTypes.add("Causative agent (attribute)");
057                ignoredTypes.add("Course (attribute)");
058                ignoredTypes.add("Finding site (attribute)");
059                ignoredTypes.add("Has definitional manifestation (attribute)");
060
061                String sourceId = theRecord.get("sourceId");
062                String destinationId = theRecord.get("destinationId");
063                String typeId = theRecord.get("typeId");
064                boolean active = "1".equals(theRecord.get("active"));
065
066                TermConcept typeConcept = myCode2concept.get(typeId);
067                TermConcept sourceConcept = myCode2concept.get(sourceId);
068                TermConcept targetConcept = myCode2concept.get(destinationId);
069                if (sourceConcept != null && targetConcept != null && typeConcept != null) {
070                        if (typeConcept.getDisplay().equals("Is a (attribute)")) {
071                                TermConceptParentChildLink.RelationshipTypeEnum relationshipType =
072                                                TermConceptParentChildLink.RelationshipTypeEnum.ISA;
073                                if (!sourceId.equals(destinationId)) {
074                                        if (active) {
075                                                TermConceptParentChildLink link = new TermConceptParentChildLink();
076                                                link.setChild(sourceConcept);
077                                                link.setParent(targetConcept);
078                                                link.setRelationshipType(relationshipType);
079                                                link.setCodeSystem(myCodeSystemVersion);
080
081                                                targetConcept.addChild(sourceConcept, relationshipType);
082                                        } else {
083                                                // not active, so we're removing any existing links
084                                                for (TermConceptParentChildLink next :
085                                                                new ArrayList<TermConceptParentChildLink>(targetConcept.getChildren())) {
086                                                        if (next.getRelationshipType() == relationshipType) {
087                                                                if (next.getChild().getCode().equals(sourceConcept.getCode())) {
088                                                                        next.getParent().getChildren().remove(next);
089                                                                        next.getChild().getParents().remove(next);
090                                                                }
091                                                        }
092                                                }
093                                        }
094                                }
095                        } else if (ignoredTypes.contains(typeConcept.getDisplay())) {
096                                // ignore
097                        } else {
098                                // ourLog.warn("Unknown relationship type: {}/{}", typeId, typeConcept.getDisplay());
099                        }
100                }
101        }
102}