001package org.hl7.fhir.r5.renderers.utils;
002
003import org.hl7.fhir.r5.model.Bundle;
004import org.hl7.fhir.r5.model.Bundle.BundleEntryComponent;
005import org.hl7.fhir.r5.model.DomainResource;
006import org.hl7.fhir.r5.model.Parameters;
007import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent;
008import org.hl7.fhir.r5.model.Resource;
009import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
010import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContextType;
011import org.w3c.dom.Element;
012
013public class Resolver {
014
015  public enum ResourceContextType {
016    PARAMETERS, BUNDLE
017  }
018
019  public interface IReferenceResolver {
020    ResourceWithReference resolve(RenderingContext context, String url);
021  }
022
023  public static class ResourceContext {
024    private ResourceContextType type;
025    private Resource containerResource;
026    private org.hl7.fhir.r5.elementmodel.Element containerElement;
027
028    DomainResource resourceResource;
029    org.hl7.fhir.r5.elementmodel.Element resourceElement;
030
031    public ResourceContext(ResourceContextType type, Resource bundle, DomainResource dr) {
032      super();
033      this.type = type;
034      this.containerResource = bundle;
035      this.resourceResource = dr;
036    }
037
038    public ResourceContext(ResourceContextType type, org.hl7.fhir.r5.elementmodel.Element bundle, org.hl7.fhir.r5.elementmodel.Element dr) {
039      super();
040      this.type = type;
041      this.containerElement = bundle;
042      this.resourceElement = dr;
043    }
044
045//    public ResourceContext(Object bundle, Element doc) {
046//      // TODO Auto-generated constructor stub
047//    }
048
049//    public Bundle getBundleResource() {
050//      return containerResource;
051//    }
052
053
054    //    public org.hl7.fhir.r5.elementmodel.Element getBundleElement() {
055//      return containerElement;
056//    }
057//
058    public DomainResource getResourceResource() {
059      return resourceResource;
060    }
061
062    public org.hl7.fhir.r5.elementmodel.Element getResourceElement() {
063      return resourceElement;
064    }
065
066    public BundleEntryComponent resolve(String value) {
067      if (value.startsWith("#")) {
068        if (resourceResource != null) {
069          for (Resource r : resourceResource.getContained()) {
070            if (r.getId().equals(value.substring(1))) {
071              BundleEntryComponent be = new BundleEntryComponent();
072              be.setResource(r);
073              return be;
074            }
075          }
076        }
077        return null;
078      }
079      if (type == ResourceContextType.BUNDLE) {
080        if (containerResource != null) {
081          for (BundleEntryComponent be : ((Bundle) containerResource).getEntry()) {
082            if (be.getFullUrl().equals(value))
083              return be;
084            if (value.equals(be.getResource().fhirType()+"/"+be.getResource().getId()))
085              return be;
086          }
087        } 
088      }
089      if (type == ResourceContextType.PARAMETERS) {
090        if (containerResource != null) {
091          for (ParametersParameterComponent p : ((Parameters) containerResource).getParameter()) {
092            if (p.getResource() != null && value.equals(p.getResource().fhirType()+"/"+p.getResource().getId())) {
093              BundleEntryComponent be = new BundleEntryComponent();
094              be.setResource(p.getResource());
095              return be;
096              
097            }
098          }
099        } 
100      }
101      return null;
102    }
103
104    public org.hl7.fhir.r5.elementmodel.Element resolveElement(String value, String version) {
105      if (value.startsWith("#")) {
106        if (resourceElement != null) {
107          for (org.hl7.fhir.r5.elementmodel.Element r : resourceElement.getChildrenByName("contained")) {
108            if (r.getChildValue("id").equals(value.substring(1)))
109              return r;
110          }          
111        }
112        return null;
113      }
114      if (type == ResourceContextType.BUNDLE) {
115        if (containerElement != null) {
116          for (org.hl7.fhir.r5.elementmodel.Element be : containerElement.getChildren("entry")) {
117            org.hl7.fhir.r5.elementmodel.Element res = be.getNamedChild("resource");
118            if (res != null) { 
119              if (value.equals(be.getChildValue("fullUrl"))) {
120                if (checkVersion(version, res)) {
121                  return be;
122                }
123              }
124              if (value.equals(res.fhirType()+"/"+res.getChildValue("id"))) {
125                if (checkVersion(version, res)) {
126                  return be;
127                }
128              }
129            }
130          }
131        }
132      }
133      if (type == ResourceContextType.PARAMETERS) {
134        if (containerElement != null) {
135          for (org.hl7.fhir.r5.elementmodel.Element p : containerElement.getChildren("parameter")) {
136            org.hl7.fhir.r5.elementmodel.Element res = p.getNamedChild("resource");
137            if (res != null && value.equals(res.fhirType()+"/"+res.getChildValue("id"))) {
138              if (checkVersion(version, res)) {
139                return p;
140              }
141            }
142          }
143        }
144      }
145      return null;
146    }
147
148    private boolean checkVersion(String version, org.hl7.fhir.r5.elementmodel.Element res) {
149      if (version == null) {
150        return true;
151      } else if (!res.hasChild("meta")) {
152        return false;
153      } else {
154        org.hl7.fhir.r5.elementmodel.Element meta = res.getNamedChild("meta");
155        return version.equals(meta.getChildValue("version"));
156      }
157    }
158  }
159
160  public static class ResourceWithReference {
161
162    private String reference;
163    private ResourceWrapper resource;
164
165    public ResourceWithReference(String reference, ResourceWrapper resource) {
166      this.reference = reference;
167      this.resource = resource;
168    }
169
170    public String getReference() {
171      return reference;
172    }
173
174    public ResourceWrapper getResource() {
175      return resource;
176    }
177  }
178
179
180
181}