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.loinc;
021
022import ca.uhn.fhir.i18n.Msg;
023import ca.uhn.fhir.jpa.entity.TermConcept;
024import ca.uhn.fhir.jpa.term.IZipContentsHandlerCsv;
025import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
026import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
027import org.apache.commons.csv.CSVRecord;
028import org.hl7.fhir.r4.model.CodeSystem;
029import org.hl7.fhir.r4.model.ConceptMap;
030import org.hl7.fhir.r4.model.ValueSet;
031import org.slf4j.Logger;
032import org.slf4j.LoggerFactory;
033
034import java.util.List;
035import java.util.Map;
036import java.util.Properties;
037
038import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_CODESYSTEM_VERSION;
039import static org.apache.commons.lang3.StringUtils.trim;
040
041public class LoincDocumentOntologyHandler extends BaseLoincHandler implements IZipContentsHandlerCsv {
042        private static final Logger ourLog = LoggerFactory.getLogger(LoincDocumentOntologyHandler.class);
043
044        public static final String DOCUMENT_ONTOLOGY_CODES_VS_ID = "loinc-document-ontology";
045        public static final String DOCUMENT_ONTOLOGY_CODES_VS_URI = "http://loinc.org/vs/loinc-document-ontology";
046        public static final String DOCUMENT_ONTOLOGY_CODES_VS_NAME = "LOINC Document Ontology Codes";
047        private final Map<String, TermConcept> myCode2Concept;
048
049        public LoincDocumentOntologyHandler(
050                        Map<String, TermConcept> theCode2concept,
051                        Map<String, CodeSystem.PropertyType> thePropertyNames,
052                        List<ValueSet> theValueSets,
053                        List<ConceptMap> theConceptMaps,
054                        Properties theUploadProperties,
055                        String theCopyrightStatement) {
056                super(theCode2concept, theValueSets, theConceptMaps, theUploadProperties, theCopyrightStatement);
057                myCode2Concept = theCode2concept;
058        }
059
060        @Override
061        public void accept(CSVRecord theRecord) {
062
063                String loincNumber = trim(theRecord.get("LoincNumber"));
064                String partNumber = trim(theRecord.get("PartNumber"));
065                String partTypeName = trim(theRecord.get("PartTypeName"));
066                String partSequenceOrder = trim(theRecord.get("PartSequenceOrder"));
067                String partName = trim(theRecord.get("PartName"));
068
069                // RSNA Codes VS
070                String valueSetId;
071                String codeSystemVersionId = myUploadProperties.getProperty(LOINC_CODESYSTEM_VERSION.getCode());
072                if (codeSystemVersionId != null) {
073                        valueSetId = DOCUMENT_ONTOLOGY_CODES_VS_ID + "-" + codeSystemVersionId;
074                } else {
075                        valueSetId = DOCUMENT_ONTOLOGY_CODES_VS_ID;
076                }
077                ValueSet vs = getValueSet(valueSetId, DOCUMENT_ONTOLOGY_CODES_VS_URI, DOCUMENT_ONTOLOGY_CODES_VS_NAME, null);
078                addCodeAsIncludeToValueSet(vs, ITermLoaderSvc.LOINC_URI, loincNumber, null);
079
080                // Part Properties
081                String loincCodePropName;
082                switch (partTypeName) {
083                        case "Document.Kind":
084                                loincCodePropName = "document-kind";
085                                break;
086                        case "Document.Role":
087                                loincCodePropName = "document-role";
088                                break;
089                        case "Document.Setting":
090                                loincCodePropName = "document-setting";
091                                break;
092                        case "Document.SubjectMatterDomain":
093                                loincCodePropName = "document-subject-matter-domain";
094                                break;
095                        case "Document.TypeOfService":
096                                loincCodePropName = "document-type-of-service";
097                                break;
098                        default:
099                                throw new InternalErrorException(Msg.code(917) + "Unknown PartTypeName: " + partTypeName);
100                }
101
102                TermConcept code = myCode2Concept.get(loincNumber);
103                if (code != null) {
104                        code.addPropertyCoding(loincCodePropName, ITermLoaderSvc.LOINC_URI, partNumber, partName);
105                        ourLog.debug("Adding coding property: {} to concept.code {}", loincCodePropName, partNumber);
106                }
107        }
108}