Skip to content

Commit

Permalink
implement default values and multiple values
Browse files Browse the repository at this point in the history
  • Loading branch information
nr23730 committed Feb 26, 2024
1 parent 571c4a1 commit 1b94a10
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 40 deletions.
51 changes: 35 additions & 16 deletions src/main/java/de/uksh/medic/etl/OpenEhrObds.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public static void main(String[] args) throws IOException {

// ToDo: Replace with Kafka consumer

File f = new File("tod.xml");
File f = new File("tuko.xml");

Map<String, Object> m = new LinkedHashMap<>();
walkXmlTree(xmlMapper.readValue(f, new TypeReference<LinkedHashMap<String, Object>>() {
Expand All @@ -97,6 +97,7 @@ public static void walkXmlTree(Set<Map.Entry<String, Object>> xmlSet, int depth,
Mapping m = Settings.getMapping().get(path);

Map<String, Object> mapped = convertMdr(xmlSet, m);
listConv(mapped);
mapped.entrySet().forEach(e -> queryFhirTs(m, e));
Map<String, Object> result = formatMap((Map<String, Object>) mapped);

Expand Down Expand Up @@ -149,27 +150,45 @@ public static void walkXmlTree(Set<Map.Entry<String, Object>> xmlSet, int depth,

}

@SuppressWarnings("unchecked")
private static void listConv(Map<String, Object> input) {
input.entrySet().forEach(e -> {
switch (e.getValue()) {
case List l -> {
}
default -> {
e.setValue(List.of(e.getValue()));
}
}
});
}

@SuppressWarnings({ "unchecked", "rawtypes" })
private static void queryFhirTs(Mapping m, Map.Entry<String, Object> e) {
MappingAttributes fa = FHIR_ATTRIBUTES.get(m.getTarget()).get(e.getKey());
if (fa != null && fa.getSystem() != null) {
String code = switch (e.getValue()) {
case String c -> c;
case Map map -> ((Map<String, String>) map).get("code");
default -> null;
};
if (fa.getConceptMap() == null) {
String version = switch (e.getValue()) {
case String c -> fa.getVersion();
case Map map -> ((Map<String, String>) map).get("version");
List<Object> listed = new ArrayList<>();
for (Object o : (List) e.getValue()) {
if (fa != null && fa.getSystem() != null) {
String code = switch (o) {
case String c -> c;
case Map map -> ((Map<String, String>) map).get("code");
default -> null;
};
e.setValue(FhirResolver.lookUp(fa.getSystem(), version, code));
} else if (fa.getConceptMap() != null) {
e.setValue(FhirResolver.conceptMap(fa.getConceptMap(), fa.getId(), fa.getSource(),
fa.getTarget(), code));
if (fa.getConceptMap() == null) {
String version = switch (o) {
case String c -> fa.getVersion();
case Map map -> ((Map<String, String>) map).get("version");
default -> null;
};
listed.add(FhirResolver.lookUp(fa.getSystem(), version, code));
} else if (fa.getConceptMap() != null) {
listed.add(FhirResolver.conceptMap(fa.getConceptMap(), fa.getId(), fa.getSource(),
fa.getTarget(), code));
}
} else {
listed.add(o);
}
}
e.setValue(listed);
}

private static Map<String, Object> formatMap(Map<String, Object> input) {
Expand Down
15 changes: 10 additions & 5 deletions src/main/java/de/uksh/medic/etl/openehrmapper/EHRParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
public class EHRParser {
public String build(Map<String, Object> map)
throws ParserConfigurationException, SAXException, XPathExpressionException, IOException {
String file = "oBDS_Tod.opt";
String file = "oBDS_Tumorkonferenz.opt";
String path = "/template/definition[rm_type_name = \"COMPOSITION\"]/attributes[rm_attribute_name=\"content\"]";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

Expand All @@ -43,14 +43,17 @@ public String build(Map<String, Object> map)
Document doc = builder.parse(new File(file));

composition.setArchetypeNodeId(
((String) xp.evaluate("/template/definition/archetype_id", doc, XPathConstants.STRING)).trim());
((String) xp.evaluate("/template/definition/archetype_id", doc, XPathConstants.STRING))
.trim());

composition.setNameAsString(
((String) xp.evaluate("/template/definition/template_id", doc, XPathConstants.STRING)).trim());
((String) xp.evaluate("/template/definition/template_id", doc, XPathConstants.STRING))
.trim());

Archetyped archetypeDetails = new Archetyped();
archetypeDetails.setArchetypeId(new ArchetypeID(
((String) xp.evaluate("/template/definition/archetype_id", doc, XPathConstants.STRING)).trim()));
((String) xp.evaluate("/template/definition/archetype_id", doc, XPathConstants.STRING))
.trim()));

TemplateId templateId = new TemplateId();
templateId.setValue(((String) xp.evaluate("/template/template_id", doc, XPathConstants.STRING)).trim());
Expand All @@ -72,14 +75,16 @@ public String build(Map<String, Object> map)

Generator g = new Generator(doc);
ArrayList<ContentItem> content = new ArrayList<ContentItem>();
Map<String, Object> applyMap = Generator.applyDefaults(map);
composition.setContent(content);

Generator.processAttributeChildren(path, "", content, map);
Generator.processAttributeChildren(path, "", content, applyMap);

System.out.println("Finished JSON-Generation. Generating String.");

String ehr = JacksonUtil.getObjectMapper().writeValueAsString(composition);
return ehr;

}

}
130 changes: 111 additions & 19 deletions src/main/java/de/uksh/medic/etl/openehrmapper/Generator.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import com.nedap.archie.rm.datastructures.ItemTree;
import com.nedap.archie.rm.datastructures.PointEvent;
import com.nedap.archie.rm.datatypes.CodePhrase;
import com.nedap.archie.rm.datavalues.DataValue;
import com.nedap.archie.rm.datavalues.DvBoolean;
import com.nedap.archie.rm.datavalues.DvCodedText;
import com.nedap.archie.rm.datavalues.DvIdentifier;
Expand Down Expand Up @@ -203,6 +202,7 @@ public static void gen_INSTRUCTION(String path, String name, Object jsonmap, Map
instruction.setLanguage(new CodePhrase(new TerminologyId("ISO_639-1"), "de"));
instruction.setEncoding(new CodePhrase(new TerminologyId("IANA_character-sets"), "UTF-8"));
instruction.setSubject(new PartySelf());
instruction.setNarrative(new DvText("asdf"));

if (map.containsKey(paramName)) {
List<Activity> activities = new ArrayList<>();
Expand All @@ -222,7 +222,7 @@ public static void gen_ACTIVITY(String path, String name, Object jsonmap, Map<St
Boolean oa = (Boolean) XP.evaluate(oap, opt, XPathConstants.BOOLEAN);

Activity activity = new Activity();
// activity.setArchetypeDetails(new Archetyped(new ArchetypeID(nodeId), "1.1.0"));
activity.setActionArchetypeId("openEHR-EHR-INSTRUCTION.service_request.v1");
activity.setArchetypeNodeId(nodeId);
activity.setNameAsString(getLabel(getNodeId(path), nodeId));

Expand Down Expand Up @@ -329,15 +329,18 @@ public static void gen_ELEMENT(String path, String name, Object jsonmap, Map<Str
if (!map.containsKey(nodeId)) {
return;
}

Element el = new Element();
el.setArchetypeNodeId(nodeId);
el.setNameAsString(getLabel(nodeId, name));
switch (map.get(nodeId)) {
case DataValue d -> el.setValue(d);
default -> processAttributeChildren(newPath, nodeId, el, map);
}
((ArrayList<Element>) jsonmap).add(el);
String label = getLabel(nodeId, name);

((List) map.get(nodeId)).forEach(e -> {
Element el = new Element();
el.setArchetypeNodeId(nodeId);
el.setNameAsString(label);
Map<String, Object> mo = new HashMap<>();
mo.put(nodeId, e);
processAttributeChildren(newPath, nodeId, el, mo);
((ArrayList<Element>) jsonmap).add(el);

});
}

// HISTORY Class descriptions
Expand Down Expand Up @@ -412,15 +415,29 @@ public static void gen_DV_TEXT(String path, String name, Object jsonmap,
// CODE_PHRASE

public static void gen_DV_CODED_TEXT(String path, String name, Object jsonmap,
Map<String, Coding> map) throws Exception {
Coding coding = map.get(name);
Map<String, Object> map) throws Exception {

DvCodedText ct = new DvCodedText();
ct.setDefiningCode(new CodePhrase(
new TerminologyId("terminology://fhir.hl7.org//ValueSet/$expand?url=" + coding.getSystem(),
coding.getVersion()),
coding.getCode()));
ct.setValue(coding.getCode());
((Element) jsonmap).setValue(ct);
switch (map.get(name)) {
case Coding coding -> {
ct.setDefiningCode(new CodePhrase(
new TerminologyId("terminology://fhir.hl7.org//ValueSet/$expand?url=" + coding.getSystem(),
coding.getVersion()),
coding.getCode(), coding.getDisplay()));
ct.setValue(coding.getDisplay());
((Element) jsonmap).setValue(ct);
}
case String s -> {
String display = getLocalTerminologyTerm(path, s);
ct.setDefiningCode(new CodePhrase(
new TerminologyId("local_terms"),
s, display));
ct.setValue(display);
((Element) jsonmap).setValue(ct);
}
default -> {
}
}

}

Expand Down Expand Up @@ -514,6 +531,16 @@ private static String getTypeLabel(String path, String code) throws Exception {
return CACHE.get(newPath);
}

private static String getLocalTerminologyTerm(String path, String code) throws Exception {
String newPath = "//term_definitions[@code=\"local_terms::" + code + "\"]/items/text()";
if (!CACHE.containsKey(newPath)) {
XPathExpression expr = XP.compile(newPath);
CACHE.put(newPath, ((String) expr.evaluate(opt, XPathConstants.STRING)).replaceAll("^* (?m) ", "")
.replaceAll("\\n", " "));
}
return CACHE.get(newPath);
}

private static String getNodeId(String path) throws Exception {
String newPath = path + "/node_id";
if (!CACHE.containsKey(newPath)) {
Expand All @@ -532,4 +559,69 @@ private static String getArcheTypeId(String path) throws Exception {
return CACHE.get(newPath);
}

public static Map<String, Object> getDefaultValues() {
Map<String, Object> defaults = new HashMap<>();
Map<String, Object> current = defaults;
String path = "//constraints/attributes[children/default_value]";
try {
XPathExpression expr = XP.compile(path);
NodeList nl = (NodeList) expr.evaluate(opt, XPathConstants.NODESET);
for (int i = 1; i <= nl.getLength(); i++) {
XPathExpression exprC = XP.compile(path + "[" + i + "]/children/default_value/value/text()");
XPathExpression exprP = XP.compile(path + "[" + i + "]/differential_path/text()");
String value = (String) exprC.evaluate(opt, XPathConstants.STRING);
String differentialPath = ((String) exprP.evaluate(opt, XPathConstants.STRING)).trim();
List<String> l = List.of(differentialPath.split("/"));
String last = l.getLast().split("(\\[|\\])")[1];
for (int j = 1; j < l.size() - 1; j++) {
String s = l.get(j);
if (s.contains("description")) {
continue;
}
Map<String, Object> n = new HashMap<>();
String s2 = s.split("(\\[|\\])")[1];
current.put(s2, n);
current = n;
}
current.put(last, List.of(value));
}
} catch (XPathExpressionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return defaults;
}

public static Map<String, Object> applyDefaults(Map<String, Object> map) {
Map<String, Object> defaults = getDefaultValues();
deepMerge(defaults, map);
return defaults;
}

@SuppressWarnings({ "rawtypes", "unchecked" })
private static void deepMerge(Map<String, Object> map1, Map<String, Object> map2) {
for (String key : map2.keySet()) {
Object value2 = map2.get(key);
if (map1.containsKey(key)) {
Object value1 = map1.get(key);
if (value1 instanceof Map && value2 instanceof Map) {
deepMerge((Map<String, Object>) value1, (Map<String, Object>) value2);
} else if (value1 instanceof List && value2 instanceof List) {
map1.put(key, merge((List) value1, (List) value2));
} else {
map1.put(key, value2);
}
} else {
map1.put(key, value2);
}
}
}

@SuppressWarnings("rawtypes")
private static List merge(List list1, List list2) {
list2.removeAll(list1);
list1.addAll(list2);
return list1;
}

}

0 comments on commit 1b94a10

Please sign in to comment.