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