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