Skip to content
Open
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
Expand Up @@ -396,8 +396,7 @@ private static void fixArchetypeSlotExpression(Expression expression) {
Expression rightOperand = binary.getRightOperand();
if (rightOperand instanceof Constraint) {
Constraint<?> constraint = (Constraint<?>) rightOperand;
if (constraint.getItem() != null && constraint.getItem().getConstraint() != null && !constraint.getItem().getConstraint().isEmpty() &&
constraint.getItem() instanceof CString) {
if (constraint.getItem() != null && constraint.getItem() instanceof CString && constraint.getItem().getConstraint() != null && !((CString) constraint.getItem()).getConstraint().isEmpty()) {
CString cString = (CString) constraint.getItem();
if (cString.getConstraint() == null || cString.getConstraint().isEmpty()) {
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.nedap.archie.adl14;

import com.google.common.collect.Lists;
import com.nedap.archie.adl14.log.CreatedCode;
import com.nedap.archie.adl14.log.ReasonForCodeCreation;
import com.nedap.archie.aom.*;
Expand Down Expand Up @@ -56,8 +55,8 @@ private void convert(CObject cObject) {
for (CPrimitiveObject<?, ?> cPrimitiveObject : termCodes) {
CTerminologyCode cTerminologyCode = (CTerminologyCode) cPrimitiveObject;
convertCTerminologyCode(cTerminologyCode);
if(cTerminologyCode.getConstraint().size() == 1) {
String constraint = cTerminologyCode.getConstraint().get(0);
if(cTerminologyCode.getConstraint() != null) {
String constraint = cTerminologyCode.getConstraint();
if(AOMUtils.isValueCode(constraint)) {
atCodes.add(constraint);
}
Expand Down Expand Up @@ -91,103 +90,132 @@ private void convert(CAttribute attribute) {
}
}

/**
* Converts a single-code {@link CTerminologyCode} constraint from ADL 1.4 to ADL 2 format.
* Multi-code constraints (stored via {@link CTerminologyCode#getPendingCodes()} by the ADL 1.4 parser)
* are delegated to {@link #convertMultiCodeTerminologyCode}.
* <p>
* Three cases are handled:
* <ul>
* <li>Local at-code (e.g. {@code at0001}): converted to its ADL 2 equivalent.</li>
* <li>Local ac-code (e.g. {@code ac0001}): converted to its ADL 2 value-set code equivalent.</li>
* <li>External terminology code (e.g. {@code [snomed-ct::12345]}): a term binding is created and
* a new local at-code is generated to reference it.</li>
* </ul>
*/
private void convertCTerminologyCode(CTerminologyCode cTerminologyCode) {
if(cTerminologyCode.getConstraint() != null && !cTerminologyCode.getConstraint().isEmpty()) {
String firstConstraint = cTerminologyCode.getConstraint().get(0);
TerminologyCode termCode = TerminologyCode.createFromString(firstConstraint);
boolean isLocalCode = termCode.getTerminologyId() == null || termCode.getTerminologyId().equalsIgnoreCase("local");
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));
} else {
Set<String> localCodes = new LinkedHashSet<>();
for(String code:cTerminologyCode.getConstraint()) {
String newCode = converter.convertValueCode(code);
converter.addConvertedCode(code, newCode);
localCodes.add(newCode);
}
List<String> pendingCodes = cTerminologyCode.getPendingCodes();
if (pendingCodes != null && !pendingCodes.isEmpty()) {
convertMultiCodeTerminologyCode(cTerminologyCode, pendingCodes);
return;
}

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);
}
cTerminologyCode.setConstraint(newConstraint);

} else {
if (cTerminologyCode.getConstraint().size() == 1) {
try {
//do not create a value set, create a code plus binding to the old non-local code
URI uri = new ADL14ConversionUtil(converter.getConversionConfiguration()).convertToUri(termCode);
Map<String, URI> termBindingsMap = findOrCreateTermBindings(termCode);

//TODO: check if this is a converted or old term binding - old is unusual, but could be possible!
String termBinding = findOrAddTermBindingAndCode(termCode, uri, termBindingsMap);
cTerminologyCode.setConstraint(Lists.newArrayList(termBinding));
} catch (URISyntaxException e) {
//TODO
logger.error("error converting term", e);
}
} else {
String terminologyId = cTerminologyCode.getConstraint().get(0);
termCode = TerminologyCode.createFromString(terminologyId, null, cTerminologyCode.getConstraint().get(1));
Map<String, URI> termBindingsMap = findOrCreateTermBindings(termCode);
List<String> atCodes = new ArrayList<>();
List<String> constraints = new ArrayList<>(cTerminologyCode.getConstraint());
cTerminologyCode.setConstraint(atCodes);
for(int i = 1; i < constraints.size(); i++) {
String constraint = constraints.get(i);
try {
if(constraint.startsWith("[") && constraint.endsWith("]")) {
TerminologyCode constraintCode = TerminologyCode.createFromString(constraint);
URI uri = new ADL14ConversionUtil(converter.getConversionConfiguration()).convertToUri(constraintCode);
atCodes.add(findOrAddTermBindingAndCode(constraintCode, uri, termBindingsMap));
} else {
TerminologyCode constraintCode = new TerminologyCode();
constraintCode.setTerminologyId(terminologyId);
constraintCode.setCodeString(constraint);
URI uri = new ADL14ConversionUtil(converter.getConversionConfiguration()).convertToUri(constraintCode);
atCodes.add(findOrAddTermBindingAndCode(constraintCode, uri, termBindingsMap));
}
String constraint = cTerminologyCode.getConstraint();
if (constraint == null) {
return;
}

} catch (URISyntaxException e) {
e.printStackTrace();
}
}
ValueSet valueSet = findOrCreateValueSet(cTerminologyCode.getArchetype(), new LinkedHashSet<>(atCodes), cTerminologyCode);
cTerminologyCode.setConstraint(Lists.newArrayList(valueSet.getId()));
TerminologyCode termCode = TerminologyCode.createFromString(constraint);
boolean isLocalCode = termCode.getTerminologyId() == null
|| termCode.getTerminologyId().equalsIgnoreCase("local");

}
if (isLocalCode && AOMUtils.isValueCode(constraint)) {
// Single local at-code: convert it to its ADL 2 equivalent
String newCode = converter.convertValueCode(constraint);
converter.addConvertedCode(constraint, newCode);
cTerminologyCode.setConstraint(newCode);
} else if (isLocalCode && AOMUtils.isValueSetCode(termCode.getCodeString())) {
// Local value-set reference: convert the ac-code to its ADL 2 equivalent
String newCode = converter.convertValueSetCode(termCode.getCodeString());
converter.addConvertedCode(termCode.getCodeString(), newCode);
cTerminologyCode.setConstraint(newCode);
} else {
// External terminology: create a term binding and generate a new at-code to reference it
try {
URI uri = new ADL14ConversionUtil(converter.getConversionConfiguration()).convertToUri(termCode);
Map<String, URI> termBindingsMap = findOrCreateTermBindings(termCode);
cTerminologyCode.setConstraint(findOrAddTermBindingAndCode(termCode, uri, termBindingsMap));
} catch (URISyntaxException e) {
logger.error("error converting term", e);
}
if(cTerminologyCode.getAssumedValue() != null) {
TerminologyCode assumedValue = cTerminologyCode.getAssumedValue();
if(isLocalCode) {
String newCode = converter.convertValueCode(assumedValue.getCodeString());
assumedValue.setCodeString(newCode);
assumedValue.setTerminologyId(null);
} else {
try {
Map<String, URI> termBindingsMap = findOrCreateTermBindings(assumedValue);
URI uri = new ADL14ConversionUtil(converter.getConversionConfiguration()).convertToUri(assumedValue);
assumedValue.setCodeString(findOrAddTermBindingAndCode(assumedValue, uri, termBindingsMap));
assumedValue.setTerminologyId(null);
assumedValue.setTerminologyVersion(null);
} catch (URISyntaxException e) {
//TODO
e.printStackTrace();
}
}

convertAssumedValue(cTerminologyCode, isLocalCode);
}

/**
* Converts a multi-code {@link CTerminologyCode} constraint from ADL 1.4 to ADL 2 format.
* In ADL 1.4, a constraint may reference multiple codes inline (e.g.
* {@code [local::at0001, at0002]} or {@code [snomed-ct::12345, 67890]}). ADL 2 represents
* these as a value set (ac-code), which this method creates.
* <p>
* The {@code pendingCodes} list was populated by the ADL 1.4 parser:
* <ul>
* <li>For local codes: raw at-codes, e.g. {@code ["at0001", "at0002"]}.</li>
* <li>For external codes: full term code refs normalised by the parser,
* e.g. {@code ["[snomed-ct::12345]", "[snomed-ct::67890]"]}.</li>
* </ul>
* In both cases a value set is created and the constraint is set to its ac-code.
*/
private void convertMultiCodeTerminologyCode(CTerminologyCode cTerminologyCode, List<String> pendingCodes) {
TerminologyCode firstCode = TerminologyCode.createFromString(pendingCodes.get(0));
boolean isLocalCode = firstCode.getTerminologyId() == null
|| firstCode.getTerminologyId().equalsIgnoreCase("local");

if (isLocalCode) {
// Convert each at-code and group them into a new value set
Set<String> convertedCodes = new LinkedHashSet<>();
for (String code : pendingCodes) {
String newCode = converter.convertValueCode(code);
converter.addConvertedCode(code, newCode);
convertedCodes.add(newCode);
}
ValueSet valueSet = findOrCreateValueSet(cTerminologyCode.getArchetype(), convertedCodes, cTerminologyCode);
cTerminologyCode.setConstraint(valueSet.getId());
} else {
// Create a term binding for each external code, then group the resulting at-codes into a value set
Map<String, URI> termBindingsMap = findOrCreateTermBindings(firstCode);
List<String> atCodes = new ArrayList<>();
for (String code : pendingCodes) {
TerminologyCode termCode = TerminologyCode.createFromString(code);
try {
URI uri = new ADL14ConversionUtil(converter.getConversionConfiguration()).convertToUri(termCode);
atCodes.add(findOrAddTermBindingAndCode(termCode, uri, termBindingsMap));
} catch (URISyntaxException e) {
logger.error("error converting term", e);
}
}
if (!atCodes.isEmpty()) {
ValueSet valueSet = findOrCreateValueSet(cTerminologyCode.getArchetype(), new LinkedHashSet<>(atCodes), cTerminologyCode);
cTerminologyCode.setConstraint(valueSet.getId());
}
}

convertAssumedValue(cTerminologyCode, isLocalCode);
}

/**
* Converts the assumed value of a {@link CTerminologyCode} from ADL 1.4 to ADL 2 format,
* mirroring the logic used for the constraint itself.
*/
private void convertAssumedValue(CTerminologyCode cTerminologyCode, boolean isLocalCode) {
if (cTerminologyCode.getAssumedValue() == null) {
return;
}
TerminologyCode assumedValue = cTerminologyCode.getAssumedValue();
if (isLocalCode) {
assumedValue.setCodeString(converter.convertValueCode(assumedValue.getCodeString()));
assumedValue.setTerminologyId(null);
} else {
try {
Map<String, URI> termBindingsMap = findOrCreateTermBindings(assumedValue);
URI uri = new ADL14ConversionUtil(converter.getConversionConfiguration()).convertToUri(assumedValue);
assumedValue.setCodeString(findOrAddTermBindingAndCode(assumedValue, uri, termBindingsMap));
assumedValue.setTerminologyId(null);
assumedValue.setTerminologyVersion(null);
} catch (URISyntaxException e) {
logger.error("error converting term", e);
}
}
}

Expand Down Expand Up @@ -250,9 +278,9 @@ private ValueSet findOrCreateValueSet(Archetype archetype, Set<String> localCode
CObject cObject = cAttributeInParent.getChildren().get(0);
if(cObject instanceof CTerminologyCode) {
CTerminologyCode termCodeInParent = (CTerminologyCode) cObject;
if(termCodeInParent.getConstraint() != null && !termCodeInParent.getConstraint().isEmpty()) {
if(termCodeInParent.getConstraint().get(0).startsWith("ac")) {
idInparent = termCodeInParent.getConstraint().get(0);
if(termCodeInParent.getConstraint() != null) {
if(termCodeInParent.getConstraint().startsWith("ac")) {
idInparent = termCodeInParent.getConstraint();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@ private Set<String> gatherUsedValueSets(CAttribute attribute) {
Set<String> result = new LinkedHashSet<>();
for(CObject child:attribute.getChildren()) {
if(child instanceof CTerminologyCode) {
for(String constraint:((CTerminologyCode) child).getConstraint()) {
String constraint = ((CTerminologyCode) child).getConstraint();
if(constraint != null) {
if(constraint.startsWith("ac")) {
result.add(constraint);
}
Expand All @@ -215,7 +216,7 @@ private Set<String> gatherUsedValueSets(CAttribute attribute) {
for(CPrimitiveTuple primitiveTuple:tuple.getTuples()) {
CTerminologyCode cTermCode = (CTerminologyCode) primitiveTuple.getMember(symbolIndex);
if(cTermCode != null) {
atCodes.addAll(cTermCode.getConstraint());
atCodes.addAll(cTermCode.getConstraintAsList());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
import com.nedap.archie.base.Interval;
import com.nedap.archie.base.terminology.TerminologyCode;

import java.util.Arrays;

public class CDVOrdinalItem {

private Integer value;
Expand Down Expand Up @@ -35,7 +33,7 @@ public CTerminologyCode getSymbolAdl2() {
return null;
}
CTerminologyCode result = new CTerminologyCode();
result.setConstraint(Arrays.asList(symbol.toString()));
result.setConstraint(symbol.toString());
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ private CObject parseNonPrimitiveObject(C_non_primitive_objectContext objectCont
CTerminologyCode cCode = new CTerminologyCode();

TerminologyCode code = TerminologyCode.createFromString(ordinal_termContext.c_terminology_code().getText());
cCode.addConstraint(code.getCodeString());
cCode.setConstraint(code.getCodeString());

primitiveTuple.addMember(cValue);
primitiveTuple.addMember(cCode);
Expand Down Expand Up @@ -275,7 +275,7 @@ private void parseCDVQuantity(C_non_primitive_objectContext objectContext, CComp
CAttribute property = new CAttribute("property");
CTerminologyCode code = new CTerminologyCode();
//will be converted later
code.addConstraint(cdvQuantity.getProperty().toString());
code.setConstraint(cdvQuantity.getProperty().toString());
property.addChild(code);
result.addAttribute(property);
}
Expand Down
Loading