use of org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent in project org.hl7.fhir.core by hapifhir.
the class StructureMapUtilities method translate.
public Base translate(TransformContext context, StructureMap map, Base source, String conceptMapUrl, String fieldToReturn) throws FHIRException {
Coding src = new Coding();
if (source.isPrimitive()) {
src.setCode(source.primitiveValue());
} else if ("Coding".equals(source.fhirType())) {
Base[] b = source.getProperty("system".hashCode(), "system", true);
if (b.length == 1)
src.setSystem(b[0].primitiveValue());
b = source.getProperty("code".hashCode(), "code", true);
if (b.length == 1)
src.setCode(b[0].primitiveValue());
} else if ("CE".equals(source.fhirType())) {
Base[] b = source.getProperty("codeSystem".hashCode(), "codeSystem", true);
if (b.length == 1)
src.setSystem(b[0].primitiveValue());
b = source.getProperty("code".hashCode(), "code", true);
if (b.length == 1)
src.setCode(b[0].primitiveValue());
} else
throw new FHIRException("Unable to translate source " + source.fhirType());
String su = conceptMapUrl;
if (conceptMapUrl.equals("http://hl7.org/fhir/ConceptMap/special-oid2uri")) {
String uri = worker.oid2Uri(src.getCode());
if (uri == null)
uri = "urn:oid:" + src.getCode();
if ("uri".equals(fieldToReturn))
return new UriType(uri);
else
throw new FHIRException("Error in return code");
} else {
ConceptMap cmap = null;
if (conceptMapUrl.startsWith("#")) {
for (Resource r : map.getContained()) {
if (r instanceof ConceptMap && ((ConceptMap) r).getId().equals(conceptMapUrl.substring(1))) {
cmap = (ConceptMap) r;
su = map.getUrl() + "#" + conceptMapUrl;
}
}
if (cmap == null)
throw new FHIRException("Unable to translate - cannot find map " + conceptMapUrl);
} else {
if (conceptMapUrl.contains("#")) {
String[] p = conceptMapUrl.split("\\#");
StructureMap mapU = worker.fetchResource(StructureMap.class, p[0]);
for (Resource r : mapU.getContained()) {
if (r instanceof ConceptMap && ((ConceptMap) r).getId().equals(p[1])) {
cmap = (ConceptMap) r;
su = conceptMapUrl;
}
}
}
if (cmap == null)
cmap = worker.fetchResource(ConceptMap.class, conceptMapUrl);
}
Coding outcome = null;
boolean done = false;
String message = null;
if (cmap == null) {
if (services == null)
message = "No map found for " + conceptMapUrl;
else {
outcome = services.translate(context.getAppInfo(), src, conceptMapUrl);
done = true;
}
} else {
List<SourceElementComponentWrapper> list = new ArrayList<SourceElementComponentWrapper>();
for (ConceptMapGroupComponent g : cmap.getGroup()) {
for (SourceElementComponent e : g.getElement()) {
if (!src.hasSystem() && src.getCode().equals(e.getCode()))
list.add(new SourceElementComponentWrapper(g, e));
else if (src.hasSystem() && src.getSystem().equals(g.getSource()) && src.getCode().equals(e.getCode()))
list.add(new SourceElementComponentWrapper(g, e));
}
}
if (list.size() == 0)
done = true;
else if (list.get(0).comp.getTarget().size() == 0)
message = "Concept map " + su + " found no translation for " + src.getCode();
else {
for (TargetElementComponent tgt : list.get(0).comp.getTarget()) {
if (tgt.getEquivalence() == null || EnumSet.of(ConceptMapEquivalence.EQUAL, ConceptMapEquivalence.RELATEDTO, ConceptMapEquivalence.EQUIVALENT, ConceptMapEquivalence.WIDER).contains(tgt.getEquivalence())) {
if (done) {
message = "Concept map " + su + " found multiple matches for " + src.getCode();
done = false;
} else {
done = true;
outcome = new Coding().setCode(tgt.getCode()).setSystem(list.get(0).group.getTarget());
}
} else if (tgt.getEquivalence() == ConceptMapEquivalence.UNMATCHED) {
done = true;
}
}
if (!done)
message = "Concept map " + su + " found no usable translation for " + src.getCode();
}
}
if (!done)
throw new FHIRException(message);
if (outcome == null)
return null;
if ("code".equals(fieldToReturn))
return new CodeType(outcome.getCode());
else
return outcome;
}
}
use of org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent in project org.hl7.fhir.core by hapifhir.
the class MappingSheetParser method readConceptMap.
private void readConceptMap(ConceptMap cm) throws FHIRException {
for (ConceptMapGroupComponent g : cm.getGroup()) {
for (SourceElementComponent e : g.getElement()) {
if (e.hasId() && e.getTarget().size() == 1 && e.hasExtension(ToolingExtensions.EXT_MAPPING_TYPE)) {
TargetElementComponent t = e.getTargetFirstRep();
MappingRow row = new MappingRow();
row.sequence = e.getId();
row.identifier = e.getCode();
row.name = e.getExtensionString(ToolingExtensions.EXT_MAPPING_NAME);
row.dataType = e.getExtensionString(ToolingExtensions.EXT_MAPPING_TYPE);
row.cardinality = e.getExtensionString(ToolingExtensions.EXT_MAPPING_CARD);
if (e.getTargetFirstRep().getEquivalence() == ConceptMapEquivalence.UNMATCHED) {
row.attribute = "N/A";
} else {
OtherElementComponent dep = getDependency(t, "http://hl7.org/fhirpath");
if (dep != null)
row.condition = dep.getValue();
row.attribute = t.getCode();
row.type = t.getExtensionString(ToolingExtensions.EXT_MAPPING_TGTTYPE);
row.minMax = t.getExtensionString(ToolingExtensions.EXT_MAPPING_TGTCARD);
row.dtMapping = t.getExtensionString("http://hl7.org/fhir/StructureDefinition/ConceptMap-type-mapping");
row.vocabMapping = t.getExtensionString("http://hl7.org/fhir/StructureDefinition/ConceptMap-vocab-mapping");
if (t.getProduct().size() > 0) {
row.derived = t.getProductFirstRep().getProperty();
row.derivedMapping = t.getProductFirstRep().getValue();
}
}
row.comments = t.getComment();
rows.add(row);
}
}
}
}
use of org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent in project org.hl7.fhir.core by hapifhir.
the class StructureMapUtilities method parseConceptMap.
private void parseConceptMap(StructureMap result, FHIRLexer lexer) throws FHIRLexerException {
lexer.token("conceptmap");
ConceptMap map = new ConceptMap();
String id = lexer.readConstant("map id");
if (id.startsWith("#")) {
throw lexer.error("Concept Map identifier must start with #");
}
map.setId(id);
// todo: how to add this to the text format
map.setStatus(PublicationStatus.DRAFT);
result.getContained().add(map);
lexer.token("{");
// lexer.token("source");
// map.setSource(new UriType(lexer.readConstant("source")));
// lexer.token("target");
// map.setSource(new UriType(lexer.readConstant("target")));
Map<String, String> prefixes = new HashMap<String, String>();
while (lexer.hasToken("prefix")) {
lexer.token("prefix");
String n = lexer.take();
lexer.token("=");
String v = lexer.readConstant("prefix url");
prefixes.put(n, v);
}
while (lexer.hasToken("unmapped")) {
lexer.token("unmapped");
lexer.token("for");
String n = readPrefix(prefixes, lexer);
ConceptMapGroupComponent g = getGroup(map, n, null);
lexer.token("=");
String v = lexer.take();
if (v.equals("provided")) {
g.getUnmapped().setMode(ConceptMapGroupUnmappedMode.PROVIDED);
} else {
throw lexer.error("Only unmapped mode PROVIDED is supported at this time");
}
}
while (!lexer.hasToken("}")) {
String srcs = readPrefix(prefixes, lexer);
lexer.token(":");
String sc = lexer.getCurrent().startsWith("\"") ? lexer.readConstant("code") : lexer.take();
ConceptMapEquivalence eq = readEquivalence(lexer);
String tgts = (eq != ConceptMapEquivalence.UNMATCHED) ? readPrefix(prefixes, lexer) : "";
ConceptMapGroupComponent g = getGroup(map, srcs, tgts);
SourceElementComponent e = g.addElement();
e.setCode(sc);
if (e.getCode().startsWith("\"")) {
e.setCode(lexer.processConstant(e.getCode()));
}
TargetElementComponent tgt = e.addTarget();
tgt.setEquivalence(eq);
if (tgt.getEquivalence() != ConceptMapEquivalence.UNMATCHED) {
lexer.token(":");
tgt.setCode(lexer.take());
if (tgt.getCode().startsWith("\"")) {
tgt.setCode(lexer.processConstant(tgt.getCode()));
}
}
tgt.setComment(lexer.getFirstComment());
}
lexer.token("}");
}
use of org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent in project org.hl7.fhir.core by hapifhir.
the class ConceptMapSpreadsheetGenerator method renderGroup.
private void renderGroup(ConceptMapGroupComponent grp, int i) {
Sheet sheet = makeSheet("Mapping Table " + Integer.toString(i));
addHeaders(sheet, "Source", "Display", "Relationship", "Target", "Display");
addRow(sheet, grp.getSource(), "", "", grp.getTarget(), "");
for (SourceElementComponent s : grp.getElement()) {
for (TargetElementComponent t : s.getTarget()) {
addRow(sheet, s.getCode(), s.getDisplay(), t.getEquivalenceElement().asStringValue(), t.getCode(), t.getDisplay());
}
}
}
use of org.hl7.fhir.r5.model.ConceptMap.TargetElementComponent in project org.hl7.fhir.core by hapifhir.
the class ConceptMapRenderer method render.
public boolean render(XhtmlNode x, ConceptMap cm) throws FHIRFormatError, DefinitionException, IOException {
x.h2().addText(cm.getName() + " (" + cm.getUrl() + ")");
XhtmlNode p = x.para();
p.tx("Mapping from ");
if (cm.hasSource())
AddVsRef(cm.getSource().primitiveValue(), p);
else
p.tx("(not specified)");
p.tx(" to ");
if (cm.hasTarget())
AddVsRef(cm.getTarget().primitiveValue(), p);
else
p.tx("(not specified)");
p = x.para();
if (cm.getExperimental())
p.addText(Utilities.capitalize(cm.getStatus().toString()) + " (not intended for production usage). ");
else
p.addText(Utilities.capitalize(cm.getStatus().toString()) + ". ");
p.tx("Published on " + (cm.hasDate() ? cm.getDateElement().toHumanDisplay() : "?ngen-10?") + " by " + cm.getPublisher());
if (!cm.getContact().isEmpty()) {
p.tx(" (");
boolean firsti = true;
for (ContactDetail ci : cm.getContact()) {
if (firsti)
firsti = false;
else
p.tx(", ");
if (ci.hasName())
p.addText(ci.getName() + ": ");
boolean first = true;
for (ContactPoint c : ci.getTelecom()) {
if (first)
first = false;
else
p.tx(", ");
addTelecom(p, c);
}
}
p.tx(")");
}
p.tx(". ");
p.addText(cm.getCopyright());
if (!Utilities.noString(cm.getDescription()))
addMarkdown(x, cm.getDescription());
x.br();
CodeSystem cs = getContext().getWorker().fetchCodeSystem("http://hl7.org/fhir/concept-map-relationship");
if (cs == null)
cs = getContext().getWorker().fetchCodeSystem("http://hl7.org/fhir/concept-map-equivalence");
String eqpath = cs == null ? null : cs.getUserString("path");
for (ConceptMapGroupComponent grp : cm.getGroup()) {
String src = grp.getSource();
boolean comment = false;
boolean ok = true;
Map<String, HashSet<String>> sources = new HashMap<String, HashSet<String>>();
Map<String, HashSet<String>> targets = new HashMap<String, HashSet<String>>();
sources.put("code", new HashSet<String>());
targets.put("code", new HashSet<String>());
SourceElementComponent cc = grp.getElement().get(0);
String dst = grp.getTarget();
sources.get("code").add(grp.getSource());
targets.get("code").add(grp.getTarget());
for (SourceElementComponent ccl : grp.getElement()) {
ok = ok && ccl.getTarget().size() == 1 && ccl.getTarget().get(0).getDependsOn().isEmpty() && ccl.getTarget().get(0).getProduct().isEmpty();
for (TargetElementComponent ccm : ccl.getTarget()) {
comment = comment || !Utilities.noString(ccm.getComment());
for (OtherElementComponent d : ccm.getDependsOn()) {
if (!sources.containsKey(d.getProperty()))
sources.put(d.getProperty(), new HashSet<String>());
sources.get(d.getProperty()).add(d.getSystem());
}
for (OtherElementComponent d : ccm.getProduct()) {
if (!targets.containsKey(d.getProperty()))
targets.put(d.getProperty(), new HashSet<String>());
targets.get(d.getProperty()).add(d.getSystem());
}
}
}
String display;
if (ok) {
// simple
XhtmlNode tbl = x.table("grid");
XhtmlNode tr = tbl.tr();
tr.td().b().tx("Source Code");
tr.td().b().tx("Relationship");
tr.td().b().tx("Destination Code");
if (comment)
tr.td().b().tx("Comment");
for (SourceElementComponent ccl : grp.getElement()) {
tr = tbl.tr();
XhtmlNode td = tr.td();
td.addText(ccl.getCode());
display = getDisplayForConcept(systemFromCanonical(grp.getSource()), versionFromCanonical(grp.getSource()), ccl.getCode());
if (display != null && !isSameCodeAndDisplay(ccl.getCode(), display))
td.tx(" (" + display + ")");
TargetElementComponent ccm = ccl.getTarget().get(0);
if (!ccm.hasEquivalence())
tr.td().tx(":" + "(" + ConceptMapEquivalence.NULL.toCode() + ")");
else {
String code = ccm.getEquivalenceElement().primitiveValue();
tr.td().ah(eqpath + "#" + code).tx(presentEquivalenceCode(code));
}
td = tr.td();
td.addText(ccm.getCode());
display = getDisplayForConcept(systemFromCanonical(grp.getTarget()), versionFromCanonical(grp.getTarget()), ccm.getCode());
if (display != null && !isSameCodeAndDisplay(ccm.getCode(), display))
td.tx(" (" + display + ")");
if (comment)
tr.td().addText(ccm.getComment());
addUnmapped(tbl, grp);
}
} else {
boolean hasRelationships = false;
for (int si = 0; si < grp.getElement().size(); si++) {
SourceElementComponent ccl = grp.getElement().get(si);
for (int ti = 0; ti < ccl.getTarget().size(); ti++) {
TargetElementComponent ccm = ccl.getTarget().get(ti);
if (ccm.hasEquivalence()) {
hasRelationships = true;
}
}
}
XhtmlNode tbl = x.table("grid");
XhtmlNode tr = tbl.tr();
XhtmlNode td;
tr.td().colspan(Integer.toString(1 + sources.size())).b().tx("Source Concept Details");
if (hasRelationships) {
tr.td().b().tx("Relationship");
}
tr.td().colspan(Integer.toString(1 + targets.size())).b().tx("Destination Concept Details");
if (comment) {
tr.td().b().tx("Comment");
}
tr = tbl.tr();
if (sources.get("code").size() == 1) {
String url = sources.get("code").iterator().next();
renderCSDetailsLink(tr, url, true);
} else
tr.td().b().tx("Code");
for (String s : sources.keySet()) {
if (!s.equals("code")) {
if (sources.get(s).size() == 1) {
String url = sources.get(s).iterator().next();
renderCSDetailsLink(tr, url, false);
} else
tr.td().b().addText(getDescForConcept(s));
}
}
if (hasRelationships) {
tr.td();
}
if (targets.get("code").size() == 1) {
String url = targets.get("code").iterator().next();
renderCSDetailsLink(tr, url, true);
} else
tr.td().b().tx("Code");
for (String s : targets.keySet()) {
if (!s.equals("code")) {
if (targets.get(s).size() == 1) {
String url = targets.get(s).iterator().next();
renderCSDetailsLink(tr, url, false);
} else
tr.td().b().addText(getDescForConcept(s));
}
}
if (comment)
tr.td();
for (int si = 0; si < grp.getElement().size(); si++) {
SourceElementComponent ccl = grp.getElement().get(si);
boolean slast = si == grp.getElement().size() - 1;
boolean first = true;
if (false) {
tr = tbl.tr();
td = tr.td().style("border-right-width: 0px");
if (!first)
td.style("border-top-style: none");
else
td.style("border-bottom-style: none");
if (sources.get("code").size() == 1)
td.addText(ccl.getCode());
else
td.addText(grp.getSource() + " / " + ccl.getCode());
display = getDisplayForConcept(systemFromCanonical(grp.getSource()), versionFromCanonical(grp.getSource()), ccl.getCode());
tr.td().style("border-left-width: 0px").tx(display == null ? "" : display);
tr.td().colspan("4").style("background-color: #efefef").tx("(not mapped)");
} else {
for (int ti = 0; ti < ccl.getTarget().size(); ti++) {
TargetElementComponent ccm = ccl.getTarget().get(ti);
boolean last = ti == ccl.getTarget().size() - 1;
tr = tbl.tr();
td = tr.td().style("border-right-width: 0px");
if (!first && !last)
td.style("border-top-style: none; border-bottom-style: none");
else if (!first)
td.style("border-top-style: none");
else if (!last)
td.style("border-bottom-style: none");
if (first) {
if (sources.get("code").size() == 1)
td.addText(ccl.getCode());
else
td.addText(grp.getSource() + " / " + ccl.getCode());
display = ccl.hasDisplay() ? ccl.getDisplay() : getDisplayForConcept(systemFromCanonical(grp.getSource()), versionFromCanonical(grp.getSource()), ccl.getCode());
td = tr.td();
if (!last)
td.style("border-left-width: 0px; border-bottom-style: none");
else
td.style("border-left-width: 0px");
td.tx(display == null ? "" : display);
} else {
// for display
td = tr.td();
if (!last)
td.style("border-left-width: 0px; border-top-style: none; border-bottom-style: none");
else
td.style("border-top-style: none; border-left-width: 0px");
}
for (String s : sources.keySet()) {
if (!s.equals("code")) {
td = tr.td();
if (first) {
td.addText(getValue(ccm.getDependsOn(), s, sources.get(s).size() != 1));
display = getDisplay(ccm.getDependsOn(), s);
if (display != null)
td.tx(" (" + display + ")");
}
}
}
first = false;
if (hasRelationships) {
if (!ccm.hasEquivalence())
tr.td();
else {
String code = ccm.getEquivalenceElement().toString();
tr.td().ah(eqpath + "#" + code).tx(presentEquivalenceCode(code));
}
}
td = tr.td().style("border-right-width: 0px");
if (targets.get("code").size() == 1)
td.addText(ccm.getCode());
else
td.addText(grp.getTarget() + " / " + ccm.getCode());
display = ccm.hasDisplay() ? ccm.getDisplay() : getDisplayForConcept(systemFromCanonical(grp.getTarget()), versionFromCanonical(grp.getTarget()), ccm.getCode());
tr.td().style("border-left-width: 0px").tx(display == null ? "" : display);
for (String s : targets.keySet()) {
if (!s.equals("code")) {
td = tr.td();
td.addText(getValue(ccm.getProduct(), s, targets.get(s).size() != 1));
display = getDisplay(ccm.getProduct(), s);
if (display != null)
td.tx(" (" + display + ")");
}
}
if (comment)
tr.td().addText(ccm.getComment());
}
}
addUnmapped(tbl, grp);
}
}
}
return true;
}
Aggregations