001package org.hl7.fhir.r5.renderers.utils;
002
003import java.io.IOException;
004
005import org.hl7.fhir.utilities.MarkedToMoveToAdjunctPackage;
006
007@MarkedToMoveToAdjunctPackage
008public class Resolver {
009
010
011  public interface IReferenceResolver {
012    ResourceWithReference resolve(RenderingContext context, String url, String version) throws IOException;
013    
014    /**
015     * returns the correct literal URL for the specified logical uri
016     * @param context
017     * @param value
018     * @return
019     */
020    String resolveUri(RenderingContext context, String uri);
021  }
022
023  /*
024  public static class ResourceContext {
025    private ResourceContext container;
026
027    Resource resource;
028    org.hl7.fhir.r5.elementmodel.Element element;
029
030    public ResourceContext(ResourceContext container, Resource dr) {
031      super();
032      this.container = container;
033      this.resource = dr;
034    }
035
036    public ResourceContext(ResourceContext container, org.hl7.fhir.r5.elementmodel.Element dr) {
037      super();
038      this.container = container;
039      this.element = dr;
040    }
041
042    
043//    public ResourceContext(Object bundle, Element doc) {
044//      // TODO Auto-generated constructor stub
045//    }
046
047//    public Bundle getBundleResource() {
048//      return containerResource;
049//    }
050
051
052    public ResourceContext(ResourceContext container, ResourceWrapper rw) {
053      super();
054      this.container = container;
055      // todo: howto do this better?
056      
057      if (rw instanceof DirectWrappers.ResourceWrapperDirect) {
058        this.resource = ((DirectWrappers.ResourceWrapperDirect) rw).getResource();
059      } else if (rw instanceof ElementWrappers.ResourceWrapperMetaElement) {
060        this.element = ((ElementWrappers.ResourceWrapperMetaElement) rw).getElement();
061      } else {
062        // this is not supported for now... throw new Error("Not supported yet");
063      }
064    }
065
066    public ResourceContext getContainer() {
067      return container;
068    }
069
070    public void setContainer(ResourceContext container) {
071      this.container = container;
072    }
073
074    //    public org.hl7.fhir.r5.elementmodel.Element getBundleElement() {
075//      return containerElement;
076//    }
077//
078    public Resource getResource() {
079      return resource;
080    }
081
082    public org.hl7.fhir.r5.elementmodel.Element getElement() {
083      return element;
084    }
085
086    public BundleEntryComponent resolve(String value) {
087      if (value.startsWith("#")) {
088        if (resource instanceof DomainResource) {
089          DomainResource dr = (DomainResource) resource;
090          for (Resource r : dr.getContained()) {
091            if (r.getId().equals(value.substring(1))) {
092              BundleEntryComponent be = new BundleEntryComponent();
093              be.setResource(r);
094              return be;
095            }
096          }
097        }
098        return null;
099      }
100      
101      if (resource instanceof Bundle) {
102        Bundle b = (Bundle) resource;
103        for (BundleEntryComponent be : b.getEntry()) {
104          if (be.hasFullUrl() && be.getFullUrl().equals(value))
105            return be;
106          if (value.equals(be.getResource().fhirType()+"/"+be.getResource().getId()))
107            return be;
108        }
109      } 
110
111      if (resource instanceof Parameters) {
112        Parameters pp = (Parameters) resource;
113        for (ParametersParameterComponent p : pp.getParameter()) {
114          if (p.getResource() != null && value.equals(p.getResource().fhirType()+"/"+p.getResource().getId())) {
115            BundleEntryComponent be = new BundleEntryComponent();
116            be.setResource(p.getResource());
117            return be;
118
119          }
120        }
121      } 
122
123      return container != null ? container.resolve(value) : null;
124    }
125
126    public org.hl7.fhir.r5.elementmodel.Element resolveElement(String value, String version) {
127      if (value.startsWith("#")) {
128        if (element != null) {
129          for (org.hl7.fhir.r5.elementmodel.Element r : element.getChildrenByName("contained")) {
130            if (r.getChildValue("id").equals(value.substring(1)))
131              return r;
132          }          
133        }
134        return null;
135      }
136      if (element != null) {
137        if (element.fhirType().equals("Bundle")) {
138          for (org.hl7.fhir.r5.elementmodel.Element be : element.getChildren("entry")) {
139            org.hl7.fhir.r5.elementmodel.Element res = be.getNamedChild("resource");
140            if (res != null) { 
141              if (value.equals(be.getChildValue("fullUrl"))) {
142                if (checkVersion(version, res)) {
143                  return be;
144                }
145              }
146              if (value.equals(res.fhirType()+"/"+res.getChildValue("id"))) {
147                if (checkVersion(version, res)) {
148                  return be;
149                }
150              }
151            }
152          }
153        }
154        if (element.fhirType().equals("Parameters")) {
155          for (org.hl7.fhir.r5.elementmodel.Element p : element.getChildren("parameter")) {
156            org.hl7.fhir.r5.elementmodel.Element res = p.getNamedChild("resource");
157            if (res != null && value.equals(res.fhirType()+"/"+res.getChildValue("id"))) {
158              if (checkVersion(version, res)) {
159                return p;
160              }
161            }
162          }
163        }
164      }
165      return container != null ? container.resolveElement(value, version) : null;
166    }
167
168    private boolean checkVersion(String version, org.hl7.fhir.r5.elementmodel.Element res) {
169      if (version == null) {
170        return true;
171      } else if (!res.hasChild("meta")) {
172        return false;
173      } else {
174        org.hl7.fhir.r5.elementmodel.Element meta = res.getNamedChild("meta");
175        return version.equals(meta.getChildValue("version"));
176      }
177    }
178  }
179*/
180
181  public enum ResourceReferenceKind {
182    CONTAINED, BUNDLE, EXTERNAL, UNKNOWN, CONTAINER
183
184  }
185  
186  public static class ResourceWithReference {
187
188    private ResourceReferenceKind kind;
189    private String urlReference;
190    private String webPath;
191    private ResourceWrapper resource;
192
193    public ResourceWithReference(ResourceReferenceKind kind, String urlReference, String webPath, ResourceWrapper resource) {
194      super();
195      this.kind = kind;
196      this.urlReference = urlReference;
197      this.webPath = webPath;
198      this.resource = resource;
199    }
200
201    public ResourceReferenceKind getKind() {
202      return kind;
203    }
204
205    public String getUrlReference() {
206      return urlReference;
207    }
208
209    public String getWebPath() {
210      return webPath == null ? urlReference : webPath;
211    }
212
213    public ResourceWrapper getResource() {
214      return resource;
215    }
216  }
217
218
219
220}