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.jpa.entity.TermCodeSystemVersion;
023import ca.uhn.fhir.jpa.entity.TermConcept;
024import ca.uhn.fhir.jpa.term.api.ITermLoaderSvc;
025import org.apache.commons.csv.CSVRecord;
026import org.hl7.fhir.r4.model.ConceptMap;
027import org.hl7.fhir.r4.model.ValueSet;
028
029import java.util.List;
030import java.util.Map;
031import java.util.Properties;
032
033import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_ANSWERLIST_VERSION;
034import static ca.uhn.fhir.jpa.term.loinc.LoincUploadPropertiesEnum.LOINC_CODESYSTEM_VERSION;
035import static org.apache.commons.lang3.StringUtils.isNotBlank;
036import static org.apache.commons.lang3.StringUtils.trim;
037
038public class LoincAnswerListHandler extends BaseLoincHandler {
039
040        private final Map<String, TermConcept> myCode2Concept;
041        private final TermCodeSystemVersion myCodeSystemVersion;
042
043        public LoincAnswerListHandler(
044                        TermCodeSystemVersion theCodeSystemVersion,
045                        Map<String, TermConcept> theCode2concept,
046                        List<ValueSet> theValueSets,
047                        List<ConceptMap> theConceptMaps,
048                        Properties theUploadProperties,
049                        String theCopyrightStatement) {
050                super(theCode2concept, theValueSets, theConceptMaps, theUploadProperties, theCopyrightStatement);
051                myCodeSystemVersion = theCodeSystemVersion;
052                myCode2Concept = theCode2concept;
053        }
054
055        @Override
056        public void accept(CSVRecord theRecord) {
057
058                // this is the code for the list (will repeat)
059                String answerListId = trim(theRecord.get("AnswerListId"));
060                String answerListName = trim(theRecord.get("AnswerListName"));
061                String answerListOid = trim(theRecord.get("AnswerListOID"));
062                String externallyDefined = trim(theRecord.get("ExtDefinedYN"));
063                String extenrallyDefinedCs = trim(theRecord.get("ExtDefinedAnswerListCodeSystem"));
064                String externallyDefinedLink = trim(theRecord.get("ExtDefinedAnswerListLink"));
065                // this is the code for the actual answer (will not repeat)
066                String answerString = trim(theRecord.get("AnswerStringId"));
067                String sequenceNumber = trim(theRecord.get("SequenceNumber"));
068                String displayText = trim(theRecord.get("DisplayText"));
069                String extCodeId = trim(theRecord.get("ExtCodeId"));
070                String extCodeDisplayName = trim(theRecord.get("ExtCodeDisplayName"));
071                String extCodeSystem = trim(theRecord.get("ExtCodeSystem"));
072                String extCodeSystemVersion = trim(theRecord.get("ExtCodeSystemVersion"));
073
074                // Answer list code
075                if (!myCode2Concept.containsKey(answerListId)) {
076                        TermConcept concept = new TermConcept(myCodeSystemVersion, answerListId);
077                        concept.setDisplay(answerListName);
078                        myCode2Concept.put(answerListId, concept);
079                }
080
081                // Answer list ValueSet
082                String valueSetId;
083                String codeSystemVersionId = myUploadProperties.getProperty(LOINC_CODESYSTEM_VERSION.getCode());
084                if (codeSystemVersionId != null) {
085                        valueSetId = answerListId + "-" + codeSystemVersionId;
086                } else {
087                        valueSetId = answerListId;
088                }
089                ValueSet vs = getValueSet(
090                                valueSetId, "http://loinc.org/vs/" + answerListId, answerListName, LOINC_ANSWERLIST_VERSION.getCode());
091                if (vs.getIdentifier().isEmpty()) {
092                        vs.addIdentifier().setSystem("urn:ietf:rfc:3986").setValue("urn:oid:" + answerListOid);
093                }
094
095                if (isNotBlank(answerString)) {
096
097                        // Answer code
098                        if (!myCode2Concept.containsKey(answerString)) {
099                                TermConcept concept = new TermConcept(myCodeSystemVersion, answerString);
100                                concept.setDisplay(displayText);
101                                if (isNotBlank(sequenceNumber) && sequenceNumber.matches("^[0-9]$")) {
102                                        concept.setSequence(Integer.parseInt(sequenceNumber));
103                                }
104                                myCode2Concept.put(answerString, concept);
105                        }
106
107                        vs.getCompose()
108                                        .getIncludeFirstRep()
109                                        .setSystem(ITermLoaderSvc.LOINC_URI)
110                                        .setVersion(codeSystemVersionId)
111                                        .addConcept()
112                                        .setCode(answerString)
113                                        .setDisplay(displayText);
114                }
115        }
116}