001package org.hl7.fhir.r5.utils;
002
003import org.hl7.fhir.r5.context.CanonicalResourceManager.CanonicalResourceProxy;
004import org.hl7.fhir.r5.model.ElementDefinition;
005import org.hl7.fhir.r5.model.Enumerations.BindingStrength;
006import org.hl7.fhir.utilities.Utilities;
007import org.hl7.fhir.r5.model.PackageInformation;
008import org.hl7.fhir.r5.model.StructureDefinition;
009
010public class PackageHackerR5 {
011
012  public static void fixLoadedResource(CanonicalResourceProxy r, PackageInformation packageInfo) {
013   if ("http://terminology.hl7.org/CodeSystem/v2-0391|2.6".equals(r.getUrl())) {
014     r.hack("http://terminology.hl7.org/CodeSystem/v2-0391-2.6", "2.6");
015   }
016   if ("http://terminology.hl7.org/CodeSystem/v2-0391|2.4".equals(r.getUrl())) {
017     r.hack("http://terminology.hl7.org/CodeSystem/v2-0391-2.4", "2.4");
018   }
019   if ("http://terminology.hl7.org/CodeSystem/v2-0360|2.7".equals(r.getUrl())) {
020     r.hack("http://terminology.hl7.org/CodeSystem/v2-0360-2.7", "2.7");
021   }
022
023   if ("http://terminology.hl7.org/CodeSystem/v2-0006|2.1".equals(r.getUrl())) {
024     r.hack("http://terminology.hl7.org/CodeSystem/v2-0006-2.1", "2.1");
025   }
026
027   if ("http://terminology.hl7.org/CodeSystem/v2-0360|2.7".equals(r.getUrl())) {
028     r.hack("http://terminology.hl7.org/CodeSystem/v2-0360-2.7", "2.7");
029   }
030
031   if ("http://terminology.hl7.org/CodeSystem/v2-0006|2.4".equals(r.getUrl())) {
032     r.hack("http://terminology.hl7.org/CodeSystem/v2-0006-2.4", "2.4");
033   }
034
035   if ("http://terminology.hl7.org/CodeSystem/v2-0360|2.3.1".equals(r.getUrl())) {
036     r.hack("http://terminology.hl7.org/CodeSystem/v2-0360-2.3.1", "2.3.1");
037   }
038
039   if ("http://hl7.org/fhir/ValueSet/languages".equals(r.getUrl())) {
040     r.getResource().setExperimental(false);
041   }
042   
043   if ("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor".equals(r.getUrl()) && "4.0.1".equals(r.getVersion())) {
044     StructureDefinition sd = (StructureDefinition) r.getResource();
045     for (ElementDefinition ed : sd.getSnapshot().getElement()) {
046       if (ed.hasBinding() && "http://terminology.hl7.org/ValueSet/v3-NullFlavor|4.0.1".equals(ed.getBinding().getValueSet())) {
047         ed.getBinding().setValueSet("http://terminology.hl7.org/ValueSet/v3-NullFlavor");
048       }
049     }
050     for (ElementDefinition ed : sd.getDifferential().getElement()) {
051       if (ed.hasBinding() && "http://terminology.hl7.org/ValueSet/v3-NullFlavor|4.0.1".equals(ed.getBinding().getValueSet())) {
052         ed.getBinding().setValueSet("http://terminology.hl7.org/ValueSet/v3-NullFlavor");
053       }
054     }
055   }
056   if ("http://hl7.org/fhir/StructureDefinition/DeviceUseStatement".equals(r.getUrl()) && "4.0.1".equals(r.getVersion())) {
057     StructureDefinition sd = (StructureDefinition) r.getResource();
058     for (ElementDefinition ed : sd.getSnapshot().getElement()) {
059       if (ed.hasRequirements()) {
060         ed.setRequirements(ed.getRequirements().replace("[http://hl7.org/fhir/StructureDefinition/bodySite](null.html)", "[http://hl7.org/fhir/StructureDefinition/bodySite](http://hl7.org/fhir/extension-bodysite.html)"));
061       }
062     }
063     for (ElementDefinition ed : sd.getDifferential().getElement()) {
064       if (ed.hasRequirements()) {
065         ed.setRequirements(ed.getRequirements().replace("[http://hl7.org/fhir/StructureDefinition/bodySite](null.html)", "[http://hl7.org/fhir/StructureDefinition/bodySite](http://hl7.org/fhir/extension-bodysite.html)"));
066       }
067     }
068   }
069   if (r.getUrl() != null && r.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition/") && "StructureDefinition".equals(r.getType()) && "4.0.1".equals(r.getVersion())) {
070     // the R4 profile wrongly applies this value set to all types. Fixing it properly is too big a thing to do here, but we can at least back off the binding strength
071     StructureDefinition sd = (StructureDefinition) r.getResource();
072     if (sd.getType().equals("Observation") && ("http://hl7.org/fhir/StructureDefinition/vitalsigns".equals(sd.getUrl()) || "http://hl7.org/fhir/StructureDefinition/vitalsigns".equals(sd.getBaseDefinition()))) {
073       for (ElementDefinition ed : sd.getSnapshot().getElement()) {
074         if (ed.getPath().equals("Observation.component.value[x]") && ed.hasBinding() && "http://hl7.org/fhir/ValueSet/ucum-vitals-common|4.0.1".equals(ed.getBinding().getValueSet())) {
075           ed.getBinding().setStrength(BindingStrength.EXTENSIBLE);
076         }
077       }
078       for (ElementDefinition ed : sd.getDifferential().getElement()) {
079         if (ed.getPath().equals("Observation.component.value[x]") && ed.hasBinding() && "http://hl7.org/fhir/ValueSet/ucum-vitals-common|4.0.1".equals(ed.getBinding().getValueSet())) {
080           ed.getBinding().setStrength(BindingStrength.EXTENSIBLE);
081         }
082       }
083     }
084   }
085   // work around an r2b issue
086   if (packageInfo.getId().equals("hl7.fhir.r2b.core") && r.getType().equals("StructureDefinition")) {
087     StructureDefinition sd = (StructureDefinition) r.getResource();
088     for (ElementDefinition ed : sd.getSnapshot().getElement()) {
089       if (ed.getPath().equals(sd.getType()+".id")) {
090         ed.getBase().setMax("1");
091       }
092     }
093   }
094   
095   // work around a r4 version of extension pack issue
096   if (packageInfo.getId().equals("hl7.fhir.uv.extensions.r4") && r.getType().equals("StructureDefinition")) {
097     StructureDefinition sd = (StructureDefinition) r.getResource();
098     for (ElementDefinition ed : sd.getSnapshot().getElement()) {
099       if (ed.getType().removeIf(tr -> Utilities.existsInList(tr.getCode(), "integer64", "CodeableReference", "RatioRange", "Availability", "ExtendedContactDetail"))) {
100         sd.setUserData("fixed-by-loader", true);
101       }
102     }
103     for (ElementDefinition ed : sd.getDifferential().getElement()) {
104       if (ed.getType().removeIf(tr -> Utilities.existsInList(tr.getCode(), "integer64", "CodeableReference", "RatioRange", "Availability", "ExtendedContactDetail"))) {
105         sd.setUserData("fixed-by-loader", true);
106       }
107     }
108   }
109   if (r.hasUrl() && r.getUrl().contains("|")) {
110     assert false;
111   }
112   
113  }
114
115}