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}