Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.nedap.archie.adl14;

import com.nedap.archie.adl14.terms.TerminologyUriTemplate;
import com.nedap.archie.rminfo.ArchieAOMInfoLookup;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -21,21 +22,25 @@ public class ADL14ConversionConfiguration {
*/
private boolean applyDiff = true;


/**
* ADL 1.4 contains no rm release version, 2 does. So one needs to be added. Set to the desired rm_release. Defaults to 1.1.0
*/
private String rmRelease = "1.1.0";

/**
* Set to the code system the ADL 1.4 archetype should be converted into. Options: ID_CODED, AT_CODED. Defaults to ID_CODED.
*/
private NodeIdCodeSystem nodeIdCodeSystem = NodeIdCodeSystem.ID_CODED;
public enum NodeIdCodeSystem {
ID_CODED,
AT_CODED
}

// GETTERS
public List<TerminologyUriTemplate> getTerminologyConversionTemplates() {
return terminologyConversionTemplates;
}

public void setTerminologyConversionTemplates(List<TerminologyUriTemplate> terminologyConversionTemplates) {
this.terminologyConversionTemplates = terminologyConversionTemplates;
}

public TerminologyUriTemplate getTerminologyUriTemplate(String terminologyId, String version) {
Optional<TerminologyUriTemplate> result = terminologyConversionTemplates.stream().filter(template ->
template.getTerminologyId().equalsIgnoreCase(terminologyId) &&
Expand All @@ -52,23 +57,40 @@ public boolean isAllowDuplicateFieldNames() {
return allowDuplicateFieldNames;
}

public void setAllowDuplicateFieldNames(boolean allowDuplicateFieldNames) {
this.allowDuplicateFieldNames = allowDuplicateFieldNames;
}

public boolean isApplyDiff() {
return applyDiff;
}

public void setApplyDiff(boolean applyDiff) {
this.applyDiff = applyDiff;
}

public String getRmRelease() {
return rmRelease;
}

public NodeIdCodeSystem getNodeIdCodeSystem() {
return nodeIdCodeSystem;
}

public String getAdlVersion() {
return ArchieAOMInfoLookup.ADL_VERSION;
}

// SETTERS
public void setTerminologyConversionTemplates(List<TerminologyUriTemplate> terminologyConversionTemplates) {
this.terminologyConversionTemplates = terminologyConversionTemplates;
}

public void setAllowDuplicateFieldNames(boolean allowDuplicateFieldNames) {
this.allowDuplicateFieldNames = allowDuplicateFieldNames;
}

public void setApplyDiff(boolean applyDiff) {
this.applyDiff = applyDiff;
}

public void setRmRelease(String rmRelease) {
this.rmRelease = rmRelease;
}

public void setNodeIdCodeSystem(NodeIdCodeSystem nodeIdCodeSystem) {
this.nodeIdCodeSystem = nodeIdCodeSystem;
}
}
47 changes: 32 additions & 15 deletions aom/src/main/java/com/nedap/archie/adl14/ADL14NodeIDConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ public ADL14NodeIDConverter(MetaModelProvider metaModelProvider, Archetype arche
this.termConstraintConverter = new ADL14TermConstraintConverter(this, archetype, flatParentArchetype);
this.previousConversionApplier = new PreviousConversionApplier(this, archetype, oldLog);
this.conversionResult = conversionResult;

}

public ADL14ConversionConfiguration getConversionConfiguration() {
Expand Down Expand Up @@ -154,7 +153,6 @@ private List<String> findUnnecessaryCodes(CObject cObject, Map<String, Archetype
public static void convertTermDefinitions(Archetype archetype, Map<String, ConvertedCodeResult> convertedCodes, List<String> unnecessaryCodes) {
archetype.getTerminology().getTermDefinitions().replaceAll((language, terms) -> {
Map<String, ArchetypeTerm> newTerms = new LinkedHashMap<>();

for (Map.Entry<String, ArchetypeTerm> entry : terms.entrySet()) {
String oldCode = entry.getKey();
if (!unnecessaryCodes.contains(oldCode)) {
Expand All @@ -178,11 +176,8 @@ public static void convertTermDefinitions(Archetype archetype, Map<String, Conve

return newTerms;
});

//the terminology can still contain old unused codes now. The archetype validation will warn about that later
}


/**
* Replace old id's in term bindings with the new codes
*/
Expand Down Expand Up @@ -248,7 +243,7 @@ private void generateMissingNodeIds(CObject cObject) {
//if found, this is a specialization of said node and needs to be checked for differences and/or
//given the same node id
//if not found, generate/synthesize a new node id.
String parentPath = AOMUtils.pathAtSpecializationLevel(cObject.getPathSegments(), archetype.specializationDepth() - 1);
String parentPath = pathAtSpecializationLevel(cObject.getPathSegments(), archetype.specializationDepth() - 1);

CAttribute cAttributeInParent = flatParentArchetype.itemAtPath(parentPath);
if (cAttributeInParent != null) {
Expand Down Expand Up @@ -305,7 +300,11 @@ private void createSpecialisedNodeId(CObject cObject, String path, List<CObject>
* Object needs a new nodeId, generate the next valid nodeId and add in to the terminology
*/
private void synthesizeNodeId(CObject cObject, String path) {
cObject.setNodeId(idCodeGenerator.generateNextIdCode());
if (codeSystemIsIdCoded()) {
cObject.setNodeId(idCodeGenerator.generateNextIdCode());
} else {
cObject.setNodeId(idCodeGenerator.generateNextValueCode());
}
CreatedCode createdCode = new CreatedCode(cObject.getNodeId(), ReasonForCodeCreation.C_OBJECT_WITHOUT_NODE_ID);
createdCode.setRmTypeName(cObject.getRmTypeName());
createdCode.setPathCreated(path);
Expand Down Expand Up @@ -352,7 +351,7 @@ private void convert(CObject cObject) {
//VSSID validation does not exist in ADL 1.4. Fix it here

if (flatParentArchetype != null) {
String parentPath = AOMUtils.pathAtSpecializationLevel(cObject.getPathSegments(), archetype.specializationDepth() - 1);
String parentPath = pathAtSpecializationLevel(cObject.getPathSegments(), archetype.specializationDepth() - 1);
CObject cObjectInParent = flatParentArchetype.itemAtPath(parentPath);
if (cObjectInParent instanceof ArchetypeSlot && !cObjectInParent.getNodeId().equalsIgnoreCase(cObject.getNodeId())) {
//specializing a node id for an archetype slot is not allowed in ADL 2. Set to parent node id.
Expand Down Expand Up @@ -429,16 +428,15 @@ private static void fixArchetypeSlotExpression(Expression expression) {
}

/**
* If the object has a nodeId
* If the object has a nodeId & code system should be id coded
* - replace it with a new nodeId
* - store the old and new nodeId as a converted code
*/
private void calculateNewNodeId(CObject cObject) {
if (cObject.getNodeId() != null) {
if (cObject.getNodeId() != null && codeSystemIsIdCoded()) {
String oldNodeId = cObject.getNodeId();
String newNodeId = convertNodeId(oldNodeId);
addConvertedCode(oldNodeId, newNodeId);

cObject.setNodeId(newNodeId);
}
}
Expand Down Expand Up @@ -469,7 +467,7 @@ public String convertNodeId(String oldNodeId) {
/**
* Convert old code into an at code
*/
protected String convertValueCode(String oldCode) {
protected String convertIntoAtCode(String oldCode) {
ConvertedCodeResult convertedCodeResult = convertedCodes.get(oldCode);
if (convertedCodeResult != null && convertedCodeResult.hasValueCode()) {
return convertedCodeResult.getValueCode();
Expand Down Expand Up @@ -501,18 +499,19 @@ public static String convertCode(String oldCode, String newCodePrefix) {
nodeIdUtil.setPrefix(newCodePrefix); //will automatically strip the leading zeroes due to integer-parsing
if (!oldCode.startsWith("at0.") && !oldCode.startsWith("ac0.")) {
//a bit tricky, since the root of an archetype starts with at0000.0, but that's different from this I guess
nodeIdUtil.getCodes().set(0, nodeIdUtil.getCodes().get(0) + 1); //increment with 1, old is 0-based
nodeIdUtil.getCodes().set(0, String.valueOf(Integer.parseInt(nodeIdUtil.getCodes().get(0)) + 1)); // increment with 1, old is 0-based
}
return nodeIdUtil.toString();
}

/**
* Convert all old codes in a path in the new codes
* Convert all old codes in a path in the new codes.
* If the code system should be at coded, the code should stay the same.
*/
public String convertPath(String key) {
APathQuery aPathQuery = new APathQuery(key);
for (PathSegment segment : aPathQuery.getPathSegments()) {
if (segment.getNodeId() != null) {
if (codeSystemIsIdCoded() && segment.getNodeId() != null) {
segment.setNodeId(convertNodeId(segment.getNodeId()));
}
}
Expand All @@ -533,4 +532,22 @@ public ADL2ConversionResult getConversionResult() {
protected IdCodeGenerator getIdCodeGenerator() {
return idCodeGenerator;
}

/**
*
*/
public boolean codeSystemIsIdCoded() {
return conversionConfiguration.getNodeIdCodeSystem().equals(ADL14ConversionConfiguration.NodeIdCodeSystem.ID_CODED);
}

/**
* Returns the path at the given specialization level. Takes node system of converter into account.
*/
private String pathAtSpecializationLevel(List<PathSegment> pathSegments, int specializationLevel) {
if (codeSystemIsIdCoded()) {
return AOMUtils.pathAtSpecializationLevel(pathSegments, specializationLevel);
} else {
return AOMUtils.pathAtSpecializationLevelAtCoded(pathSegments, specializationLevel);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ public void convert() {
}

private void convert(CObject cObject) {

if (cObject instanceof CTerminologyCode) {
convertCTerminologyCode((CTerminologyCode) cObject);
}
Expand Down Expand Up @@ -99,31 +98,42 @@ private void convertCTerminologyCode(CTerminologyCode cTerminologyCode) {
if(isLocalCode && AOMUtils.isValueCode(firstConstraint)) {
//local codes
if(cTerminologyCode.getConstraint().size() == 1) {
//do not create a value set, just convert the code
String newCode = converter.convertValueCode(firstConstraint);
converter.addConvertedCode(firstConstraint, newCode);
cTerminologyCode.setConstraint(Lists.newArrayList(newCode));
// do not create a value set, just convert the code
// if the code system should be at coded, the code stays the same
if (converter.codeSystemIsIdCoded()) {
String newCode = converter.convertIntoAtCode(firstConstraint);
converter.addConvertedCode(firstConstraint, newCode);
cTerminologyCode.setConstraint(Lists.newArrayList(newCode));
}
} else {
// Create a valueSet for these terminology codes
Set<String> localCodes = new LinkedHashSet<>();
for(String code:cTerminologyCode.getConstraint()) {
String newCode = converter.convertValueCode(code);
converter.addConvertedCode(code, newCode);
localCodes.add(newCode);
if (converter.codeSystemIsIdCoded()) {
// If the code system should be id coded, we need to convert the local codes into at codes
String newCode = converter.convertIntoAtCode(code);
converter.addConvertedCode(code, newCode);
localCodes.add(newCode);
} else {
// If the code system should be at coded, we can keep the local codes as they are
localCodes.add(code);
}
}

ValueSet valueSet = findOrCreateValueSet(cTerminologyCode.getArchetype(), localCodes, cTerminologyCode);
cTerminologyCode.setConstraint(Lists.newArrayList(valueSet.getId()));
}
} else if (isLocalCode && AOMUtils.isValueSetCode(termCode.getCodeString())) {
List<String> newConstraint = new ArrayList<>();
for(String constraint:cTerminologyCode.getConstraint()) {
TerminologyCode code = TerminologyCode.createFromString(constraint);
String newCode = converter.convertValueSetCode(code.getCodeString());
converter.addConvertedCode(termCode.getCodeString(), newCode);
newConstraint.add(newCode);
if (converter.codeSystemIsIdCoded()) {
List<String> newConstraint = new ArrayList<>();
for(String constraint:cTerminologyCode.getConstraint()) {
TerminologyCode code = TerminologyCode.createFromString(constraint);
String newCode = converter.convertValueSetCode(code.getCodeString());
converter.addConvertedCode(termCode.getCodeString(), newCode);
newConstraint.add(newCode);
}
cTerminologyCode.setConstraint(newConstraint);
}
cTerminologyCode.setConstraint(newConstraint);

} else {
if (cTerminologyCode.getConstraint().size() == 1) {
try {
Expand Down Expand Up @@ -172,7 +182,7 @@ private void convertCTerminologyCode(CTerminologyCode cTerminologyCode) {
if(cTerminologyCode.getAssumedValue() != null) {
TerminologyCode assumedValue = cTerminologyCode.getAssumedValue();
if(isLocalCode) {
String newCode = converter.convertValueCode(assumedValue.getCodeString());
String newCode = converter.convertIntoAtCode(assumedValue.getCodeString());
assumedValue.setCodeString(newCode);
assumedValue.setTerminologyId(null);
} else {
Expand Down Expand Up @@ -323,11 +333,17 @@ protected ArchetypeTerm getTerm(String language, CObject owningConstraint) {
while(cObject != null) {
if (cObject.getNodeId() != null) {
String oldCode = converter.getOldCodeForNewCode(cObject.getNodeId());
if(oldCode != null && archetype.getTerminology().getTermDefinition(language, oldCode) != null) {
if (oldCode != null && archetype.getTerminology().getTermDefinition(language, oldCode) != null) {
ArchetypeTerm term = archetype.getTerminology().getTermDefinition(language, oldCode);
if(term != null) {
return term;
}
} else if (archetype.getTerminology().getTermDefinition(language, cObject.getNodeId()) != null) {
// It is not converted, so just use the node id of the object to find the term
ArchetypeTerm term = archetype.getTerminology().getTermDefinition(language, cObject.getNodeId());
if(term != null) {
return term;
}
}
}
cObject = cObject.getParent() == null ? null : cObject.getParent().getParent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ public CComplexObject parseComplexObject(C_complex_objectContext context) {
if(context.type_id() != null) {
object.setRmTypeName(context.type_id().getText());
}
if(context.ID_CODE() != null) {
object.setNodeId(context.ID_CODE().getText());
if(context.node_identifier() != null) {
object.setNodeId(context.node_identifier().getText());
} else if (context.ROOT_ID_CODE() != null) {
object.setNodeId(context.ROOT_ID_CODE().getText());
}
Expand Down Expand Up @@ -267,7 +267,7 @@ private List<CObject> parseCObjects(C_objectsContext objectsContext) {
} else if (siblingOrderContext.SYM_BEFORE() != null) {
siblingOrder.setBefore(true);
}
siblingOrder.setSiblingNodeId(siblingOrderContext.ID_CODE().getText());
siblingOrder.setSiblingNodeId(siblingOrderContext.node_identifier().getText());
cobject.setSiblingOrder(siblingOrder);
}

Expand Down Expand Up @@ -305,15 +305,15 @@ private CComplexObjectProxy parseCComplexObjectProxy(C_complex_object_proxyConte
proxy.setOccurrences(this.parseMultiplicityInterval(proxyContext.c_occurrences()));
proxy.setTargetPath(proxyContext.adl_path().getText());
proxy.setRmTypeName(proxyContext.type_id().getText());
proxy.setNodeId(proxyContext.ID_CODE().getText());
proxy.setNodeId(proxyContext.node_identifier().getText());
return proxy;
}

private CArchetypeRoot parseArchetypeRoot(C_archetype_rootContext archetypeRootContext) {
CArchetypeRoot root = new CArchetypeRoot();

root.setRmTypeName(archetypeRootContext.type_id().getText());
root.setNodeId(archetypeRootContext.ID_CODE().getText());
root.setNodeId(archetypeRootContext.node_identifier().getText());
if(archetypeRootContext.archetype_ref() != null) {
root.setArchetypeRef(archetypeRootContext.archetype_ref().getText());
}
Expand All @@ -329,7 +329,7 @@ private CArchetypeRoot parseArchetypeRoot(C_archetype_rootContext archetypeRootC
private ArchetypeSlot parseArchetypeSlot(Archetype_slotContext slotContext) {
ArchetypeSlot slot = new ArchetypeSlot();

slot.setNodeId(slotContext.ID_CODE().getText());
slot.setNodeId(slotContext.node_identifier().getText());
slot.setRmTypeName(slotContext.type_id().getText());
if(slotContext.SYM_CLOSED() != null) {
slot.setClosed(true);
Expand Down
Loading