001package org.hl7.fhir.r5.context;
002
003import org.hl7.fhir.r5.model.*;
004import org.hl7.fhir.r5.utils.UserDataNames;
005import org.hl7.fhir.r5.utils.xver.XVerExtensionManagerFactory;
006
007import java.util.List;
008
009public class CoreVersionPinner {
010
011  IWorkerContext context;
012  public CoreVersionPinner(IWorkerContext context) {
013    this.context = context;
014  }
015
016  public void pinCoreVersions(List<CodeSystem> cslist, List<ValueSet> vslist, List<StructureDefinition> sdList) {
017    for (CodeSystem cs : cslist) {
018      pinCoreVersionVS(cs.getValueSetElement());
019      // this is for thoroughness, though there are no supplements in nay core version
020      pinCoreVersionCS(cs.getSupplementsElement());
021    }
022    for (ValueSet vs : vslist) {
023      for (ValueSet.ConceptSetComponent vsi : vs.getCompose().getInclude()) {
024        pinCoreVersions(vsi);
025      }
026      for (ValueSet.ConceptSetComponent vsi : vs.getCompose().getExclude()) {
027        pinCoreVersions(vsi);
028      }
029    }
030    for (StructureDefinition sd : sdList) {
031      pinCoreVersionSD(sd.getBaseDefinitionElement());
032      for (ElementDefinition ed : sd.getDifferential().getElement()) {
033        pinCoreVersions(ed);
034      }
035      for (ElementDefinition ed : sd.getSnapshot().getElement()) {
036        pinCoreVersions(ed);
037      }
038    }
039  }
040
041  private void pinCoreVersions(ElementDefinition ed) {
042    for (ElementDefinition.TypeRefComponent tr : ed.getType()) {
043      for (CanonicalType ct : tr.getProfile()) {
044        pinCoreVersionSD(ct);
045      }
046      for (CanonicalType ct : tr.getTargetProfile()) {
047        pinCoreVersionSD(ct);
048      }
049    }
050    // for thoroughness - this is only defined in R5 but not used in core, and it's pinned there
051    for (CanonicalType ct : ed.getValueAlternatives()) {
052      pinCoreVersionSD(ct);
053    }
054    if (ed.hasBinding()) {
055      pinCoreVersionVS(ed.getBinding().getValueSetElement());
056      for (ElementDefinition.ElementDefinitionBindingAdditionalComponent adb : ed.getBinding().getAdditional()) {
057        pinCoreVersionVS(adb.getValueSetElement());
058      }
059    }
060
061  }
062
063  private void pinCoreVersions(ValueSet.ConceptSetComponent vsi) {
064    for (CanonicalType ct : vsi.getValueSet()) {
065      pinCoreVersionVS(ct);
066    }
067    if (vsi.hasSystem() && !vsi.hasVersion()) {
068      CodeSystem cs = context.fetchResource(CodeSystem.class, vsi.getSystem());
069      if (cs != null && cs.hasVersion() && !vsi.getSystem().contains("terminology.hl7.org")) {
070        vsi.setVersion(cs.getVersion());
071        vsi.getVersionElement().setUserData(UserDataNames.VERSION_PINNED_ON_LOAD, true);
072      }
073    }
074  }
075
076  private void pinCoreVersionCS(CanonicalType ct) {
077    if (ct.hasValue() && !ct.getValue().contains("|") && !ct.getValue().contains("terminology.hl7.org")) {
078      CodeSystem cs = context.fetchResource(CodeSystem.class, ct.getValue());
079      if (cs != null && cs.hasVersion()) {
080        ct.setValue(ct.getValue() + "|" + cs.getVersion());
081        ct.setUserData(UserDataNames.VERSION_PINNED_ON_LOAD, true);
082      }
083    }
084  }
085
086  private void pinCoreVersionVS(CanonicalType ct) {
087    if (ct.hasValue() && !ct.getValue().contains("|") && !ct.getValue().contains("terminology.hl7.org")) {
088      ValueSet vs = context.fetchResource(ValueSet.class, ct.getValue());
089      if (vs != null && vs.hasVersion()) {
090        ct.setValue(ct.getValue() + "|" + vs.getVersion());
091        ct.setUserData(UserDataNames.VERSION_PINNED_ON_LOAD, true);
092      }
093    }
094  }
095
096  private void pinCoreVersionSD(CanonicalType ct) {
097    if (ct.hasValue() && !ct.getValue().contains("|")) {
098      StructureDefinition sd = context.fetchResource(StructureDefinition.class, ct.getValue());
099      if (sd != null && sd.hasVersion()) {
100        ct.setValue(ct.getValue() + "|" + sd.getVersion());
101        ct.setUserData(UserDataNames.VERSION_PINNED_ON_LOAD, true);
102      }
103    }
104  }
105
106}