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