improved ConceptMap rendering for cross-version IG
This commit is contained in:
parent
1c98b06189
commit
eb7d66685e
|
@ -24,6 +24,7 @@ import org.hl7.fhir.r5.model.ContactDetail;
|
||||||
import org.hl7.fhir.r5.model.ContactPoint;
|
import org.hl7.fhir.r5.model.ContactPoint;
|
||||||
import org.hl7.fhir.r5.model.Enumerations.ConceptMapRelationship;
|
import org.hl7.fhir.r5.model.Enumerations.ConceptMapRelationship;
|
||||||
import org.hl7.fhir.r5.model.Resource;
|
import org.hl7.fhir.r5.model.Resource;
|
||||||
|
import org.hl7.fhir.r5.renderers.ConceptMapRenderer.CollateralDefinition;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||||
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
|
||||||
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
import org.hl7.fhir.r5.utils.ToolingExtensions;
|
||||||
|
@ -34,15 +35,34 @@ import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||||
|
|
||||||
public class ConceptMapRenderer extends TerminologyRenderer {
|
public class ConceptMapRenderer extends TerminologyRenderer {
|
||||||
|
|
||||||
|
public static class CollateralDefinition {
|
||||||
|
private Resource resource;
|
||||||
|
private String label;
|
||||||
|
public CollateralDefinition(Resource resource, String label) {
|
||||||
|
super();
|
||||||
|
this.resource = resource;
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
public Resource getResource() {
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public enum RenderMultiRowSortPolicy {
|
public enum RenderMultiRowSortPolicy {
|
||||||
UNSORTED, FIRST_COL, LAST_COL
|
UNSORTED, FIRST_COL, LAST_COL
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IMultiMapRendererAdvisor {
|
public interface IMultiMapRendererAdvisor {
|
||||||
public List<Coding> getMembers(String uri);
|
public RenderMultiRowSortPolicy sortPolicy(Object rmmContext);
|
||||||
public boolean describeMap(ConceptMap map, XhtmlNode x);
|
public List<Coding> getMembers(Object rmmContext, String uri);
|
||||||
public String getLink(String system, String code);
|
public boolean describeMap(Object rmmContext, ConceptMap map, XhtmlNode x);
|
||||||
|
public boolean hasCollateral(Object rmmContext);
|
||||||
|
public List<CollateralDefinition> getCollateral(Object rmmContext, String uri); // URI identifies which column the collateral is for
|
||||||
|
public String getLink(Object rmmContext, String system, String code);
|
||||||
|
public boolean makeMapLinks();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MultipleMappingRowSorter implements Comparator<MultipleMappingRow> {
|
public static class MultipleMappingRowSorter implements Comparator<MultipleMappingRow> {
|
||||||
|
@ -381,7 +401,7 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
||||||
}
|
}
|
||||||
XhtmlNode pp = x.para();
|
XhtmlNode pp = x.para();
|
||||||
pp.b().tx(/*!#*/"Group "+gc);
|
pp.b().tx(/*!#*/"Group "+gc);
|
||||||
pp.tx(/*!#*/"Mapping from ");
|
pp.tx(" "+/*!#*/"Mapping from ");
|
||||||
if (grp.hasSource()) {
|
if (grp.hasSource()) {
|
||||||
renderCanonical(cm, pp, grp.getSource());
|
renderCanonical(cm, pp, grp.getSource());
|
||||||
} else {
|
} else {
|
||||||
|
@ -724,36 +744,55 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static XhtmlNode renderMultipleMaps(String start, String startLink, List<ConceptMap> maps, IMultiMapRendererAdvisor advisor, RenderMultiRowSortPolicy sort) {
|
public static XhtmlNode renderMultipleMaps(String start, List<ConceptMap> maps, IMultiMapRendererAdvisor advisor, Object rmmContext) {
|
||||||
// 1+1 column for each provided map
|
// 1+1 column for each provided map
|
||||||
List<MultipleMappingRow> rowSets = new ArrayList<>();
|
List<MultipleMappingRow> rowSets = new ArrayList<>();
|
||||||
for (int i = 0; i < maps.size(); i++) {
|
for (int i = 0; i < maps.size(); i++) {
|
||||||
populateRows(rowSets, maps.get(i), i, advisor);
|
populateRows(rowSets, maps.get(i), i, advisor, rmmContext);
|
||||||
}
|
}
|
||||||
collateRows(rowSets);
|
collateRows(rowSets);
|
||||||
if (sort != RenderMultiRowSortPolicy.UNSORTED) {
|
if (advisor.sortPolicy(rmmContext) != RenderMultiRowSortPolicy.UNSORTED) {
|
||||||
Collections.sort(rowSets, new MultipleMappingRowSorter(sort == RenderMultiRowSortPolicy.FIRST_COL));
|
Collections.sort(rowSets, new MultipleMappingRowSorter(advisor.sortPolicy(rmmContext) == RenderMultiRowSortPolicy.FIRST_COL));
|
||||||
}
|
}
|
||||||
XhtmlNode div = new XhtmlNode(NodeType.Element, "div");
|
XhtmlNode div = new XhtmlNode(NodeType.Element, "div");
|
||||||
XhtmlNode tbl = div.table("none").style("text-align: left; border-spacing: 0; padding: 5px");
|
XhtmlNode tbl = div.table("none").style("text-align: left; border-spacing: 0; padding: 5px");
|
||||||
XhtmlNode tr = tbl.tr();
|
XhtmlNode tr = tbl.tr();
|
||||||
styleCell(tr.td(), false, true, 5).b().ahOrNot(startLink).tx(start);
|
styleCell(tr.td(), false, true, 5).b().tx(start);
|
||||||
for (ConceptMap map : maps) {
|
for (ConceptMap map : maps) {
|
||||||
XhtmlNode td = styleCell(tr.td(), false, true, 5).colspan(2);
|
XhtmlNode td = styleCell(tr.td(), false, true, 5).colspan(2);
|
||||||
if (!advisor.describeMap(map, td)) {
|
if (!advisor.describeMap(rmmContext, map, td)) {
|
||||||
if (map.hasWebPath()) {
|
if (map.hasWebPath() && advisor.makeMapLinks()) {
|
||||||
td.b().ah(map.getWebPath(), map.getVersionedUrl()).tx(map.present());
|
td.b().ah(map.getWebPath(), map.getVersionedUrl()).tx(map.present());
|
||||||
} else {
|
} else {
|
||||||
td.b().tx(map.present());
|
td.b().tx(map.present());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (advisor.hasCollateral(rmmContext)) {
|
||||||
|
tr = tbl.tr();
|
||||||
|
renderLinks(styleCell(tr.td(), false, true, 5), advisor.getCollateral(rmmContext, null));
|
||||||
|
for (ConceptMap map : maps) {
|
||||||
|
renderLinks(styleCell(tr.td(), false, true, 5).colspan(2), advisor.getCollateral(rmmContext, map.getUrl()));
|
||||||
|
}
|
||||||
|
}
|
||||||
for (MultipleMappingRow row : rowSets) {
|
for (MultipleMappingRow row : rowSets) {
|
||||||
renderMultiRow(tbl, row, maps, advisor);
|
renderMultiRow(tbl, row, maps, advisor, rmmContext);
|
||||||
}
|
}
|
||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void renderLinks(XhtmlNode td, List<CollateralDefinition> collateral) {
|
||||||
|
if (collateral.size() > 0) {
|
||||||
|
td.tx(/*!#*/"Links:");
|
||||||
|
td.tx(" ");
|
||||||
|
boolean first = true;
|
||||||
|
for (CollateralDefinition c : collateral) {
|
||||||
|
if (first) first = false; else td.tx(", ");
|
||||||
|
td.ah(c.getResource().getWebPath()).tx(c.getLabel());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void collateRows(List<MultipleMappingRow> rowSets) {
|
private static void collateRows(List<MultipleMappingRow> rowSets) {
|
||||||
List<MultipleMappingRow> toDelete = new ArrayList<ConceptMapRenderer.MultipleMappingRow>();
|
List<MultipleMappingRow> toDelete = new ArrayList<ConceptMapRenderer.MultipleMappingRow>();
|
||||||
for (MultipleMappingRow rowSet : rowSets) {
|
for (MultipleMappingRow rowSet : rowSets) {
|
||||||
|
@ -769,7 +808,7 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
||||||
rowSets.removeAll(toDelete);
|
rowSets.removeAll(toDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void renderMultiRow(XhtmlNode tbl, MultipleMappingRow rows, List<ConceptMap> maps, IMultiMapRendererAdvisor advisor) {
|
private static void renderMultiRow(XhtmlNode tbl, MultipleMappingRow rows, List<ConceptMap> maps, IMultiMapRendererAdvisor advisor, Object rmmContext) {
|
||||||
int rowCounter = 0;
|
int rowCounter = 0;
|
||||||
for (MultipleMappingRowItem row : rows.rowSets) {
|
for (MultipleMappingRowItem row : rows.rowSets) {
|
||||||
XhtmlNode tr = tbl.tr();
|
XhtmlNode tr = tbl.tr();
|
||||||
|
@ -791,7 +830,7 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
||||||
if (cell.code == null) {
|
if (cell.code == null) {
|
||||||
styleCell(tr.td(), rowCounter == 0, true, 5).rowspan(c).style("background-color: #eeeeee");
|
styleCell(tr.td(), rowCounter == 0, true, 5).rowspan(c).style("background-color: #eeeeee");
|
||||||
} else {
|
} else {
|
||||||
String link = advisor.getLink(cell.system, cell.code);
|
String link = advisor.getLink(rmmContext, cell.system, cell.code);
|
||||||
XhtmlNode x = null;
|
XhtmlNode x = null;
|
||||||
if (link != null) {
|
if (link != null) {
|
||||||
x = styleCell(tr.td(), rowCounter == 0, true, 5).attributeNN("title", cell.display).rowspan(c).ah(link);
|
x = styleCell(tr.td(), rowCounter == 0, true, 5).attributeNN("title", cell.display).rowspan(c).ah(link);
|
||||||
|
@ -839,7 +878,7 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
||||||
if (cell.code == null) {
|
if (cell.code == null) {
|
||||||
styleCell(tr.td(), rowCounter == 0, true, 5).rowspan(c).style("background-color: #eeeeee");
|
styleCell(tr.td(), rowCounter == 0, true, 5).rowspan(c).style("background-color: #eeeeee");
|
||||||
} else {
|
} else {
|
||||||
String link = advisor.getLink(cell.system, cell.code);
|
String link = advisor.getLink(rmmContext, cell.system, cell.code);
|
||||||
XhtmlNode x = null;
|
XhtmlNode x = null;
|
||||||
if (link != null) {
|
if (link != null) {
|
||||||
x = styleCell(tr.td(), rowCounter == 0, true, 5).attributeNN("title", cell.display).rowspan(c).ah(link);
|
x = styleCell(tr.td(), rowCounter == 0, true, 5).attributeNN("title", cell.display).rowspan(c).ah(link);
|
||||||
|
@ -872,10 +911,10 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
||||||
return td;
|
return td;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void populateRows(List<MultipleMappingRow> rowSets, ConceptMap map, int i, IMultiMapRendererAdvisor advisor) {
|
private static void populateRows(List<MultipleMappingRow> rowSets, ConceptMap map, int i, IMultiMapRendererAdvisor advisor, Object rmmContext) {
|
||||||
// if we can resolve the value set, we create entries for it
|
// if we can resolve the value set, we create entries for it
|
||||||
if (map.hasSourceScope()) {
|
if (map.hasSourceScope()) {
|
||||||
List<Coding> codings = advisor.getMembers(map.getSourceScope().primitiveValue());
|
List<Coding> codings = advisor.getMembers(rmmContext, map.getSourceScope().primitiveValue());
|
||||||
if (codings != null) {
|
if (codings != null) {
|
||||||
for (Coding c : codings) {
|
for (Coding c : codings) {
|
||||||
MultipleMappingRow row = i == 0 ? null : findExistingRowBySource(rowSets, c.getSystem(), c.getCode(), i);
|
MultipleMappingRow row = i == 0 ? null : findExistingRowBySource(rowSets, c.getSystem(), c.getCode(), i);
|
||||||
|
@ -935,7 +974,7 @@ public class ConceptMapRenderer extends TerminologyRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (map.hasTargetScope()) {
|
if (map.hasTargetScope()) {
|
||||||
List<Coding> codings = advisor.getMembers(map.getTargetScope().primitiveValue());
|
List<Coding> codings = advisor.getMembers(rmmContext, map.getTargetScope().primitiveValue());
|
||||||
if (codings != null) {
|
if (codings != null) {
|
||||||
for (Coding c : codings) {
|
for (Coding c : codings) {
|
||||||
MultipleMappingRow row = findExistingRowByTarget(rowSets, c.getSystem(), c.getCode(), i);
|
MultipleMappingRow row = findExistingRowByTarget(rowSets, c.getSystem(), c.getCode(), i);
|
||||||
|
|
Loading…
Reference in New Issue