Skip to content

Commit be673b1

Browse files
committed
Parse domain specific types, add conversion config to archie-utils
1 parent efa90f9 commit be673b1

17 files changed

Lines changed: 277 additions & 140 deletions

File tree

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,8 @@ The following features are experimental. This means its working or API will like
453453
Starting from version 0.7, Archie can import ADL 1.4 files, and convert them to ADL 2. To do so, do the following:
454454

455455
```java
456-
ADL14ConversionConfiguration conversionConfiguration = new ADL14ConversionConfiguration();
456+
//this is the default configuration. You can implement your own if you want to
457+
ADL14ConversionConfiguration conversionConfiguration = OpenEHRADL14ConversionConfiguration.getConfig();
457458
ADL14Converter converter = new ADL14Converter(BuiltinReferenceModels.getMetaModels(), conversionConfiguration);
458459

459460
List<Archetype> archetypes = new ArrayList<>();
@@ -498,7 +499,7 @@ The conversion log can be serialized to a file for storage using Jackson, so it
498499

499500
### Conversion Configuration
500501

501-
You may have noticed an instance of `ADL14ConversionConfiguration` in the previous example. In this configuration the mapping from term codes as used in ADL 1.4 to term URIs as used in ADL 2 can be specified. See the `ConversionConfigForTest.java` file for an example on how this works, and how this can be serialized to a file, and the file `/tools/src/test/java/com/nedap/archie/adl14/configuration.json` for an example of a simple serialized configuration that contains sane defaults for snomed, loinc and openehr URIs.
502+
You may have noticed an instance of `ADL14ConversionConfiguration` in the previous example. In this configuration the mapping from term codes as used in ADL 1.4 to term URIs as used in ADL 2 can be specified. The archie-utils package provides a default configuration in the class `OpenEHRADL14ConversionConfiguration`. It is possible to supply your own, see the default implementation on how this works, and how this can be serialized to a file, and the file `/archie-utils/src/main/resources/adl14conversionconfiguration.json` for an example of a simple serialized configuration that contains sane defaults for snomed, loinc and openehr URIs.
502503

503504
If you leave the configuration empty, the converter will fall back to a default URI conversion.
504505

aom/src/main/java/com/nedap/archie/adl14/treewalkers/Adl14CComplexObjectParser.java

Lines changed: 137 additions & 113 deletions
Large diffs are not rendered by default.

archie-utils/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
description = "Utils for the Archie OpenEHR library"
1+
description = "OpenEHR-RM specific utils for the Archie OpenEHR library"
22

33
dependencies {
44
compile project(':base')

tools/src/test/java/com/nedap/archie/adl14/ConversionConfigForTest.java renamed to archie-utils/src/main/java/com/nedap/archie/adl14/OpenEHRADL14ConversionConfiguration.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
package com.nedap.archie.adl14;
22

3+
34
import com.nedap.archie.json.JacksonUtil;
45

56
import java.io.IOException;
67
import java.io.InputStream;
78

8-
public class ConversionConfigForTest {
9-
9+
public class OpenEHRADL14ConversionConfiguration {
1010

1111
public static ADL14ConversionConfiguration getConfig() throws IOException {
12-
13-
try(InputStream stream = ConversionConfigForTest.class.getResourceAsStream("configuration.json")) {
12+
try(InputStream stream = OpenEHRADL14ConversionConfiguration.class.getResourceAsStream("/adl14conversionconfiguration.json")) {
1413
return JacksonUtil.getObjectMapper().readValue(stream, ADL14ConversionConfiguration.class);
1514
}
16-
1715
}
16+
1817
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"terminology_conversion_templates": [
3+
{
4+
"terminology_id": "snomedct",
5+
"template": "http://snomed.info/id/$code_string"
6+
},
7+
{
8+
"terminology_id": "snomed-ct",
9+
"template": "http://snomed.info/id/$code_string"
10+
},
11+
{
12+
"terminology_id": "snomed",
13+
"template": "http://snomed.info/id/$code_string"
14+
},
15+
{
16+
"terminology_id": "openehr",
17+
"template": "http://openehr.org/id/$code_string"
18+
},
19+
{
20+
"terminology_id": "loinc",
21+
"template": "http://loinc.org/id/$code_string"
22+
}
23+
24+
]
25+
}

opt14/src/main/java/com/nedap/archie/opt14/IntervalConverter.java renamed to opt14/src/main/java/com/nedap/archie/opt14/BaseTypesConverter.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
import com.nedap.archie.base.Cardinality;
44
import com.nedap.archie.base.Interval;
55
import com.nedap.archie.base.MultiplicityInterval;
6+
import com.nedap.archie.base.terminology.TerminologyCode;
67

7-
public class IntervalConverter {
8+
public class BaseTypesConverter {
89

910
public static Cardinality convertCardinality(CARDINALITY cardinality14) {
1011
if(cardinality14 == null) {
@@ -52,4 +53,11 @@ public static com.nedap.archie.base.Interval<Double> convertInterval(IntervalOfR
5253
range.isUpperIncluded() == null ? true : range.isUpperIncluded());
5354
}
5455

56+
public static TerminologyCode convert(CODEPHRASE definingCode) {
57+
if(definingCode == null) {
58+
return null;
59+
}
60+
return TerminologyCode.createFromString(definingCode.getTerminologyId().getValue(), null, definingCode.getCodeString());
61+
}
62+
5563
}

opt14/src/main/java/com/nedap/archie/opt14/DefinitionConverter.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
import com.nedap.archie.aom.Template;
1010
import com.nedap.archie.aom.TemplateOverlay;
1111

12-
import static com.nedap.archie.opt14.IntervalConverter.convertCardinality;
13-
import static com.nedap.archie.opt14.IntervalConverter.convertMultiplicity;
12+
import static com.nedap.archie.opt14.BaseTypesConverter.convertCardinality;
13+
import static com.nedap.archie.opt14.BaseTypesConverter.convertMultiplicity;
1414
import static com.nedap.archie.opt14.PrimitiveConverter.convertPrimitive;
1515

1616
public class DefinitionConverter {
@@ -30,7 +30,7 @@ private CComplexObject convert(CCOMPLEXOBJECT cComplexObject14) {
3030
CComplexObject cComplexObject = new CComplexObject();
3131
cComplexObject.setNodeId(cComplexObject14.getNodeId());
3232
cComplexObject.setRmTypeName(cComplexObject14.getRmTypeName());
33-
cComplexObject.setOccurrences(IntervalConverter.convertMultiplicity(cComplexObject14.getOccurrences()));
33+
cComplexObject.setOccurrences(BaseTypesConverter.convertMultiplicity(cComplexObject14.getOccurrences()));
3434

3535
for (CATTRIBUTE attribute14 : cComplexObject14.getAttributes()) {
3636
cComplexObject.addAttribute(convert(attribute14));
@@ -81,7 +81,7 @@ private CObject convertSlot(ARCHETYPESLOT cobject14) {
8181
archetypeSlot.setNodeId(cobject14.getNodeId());
8282
archetypeSlot.setRmTypeName(cobject14.getRmTypeName());
8383

84-
archetypeSlot.setOccurrences(IntervalConverter.convertMultiplicity(cobject14.getOccurrences()));
84+
archetypeSlot.setOccurrences(BaseTypesConverter.convertMultiplicity(cobject14.getOccurrences()));
8585
//TODO: assertions for include/exclude, should be straightforward
8686
return archetypeSlot;
8787
}
@@ -99,7 +99,7 @@ private CObject convertRoot(CARCHETYPEROOT cRoot14) {
9999
CArchetypeRoot root = new CArchetypeRoot();
100100
root.setArchetypeRef(overlay.getArchetypeId().getFullId());
101101
root.setNodeId(cRoot14.getNodeId());
102-
root.setOccurrences(IntervalConverter.convertMultiplicity(cRoot14.getOccurrences()));
102+
root.setOccurrences(BaseTypesConverter.convertMultiplicity(cRoot14.getOccurrences()));
103103
root.setRmTypeName(cRoot14.getRmTypeName());
104104
return root;
105105
}

opt14/src/main/java/com/nedap/archie/opt14/DescriptionConverter.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@ public static void convert(Template template, OPERATIONALTEMPLATE opt14) {
1919
author.put(item.getId(), item.getValue());
2020
}
2121
}
22+
if(description14.getOtherDetails() != null) {
23+
for(StringDictionaryItem item:description14.getOtherDetails()) {
24+
description.getOtherDetails().put(item.getId(), item.getValue());
25+
}
26+
}
27+
28+
description.setOtherContributors(description14.getOtherContributors());
29+
2230
description.setOriginalAuthor(author);
2331
template.setDescription(description);
2432

25-
template.setOriginalLanguage(
26-
TerminologyCode.createFromString(
27-
opt14.getLanguage().getTerminologyId().getValue(),
28-
null,
29-
opt14.getLanguage().getCodeString()));
33+
template.setOriginalLanguage(BaseTypesConverter.convert(opt14.getLanguage()));
3034
//TODO: implement me further
3135
}
3236
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,82 @@
11
package com.nedap.archie.opt14;
22

3+
import com.nedap.archie.adl14.aom14.CDVOrdinal;
4+
import com.nedap.archie.adl14.aom14.CDVOrdinalItem;
5+
import com.nedap.archie.adl14.aom14.CDVQuantity;
6+
7+
import com.nedap.archie.adl14.aom14.CDVQuantityAssumedValue;
8+
import com.nedap.archie.adl14.aom14.CDVQuantityItem;
9+
import com.nedap.archie.adl14.treewalkers.Adl14CComplexObjectParser;
310
import com.nedap.archie.aom.CObject;
11+
import com.nedap.archie.base.terminology.TerminologyCode;
12+
13+
import java.util.LinkedHashMap;
14+
import java.util.Map;
15+
16+
import static com.nedap.archie.opt14.BaseTypesConverter.convert;
417

518
public class DomainTypeConverter {
619
public static CObject convertDomainType(CDOMAINTYPE cobject14) {
20+
if(cobject14 instanceof CDVORDINAL) {
21+
return convertCDVOrdinal((CDVORDINAL) cobject14);
22+
} else if (cobject14 instanceof CDVQUANTITY) {
23+
return convertCDVQuantity((CDVQUANTITY) cobject14);
24+
} else if (cobject14 instanceof CDVSTATE) {
25+
26+
} else if (cobject14 instanceof CCODEPHRASE) {
27+
28+
}
729
return null;
830
}
31+
32+
private static CObject convertCDVOrdinal(CDVORDINAL ordinal14) {
33+
CDVOrdinal ordinal = new CDVOrdinal();
34+
Map<String, CDVOrdinalItem> items = new LinkedHashMap<>();
35+
if(ordinal14.getList() != null) {
36+
Integer i = 0;
37+
for(DVORDINAL dvordinal14:ordinal14.getList()) {
38+
CDVOrdinalItem item = new CDVOrdinalItem();
39+
item.setValue(dvordinal14.getValue());
40+
if(dvordinal14.getSymbol() != null) {
41+
item.setSymbol(convert(dvordinal14.getSymbol().getDefiningCode()));
42+
}
43+
items.put(i.toString(), item);
44+
i++;
45+
}
46+
}
47+
//TODO: no assumed value in our own model, but there is in the OPT form.
48+
49+
return Adl14CComplexObjectParser.convertCDVOrdinal(ordinal);
50+
}
51+
52+
private static CObject convertCDVQuantity(CDVQUANTITY cobject14) {
53+
CDVQUANTITY quantity14 = cobject14;
54+
CDVQuantity quantity = new CDVQuantity();
55+
Map<String, CDVQuantityItem> items = new LinkedHashMap<>();
56+
57+
if(quantity14.getList() != null) {
58+
Integer i = 0;
59+
for(CQUANTITYITEM item14:quantity14.getList()) {
60+
CDVQuantityItem item = new CDVQuantityItem();
61+
item.setMagnitude(BaseTypesConverter.convertInterval(item14.getMagnitude()));
62+
item.setPrecision(BaseTypesConverter.convertInterval(item14.getPrecision()));
63+
item.setUnits(item14.getUnits());
64+
items.put(i.toString(), item);
65+
i++;
66+
}
67+
}
68+
quantity.setList(items);
69+
70+
quantity.setProperty(convert(quantity14.getProperty()));
71+
72+
DVQUANTITY assumedValue14 = quantity14.getAssumedValue();
73+
if(assumedValue14 != null) {
74+
CDVQuantityAssumedValue assumedValue = new CDVQuantityAssumedValue();
75+
assumedValue.setMagnitude(assumedValue14.getMagnitude());
76+
assumedValue.setPrecision(assumedValue14.getPrecision() == null ? null : assumedValue14.getPrecision().longValue());
77+
assumedValue.setUnits(assumedValue14.getUnits());
78+
quantity.setAssumedValue(assumedValue);
79+
}
80+
return Adl14CComplexObjectParser.convertCDvQuantity(quantity);
81+
}
982
}

opt14/src/main/java/com/nedap/archie/opt14/Opt14Converter.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ public Template convert(OPERATIONALTEMPLATE opt14) {
99
Template template = new Template();
1010
template.setArchetypeId(new ArchetypeHRID("openEHR-EHR-" + opt14.getDefinition().getRmTypeName() + "." + opt14.getTemplateId().getValue() + "v1.0.0"));
1111
template.setParentArchetypeId(opt14.getDefinition().getArchetypeId().getValue());
12+
if(opt14.getUid() != null) {
13+
template.setUid(opt14.getUid().getValue());
14+
}
1215
DescriptionConverter.convert(template, opt14);
1316

1417
new DefinitionConverter().convert(template, opt14);

0 commit comments

Comments
 (0)