
001package org.hl7.fhir.r5.renderers.mappings; 002 003import java.util.ArrayList; 004import java.util.List; 005 006import org.hl7.fhir.r5.fhirpath.ExpressionNode; 007import org.hl7.fhir.r5.fhirpath.FHIRPathEngine; 008import org.hl7.fhir.r5.fhirpath.TypeDetails; 009import org.hl7.fhir.r5.fhirpath.ExpressionNode.Function; 010import org.hl7.fhir.r5.fhirpath.ExpressionNode.Kind; 011import org.hl7.fhir.r5.fhirpath.ExpressionNode.Operation; 012import org.hl7.fhir.r5.model.Base; 013import org.hl7.fhir.r5.model.ElementDefinition; 014import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionMappingComponent; 015import org.hl7.fhir.r5.model.StructureDefinition; 016import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionMappingComponent; 017import org.hl7.fhir.r5.renderers.StructureDefinitionRenderer.Column; 018import org.hl7.fhir.r5.renderers.utils.RenderingContext; 019import org.hl7.fhir.utilities.SourceLocation; 020import org.hl7.fhir.utilities.xhtml.XhtmlNode; 021 022public class StructureDefinitionMappingProvider extends ModelMappingProvider { 023 024 private StructureDefinition sd; 025 private StructureDefinitionMappingComponent map; 026 private FHIRPathEngine fpe; 027 028 public StructureDefinitionMappingProvider(RenderingContext context, StructureDefinition dest, boolean reverse, StructureDefinition sd, StructureDefinitionMappingComponent map, FHIRPathEngine fpe) { 029 super(context, dest, reverse); 030 this.sd = sd; 031 this.map = map; 032 this.fpe = fpe; 033 } 034 035 @Override 036 public Column makeColumn(String id) { 037 return new Column(id, map.getName(), dest == null ? "??" : dest.present(), null); 038 } 039 040 @Override 041 public void render(ElementDefinition element, XhtmlNode div) { 042 if (reverse) { 043 List<ElementDefinition> sources = new ArrayList<>(); 044 for (ElementDefinition ed : dest.getSnapshot().getElement()) { 045 ElementDefinitionMappingComponent m = null; 046 for (ElementDefinitionMappingComponent t : ed.getMapping()) { 047 if (t.hasIdentity() && t.getIdentity().equals(map.getIdentity())) { 048 m = t; 049 } 050 } 051 if (m != null) { 052 String[] maps = (m.getMap() == null ? "" : m.getMap()).split("\\,"); 053 for (String s : maps) { 054 String tgt = processMap(s); 055 if (tgt != null && tgt.equals(element.getId()) || tgt.equals(element.getPath())) { 056 sources.add(ed); 057 } 058 } 059 } 060 } 061 if (sources.size() == 1) { 062 renderElementLink(div, sources.get(0)); 063 } else { 064 XhtmlNode ul = div.ul(); 065 for (ElementDefinition ed : sources) { 066 renderElementLink(ul.li(), ed); 067 } 068 } 069 } else { 070 ElementDefinitionMappingComponent m = null; 071 for (ElementDefinitionMappingComponent t : element.getMapping()) { 072 if (t.hasIdentity() && t.getIdentity().equals(map.getIdentity())) { 073 m = t; 074 } 075 } 076 if (m != null) { 077 String[] maps = (m.getMap() == null ? "" : m.getMap()).split("\\,"); 078 if (maps.length == 1) { 079 renderMap(div, maps[0]); 080 } else { 081 XhtmlNode ul = div.ul(); 082 for (String s : maps) { 083 renderMap(ul.li(), s); 084 } 085 } 086 if (m.hasComment()) { 087 div.i().tx(m.getComment()); 088 } 089 } 090 } 091 } 092 093 private String processMap(String s) { 094 if (s.contains(":")) { 095 String l = s.substring(0, s.indexOf(":")); 096 return l; 097 } else { 098 try { 099 ExpressionNode exp = fpe.parse(s); 100 stripFunctions(exp); 101 return exp.toString(); 102 } catch (Exception e) { 103 return null; 104 } 105 } 106 } 107 108 private void renderElementLink(XhtmlNode div, ElementDefinition ed) { 109 div.ah(ref()+"#"+ed.getId()).tx(ed.getPath()); 110 } 111 112 private void renderMap(XhtmlNode x, String s) { 113 // the approved syntax is id: fhirPath, or it's just rendered directly 114 if (s.contains(":")) { 115 String l = s.substring(0, s.indexOf(":")); 116 String r = s.substring(s.indexOf(":")+1); 117 if (dest != null && dest.getSnapshot().getElementById(l) != null) { 118 x.ah(ref()+"#"+l, l).tx(r); 119 } else { 120 x.tx(r); 121 } 122 } else { 123 try { 124 ExpressionNode exp = fpe.parse(s); 125 stripFunctions(exp); 126 String p = exp.toString(); 127 if (dest.getSnapshot().getElementById(p) != null) { 128 x.ah(ref()+"#"+p, p).tx(s); 129 } else { 130 x.tx(s); 131 } 132 } catch (Exception e) { 133 x.tx(s); 134 } 135 } 136 } 137 138 private void stripFunctions(ExpressionNode exp) { 139 while (exp.getInner() != null && exp.getInner().getKind() == Kind.Function) { 140 exp.setInner(exp.getInner().getInner()); 141 } 142 if (exp.getInner() != null) { 143 stripFunctions(exp.getInner()); 144 } 145 } 146}