001package org.hl7.fhir.r5.renderers.utils; 002 003import java.io.IOException; 004import java.io.UnsupportedEncodingException; 005import java.util.ArrayList; 006import java.util.List; 007 008import org.hl7.fhir.exceptions.FHIRException; 009import org.hl7.fhir.r5.model.Base; 010import org.hl7.fhir.r5.model.CanonicalResource; 011import org.hl7.fhir.r5.model.DomainResource; 012import org.hl7.fhir.r5.model.ElementDefinition; 013import org.hl7.fhir.r5.model.Encounter; 014import org.hl7.fhir.r5.model.Narrative.NarrativeStatus; 015import org.hl7.fhir.r5.model.Patient; 016import org.hl7.fhir.r5.model.Property; 017import org.hl7.fhir.r5.model.Resource; 018import org.hl7.fhir.r5.model.StructureDefinition; 019import org.hl7.fhir.r5.renderers.EncounterRenderer; 020import org.hl7.fhir.r5.renderers.PatientRenderer; 021import org.hl7.fhir.r5.renderers.ResourceRenderer; 022import org.hl7.fhir.r5.renderers.utils.BaseWrappers.BaseWrapper; 023import org.hl7.fhir.r5.renderers.utils.BaseWrappers.PropertyWrapper; 024import org.hl7.fhir.r5.renderers.utils.BaseWrappers.RendererWrapperImpl; 025import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper; 026import org.hl7.fhir.r5.renderers.utils.BaseWrappers.WrapperBaseImpl; 027import org.hl7.fhir.utilities.xhtml.XhtmlNode; 028 029public class DirectWrappers { 030 031 public static class PropertyWrapperDirect extends RendererWrapperImpl implements PropertyWrapper { 032 private Property wrapped; 033 private List<BaseWrapper> list; 034 private ElementDefinition ed; 035 036 public PropertyWrapperDirect(RenderingContext context, Property wrapped) { 037 super(context); 038 if (wrapped == null) 039 throw new Error("wrapped == null"); 040 this.wrapped = wrapped; 041 } 042 043 public PropertyWrapperDirect(RenderingContext context, Property wrapped, ElementDefinition ed) { 044 super(context); 045 if (wrapped == null) 046 throw new Error("wrapped == null"); 047 this.wrapped = wrapped; 048 this.ed = ed; 049 } 050 051 @Override 052 public String getName() { 053 return wrapped.getName(); 054 } 055 056 public Property getWrapped() { 057 return wrapped; 058 } 059 060 @Override 061 public boolean hasValues() { 062 return wrapped.hasValues(); 063 } 064 065 @Override 066 public List<BaseWrapper> getValues() { 067 if (list == null) { 068 list = new ArrayList<BaseWrapper>(); 069 for (Base b : wrapped.getValues()) 070 list.add(b == null ? null : new BaseWrapperDirect(context, b)); 071 } 072 return list; 073 } 074 075 @Override 076 public String getTypeCode() { 077 return wrapped.getTypeCode(); 078 } 079 080 @Override 081 public String getDefinition() { 082 return wrapped.getDefinition(); 083 } 084 085 @Override 086 public int getMinCardinality() { 087 return wrapped.getMinCardinality(); 088 } 089 090 @Override 091 public int getMaxCardinality() { 092 return wrapped.getMinCardinality(); 093 } 094 095 @Override 096 public StructureDefinition getStructure() { 097 return wrapped.getStructure(); 098 } 099 100 @Override 101 public BaseWrapper value() { 102 if (getValues().size() != 1) 103 throw new Error("Access single value, but value count is "+getValues().size()); 104 return getValues().get(0); 105 } 106 107 public String toString() { 108 return "#."+wrapped.toString(); 109 } 110 111 @Override 112 public ResourceWrapper getAsResource() { 113 return new ResourceWrapperDirect(context, (Resource) wrapped.getValues().get(0)); 114 } 115 116 @Override 117 public String fhirType() { 118 return wrapped.getTypeCode(); 119 } 120 121 @Override 122 public ElementDefinition getElementDefinition() { 123 return ed; 124 } 125 } 126 127 public static class BaseWrapperDirect extends WrapperBaseImpl implements BaseWrapper { 128 private Base wrapped; 129 private List<PropertyWrapper> list; 130 131 public BaseWrapperDirect(RenderingContext context, Base wrapped) { 132 super(context); 133 if (wrapped == null) 134 throw new Error("wrapped == null"); 135 this.wrapped = wrapped; 136 } 137 138 @Override 139 public Base getBase() { 140 return wrapped; 141 } 142 143 @Override 144 public List<PropertyWrapper> children() { 145 if (list == null) { 146 list = new ArrayList<PropertyWrapper>(); 147 for (Property p : wrapped.children()) 148 list.add(new PropertyWrapperDirect(context, p)); 149 } 150 return list; 151 152 } 153 154 @Override 155 public PropertyWrapper getChildByName(String name) { 156 Property p = wrapped.getChildByName(name); 157 if (p == null) 158 return null; 159 else 160 return new PropertyWrapperDirect(context, p); 161 } 162 163 @Override 164 public String fhirType() { 165 return wrapped.fhirType(); 166 } 167 168 @Override 169 public ResourceWrapper getResource() throws UnsupportedEncodingException, IOException, FHIRException { 170 return new DirectWrappers.ResourceWrapperDirect(getContext(), (Resource) wrapped); 171 } 172 173 } 174 175 public static class ResourceWrapperDirect extends WrapperBaseImpl implements ResourceWrapper { 176 private Resource wrapped; 177 178 public ResourceWrapperDirect(RenderingContext context, Resource wrapped) { 179 super(context); 180 if (wrapped == null) 181 throw new Error("wrapped == null"); 182 this.wrapped = wrapped; 183 } 184 185 @Override 186 public List<ResourceWrapper> getContained() { 187 List<ResourceWrapper> list = new ArrayList<ResourceWrapper>(); 188 if (wrapped instanceof DomainResource) { 189 DomainResource dr = (DomainResource) wrapped; 190 for (Resource c : dr.getContained()) { 191 list.add(new ResourceWrapperDirect(context, c)); 192 } 193 } 194 return list; 195 } 196 197 @Override 198 public String getId() { 199 return wrapped.getId(); 200 } 201 202 @Override 203 public XhtmlNode getNarrative() { 204 if (wrapped instanceof DomainResource) { 205 DomainResource dr = (DomainResource) wrapped; 206 if (dr.hasText() && dr.getText().hasDiv()) 207 return dr.getText().getDiv(); 208 } 209 return null; 210 } 211 212 @Override 213 public String getName() { 214 return wrapped.getResourceType().toString(); 215 } 216 217 @Override 218 public String getNameFromResource() { 219 Property name = wrapped.getChildByName("name"); 220 if (name != null && name.hasValues()) { 221 Base b = name.getValues().get(0); 222 if (b.isPrimitive()) { 223 return b.primitiveValue(); 224 } else if (b.fhirType().equals("HumanName")) { 225 Property family = b.getChildByName("family"); 226 Property given = wrapped.getChildByName("given"); 227 String s = given != null && given.hasValues() ? given.getValues().get(0).primitiveValue() : ""; 228 if (family != null && family.hasValues()) { 229 String v = family.getValues().get(0).primitiveValue(); 230 if (v == null) { 231 s = s + " " + "??"; 232 } else { 233 s = s + " " + v.toUpperCase(); 234 } 235 } 236 return s; 237 } else { 238 Property p = b.getChildByName("name"); 239 if (p == null || !p.hasValues()) { 240 p = b.getChildByName("name"); 241 } 242 if (p == null || !p.hasValues()) { 243 p = b.getChildByName("text"); 244 } 245 if (p == null || !p.hasValues()) { 246 p = b.getChildByName("value"); 247 } 248 if (p == null || !p.hasValues()) { 249 p = b.getChildByName("productName"); // MedicinalProductDefinition 250 } 251 if (p == null || !p.hasValues()) { 252 throw new Error("What to render for 'name'? Type is "+b.fhirType()); 253 } else { 254 return p.getValues().get(0).primitiveValue(); 255 } 256 } 257 } 258 return null; 259 } 260 261 @Override 262 public List<PropertyWrapper> children() { 263 List<PropertyWrapper> list = new ArrayList<PropertyWrapper>(); 264 if (wrapped.children() != null) { 265 for (Property c : wrapped.children()) 266 list.add(new PropertyWrapperDirect(context, c)); 267 } 268 return list; 269 } 270 271 @Override 272 public void describe(XhtmlNode x) throws UnsupportedEncodingException, IOException { 273 if (wrapped instanceof CanonicalResource) { 274 x.tx(((CanonicalResource) wrapped).present()); 275 } else if (wrapped instanceof Patient) { 276 new PatientRenderer(getContext()).describe(x, (Patient) wrapped); 277 } else if (wrapped instanceof Encounter) { 278 new EncounterRenderer(getContext()).describe(x, (Encounter) wrapped); 279 } 280 } 281 282 @Override 283 public void injectNarrative(ResourceRenderer renderer, XhtmlNode x, NarrativeStatus status) { 284 renderer.inject((DomainResource) wrapped, x, status); 285 286 } 287 288 @Override 289 public BaseWrapper root() { 290 return new BaseWrapperDirect(context, wrapped); 291 } 292 293 @Override 294 public StructureDefinition getDefinition() { 295 return context.getWorker().fetchTypeDefinition(wrapped.fhirType()); 296 } 297 298 @Override 299 public Base getBase() { 300 return wrapped; 301 } 302 303 @Override 304 public boolean hasNarrative() { 305 StructureDefinition sd = context.getWorker().fetchTypeDefinition(wrapped.fhirType()); 306 while (sd != null) { 307 if ("DomainResource".equals(sd.getType())) { 308 return true; 309 } 310 sd = context.getWorker().fetchResource(StructureDefinition.class, sd.getBaseDefinition(), sd); 311 } 312 return false; 313 314 } 315 316 @Override 317 public String fhirType() { 318 return wrapped.fhirType(); 319 } 320 321 @Override 322 public PropertyWrapper getChildByName(String name) { 323 Property p = wrapped.getChildByName(name); 324 if (p == null) 325 return null; 326 else 327 return new PropertyWrapperDirect(context, p); 328 } 329 330 public Resource getResource() { 331 return wrapped; 332 } 333 334 } 335 336}