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.MarkedToMoveToAdjunctPackage;
007import org.hl7.fhir.utilities.Utilities;
008import org.hl7.fhir.r5.model.PackageInformation;
009import org.hl7.fhir.r5.model.StructureDefinition;
010
011@MarkedToMoveToAdjunctPackage
012public class PackageHackerR5 {
013
014  public static void fixLoadedResource(CanonicalResourceProxy r, PackageInformation packageInfo) {
015   if ("http://terminology.hl7.org/CodeSystem/v2-0391|2.6".equals(r.getUrl())) {
016     r.hack("http://terminology.hl7.org/CodeSystem/v2-0391-2.6", "2.6");
017   }
018   if ("http://terminology.hl7.org/CodeSystem/v2-0391|2.4".equals(r.getUrl())) {
019     r.hack("http://terminology.hl7.org/CodeSystem/v2-0391-2.4", "2.4");
020   }
021   if ("http://terminology.hl7.org/CodeSystem/v2-0360|2.7".equals(r.getUrl())) {
022     r.hack("http://terminology.hl7.org/CodeSystem/v2-0360-2.7", "2.7");
023   }
024
025   if ("http://terminology.hl7.org/CodeSystem/v2-0006|2.1".equals(r.getUrl())) {
026     r.hack("http://terminology.hl7.org/CodeSystem/v2-0006-2.1", "2.1");
027   }
028
029   if ("http://terminology.hl7.org/CodeSystem/v2-0360|2.7".equals(r.getUrl())) {
030     r.hack("http://terminology.hl7.org/CodeSystem/v2-0360-2.7", "2.7");
031   }
032
033   if ("http://terminology.hl7.org/CodeSystem/v2-0006|2.4".equals(r.getUrl())) {
034     r.hack("http://terminology.hl7.org/CodeSystem/v2-0006-2.4", "2.4");
035   }
036
037   if ("http://terminology.hl7.org/CodeSystem/v2-0360|2.3.1".equals(r.getUrl())) {
038     r.hack("http://terminology.hl7.org/CodeSystem/v2-0360-2.3.1", "2.3.1");
039   }
040
041   if ("http://hl7.org/fhir/ValueSet/languages".equals(r.getUrl())) {
042     r.getResource().setExperimental(false);
043   }
044   
045   if ("http://hl7.org/fhir/StructureDefinition/iso21090-nullFlavor".equals(r.getUrl()) && "4.0.1".equals(r.getVersion())) {
046     StructureDefinition sd = (StructureDefinition) r.getResource();
047     for (ElementDefinition ed : sd.getSnapshot().getElement()) {
048       if (ed.hasBinding() && "http://terminology.hl7.org/ValueSet/v3-NullFlavor|4.0.1".equals(ed.getBinding().getValueSet())) {
049         ed.getBinding().setValueSet("http://terminology.hl7.org/ValueSet/v3-NullFlavor");
050       }
051     }
052     for (ElementDefinition ed : sd.getDifferential().getElement()) {
053       if (ed.hasBinding() && "http://terminology.hl7.org/ValueSet/v3-NullFlavor|4.0.1".equals(ed.getBinding().getValueSet())) {
054         ed.getBinding().setValueSet("http://terminology.hl7.org/ValueSet/v3-NullFlavor");
055       }
056     }
057   }
058   if ("http://hl7.org/fhir/StructureDefinition/DeviceUseStatement".equals(r.getUrl()) && "4.0.1".equals(r.getVersion())) {
059     StructureDefinition sd = (StructureDefinition) r.getResource();
060     for (ElementDefinition ed : sd.getSnapshot().getElement()) {
061       if (ed.hasRequirements()) {
062         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)"));
063       }
064     }
065     for (ElementDefinition ed : sd.getDifferential().getElement()) {
066       if (ed.hasRequirements()) {
067         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)"));
068       }
069     }
070   }
071   if ("http://hl7.org/fhir/StructureDefinition/ServiceRequest".equals(r.getUrl()) && "4.0.1".equals(r.getVersion())) {
072     StructureDefinition sd = (StructureDefinition) r.getResource();
073     for (ElementDefinition ed : sd.getSnapshot().getElement()) {
074       if (ed.hasBinding()) {
075         if ("Codes for tests or services that can be carried out by a designated individual, organization or healthcare service.  For laboratory, LOINC is  (preferred)[http://build.fhir.org/terminologies.html#preferred] and a valueset using LOINC Order codes is available [here](valueset-diagnostic-requests.html).".equals(ed.getBinding().getDescription())) {
076           ed.getBinding().setDescription("Codes for tests or services that can be carried out by a designated individual, organization or healthcare service.  For laboratory, LOINC is  (preferred)[http://build.fhir.org/terminologies.html#preferred].");
077         }
078       }
079     }
080     for (ElementDefinition ed : sd.getDifferential().getElement()) {
081       if (ed.hasBinding()) {
082         if ("Codes for tests or services that can be carried out by a designated individual, organization or healthcare service.  For laboratory, LOINC is  (preferred)[http://build.fhir.org/terminologies.html#preferred] and a valueset using LOINC Order codes is available [here](valueset-diagnostic-requests.html).".equals(ed.getBinding().getDescription())) {
083           ed.getBinding().setDescription("Codes for tests or services that can be carried out by a designated individual, organization or healthcare service.  For laboratory, LOINC is  (preferred)[http://build.fhir.org/terminologies.html#preferred].");
084         }
085       }
086     }
087   }
088   if (r.getUrl() != null && r.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition/") && "StructureDefinition".equals(r.getType()) && "4.0.1".equals(r.getVersion())) {
089     // 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
090     StructureDefinition sd = (StructureDefinition) r.getResource();
091     if (sd.getType().equals("Observation") && ("http://hl7.org/fhir/StructureDefinition/vitalsigns".equals(sd.getUrl()) || "http://hl7.org/fhir/StructureDefinition/vitalsigns".equals(sd.getBaseDefinition()))) {
092       for (ElementDefinition ed : sd.getSnapshot().getElement()) {
093         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())) {
094           ed.getBinding().setStrength(BindingStrength.EXTENSIBLE);
095         }
096       }
097       for (ElementDefinition ed : sd.getDifferential().getElement()) {
098         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())) {
099           ed.getBinding().setStrength(BindingStrength.EXTENSIBLE);
100         }
101       }
102     }
103   }
104   // work around an r2b issue
105   if (packageInfo.getId().equals("hl7.fhir.r2b.core") && r.getType().equals("StructureDefinition")) {
106     StructureDefinition sd = (StructureDefinition) r.getResource();
107     for (ElementDefinition ed : sd.getSnapshot().getElement()) {
108       if (ed.getPath().equals(sd.getType()+".id")) {
109         ed.getBase().setMax("1");
110       }
111     }
112   }
113   
114   // work around a r4 version of extension pack issue
115   if (packageInfo.getId().equals("hl7.fhir.uv.extensions.r4") && r.getType().equals("StructureDefinition")) {
116     StructureDefinition sd = (StructureDefinition) r.getResource();
117     for (ElementDefinition ed : sd.getSnapshot().getElement()) {
118       if (ed.getType().removeIf(tr -> Utilities.existsInList(tr.getCode(), "integer64", "CodeableReference", "RatioRange", "Availability", "ExtendedContactDetail"))) {
119         // sd.setUserData(UserDataNames.fixed_by_loader, true);
120         // don't need to track this (for now)
121       }
122     }
123     for (ElementDefinition ed : sd.getDifferential().getElement()) {
124       if (ed.getType().removeIf(tr -> Utilities.existsInList(tr.getCode(), "integer64", "CodeableReference", "RatioRange", "Availability", "ExtendedContactDetail"))) {
125         // sd.setUserData(UserDataNames.fixed_by_loader, true);
126         // don't need to track this (for now)
127       }
128     }
129   }
130   if (r.hasUrl() && r.getUrl().contains("|")) {
131     assert false;
132   }
133   
134  }
135
136}