001package org.hl7.fhir.r5.utils.xver;
002
003import org.hl7.fhir.exceptions.FHIRException;
004import org.hl7.fhir.r5.context.IWorkerContext;
005import org.hl7.fhir.r5.model.ElementDefinition;
006import org.hl7.fhir.r5.model.StructureDefinition;
007import org.hl7.fhir.utilities.VersionUtilities;
008import org.hl7.fhir.utilities.json.model.JsonObject;
009import org.hl7.fhir.utilities.json.parser.JsonParser;
010
011import java.io.IOException;
012import java.util.HashMap;
013import java.util.Map;
014
015public class XVerExtensionManagerNew extends XVerExtensionManager {
016
017  private Map<String, JsonObject> lists = new HashMap<>();
018  private final IXverManagerPackageLoader loader;
019
020  public interface IXverManagerPackageLoader {
021    public void loadPackage(String idAndVer) throws IOException;
022  }
023  
024  public XVerExtensionManagerNew(IWorkerContext context, IXverManagerPackageLoader loader) {
025    super(context);
026    this.loader = loader;
027  }
028
029  @Override
030  public XVerExtensionStatus status(String url) {
031    if (url.length() < 54) {
032      return XVerExtensionStatus.Invalid;
033    }
034    String v = url.substring(20, 23);
035    String tv = VersionUtilities.getNameForVersion(v).toLowerCase();
036    if (tv.contains("?")) {
037      return XVerExtensionStatus.BadVersion;
038    }
039
040    String sv = VersionUtilities.getNameForVersion(context.getVersion()).toLowerCase();
041    String pid = "hl7.fhir.uv.xver-"+tv+"."+sv;
042    if (!context.hasPackage(pid, "dev")) {
043      try {
044        loader.loadPackage(pid+"#dev");
045      } catch (IOException e) {
046        return XVerExtensionStatus.BadVersion;
047      }
048    }
049    StructureDefinition sd = context.fetchResource(StructureDefinition.class, url);
050    if (sd == null) {
051      // well, it's not an approved extension, but why? We're going to look in the old
052      // version stuff to see whether it's a valid element or not - it'll affect the return value.
053      if (isValidPath(v, url)) {
054        return XVerExtensionStatus.NotAllowed;
055      } else {
056        return XVerExtensionStatus.Unknown;
057      }
058    } else {
059      return XVerExtensionStatus.Valid;
060    }
061  }
062
063  private boolean isValidPath(String v, String url) {
064    if (!lists.containsKey(v)) {
065      if (context.hasBinaryKey("xver-paths-" + v + ".json")) {
066        try {
067          lists.put(v, JsonParser.parseObject(context.getBinaryForKey("xver-paths-" + v + ".json")));
068        } catch (IOException e1) {
069          throw new FHIRException(e1);
070        }
071
072        url = url.replace("%5Bx%5D", "[x]");
073        String e = url.substring(54);
074        JsonObject root = lists.get(v);
075        JsonObject path = root.getJsonObject(e);
076        if (path == null) {
077          path = root.getJsonObject(e + "[x]");
078        }
079        if (path != null) {
080          return true;
081        }
082      }
083    }
084    return false;
085  }
086
087
088  @Override
089  public StructureDefinition getDefinition(String url) {
090    return context.fetchResource(StructureDefinition.class, url);
091  }
092}
093