Skip to content

Commit

Permalink
First parts of an OPT14 parser
Browse files Browse the repository at this point in the history
  • Loading branch information
pieterbos committed Jan 3, 2021
1 parent 3315af2 commit efa90f9
Show file tree
Hide file tree
Showing 27 changed files with 7,683 additions and 0 deletions.
43 changes: 43 additions & 0 deletions opt14/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
plugins {
id 'com.github.edeandrea.xjc-generation' version '1.5'
}

description = "OPT 1.4 parser and converter to ADL 2"

ext {
jaxbVersion = '2.3.1'
}

dependencies {
compile project(':grammars')
compile project(':base')
compile project(':aom')
compile project(':bmm')
compile project(':path-queries')
compile project(':utils')
compile project(':tools')
testCompile project(':openehr-rm')
testCompile project(':archie-utils')
testCompile project(':i18n')
testCompile project(':test-rm')
testCompile project(':referencemodels')


xjc "javax.xml.bind:jaxb-api:$jaxbVersion"
xjc "org.glassfish.jaxb:jaxb-runtime:$jaxbVersion"
xjc "org.glassfish.jaxb:jaxb-xjc:$jaxbVersion"
}

xjcGeneration {
defaultAdditionalXjcOptions = ['encoding': 'UTF-8']
defaultBindingFile = null //file 'src/main/resources//xjc/xjc.xjb.xml'

schemas {
opt14 {
schemaFile = 'Template.xsd'
javaPackageName = 'com.nedap.archie.opt14'
}

}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.nedap.archie.opt14;

public class DefaultValueConverter {
//TODO: default values
}
108 changes: 108 additions & 0 deletions opt14/src/main/java/com/nedap/archie/opt14/DefinitionConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package com.nedap.archie.opt14;

import com.nedap.archie.aom.ArchetypeHRID;
import com.nedap.archie.aom.ArchetypeSlot;
import com.nedap.archie.aom.CArchetypeRoot;
import com.nedap.archie.aom.CAttribute;
import com.nedap.archie.aom.CComplexObject;
import com.nedap.archie.aom.CObject;
import com.nedap.archie.aom.Template;
import com.nedap.archie.aom.TemplateOverlay;

import static com.nedap.archie.opt14.IntervalConverter.convertCardinality;
import static com.nedap.archie.opt14.IntervalConverter.convertMultiplicity;
import static com.nedap.archie.opt14.PrimitiveConverter.convertPrimitive;

public class DefinitionConverter {

private OPERATIONALTEMPLATE opt14;
private Template template;

public void convert(Template template, OPERATIONALTEMPLATE opt14) {
this.opt14 = opt14;
this.template = template;
CARCHETYPEROOT definition = opt14.getDefinition();
template.setTerminology(TerminologyConverter.createTerminology(opt14, definition));
template.setDefinition(convert(definition));
}

private CComplexObject convert(CCOMPLEXOBJECT cComplexObject14) {
CComplexObject cComplexObject = new CComplexObject();
cComplexObject.setNodeId(cComplexObject14.getNodeId());
cComplexObject.setRmTypeName(cComplexObject14.getRmTypeName());
cComplexObject.setOccurrences(IntervalConverter.convertMultiplicity(cComplexObject14.getOccurrences()));

for (CATTRIBUTE attribute14 : cComplexObject14.getAttributes()) {
cComplexObject.addAttribute(convert(attribute14));
}
return cComplexObject;
}

private CAttribute convert(CATTRIBUTE attribute14) {
CAttribute attribute = new CAttribute();
attribute.setRmAttributeName(attribute14.getRmAttributeName());
attribute.setExistence(convertMultiplicity(attribute14.getExistence()));
if(attribute14 instanceof CMULTIPLEATTRIBUTE) {
CMULTIPLEATTRIBUTE attr14Multiple = (CMULTIPLEATTRIBUTE) attribute14;
attribute.setCardinality(convertCardinality(attr14Multiple.getCardinality()));
attribute.setMultiple(true);
} else if (attribute14 instanceof CSINGLEATTRIBUTE) {
//ok no one cares about this class
attribute.setMultiple(false);
}
for(COBJECT cobject14:attribute14.getChildren()) {
CObject cObject = convert(cobject14);
if(cObject != null) {
attribute.addChild(cObject);
}
}
return attribute;
}

private CObject convert(COBJECT cobject14) {
if(cobject14 instanceof CARCHETYPEROOT) {
return convertRoot((CARCHETYPEROOT) cobject14);
} else if (cobject14 instanceof CCOMPLEXOBJECT) {
return convert((CCOMPLEXOBJECT) cobject14);
} else if (cobject14 instanceof ARCHETYPESLOT) {
return convertSlot((ARCHETYPESLOT) cobject14);
} else if (cobject14 instanceof CPRIMITIVEOBJECT) {
return convertPrimitive((CPRIMITIVEOBJECT) cobject14);
} else if (cobject14 instanceof CDOMAINTYPE) {
return DomainTypeConverter.convertDomainType((CDOMAINTYPE) cobject14);
}
throw new IllegalArgumentException("unknown COBJECT subtype: " + cobject14.getClass());
}



private CObject convertSlot(ARCHETYPESLOT cobject14) {
ArchetypeSlot archetypeSlot = new ArchetypeSlot();
archetypeSlot.setNodeId(cobject14.getNodeId());
archetypeSlot.setRmTypeName(cobject14.getRmTypeName());

archetypeSlot.setOccurrences(IntervalConverter.convertMultiplicity(cobject14.getOccurrences()));
//TODO: assertions for include/exclude, should be straightforward
return archetypeSlot;
}

private CObject convertRoot(CARCHETYPEROOT cRoot14) {

TemplateOverlay overlay = new TemplateOverlay();
overlay.setArchetypeId(new ArchetypeHRID(cRoot14.getArchetypeId().getValue()));
overlay.getArchetypeId().setConceptId(overlay.getArchetypeId().getConceptId() + "ovl-1");
overlay.setParentArchetypeId(cRoot14.getArchetypeId().getValue());
overlay.setDefinition(convert(cRoot14));
overlay.setTerminology(TerminologyConverter.createTerminology(opt14, cRoot14));
template.addTemplateOverlay(overlay);

CArchetypeRoot root = new CArchetypeRoot();
root.setArchetypeRef(overlay.getArchetypeId().getFullId());
root.setNodeId(cRoot14.getNodeId());
root.setOccurrences(IntervalConverter.convertMultiplicity(cRoot14.getOccurrences()));
root.setRmTypeName(cRoot14.getRmTypeName());
return root;
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.nedap.archie.opt14;

import com.nedap.archie.aom.ResourceDescription;
import com.nedap.archie.aom.Template;
import com.nedap.archie.base.terminology.TerminologyCode;

import java.util.LinkedHashMap;
import java.util.Map;

public class DescriptionConverter {

public static void convert(Template template, OPERATIONALTEMPLATE opt14) {
RESOURCEDESCRIPTION description14 = opt14.getDescription();
ResourceDescription description = new ResourceDescription();
description.setLifecycleState(TerminologyCode.createFromString("openehr", null, description14.lifecycleState));
Map<String, String> author = new LinkedHashMap<>();
if(description14.getOriginalAuthor() != null) {
for(StringDictionaryItem item:description14.getOriginalAuthor()) {
author.put(item.getId(), item.getValue());
}
}
description.setOriginalAuthor(author);
template.setDescription(description);

template.setOriginalLanguage(
TerminologyCode.createFromString(
opt14.getLanguage().getTerminologyId().getValue(),
null,
opt14.getLanguage().getCodeString()));
//TODO: implement me further
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.nedap.archie.opt14;

import com.nedap.archie.aom.CObject;

public class DomainTypeConverter {
public static CObject convertDomainType(CDOMAINTYPE cobject14) {
return null;
}
}
55 changes: 55 additions & 0 deletions opt14/src/main/java/com/nedap/archie/opt14/IntervalConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.nedap.archie.opt14;

import com.nedap.archie.base.Cardinality;
import com.nedap.archie.base.Interval;
import com.nedap.archie.base.MultiplicityInterval;

public class IntervalConverter {

public static Cardinality convertCardinality(CARDINALITY cardinality14) {
if(cardinality14 == null) {
return null;
}
Cardinality result = new Cardinality();
result.setInterval(convertMultiplicity(cardinality14.getInterval()));
result.setOrdered(cardinality14.isIsOrdered());
result.setUnique(cardinality14.isIsUnique());
return result;
}

public static MultiplicityInterval convertMultiplicity(IntervalOfInteger existence) {
if(existence == null) {
return null;
}
return new MultiplicityInterval(
existence.getLower(),
existence.isLowerIncluded() == null ? true : existence.isLowerIncluded(),
existence.isLowerUnbounded(),
existence.getUpper(),
existence.isUpperIncluded() == null ? true : existence.isUpperIncluded(),
existence.isUpperUnbounded());
}

public static com.nedap.archie.base.Interval<Long> convertInterval(IntervalOfInteger range) {
if(range == null) {
return null;
}
return new com.nedap.archie.base.Interval<Long>(
range.getLower() == null ? null : range.getLower().longValue() ,
range.getUpper() == null ? null : range.getUpper().longValue() ,
range.isLowerIncluded() == null ? true : range.isLowerIncluded(),
range.isUpperIncluded() == null ? true : range.isUpperIncluded());
}

public static com.nedap.archie.base.Interval<Double> convertInterval(IntervalOfReal range) {
if(range == null) {
return null;
}
return new com.nedap.archie.base.Interval<Double>(
range.getLower() == null ? null : range.getLower().doubleValue() ,
range.getUpper() == null ? null : range.getUpper().doubleValue() ,
range.isLowerIncluded() == null ? true : range.isLowerIncluded(),
range.isUpperIncluded() == null ? true : range.isUpperIncluded());
}

}
17 changes: 17 additions & 0 deletions opt14/src/main/java/com/nedap/archie/opt14/Opt14Converter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.nedap.archie.opt14;

import com.nedap.archie.aom.ArchetypeHRID;
import com.nedap.archie.aom.Template;

public class Opt14Converter {

public Template convert(OPERATIONALTEMPLATE opt14) {
Template template = new Template();
template.setArchetypeId(new ArchetypeHRID("openEHR-EHR-" + opt14.getDefinition().getRmTypeName() + "." + opt14.getTemplateId().getValue() + "v1.0.0"));
template.setParentArchetypeId(opt14.getDefinition().getArchetypeId().getValue());
DescriptionConverter.convert(template, opt14);

new DefinitionConverter().convert(template, opt14);
return template;
}
}
87 changes: 87 additions & 0 deletions opt14/src/main/java/com/nedap/archie/opt14/PrimitiveConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.nedap.archie.opt14;

import com.nedap.archie.aom.CObject;
import com.nedap.archie.aom.primitives.CBoolean;
import com.nedap.archie.aom.primitives.CInteger;
import com.nedap.archie.aom.primitives.CReal;
import com.nedap.archie.aom.primitives.CString;

import static com.nedap.archie.opt14.IntervalConverter.convertInterval;

public class PrimitiveConverter {

public static CObject convertPrimitive(CPRIMITIVEOBJECT cobject14) {
CPRIMITIVE primitive14 = cobject14.getItem();
if(primitive14 instanceof CINTEGER) {
CINTEGER cinteger14 = (CINTEGER) primitive14;
CInteger cInteger = new CInteger();
if(cinteger14.getList() != null) {
for(Integer integer:cinteger14.getList()) {
cInteger.addConstraint(new com.nedap.archie.base.Interval<Long>(integer.longValue(), integer.longValue()));
}
}
if(cinteger14.getRange() != null) {
cInteger.addConstraint(convertInterval(cinteger14.getRange()));
}
if(cinteger14.getAssumedValue() != null) {
cInteger.setAssumedValue(cinteger14.getAssumedValue().longValue());
}
return cInteger;
} else if (primitive14 instanceof CREAL) {
CREAL cinteger14 = (CREAL) primitive14;
CReal cInteger = new CReal();
if(cinteger14.getList() != null) {
for(Float integer:cinteger14.getList()) {
cInteger.addConstraint(new com.nedap.archie.base.Interval<Double>(integer.doubleValue(), integer.doubleValue()));
}
}
if(cinteger14.getRange() != null) {
cInteger.addConstraint(convertInterval(cinteger14.getRange()));
}
if(cinteger14.getAssumedValue() != null) {
cInteger.setAssumedValue(cinteger14.getAssumedValue().doubleValue());
}
return cInteger;
} else if (primitive14 instanceof CBOOLEAN) {
CBOOLEAN cboolean14 = (CBOOLEAN) primitive14;
CBoolean cBoolean = new CBoolean();
if(cboolean14.isFalseValid()) {
cBoolean.addConstraint(false);
}
if(cboolean14.isTrueValid()) {
cBoolean.addConstraint(true);
}
if(cboolean14.isAssumedValue() != null) {
cBoolean.setAssumedValue(cboolean14.isAssumedValue());
}
} else if (primitive14 instanceof CSTRING) {
CSTRING cstring14 = (CSTRING) primitive14;
CString cString = new CString();
if(cstring14.getList() != null) {
cString.getConstraint().addAll(cstring14.getList());
}
if(cstring14.getPattern() != null) {
cString.getConstraint().add("/" + cstring14.getPattern() + "/");
}
if(cstring14.isListOpen() != null) {
//TODO. Just return null?
}
cString.setAssumedValue(cstring14.getAssumedValue());
return cString;
} else if (primitive14 instanceof CDATE) {
return null;
} else if (primitive14 instanceof CDATETIME) {
return null;
} else if (primitive14 instanceof CTIME) {
return null;
} else if (primitive14 instanceof CDURATION) {
return null;
}
throw new IllegalArgumentException("Uknoown primitive type found");




}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.nedap.archie.opt14;

import com.nedap.archie.aom.Template;
import com.nedap.archie.aom.terminology.ArchetypeTerm;
import com.nedap.archie.aom.terminology.ArchetypeTerminology;

import java.util.LinkedHashMap;

public class TerminologyConverter {

public static ArchetypeTerminology createTerminology(OPERATIONALTEMPLATE opt14, CARCHETYPEROOT definition) {
ArchetypeTerminology terminology = new ArchetypeTerminology();
String language = opt14.getLanguage().getCodeString();
LinkedHashMap<String, ArchetypeTerm> terms = new LinkedHashMap<>();
terminology.getTermDefinitions().put(language, terms);
for(ARCHETYPETERM term14:definition.getTermDefinitions()) {
ArchetypeTerm term = new ArchetypeTerm();
term.setCode(term14.getCode());
for(StringDictionaryItem item:term14.getItems()) {
term.put(item.getId(), item.getId());
}
terms.put(term14.getCode(), term);
}
//TODO: term bindings
return terminology;
}
}
Loading

0 comments on commit efa90f9

Please sign in to comment.