001package org.hl7.fhir.r4.terminologies;
002
003/*-
004 * #%L
005 * org.hl7.fhir.r4
006 * %%
007 * Copyright (C) 2014 - 2019 Health Level 7
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 * 
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 * 
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023
024import org.hl7.fhir.exceptions.FHIRException;
025import org.hl7.fhir.r4.context.SimpleWorkerContext;
026import org.hl7.fhir.r4.model.Coding;
027import org.hl7.fhir.r4.model.ConceptMap;
028import org.hl7.fhir.r4.model.ConceptMap.ConceptMapGroupComponent;
029import org.hl7.fhir.r4.model.ConceptMap.SourceElementComponent;
030import org.hl7.fhir.r4.model.ConceptMap.TargetElementComponent;
031import org.hl7.fhir.r4.model.Enumerations.ConceptMapEquivalence;
032
033public class ConceptMapEngine {
034
035  private SimpleWorkerContext context;
036
037  public ConceptMapEngine(SimpleWorkerContext context) {
038    this.context = context;
039  }
040
041  public Coding translate(Coding source, String url) throws FHIRException {
042    ConceptMap cm = context.fetchResource(ConceptMap.class, url);
043    if (cm == null)
044      throw new FHIRException("Unable to find ConceptMap '"+url+"'");
045    if (source.hasSystem()) 
046      return translateBySystem(cm, source.getSystem(), source.getCode());
047    else
048      return translateByJustCode(cm, source.getCode());
049  }
050
051  private Coding translateByJustCode(ConceptMap cm, String code) throws FHIRException {
052    SourceElementComponent ct = null;
053    ConceptMapGroupComponent cg = null;
054    for (ConceptMapGroupComponent g : cm.getGroup()) {
055      for (SourceElementComponent e : g.getElement()) {
056        if (code.equals(e.getCode())) {
057          if (e != null)
058            throw new FHIRException("Unable to process translate "+code+" because multiple candidate matches were found in concept map "+cm.getUrl());
059          ct = e;
060          cg = g;
061        }
062      }
063    }
064    if (ct == null)
065      return null;
066    TargetElementComponent tt = null;
067    for (TargetElementComponent t : ct.getTarget()) {
068      if (!t.hasDependsOn() && !t.hasProduct() && isOkEquivalence(t.getEquivalence())) {
069        if (tt != null)
070          throw new FHIRException("Unable to process translate "+code+" because multiple targets were found in concept map "+cm.getUrl());
071        tt = t;       
072      }
073    }
074    if (tt == null)
075      return null;
076    return new Coding().setSystem(cg.getTarget()).setVersion(cg.getTargetVersion()).setCode(tt.getCode()).setDisplay(tt.getDisplay());
077  }
078
079  private boolean isOkEquivalence(ConceptMapEquivalence equivalence) {
080    return equivalence != null && equivalence != ConceptMapEquivalence.DISJOINT && equivalence != ConceptMapEquivalence.UNMATCHED;
081  }
082
083  private Coding translateBySystem(ConceptMap cm, String system, String code) {
084    throw new Error("Not done yet");
085  }
086
087}