Skip to content

Commit 9f9e132

Browse files
committed
One more step in converting opt 1.4
1 parent cacd7bb commit 9f9e132

12 files changed

Lines changed: 363 additions & 7 deletions

aom/src/main/java/com/nedap/archie/adl14/ADL14ConversionConfiguration.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ public class ADL14ConversionConfiguration {
2121
*/
2222
private boolean applyDiff = true;
2323

24+
/** If true, allow empty node ids where specialisations occur. for OPT conversion */
25+
private boolean allowEmptyNodeIdsForSpecializations = false;
26+
2427

2528
public List<TerminologyUriTemplate> getTerminologyConversionTemplates() {
2629
return terminologyConversionTemplates;
@@ -57,4 +60,12 @@ public boolean isApplyDiff() {
5760
public void setApplyDiff(boolean applyDiff) {
5861
this.applyDiff = applyDiff;
5962
}
63+
64+
public boolean isAllowEmptyNodeIdsForSpecializations() {
65+
return allowEmptyNodeIdsForSpecializations;
66+
}
67+
68+
public void setAllowEmptyNodeIdsForSpecializations(boolean allowEmptyNodeIdsForSpecializations) {
69+
this.allowEmptyNodeIdsForSpecializations = allowEmptyNodeIdsForSpecializations;
70+
}
6071
}

aom/src/main/java/com/nedap/archie/adl14/ADL14NodeIDConverter.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,6 @@ private void convertTermBindings(Archetype archetype) {
203203
}
204204

205205
private void generateMissingNodeIds(CObject cObject) {
206-
207206
if(!(cObject instanceof CPrimitiveObject) && cObject.getNodeId() == null) {
208207
String path = cObject.getPath();
209208
if(archetype.getParentArchetypeId() != null && flatParentArchetype != null) {

aom/src/main/java/com/nedap/archie/adl14/ADL14TermConstraintConverter.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@ private void convertCTerminologyCode(CTerminologyCode cTerminologyCode) {
203203
}
204204

205205
private Map<String, URI> findOrCreateTermBindings(TerminologyCode termCode) {
206+
if(termCode.getTerminologyId() == null) {
207+
throw new IllegalArgumentException("terminology id cannot be null!");
208+
}
206209
Map<String, URI> termBindings = archetype.getTerminology().getTermBindings().get(termCode.getTerminologyId());
207210

208211
if(termBindings == null) {

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,11 @@ private CObject convertRoot(CARCHETYPEROOT cRoot14) {
101101

102102
CArchetypeRoot root = new CArchetypeRoot();
103103
root.setArchetypeRef(overlay.getArchetypeId().getFullId());
104-
setObjectBasics(cRoot14, root);
104+
if(cRoot14.getNodeId() != null && !cRoot14.getNodeId().isEmpty() && !cRoot14.getNodeId().startsWith("at0000")) {
105+
root.setNodeId(cRoot14.getNodeId());
106+
}
107+
root.setRmTypeName(cRoot14.getRmTypeName());
108+
root.setOccurrences(BaseTypesConverter.convertMultiplicity(cRoot14.getOccurrences()));
105109
return root;
106110
}
107111

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

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@
33
import com.nedap.archie.adl14.aom14.CDVOrdinal;
44
import com.nedap.archie.adl14.aom14.CDVOrdinalItem;
55
import com.nedap.archie.adl14.aom14.CDVQuantity;
6-
76
import com.nedap.archie.adl14.aom14.CDVQuantityAssumedValue;
87
import com.nedap.archie.adl14.aom14.CDVQuantityItem;
98
import com.nedap.archie.adl14.treewalkers.Adl14CComplexObjectParser;
109
import com.nedap.archie.aom.CObject;
11-
import com.nedap.archie.base.terminology.TerminologyCode;
10+
import com.nedap.archie.aom.primitives.CTerminologyCode;
1211

1312
import java.util.LinkedHashMap;
1413
import java.util.Map;
@@ -24,11 +23,30 @@ public static CObject convertDomainType(CDOMAINTYPE cobject14) {
2423
} else if (cobject14 instanceof CDVSTATE) {
2524

2625
} else if (cobject14 instanceof CCODEPHRASE) {
27-
26+
return convertCodePhrase((CCODEPHRASE) cobject14);
2827
}
2928
return null;
3029
}
3130

31+
private static CObject convertCodePhrase(CCODEPHRASE cobject14) {
32+
CTerminologyCode cTerminologyCode = new CTerminologyCode();
33+
34+
if(cobject14.getTerminologyId() != null) {
35+
cTerminologyCode.addConstraint(cobject14.getTerminologyId().getValue());
36+
} else {
37+
System.out.println("HELP");
38+
}
39+
if(cobject14.getCodeList() != null) {
40+
for(String code:cobject14.getCodeList()) {
41+
cTerminologyCode.addConstraint(code);
42+
}
43+
}
44+
if(cobject14.getAssumedValue() != null) {
45+
cTerminologyCode.setAssumedValue(BaseTypesConverter.convert(cobject14.getAssumedValue()));
46+
}
47+
return cTerminologyCode;
48+
}
49+
3250
private static CObject convertCDVOrdinal(CDVORDINAL ordinal14) {
3351
CDVOrdinal ordinal = new CDVOrdinal();
3452
Map<String, CDVOrdinalItem> items = new LinkedHashMap<>();
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.nedap.archie.opt14;
2+
3+
import com.nedap.archie.aom.Archetype;
4+
5+
public interface FlatArchetypeProvider {
6+
7+
Archetype getFlatArchetype(String archetypeId);
8+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package com.nedap.archie.opt14;
2+
3+
import com.nedap.archie.aom.Archetype;
4+
import com.nedap.archie.aom.ArchetypeModelObject;
5+
import com.nedap.archie.aom.CAttribute;
6+
import com.nedap.archie.aom.CObject;
7+
import com.nedap.archie.aom.Template;
8+
import com.nedap.archie.aom.TemplateOverlay;
9+
import com.nedap.archie.aom.terminology.ArchetypeTerminology;
10+
import com.nedap.archie.aom.utils.AOMUtils;
11+
import com.nedap.archie.aom.utils.NodeIdUtil;
12+
import com.nedap.archie.archetypevalidator.ErrorType;
13+
import com.nedap.archie.flattener.InMemoryFullArchetypeRepository;
14+
import org.openehr.utils.message.I18n;
15+
16+
public class NodeIdFixer {
17+
18+
private Archetype archetype;
19+
private Archetype flatParent;
20+
21+
public void fixNodeIds(Archetype archetype, FlatArchetypeProvider repo) {
22+
this.archetype = archetype;
23+
if(archetype.getParentArchetypeId() != null) {
24+
this.flatParent = repo.getFlatArchetype(archetype.getParentArchetypeId());
25+
}
26+
fixRootNodeId(archetype);
27+
//fixNodeId(archetype.getDefinition());
28+
29+
if(archetype instanceof Template) {
30+
Template template = (Template) archetype;
31+
32+
for(TemplateOverlay overlay:template.getTemplateOverlays()) {
33+
this.archetype = overlay;
34+
if(archetype.getParentArchetypeId() != null) {
35+
this.flatParent = repo.getFlatArchetype(overlay.getParentArchetypeId());
36+
}
37+
fixRootNodeId(overlay);
38+
//fixNodeId(overlay.getDefinition());
39+
}
40+
}
41+
}
42+
43+
private void fixRootNodeId(Archetype archetype) {
44+
int specDepth = flatParent.specializationDepth()+1;
45+
CObject cObject = archetype.getDefinition();
46+
if(cObject.isRootNode() && AOMUtils.getSpecializationDepthFromCode(cObject.getNodeId()) != specDepth) {
47+
//create id1.1.1.1.1.....1 one
48+
String newNodeId = "at0000";
49+
for(int i = 0; i < specDepth; i++) {
50+
newNodeId += ".1";
51+
}
52+
cObject.setNodeId(newNodeId);
53+
}
54+
}
55+
56+
private void fixNodeId(CObject cObject) {
57+
if(flatParent == null) {
58+
return;
59+
}
60+
61+
62+
if (cObject.isRootNode() || !cObject.getParent().isSecondOrderConstrained()) {
63+
if (AOMUtils.getSpecializationDepthFromCode(cObject.getNodeId()) <= flatParent.specializationDepth()
64+
|| new NodeIdUtil(cObject.getNodeId()).isRedefined()) {
65+
if (!AOMUtils.isPhantomPathAtLevel(cObject.getPathSegments(), flatParent.specializationDepth())) {
66+
String flatPath = AOMUtils.pathAtSpecializationLevel(cObject.getPathSegments(), flatParent.specializationDepth());
67+
CObject parentCObject = getCObject(flatParent.itemAtPath(flatPath));
68+
69+
if (parentCObject != null) {
70+
if (cObject.isProhibited()) {
71+
if (!parentCObject.getNodeId().equals(cObject.getNodeId())) {
72+
// System.out.println("fixing node id " + cObject.getNodeId() + " for archetype " + archetype.getArchetypeId());
73+
String oldNodeId = cObject.getNodeId();
74+
cObject.setNodeId(parentCObject.getNodeId());
75+
ArchetypeTerminology terminology = cObject.getArchetype().getTerminology();
76+
for(String language:terminology.getTermDefinitions().keySet()) {
77+
terminology.getTermDefinitions().get(language).remove(oldNodeId);
78+
}
79+
}
80+
}
81+
}
82+
}
83+
}
84+
}
85+
86+
for(CAttribute attribute:cObject.getAttributes()) {
87+
fixNodeId(attribute);
88+
}
89+
}
90+
91+
private void fixNodeId(CAttribute cAttribute) {
92+
for(CObject cObject:cAttribute.getChildren()) {
93+
fixNodeId(cObject);
94+
}
95+
}
96+
97+
private CObject getCObject(ArchetypeModelObject archetypeModelObject) {
98+
if(archetypeModelObject instanceof CAttribute) {
99+
CAttribute attribute = (CAttribute) archetypeModelObject;
100+
if(attribute.getChildren().size() == 1) {
101+
return attribute.getChildren().get(0);
102+
}//TODO: add a numeric identifier to the getPath() method in CObject so this can be deleted and actually works in all cases!
103+
} else if(archetypeModelObject instanceof CObject) {
104+
return (CObject) archetypeModelObject;
105+
}
106+
return null;
107+
}
108+
}
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
package com.nedap.archie.opt14;
2+
3+
import com.nedap.archie.aom.Archetype;
4+
import com.nedap.archie.aom.ArchetypeModelObject;
5+
import com.nedap.archie.aom.CAttribute;
6+
import com.nedap.archie.aom.CComplexObject;
7+
import com.nedap.archie.aom.CObject;
8+
import com.nedap.archie.aom.CPrimitiveObject;
9+
import com.nedap.archie.aom.Template;
10+
import com.nedap.archie.aom.TemplateOverlay;
11+
import com.nedap.archie.aom.primitives.CString;
12+
import com.nedap.archie.aom.terminology.ArchetypeTerm;
13+
import com.nedap.archie.aom.utils.AOMUtils;
14+
import com.nedap.archie.query.AOMPathQuery;
15+
import com.nedap.archie.query.RMPathQuery;
16+
import com.nedap.archie.rminfo.ArchieRMInfoLookup;
17+
18+
import java.util.ArrayList;
19+
import java.util.LinkedHashMap;
20+
import java.util.Map;
21+
22+
/**
23+
* Walks the archetype tree, then specializes any node ids it finds with change where required. Can be:
24+
* - different type
25+
* - different text or description
26+
* - different primitive node child (TODO: check how in Differentiator?)
27+
*
28+
*
29+
* TODO: remove simple single constraint name constraints, and put them in the terminology instead first!
30+
*
31+
*/
32+
public class NodeIdSpecializer {
33+
34+
private Archetype archetype;
35+
private Archetype flatParent;
36+
37+
public void specializeNodeIds(Archetype archetype, FlatArchetypeProvider repo) {
38+
if(archetype.getParentArchetypeId() == null) {
39+
return;
40+
}
41+
this.archetype = archetype;
42+
if(archetype.getParentArchetypeId() != null) {
43+
this.flatParent = repo.getFlatArchetype(archetype.getParentArchetypeId());
44+
}
45+
specializeNodeIds(archetype.getDefinition());
46+
47+
if(archetype instanceof Template) {
48+
Template template = (Template) archetype;
49+
50+
for(TemplateOverlay overlay:template.getTemplateOverlays()) {
51+
this.archetype = overlay;
52+
if(archetype.getParentArchetypeId() != null) {
53+
this.flatParent = repo.getFlatArchetype(overlay.getParentArchetypeId());
54+
}
55+
56+
specializeNodeIds(overlay.getDefinition());
57+
}
58+
}
59+
}
60+
61+
62+
private void specializeNodeIds(CObject cObject) {
63+
if(!(cObject instanceof CPrimitiveObject)) {
64+
String flatPath = AOMUtils.pathAtSpecializationLevel(cObject.getPathSegments(), flatParent.specializationDepth());
65+
CObject parentCObject = getCObject(flatParent.itemAtPath(flatPath));
66+
67+
if(parentCObject != null) {
68+
ArchetypeTerm term = archetype.getTerm(cObject, archetype.getOriginalLanguage().getCodeString());
69+
ArchetypeTerm parentTerm = flatParent.getTerm(parentCObject, archetype.getOriginalLanguage().getCodeString());
70+
if( cObject.getNodeId().equalsIgnoreCase(parentCObject.getNodeId())) {
71+
if(parentTerm != null && term != null) {
72+
if (!term.getText().equalsIgnoreCase(parentTerm.getText()) ||
73+
!term.getDescription().equalsIgnoreCase(parentTerm.getDescription())) {
74+
//term changes. We need a new node id
75+
System.out.println("GOT ONE!");
76+
}
77+
}
78+
}
79+
80+
} else {
81+
System.out.println("DID NOT EXPECT THIS");
82+
// throw new RuntimeException("I did not expect the Spanish inquisition!");//TODO: remove or add proper message
83+
}
84+
for(CAttribute attribute:cObject.getAttributes()) {
85+
specializeNodeIds(attribute);
86+
}
87+
}
88+
89+
}
90+
91+
private void specializeNodeIds(CAttribute attribute) {
92+
if(attribute.getRmAttributeName().equalsIgnoreCase("name")) {
93+
//ok a name constraint. If it's a simple constraint, replace it with a terminology entry please.
94+
if(attribute.getChildren().size() == 1 && attribute.getChildren().get(0).getRmTypeName().equalsIgnoreCase("DV_TEXT")) {
95+
CObject cObject = attribute.getChildren().get(0);
96+
Object o = new AOMPathQuery("/value[1]").find((CComplexObject) cObject);
97+
if(o instanceof CString) {
98+
CString nameConstraint = (CString) o;
99+
if (nameConstraint.getConstraint().size() == 1 && !CString.isRegexConstraint(nameConstraint.getConstraint().get(0))) {
100+
//remove the crap out of this attribute.
101+
attribute.setChildren(new ArrayList<>());
102+
ArchetypeTerm term = archetype.getTerm(attribute.getParent(), archetype.getOriginalLanguage().getCodeString());
103+
if (term != null) {
104+
term.setText((nameConstraint.getConstraint().get(0)));
105+
} else {
106+
term = new ArchetypeTerm();
107+
term.setCode(attribute.getParent().getNodeId());
108+
term.setText(nameConstraint.getConstraint().get(0));
109+
term.setDescription(nameConstraint.getConstraint().get(0));
110+
getOrCreateTermDefinitions().put(attribute.getParent().getNodeId(), term);
111+
}
112+
}
113+
}
114+
}
115+
}
116+
for(CObject child:attribute.getChildren()) {
117+
specializeNodeIds(child);
118+
}
119+
}
120+
121+
private Map<String, ArchetypeTerm> getOrCreateTermDefinitions() {
122+
Map<String, ArchetypeTerm> termDefs = archetype.getTerminology().getTermDefinitions().get(archetype.getOriginalLanguage().getCodeString());
123+
if(termDefs == null) {
124+
termDefs = new LinkedHashMap<>();
125+
archetype.getTerminology().getTermDefinitions().put(archetype.getOriginalLanguage().getCodeString(), termDefs);
126+
}
127+
return termDefs;
128+
}
129+
130+
private CObject getCObject(ArchetypeModelObject archetypeModelObject) {
131+
if(archetypeModelObject instanceof CAttribute) {
132+
CAttribute attribute = (CAttribute) archetypeModelObject;
133+
if(attribute.getChildren().size() == 1) {
134+
return attribute.getChildren().get(0);
135+
}//TODO: add a numeric identifier to the getPath() method in CObject so this can be deleted and actually works in all cases!
136+
} else if(archetypeModelObject instanceof CObject) {
137+
return (CObject) archetypeModelObject;
138+
}
139+
return null;
140+
}
141+
}

0 commit comments

Comments
 (0)