diff --git a/aom/src/main/java/com/nedap/archie/adl14/ADL14DefaultMultiplicitiesSetter.java b/aom/src/main/java/com/nedap/archie/adl14/ADL14DefaultMultiplicitiesSetter.java
index 4def296fb..8f158a48a 100644
--- a/aom/src/main/java/com/nedap/archie/adl14/ADL14DefaultMultiplicitiesSetter.java
+++ b/aom/src/main/java/com/nedap/archie/adl14/ADL14DefaultMultiplicitiesSetter.java
@@ -9,10 +9,10 @@
import com.nedap.archie.rminfo.MetaModels;
/**
- * Sets the default occurrences with ADL 1.4 rules, if not explicitly set in a given Archetype.
- * Useful for conversion to ADL 2, where the default values are different, and it is good to start
+ * Sets the default occurrences with ADL 1.4 rules ({1..1}), if not explicitly set in a given Archetype.
+ * Useful for conversion to ADL 2, where the default values are different ({0..*}), and it is good to start
* with the correct values already present.
- *
+ *
* Cardinality and existence are also specified to have a default value. However, this is not used
* in practice (source, several openEHR community members). Adding that to the conversion would
* lead to problems. So these are left out.
@@ -31,20 +31,9 @@ public void setDefaults(Archetype archetype) {
}
private void correctItemsMultiplicities(CObject cObject) {
- for(CAttribute attribute:cObject.getAttributes()) {
- // according to the specification, the following lines must be added.
- // however, in practice this is not followed, and adding it would
- // lead to more problems
- /*
- if(attribute.getCardinality() == null) {
- attribute.setCardinality(new Cardinality(0, 1));
- }
- if(attribute.getExistence() == null) {
- attribute.setExistence(new MultiplicityInterval(1, 1));
- }*/
- for(CObject child:attribute.getChildren()) {
- if(child.getOccurrences() == null &&
- metaModels.isMultiple(cObject.getRmTypeName(), attribute.getRmAttributeName())) {
+ for (CAttribute attribute : cObject.getAttributes()) {
+ for (CObject child : attribute.getChildren()) {
+ if (child.getOccurrences() == null && metaModels.isMultiple(cObject.getRmTypeName(), attribute.getRmAttributeName())) {
child.setOccurrences(new MultiplicityInterval(1, 1));
}
correctItemsMultiplicities(child);
diff --git a/aom/src/main/java/com/nedap/archie/adl14/ADL14DescriptionConverter.java b/aom/src/main/java/com/nedap/archie/adl14/ADL14DescriptionConverter.java
index 11d105214..d3da0474f 100644
--- a/aom/src/main/java/com/nedap/archie/adl14/ADL14DescriptionConverter.java
+++ b/aom/src/main/java/com/nedap/archie/adl14/ADL14DescriptionConverter.java
@@ -6,6 +6,11 @@
import java.util.LinkedHashMap;
import java.util.Map;
+/**
+ * Converts the Description section from ADL1.4 to ADL2
+ * Specifications ADL1.4
+ * Specifications ADL2
+ */
public class ADL14DescriptionConverter {
public void convert(Archetype archetype) {
@@ -44,12 +49,10 @@ public void convert(Archetype archetype) {
}
description.setIpAcknowledgements(acknowledgements);
}
-
String revision = description.getOtherDetails().remove("revision");
if(revision != null) {
archetype.getArchetypeId().setReleaseVersion(revision);
}
-
archetype.setGenerated(true);
}
}
diff --git a/aom/src/main/java/com/nedap/archie/adl14/ADL14NodeIDConverter.java b/aom/src/main/java/com/nedap/archie/adl14/ADL14NodeIDConverter.java
index 6a3120117..48ad8663d 100644
--- a/aom/src/main/java/com/nedap/archie/adl14/ADL14NodeIDConverter.java
+++ b/aom/src/main/java/com/nedap/archie/adl14/ADL14NodeIDConverter.java
@@ -4,14 +4,7 @@
import com.nedap.archie.adl14.log.ConvertedCodeResult;
import com.nedap.archie.adl14.log.CreatedCode;
import com.nedap.archie.adl14.log.ReasonForCodeCreation;
-import com.nedap.archie.aom.Archetype;
-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.CComplexObjectProxy;
-import com.nedap.archie.aom.CObject;
-import com.nedap.archie.aom.CPrimitiveObject;
+import com.nedap.archie.aom.*;
import com.nedap.archie.aom.primitives.CString;
import com.nedap.archie.aom.terminology.ArchetypeTerm;
import com.nedap.archie.aom.terminology.ValueSet;
@@ -21,19 +14,10 @@
import com.nedap.archie.paths.PathSegment;
import com.nedap.archie.query.APathQuery;
import com.nedap.archie.rminfo.MetaModels;
-import com.nedap.archie.rules.Assertion;
-import com.nedap.archie.rules.BinaryOperator;
-import com.nedap.archie.rules.Constraint;
-import com.nedap.archie.rules.Expression;
-import com.nedap.archie.rules.OperatorKind;
+import com.nedap.archie.rules.*;
import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -56,12 +40,10 @@ public class ADL14NodeIDConverter {
/**
* Contains a mapping between the adl 1.4 codes and the generated adl 2 code
*/
- private Map convertedCodes = new LinkedHashMap<>();
- private Map createdCodes = new LinkedHashMap<>();
- private Map createdValueSets = new LinkedHashMap<>();
-
- private Map newCodeToOldCodeMap = new LinkedHashMap<>();
-
+ private final Map convertedCodes = new LinkedHashMap<>();
+ private final Map createdCodes = new LinkedHashMap<>();
+ private final Map createdValueSets = new LinkedHashMap<>();
+ private final Map newCodeToOldCodeMap = new LinkedHashMap<>();
public ADL14NodeIDConverter(MetaModels metaModels, Archetype archetype, Archetype flatParentArchetype, ADL14ConversionConfiguration configuration, ADL2ConversionLog oldLog, ADL2ConversionResult conversionResult) {
this.metaModels = metaModels;
@@ -74,51 +56,52 @@ public ADL14NodeIDConverter(MetaModels metaModels, Archetype archetype, Archetyp
}
-
public ADL14ConversionConfiguration getConversionConfiguration() {
return conversionConfiguration;
}
public ADL2ConversionLog convert() {
metaModels.selectModel(archetype);
+
correctItemsCardinality(archetype.getDefinition());
List unnecessaryCodes = findUnnecessaryCodes(archetype.getDefinition(),
archetype.getTerminology().getTermDefinitions().get(archetype.getOriginalLanguage().getCodeString()));
convert(archetype.getDefinition());
- if(previousConversionApplier != null) {
- //tricky stuff here:
- //apply the previous conversion. This does 3 things:
- //1. add synthesized id codes in the same was as before
- //2. create previously synthesized term codes plus binding again
- //3. create previously created value sets again
- //These processes are not tricky in itself, but in what effect it has on the rest of the conversion process
- //for example, if you add an at-code to the term bindings here, it must not be converted again
- //this is done by keeping a log of converted codes in this class, and not converting any term bindings
- //unless they are in the converted codes.
- previousConversionApplier.addCreatedCodes();
- previousConversionApplier.addValueSets();
- }
+
+ //tricky stuff here:
+ //apply the previous conversion. This does 3 things:
+ //1. add synthesized id codes in the same was as before
+ //2. create previously synthesized term codes plus binding again
+ //3. create previously created value sets again
+ //These processes are not tricky in itself, but in what effect it has on the rest of the conversion process
+ //for example, if you add an at-code to the term bindings here, it must not be converted again
+ //this is done by keeping a log of converted codes in this class, and not converting any term bindings
+ //unless they are in the converted codes.
+ previousConversionApplier.addCreatedCodes();
+ previousConversionApplier.addValueSets();
this.idCodeGenerator = new OutsideRangeIdCodeGenerator(archetype);
termConstraintConverter.convert();
+
convertTermBindings(archetype);
generateMissingNodeIds(archetype.getDefinition());
-
convertTermDefinitions(archetype, convertedCodes, unnecessaryCodes);
previousConversionApplier.removeCreatedUnusedTermCodesAndValueSets();
return new ADL2ConversionLog(/*convertedCodes*/ null, createdCodes, createdValueSets);
}
+ /**
+ * Correct invalid CLUSTER.items cardinality, since for a cluster cardinality must be >= 1
+ */
private void correctItemsCardinality(CObject cObject) {
- for(CAttribute attribute:cObject.getAttributes()) {
- if(attribute.getRmAttributeName().equalsIgnoreCase("items") && cObject.getRmTypeName().equalsIgnoreCase("CLUSTER") && attribute.getCardinality() != null) {
+ for (CAttribute attribute : cObject.getAttributes()) {
+ if (attribute.getRmAttributeName().equalsIgnoreCase("items") && cObject.getRmTypeName().equalsIgnoreCase("CLUSTER") && attribute.getCardinality() != null) {
Cardinality cardinality = attribute.getCardinality();
- if(cardinality.getInterval().isUpperUnbounded() && cardinality.getInterval().getLower() == 0 && cardinality.getInterval().isLowerIncluded()) {
- //ok this is an invalid CLUSTER.items cardinality, since for a cluster this is apparently >= 1.
+ if (cardinality.getInterval().isUpperUnbounded() && cardinality.getInterval().getLower() == 0 && cardinality.getInterval().isLowerIncluded()) {
cardinality.getInterval().setLower(1);
}
}
- for(CObject child:attribute.getChildren()) {
+ for (CObject child : attribute.getChildren()) {
correctItemsCardinality(child);
}
}
@@ -127,10 +110,10 @@ private void correctItemsCardinality(CObject cObject) {
/**
* Find which node identifiers don't need to be in the archetype terminology in ADL2.
- *
+ *
* The identifiers of single object nodes defined under single-valued attributes don't need terminology definitions,
* so filter those which have a short text and "@ internal @" in the description in the original language.
- *
+ *
* @see ADL2 - 4.3.4.1. Node Identifiers
*/
private List findUnnecessaryCodes(CObject cObject, Map originalLanguageTermDefinitions) {
@@ -153,15 +136,18 @@ private List findUnnecessaryCodes(CObject cObject, Map convertedCodes, List unnecessaryCodes) {
//process the codes in alphabetical order, high to low, to prevent overwriting codes
//even better would probably be to create an empty terminology and separate all new+converted codes and old codes
//instead of doing this in place. Worth a refactor perhaps?
ArrayList sortedCodes = new ArrayList<>(convertedCodes.values());
- Comparator comparator = Comparator.comparing(r -> r.getOriginalCode());
+ Comparator comparator = Comparator.comparing(ConvertedCodeResult::getOriginalCode);
sortedCodes.sort(comparator.reversed());
- for(ConvertedCodeResult convertedCode: sortedCodes) {
+ for (ConvertedCodeResult convertedCode : sortedCodes) {
for (String language : archetype.getTerminology().getTermDefinitions().keySet()) {
Map terms = archetype.getTerminology().getTermDefinitions().get(language);
ArchetypeTerm term = terms.remove(convertedCode.getOriginalCode());
@@ -181,20 +167,24 @@ public static void convertTermDefinitions(Archetype archetype, Map> newTermBindings = new LinkedHashMap<>();
- for(String terminologyid: archetype.getTerminology().getTermBindings().keySet()) {
- Map termbindingMap = archetype.getTerminology().getTermBindings().get(terminologyid);
+ for (String terminologyId : archetype.getTerminology().getTermBindings().keySet()) {
+ Map termbindingMap = archetype.getTerminology().getTermBindings().get(terminologyId);
Map newTermbindingsMap = new LinkedHashMap<>();
- newTermBindings.put(terminologyid, newTermbindingsMap);
- for(String valueOrPath:termbindingMap.keySet()) {
- if(valueOrPath.startsWith("/")) {
+ newTermBindings.put(terminologyId, newTermbindingsMap);
+ for (String valueOrPath : termbindingMap.keySet()) {
+ if (valueOrPath.startsWith("/")) {
String newPath = convertPath(valueOrPath);
newTermbindingsMap.put(newPath, termbindingMap.get(valueOrPath));
} else if (AOMUtils.isValueCode(valueOrPath)) {
- if(convertedCodes.containsKey(valueOrPath)) {
- for(String newCode:convertedCodes.get(valueOrPath).getConvertedCodes()) {
+ if (convertedCodes.containsKey(valueOrPath)) {
+ for (String newCode : convertedCodes.get(valueOrPath).getConvertedCodes()) {
newTermbindingsMap.put(newCode, termbindingMap.get(valueOrPath));
}
} else {
@@ -203,17 +193,17 @@ private void convertTermBindings(Archetype archetype) {
conversionResult.getLog().addWarningWithLocation(ADL14ConversionMessageCode.WARNING_UNKNOWN_CODE_TYPE_IN_TERMBINDING, valueOrPath, valueOrPath);
}
} else if (AOMUtils.isValueSetCode(valueOrPath)) {
- if(convertedCodes.containsKey(valueOrPath)) {
- for(String newCode:convertedCodes.get(valueOrPath).getConvertedCodes()) {
+ if (convertedCodes.containsKey(valueOrPath)) {
+ for (String newCode : convertedCodes.get(valueOrPath).getConvertedCodes()) {
newTermbindingsMap.put(newCode, termbindingMap.get(valueOrPath));
}
} else {
//unused value set code, this can be converted
- newTermbindingsMap.put(this.convertCode(valueOrPath, "ac"), termbindingMap.get(valueOrPath));
+ newTermbindingsMap.put(convertCode(valueOrPath, "ac"), termbindingMap.get(valueOrPath));
}
} else if (AOMUtils.isIdCode(valueOrPath)) {
- if(convertedCodes.containsKey(valueOrPath)) {
- for(String newCode:convertedCodes.get(valueOrPath).getConvertedCodes()) {
+ if (convertedCodes.containsKey(valueOrPath)) {
+ for (String newCode : convertedCodes.get(valueOrPath).getConvertedCodes()) {
newTermbindingsMap.put(newCode, termbindingMap.get(valueOrPath));
}
} else {
@@ -231,28 +221,31 @@ private void convertTermBindings(Archetype archetype) {
}
}
+ /**
+ * Add missing node id's for CObjects, as long as they are not CPrimitiveObjects
+ */
private void generateMissingNodeIds(CObject cObject) {
- if(!(cObject instanceof CPrimitiveObject) && cObject.getNodeId() == null) {
+ if (!(cObject instanceof CPrimitiveObject) && cObject.getNodeId() == null) {
String path = cObject.getPath();
- if(archetype.getParentArchetypeId() != null && flatParentArchetype != null) {
+ if (archetype.getParentArchetypeId() != null && flatParentArchetype != null) {
//get the matching path in the parent archetype id. Find this node
//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 = AOMUtils.pathAtSpecializationLevel(cObject.getPathSegments(), archetype.specializationDepth() - 1);
CAttribute cAttributeInParent = flatParentArchetype.itemAtPath(parentPath);
- if(cAttributeInParent != null) {
- List childrenWithSameRmTypeName = cAttributeInParent.getChildrenByRmTypeName (cObject.getRmTypeName());
- if(childrenWithSameRmTypeName.size() == 1 ) {
+ if (cAttributeInParent != null) {
+ List childrenWithSameRmTypeName = cAttributeInParent.getChildrenByRmTypeName(cObject.getRmTypeName());
+ if (childrenWithSameRmTypeName.size() == 1) {
cObject.setNodeId(childrenWithSameRmTypeName.get(0).getNodeId());
- } else if(childrenWithSameRmTypeName.size() > 1 ) {
+ } else if (childrenWithSameRmTypeName.size() > 1) {
//this is a bit odd - it now specializes the first child it finds. Let's warn
synthesizeNodeId(cObject, path);
conversionResult.getLog().addWarningWithLocation(ADL14ConversionMessageCode.WARNING_SPECIALIZED_FIRST_MATCHING_CHILD, cObject.path());
} else if (cAttributeInParent.getChildren().size() == 1 || cObject.getParent().getChildren().size() == 1) {
- if(this.metaModels.rmTypesConformant(cObject.getRmTypeName(), cAttributeInParent.getChildren().get(0).getRmTypeName())) {
+ if (this.metaModels.rmTypesConformant(cObject.getRmTypeName(), cAttributeInParent.getChildren().get(0).getRmTypeName())) {
//this replaces a parent node, so a specialisation. add id code and possibly a term
createSpecialisedNodeId(cObject, path, Arrays.asList(cAttributeInParent.getChildren().get(0)));
} else {
@@ -269,17 +262,21 @@ private void generateMissingNodeIds(CObject cObject) {
} else {
synthesizeNodeId(cObject, path);
}
-
} else {
synthesizeNodeId(cObject, path);
}
}
- for(CAttribute attribute:cObject.getAttributes()) {
- generateMissingNodeIds(attribute);
+ for (CAttribute attribute : cObject.getAttributes()) {
+ for (CObject object : attribute.getChildren()) {
+ generateMissingNodeIds(object);
+ }
}
}
+ /**
+ * Object is a specialised node, create a specialised nodeId and add it to the terminology
+ */
private void createSpecialisedNodeId(CObject cObject, String path, List childrenWithSameRmTypeName) {
cObject.setNodeId(idCodeGenerator.generateNextSpecializedIdCode(childrenWithSameRmTypeName.get(0).getNodeId()));
CreatedCode createdCode = new CreatedCode(cObject.getNodeId(), ReasonForCodeCreation.C_OBJECT_WITHOUT_NODE_ID);
@@ -289,6 +286,9 @@ private void createSpecialisedNodeId(CObject cObject, String path, List
createTermForNewCode(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());
CreatedCode createdCode = new CreatedCode(cObject.getNodeId(), ReasonForCodeCreation.C_OBJECT_WITHOUT_NODE_ID);
@@ -298,12 +298,15 @@ private void synthesizeNodeId(CObject cObject, String path) {
createTermForNewCode(cObject);
}
+ /**
+ * Create an instance of the new nodeId to the terminology
+ */
private void createTermForNewCode(CObject cObject) {
- if(cObject.getParent().isMultiple()) {
- for(String language: archetype.getTerminology().getTermDefinitions().keySet()) {
+ if (cObject.getParent().isMultiple()) {
+ for (String language : archetype.getTerminology().getTermDefinitions().keySet()) {
//TODO: add new archetype term to conversion log?
ArchetypeTerm term = termConstraintConverter.getTerm(language, cObject);
- if(term != null) {
+ if (term != null) {
ArchetypeTerm newTerm = new ArchetypeTerm();
newTerm.setCode(cObject.getNodeId());
newTerm.setText(term.getText() + " (synthesised)");
@@ -322,42 +325,34 @@ protected void addCreatedValueSet(String nodeId, ValueSet valueSet) {
this.createdValueSets.put(nodeId, valueSet);
}
- private void generateMissingNodeIds(CAttribute attribute) {
- for(CObject cObject:attribute.getChildren()) {
- generateMissingNodeIds(cObject);
- }
- }
-
+ /**
+ * Convert node id's for cObject and all child objects within
+ */
private void convert(CObject cObject) {
-
- if(cObject instanceof CComplexObject) {
- if (cObject instanceof CArchetypeRoot) {
-
- }
+ if (cObject instanceof CComplexObject) {
calculateNewNodeId(cObject);
} else if (cObject instanceof ArchetypeSlot) {
-
calculateNewNodeId(cObject);
if (cObject.getNodeId() != null) {
//VSSID validation does not exist in ADL 1.4. Fix it here
- if(flatParentArchetype != null) {
+ if (flatParentArchetype != null) {
String parentPath = AOMUtils.pathAtSpecializationLevel(cObject.getPathSegments(), archetype.specializationDepth() - 1);
CObject cObjectInParent = flatParentArchetype.itemAtPath(parentPath);
- if (cObjectInParent != null && cObjectInParent instanceof ArchetypeSlot && !cObjectInParent.getNodeId().equalsIgnoreCase(cObject.getNodeId())) {
+ 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.
cObject.setNodeId(cObjectInParent.getNodeId());
//TODO: remove id code from terminology as well
}
}
ArchetypeSlot slot = (ArchetypeSlot) cObject;
- for(Assertion assertion:slot.getIncludes()) {
- if(assertion.getExpression() != null) {
+ for (Assertion assertion : slot.getIncludes()) {
+ if (assertion.getExpression() != null) {
fixArchetypeSlotExpression(assertion.getExpression());
}
}
- for(Assertion assertion:slot.getExcludes()) {
- if(assertion.getExpression() != null) {
+ for (Assertion assertion : slot.getExcludes()) {
+ if (assertion.getExpression() != null) {
fixArchetypeSlotExpression(assertion.getExpression());
}
}
@@ -367,14 +362,20 @@ private void convert(CObject cObject) {
calculateNewNodeId(cObject);
proxy.setTargetPath(convertPath(proxy.getTargetPath()));
}
- for(CAttribute attribute:cObject.getAttributes()) {
- convert(attribute);
+ for (CAttribute attribute : cObject.getAttributes()) {
+ for (CObject object : attribute.getChildren()) {
+ convert(object);
+ }
}
}
+ /**
+ * Fix archetype slot regex for version of archetype
+ * ADL1.4: \.v1
+ * ADL2: \.v1\..*
+ */
private static final Pattern ARCHETYPE_ID_ENDS_WITH_VERSION_PATTERN = Pattern.compile(".*v[0-9]+");
private static final Pattern ARCHETYPE_ID_ENDS_WITH_VERSION_PATTERN_REPLACE = Pattern.compile("(?\\.v[0-9]+)(?([\\|]|\\z))");//\z means end of input
-
private static void fixArchetypeSlotExpression(Expression expression) {
//match patterns in the form archetype_id/value matches {/regexp/} or archetype_id/value matches {"string"}
if (expression instanceof BinaryOperator) {
@@ -383,10 +384,10 @@ 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().size() > 0 &&
+ if (constraint.getItem() != null && constraint.getItem().getConstraint() != null && !constraint.getItem().getConstraint().isEmpty() &&
constraint.getItem() instanceof CString) {
CString cString = (CString) constraint.getItem();
- if(cString.getConstraint() == null || cString.getConstraint().isEmpty()) {
+ if (cString.getConstraint() == null || cString.getConstraint().isEmpty()) {
return;
}
String pattern = cString.getConstraint().get(0);
@@ -394,14 +395,14 @@ private static void fixArchetypeSlotExpression(Expression expression) {
//regexp
pattern = pattern.substring(1, pattern.length() - 1);
Matcher matcher = ARCHETYPE_ID_ENDS_WITH_VERSION_PATTERN_REPLACE.matcher(pattern);
- if(matcher.find()) {
+ if (matcher.find()) {
pattern = "/" + matcher.replaceAll("${version}\\\\..*${end}") + "/";
cString.getConstraint().remove(0);
cString.getConstraint().add(pattern);
}
} else {
//string instead of regexp. does this happen in any archetypes?
- if(ARCHETYPE_ID_ENDS_WITH_VERSION_PATTERN.matcher(pattern).matches()) {
+ if (ARCHETYPE_ID_ENDS_WITH_VERSION_PATTERN.matcher(pattern).matches()) {
cString.getConstraint().remove(0);
cString.getConstraint().add(pattern + ".*");
}
@@ -412,18 +413,13 @@ private static void fixArchetypeSlotExpression(Expression expression) {
}
}
-
-
-
-
+ /**
+ * If the object has a nodeId
+ * - 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 instanceof CComplexObject || cObject instanceof CArchetypeRoot || cObject instanceof ArchetypeSlot) {
- //will be calculated later
- } else if(cObject instanceof CPrimitiveObject){
- //done automatically
- }
- } else {
+ if (cObject.getNodeId() != null) {
String oldNodeId = cObject.getNodeId();
String newNodeId = convertNodeId(oldNodeId);
addConvertedCode(oldNodeId, newNodeId);
@@ -432,8 +428,11 @@ private void calculateNewNodeId(CObject cObject) {
}
}
+ /**
+ * Stores the old and new nodeIds in a map, so that all old nodeId can be converted into the same new nodeId
+ */
protected void addConvertedCode(String oldNodeId, String newNodeId) {
- if(convertedCodes.containsKey(oldNodeId)) {
+ if (convertedCodes.containsKey(oldNodeId)) {
convertedCodes.get(oldNodeId).addNewCode(newNodeId);
} else {
convertedCodes.put(oldNodeId, new ConvertedCodeResult(oldNodeId, newNodeId));
@@ -441,65 +440,75 @@ protected void addConvertedCode(String oldNodeId, String newNodeId) {
this.newCodeToOldCodeMap.put(newNodeId, oldNodeId);
}
+ /**
+ * Convert old code into an id code
+ */
public String convertNodeId(String oldNodeId) {
ConvertedCodeResult convertedCodeResult = convertedCodes.get(oldNodeId);
- if(convertedCodeResult != null && convertedCodeResult.hasIdCode()) {
+ if (convertedCodeResult != null && convertedCodeResult.hasIdCode()) {
return convertedCodeResult.getIdCode();
}
return convertCode(oldNodeId, "id");
}
+ /**
+ * Convert old code into an at code
+ */
protected String convertValueCode(String oldCode) {
ConvertedCodeResult convertedCodeResult = convertedCodes.get(oldCode);
- if(convertedCodeResult != null && convertedCodeResult.hasValueCode()) {
+ if (convertedCodeResult != null && convertedCodeResult.hasValueCode()) {
return convertedCodeResult.getValueCode();
}
return convertCode(oldCode, "at");
}
+ /**
+ * Convert old code into an ac code
+ */
public String convertValueSetCode(String oldCode) {
ConvertedCodeResult convertedCodeResult = convertedCodes.get(oldCode);
- if(convertedCodeResult != null && convertedCodeResult.hasValueCode()) {
+ if (convertedCodeResult != null && convertedCodeResult.hasValueCode()) {
return convertedCodeResult.getValueCode();
}
return convertCode(oldCode, "ac");
}
+ /**
+ * Convert old code into a code with prefix 'newCodePrefix'
+ * - Takes into account removing the leading zero's of the ADL1.4 codes
+ * - Takes into account that ADL1.4 starts with code 0 at the root and ADL2 starts with code 1
+ */
public static String convertCode(String oldCode, String newCodePrefix) {
NodeIdUtil nodeIdUtil = new NodeIdUtil(oldCode);
if (nodeIdUtil.getCodes().isEmpty()) {
return oldCode;
}
nodeIdUtil.setPrefix(newCodePrefix); //will automatically strip the leading zeroes due to integer-parsing
- if(!oldCode.startsWith("at0.") && !oldCode.startsWith("ac0.")) {
+ 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
}
return nodeIdUtil.toString();
}
- private void convert(CAttribute attribute) {
- for(CObject object:attribute.getChildren()) {
- convert(object);
- }
- }
-
+ /**
+ * Convert all old codes in a path in the new codes
+ */
public String convertPath(String key) {
APathQuery aPathQuery = new APathQuery(key);
- for(PathSegment segment:aPathQuery.getPathSegments()) {
- if(segment.getNodeId() != null) {
+ for (PathSegment segment : aPathQuery.getPathSegments()) {
+ if (segment.getNodeId() != null) {
segment.setNodeId(convertNodeId(segment.getNodeId()));
}
}
return aPathQuery.toString();
}
- public String getOldCodeForNewCode(String nodeId) {
- return this.newCodeToOldCodeMap.get(nodeId);
- }
-
- protected Archetype getFlatParentArchetype() {
- return flatParentArchetype;
+ /**
+ * Given the new nodeId, return the old code of this object
+ */
+ public String getOldCodeForNewCode(String newNodeId) {
+ return this.newCodeToOldCodeMap.get(newNodeId);
}
public ADL2ConversionResult getConversionResult() {
diff --git a/aom/src/main/java/com/nedap/archie/adl14/ADL14Parser.java b/aom/src/main/java/com/nedap/archie/adl14/ADL14Parser.java
index b032c3875..1e092e853 100644
--- a/aom/src/main/java/com/nedap/archie/adl14/ADL14Parser.java
+++ b/aom/src/main/java/com/nedap/archie/adl14/ADL14Parser.java
@@ -10,7 +10,7 @@
import com.nedap.archie.antlr.errors.ANTLRParserErrors;
import com.nedap.archie.antlr.errors.ArchieErrorListener;
import com.nedap.archie.aom.Archetype;
-import com.nedap.archie.aom.utils.ArchetypeParsePostProcesser;
+import com.nedap.archie.aom.utils.ArchetypeParsePostProcessor;
import com.nedap.archie.rminfo.MetaModels;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
@@ -74,7 +74,7 @@ public Archetype parse(CharStream stream, ADL14ConversionConfiguration conversio
walker = new ParseTreeWalker();
walker.walk(listener, tree);
result = listener.getArchetype();
- ArchetypeParsePostProcesser.fixArchetype(result);
+ ArchetypeParsePostProcessor.fixArchetype(result);
if (metaModels != null) {
metaModels.selectModel(result);
if (metaModels.getSelectedBmmModel() != null) {
diff --git a/aom/src/main/java/com/nedap/archie/adl14/ADL2ConversionResult.java b/aom/src/main/java/com/nedap/archie/adl14/ADL2ConversionResult.java
index 80aeb3654..5ed1bc82d 100644
--- a/aom/src/main/java/com/nedap/archie/adl14/ADL2ConversionResult.java
+++ b/aom/src/main/java/com/nedap/archie/adl14/ADL2ConversionResult.java
@@ -7,7 +7,7 @@
/**
* ADL 2 conversion result. Always has the archetypeId field set.
- * Either has archetype and conversionLog non-null in case of a succesful conversion, or
+ * Either has archetype and conversionLog non-null in case of a successful conversion, or
* exception non-null in case of an unexpected Exception
*/
public class ADL2ConversionResult {
@@ -18,24 +18,13 @@ public class ADL2ConversionResult {
private MessageLogger log;
private Exception exception;
- /**
- * empty constructor for JSON parsing. Do not use
- */
public ADL2ConversionResult() {
-
+ /* Empty construction for Jackson parsing */
}
public ADL2ConversionResult(Archetype archetype) {
- this.archetypeId = archetype.getArchetypeId().getFullId();
+ this(archetype.getArchetypeId().getFullId(), null);
this.archetype = archetype;
- log = new MessageLogger();
- }
-
- public ADL2ConversionResult(Archetype archetype, ADL2ConversionLog conversionLog) {
- this.archetypeId = archetype.getArchetypeId().getFullId();
- this.archetype = archetype;
- this.conversionLog = conversionLog;
- log = new MessageLogger();
}
public ADL2ConversionResult(String archetypeId, Exception exception) {
@@ -44,14 +33,11 @@ public ADL2ConversionResult(String archetypeId, Exception exception) {
log = new MessageLogger();
}
+ /** GETTERS **/
public String getArchetypeId() {
return archetypeId;
}
- public void setArchetypeId(String archetypeId) {
- this.archetypeId = archetypeId;
- }
-
public Archetype getArchetype() {
return archetype;
}
@@ -60,14 +46,6 @@ public ADL2ConversionLog getConversionLog() {
return conversionLog;
}
- public void setConversionLog(ADL2ConversionLog conversionLog) {
- this.conversionLog = conversionLog;
- }
-
- public void setArchetype(Archetype archetype) {
- this.archetype = archetype;
- }
-
public MessageLogger getLog() {
return log;
}
@@ -76,9 +54,12 @@ public Exception getException() {
return exception;
}
- public void setException(Exception exception) {
- this.exception = exception;
+ /** SETTERS **/
+ public void setArchetype(Archetype archetype) {
+ this.archetype = archetype;
}
-
+ public void setConversionLog(ADL2ConversionLog conversionLog) {
+ this.conversionLog = conversionLog;
+ }
}
diff --git a/aom/src/main/java/com/nedap/archie/adlparser/ADLParser.java b/aom/src/main/java/com/nedap/archie/adlparser/ADLParser.java
index addc9f75d..5f02a17c7 100644
--- a/aom/src/main/java/com/nedap/archie/adlparser/ADLParser.java
+++ b/aom/src/main/java/com/nedap/archie/adlparser/ADLParser.java
@@ -8,7 +8,7 @@
import com.nedap.archie.antlr.errors.ArchieErrorListener;
import com.nedap.archie.antlr.errors.ANTLRParserErrors;
import com.nedap.archie.aom.Archetype;
-import com.nedap.archie.aom.utils.ArchetypeParsePostProcesser;
+import com.nedap.archie.aom.utils.ArchetypeParsePostProcessor;
import com.nedap.archie.rminfo.MetaModels;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.*;
@@ -97,7 +97,7 @@ public Archetype parse(CharStream stream) throws ADLParseException {
walker.walk(listener, tree);
result = listener.getArchetype();
//set some values that are not directly in ODIN or ADL
- ArchetypeParsePostProcesser.fixArchetype(result);
+ ArchetypeParsePostProcessor.fixArchetype(result);
if (modelConstraintImposer != null && result.getDefinition() != null) {
modelConstraintImposer.imposeConstraints(result.getDefinition());
diff --git a/aom/src/main/java/com/nedap/archie/aom/Archetype.java b/aom/src/main/java/com/nedap/archie/aom/Archetype.java
index 583ecf964..8d85292f7 100644
--- a/aom/src/main/java/com/nedap/archie/aom/Archetype.java
+++ b/aom/src/main/java/com/nedap/archie/aom/Archetype.java
@@ -9,7 +9,7 @@
import com.nedap.archie.aom.terminology.ArchetypeTerminology;
import com.nedap.archie.aom.terminology.ValueSet;
import com.nedap.archie.aom.utils.AOMUtils;
-import com.nedap.archie.aom.utils.ArchetypeParsePostProcesser;
+import com.nedap.archie.aom.utils.ArchetypeParsePostProcessor;
import com.nedap.archie.definitions.AdlCodeDefinitions;
import com.nedap.archie.query.AOMPathQuery;
import com.nedap.archie.rminfo.RMProperty;
@@ -236,7 +236,7 @@ public Archetype clone() {
Archetype result = (Archetype) super.clone();
//fix some things that are not handled automatically
- ArchetypeParsePostProcesser.fixArchetype(result);
+ ArchetypeParsePostProcessor.fixArchetype(result);
return result;
}
diff --git a/aom/src/main/java/com/nedap/archie/aom/utils/ArchetypeParsePostProcesser.java b/aom/src/main/java/com/nedap/archie/aom/utils/ArchetypeParsePostProcessor.java
similarity index 76%
rename from aom/src/main/java/com/nedap/archie/aom/utils/ArchetypeParsePostProcesser.java
rename to aom/src/main/java/com/nedap/archie/aom/utils/ArchetypeParsePostProcessor.java
index e36308764..b3cb6187f 100644
--- a/aom/src/main/java/com/nedap/archie/aom/utils/ArchetypeParsePostProcesser.java
+++ b/aom/src/main/java/com/nedap/archie/aom/utils/ArchetypeParsePostProcessor.java
@@ -16,10 +16,10 @@
/**
* Sets some values that are not directly in ADL or ODIN, such as original language in terminology, etc.
*/
-public class ArchetypeParsePostProcesser {
+public class ArchetypeParsePostProcessor {
public static void fixArchetype(Archetype archetype) {
- if(archetype.getTerminology() != null) {
+ if (archetype.getTerminology() != null) {
ArchetypeTerminology terminology = archetype.getTerminology();
//codes are in model, but do not appear in odin. Set them here
fillArchetypeTermCodes(terminology.getTermDefinitions());
@@ -37,33 +37,33 @@ public static void fixArchetype(Archetype archetype) {
private static void setParents(Archetype archetype) {
Stack workList = new Stack<>();
workList.add(archetype.getDefinition());
- while(!workList.empty()) {
+ while (!workList.empty()) {
CObject cObject = workList.pop();
- if(cObject instanceof CPrimitiveObject) {
+ if (cObject instanceof CPrimitiveObject) {
cObject.setNodeId("id9999");//also in the implementation, but check to be sure
}
- for(CAttribute attribute:cObject.getAttributes()) {
+ for (CAttribute attribute : cObject.getAttributes()) {
attribute.setParent(cObject);
- for(CObject child:attribute.getChildren()) {
+ for (CObject child : attribute.getChildren()) {
child.setParent(attribute);
}
workList.addAll(attribute.getChildren());
}
- if(cObject instanceof CComplexObject) {
+ if (cObject instanceof CComplexObject) {
//TODO: fix tuple so it has proper multiple references to the separate structures, instead of a complete duplication of data in json
CComplexObject cComplexObject = (CComplexObject) cObject;
- for(CAttributeTuple tuple: cComplexObject.getAttributeTuples()) {
- for(CAttribute attribute:tuple.getMembers()) {
+ for (CAttributeTuple tuple : cComplexObject.getAttributeTuples()) {
+ for (CAttribute attribute : tuple.getMembers()) {
attribute.setSocParent(tuple);
attribute.setParent(cObject);
workList.addAll(attribute.getChildren());
cComplexObject.replaceAttribute(attribute);
}
- for(CPrimitiveTuple primitiveTuple:tuple.getTuples()) {
+ for (CPrimitiveTuple primitiveTuple : tuple.getTuples()) {
int index = 0;
- for(CPrimitiveObject, ?> object:primitiveTuple.getMembers()) {
- if(index < tuple.getMembers().size()) {
+ for (CPrimitiveObject, ?> object : primitiveTuple.getMembers()) {
+ if (index < tuple.getMembers().size()) {
CAttribute attribute = tuple.getMember(index);
object.setSocParent(primitiveTuple);
object.setParent(attribute);
@@ -79,9 +79,9 @@ private static void setParents(Archetype archetype) {
}
private static void fillArchetypeTermCodes(Map> termSet) {
- if(termSet != null) {
- for(Map language:termSet.values()) {
- for(String term:language.keySet()) {
+ if (termSet != null) {
+ for (Map language : termSet.values()) {
+ for (String term : language.keySet()) {
language.get(term).setCode(term);
}
}
diff --git a/tools/src/main/java/com/nedap/archie/adl14/ADL14Converter.java b/tools/src/main/java/com/nedap/archie/adl14/ADL14Converter.java
index 90a03d055..c816c628e 100644
--- a/tools/src/main/java/com/nedap/archie/adl14/ADL14Converter.java
+++ b/tools/src/main/java/com/nedap/archie/adl14/ADL14Converter.java
@@ -2,13 +2,11 @@
import com.nedap.archie.adl14.log.ADL2ConversionLog;
import com.nedap.archie.adl14.log.ADL2ConversionRunLog;
-import com.nedap.archie.terminology.OpenEHRTerminologyAccess;
-import com.nedap.archie.terminology.TerminologyAccess;
import com.nedap.archie.aom.Archetype;
import com.nedap.archie.aom.ResourceDescription;
import com.nedap.archie.aom.Template;
import com.nedap.archie.aom.TemplateOverlay;
-import com.nedap.archie.aom.utils.ArchetypeParsePostProcesser;
+import com.nedap.archie.aom.utils.ArchetypeParsePostProcessor;
import com.nedap.archie.diff.Differentiator;
import com.nedap.archie.flattener.Flattener;
import com.nedap.archie.flattener.InMemoryFullArchetypeRepository;
@@ -23,48 +21,30 @@
public class ADL14Converter {
private final MetaModels metaModels;
- private TerminologyAccess terminologyAccess = OpenEHRTerminologyAccess.getInstance();
private final ADL14ConversionConfiguration conversionConfiguration;
- private InMemoryFullArchetypeRepository existingRepository;
public ADL14Converter(MetaModels metaModels, ADL14ConversionConfiguration conversionConfiguration) {
this.metaModels = metaModels;
this.conversionConfiguration = conversionConfiguration;
}
-
- /**
- * Set the base repository for this converter. If you don't set it yourself, the converter will create an empty repository.
- * The archetypes in the repository will be used as base archetypes, but will not be converted themselves. Please
- * note that this repository will be modified, it will have all the converted archetypes added to it!
- *
- * @param existingRepository the existing repository to use
- */
- public void setExistingRepository(InMemoryFullArchetypeRepository existingRepository) {
- this.existingRepository = existingRepository;
- }
-
public ADL2ConversionResultList convert(List archetypes) {
return convert(archetypes, null);
}
public ADL2ConversionResultList convert(List archetypes, ADL2ConversionRunLog previousConversion) {
ADL2ConversionResultList resultList = new ADL2ConversionResultList();
-
- InMemoryFullArchetypeRepository repository = existingRepository;
- if(repository == null) {
- repository = new InMemoryFullArchetypeRepository();
- }
+ InMemoryFullArchetypeRepository repository = new InMemoryFullArchetypeRepository();
List unprocessed = new ArrayList<>(archetypes);
+ // ADL 1.4 does not really have templates. This code is here for the Better Care template conversion
+ // also it can be used to write our own template converter later.
+ // So add the overlays in the right order here
List templateOverlays = new ArrayList<>();
- for(Archetype ar:unprocessed) {
- //ADL 1.4 does not really have templates. This code is here for the Better Care template conversion
- //also it can be used to write our own template converter later.
- //So add the overlays in the right order here
- if(ar instanceof Template) {
- Template t = (Template) ar;
- for(TemplateOverlay overlay:t.getTemplateOverlays()) {
+ for (Archetype archetype : unprocessed) {
+ if (archetype instanceof Template) {
+ Template t = (Template) archetype;
+ for (TemplateOverlay overlay : t.getTemplateOverlays()) {
templateOverlays.add(overlay);
overlay.setRmRelease(t.getRmRelease());
}
@@ -72,24 +52,22 @@ public ADL2ConversionResultList convert(List archetypes, ADL2Conversi
}
unprocessed.addAll(templateOverlays);
- //process the archetypes ordered by specialization level
- unprocessed.sort(Comparator.comparingInt(a -> a.specializationDepth()));
+ // Process the archetypes ordered by specialization level
+ unprocessed.sort(Comparator.comparingInt(Archetype::specializationDepth));
Differentiator differentiator = new Differentiator(metaModels);
- for(Archetype archetype:unprocessed) {
-
- ADL2ConversionResult result = null;
+ for (Archetype archetype : unprocessed) {
+ ADL2ConversionResult result;
try {
if (archetype.getParentArchetypeId() != null) {
-
Archetype parent = repository.getArchetype(archetype.getParentArchetypeId());
- if(parent == null) {
+ if (parent == null) {
throw new RuntimeException(MessageFormat.format("Cannot find parent {0} for archetype {1}", archetype.getParentArchetypeId(), archetype.getArchetypeId()));
}
Archetype flatParent = new Flattener(repository, metaModels).flatten(parent);
result = convert(archetype, flatParent, previousConversion);
if (result.getArchetype() != null) {
- if(conversionConfiguration.isApplyDiff()) {
+ if (conversionConfiguration.isApplyDiff()) {
result.setArchetype(differentiator.differentiate(result.getArchetype(), flatParent, true));
} else {
result.setArchetype(differentiator.differentiate(result.getArchetype(), flatParent, false));
@@ -100,7 +78,7 @@ public ADL2ConversionResultList convert(List archetypes, ADL2Conversi
result = convert(archetype, previousConversion);
resultList.addConversionResult(result);
}
- if(result != null && result.getArchetype() != null && result.getArchetype().getArchetypeId() != null) {
+ if (result.getArchetype() != null && result.getArchetype().getArchetypeId() != null) {
repository.addArchetype(result.getArchetype());
}
} catch (Exception e) {
@@ -108,76 +86,82 @@ public ADL2ConversionResultList convert(List archetypes, ADL2Conversi
resultList.addConversionResult(result);
}
}
-
-
return resultList;
}
-
- private ADL2ConversionResult convert(Archetype archetype, ADL2ConversionRunLog previousConversion) {
+ private ADL2ConversionResult convert(Archetype archetype, ADL2ConversionRunLog previousConversion) {
return convert(archetype, null, previousConversion);
}
private ADL2ConversionResult convert(Archetype archetype, Archetype flatParent, ADL2ConversionRunLog previousConversion) {
ADL2ConversionLog previousLog = previousConversion == null ? null : previousConversion.getConversionLog(archetype.getArchetypeId().getSemanticId());
Archetype convertedArchetype = archetype.clone();
+
+ // Convert description section
new ADL14DescriptionConverter().convert(convertedArchetype);
+
+ // Convert or correct adl, rm and archetypeId versions
setCorrectVersions(convertedArchetype);
+
+ // Convert header section
convertHeader(convertedArchetype);
- addDefaultMultiplicities(convertedArchetype);
+ // Correct default multiplicities
+ new ADL14DefaultMultiplicitiesSetter(metaModels).setDefaults(convertedArchetype);
+ // Convert nodeId's
ADL2ConversionResult result = new ADL2ConversionResult(convertedArchetype);
ADL14NodeIDConverter adl14NodeIDConverter = new ADL14NodeIDConverter(this.metaModels, convertedArchetype, flatParent, conversionConfiguration, previousLog, result);
- ADL2ConversionLog conversionLog = adl14NodeIDConverter.convert();//fixes archetype in place
+ ADL2ConversionLog conversionLog = adl14NodeIDConverter.convert();
result.setConversionLog(conversionLog);
- //ADL 1.4 has cardinality, existence and occurrences always present, in ADL 2 they can be removed if same as default.
- //so remove them
+ // Remove structures that are not default in ADL1.4, but are default in ADL2
new DefaultRmStructureRemover(metaModels, true).removeRMDefaults(convertedArchetype);
- //set some values that are not directly in ODIN or ADL
- ArchetypeParsePostProcesser.fixArchetype(convertedArchetype);
+
+ // Set some values that are not directly in ODIN or ADL
+ ArchetypeParsePostProcessor.fixArchetype(convertedArchetype);
return result;
+ }
+ /**
+ * Set correct ADL and RM version for the archetype
+ * Add minor and patch version to archetypeId if minor version is not set in ADL1.4
+ */
+ private void setCorrectVersions(Archetype convertedArchetype) {
+ convertedArchetype.setAdlVersion("2.0.6");
+ convertedArchetype.setRmRelease(conversionConfiguration.getRmRelease());
+ if (convertedArchetype.getArchetypeId().getMinorVersion() == null) {
+ convertedArchetype.getArchetypeId().setReleaseVersion(convertedArchetype.getArchetypeId().getReleaseVersion() + ".0.0");
+ }
}
+ /**
+ * Move Uid and BuildUid to OtherDetails oid and build_oid respectively
+ */
private void convertHeader(Archetype convertedArchetype) {
- if(convertedArchetype.getUid() != null) {
- //if UID is in OID syntax, move it to the description
- if(convertedArchetype.getUid().matches("[0-9]+(\\.[0-9]+)+")) {
+ if (convertedArchetype.getUid() != null) {
+ // If UID is in OID syntax, move it to the description
+ if (convertedArchetype.getUid().matches("[0-9]+(\\.[0-9]+)+")) {
moveOidToMetadata(convertedArchetype, convertedArchetype.getUid(), "oid");
convertedArchetype.setUid(null);
}
}
- if(convertedArchetype.getBuildUid() != null) {
- if(convertedArchetype.getBuildUid().matches("[0-9]+\\.([0-9]+)+")) {
+ if (convertedArchetype.getBuildUid() != null) {
+ if (convertedArchetype.getBuildUid().matches("[0-9]+\\.([0-9]+)+")) {
moveOidToMetadata(convertedArchetype, convertedArchetype.getBuildUid(), "build_oid");
convertedArchetype.setBuildUid(null);
}
}
}
- private void addDefaultMultiplicities(Archetype convertedArchetype) {
- new ADL14DefaultMultiplicitiesSetter(metaModels).setDefaults(convertedArchetype);
- }
-
private void moveOidToMetadata(Archetype convertedArchetype, String oid, String oidFieldName) {
- if(convertedArchetype.getDescription() == null) {
+ if (convertedArchetype.getDescription() == null) {
convertedArchetype.setDescription(new ResourceDescription());
}
- if(convertedArchetype.getDescription().getOtherDetails() == null) {
+ if (convertedArchetype.getDescription().getOtherDetails() == null) {
convertedArchetype.getDescription().setOtherDetails(new LinkedHashMap<>());
}
convertedArchetype.getDescription().getOtherDetails().put(oidFieldName, oid);
}
-
-
- private void setCorrectVersions(Archetype result) {
- result.setAdlVersion("2.0.6");
- result.setRmRelease(conversionConfiguration.getRmRelease());
- if(result.getArchetypeId().getMinorVersion() == null) {
- result.getArchetypeId().setReleaseVersion(result.getArchetypeId().getReleaseVersion() + ".0.0");
- }
- }
}
diff --git a/tools/src/main/java/com/nedap/archie/adl14/DefaultRmStructureRemover.java b/tools/src/main/java/com/nedap/archie/adl14/DefaultRmStructureRemover.java
index 9298eedc8..3e423412e 100644
--- a/tools/src/main/java/com/nedap/archie/adl14/DefaultRmStructureRemover.java
+++ b/tools/src/main/java/com/nedap/archie/adl14/DefaultRmStructureRemover.java
@@ -17,28 +17,19 @@
*
* - attribute cardinality and existence that is exactly the attribute default
* - C_OBJECT occurrences that are exactly the default of the C_OBJECT
- * - Optionally removed attributes that are empty (without existence, cardinality or childreN) after removing default cardinality and existence,
+ * - Optionally removed attributes that are empty (without existence, cardinality or children) after removing default cardinality and existence
*
- *
*/
public class DefaultRmStructureRemover {
private final MetaModels metaModels;
+ private final boolean removeEmptyAttributes;
private BMMConstraintImposer constraintImposer;
- private boolean removeEmptyAttributes = false;
-
- /**
- * Construct a DefaultRmStructureRemover that does not remove empty attributes
- * @param metaModels the metamodels containing metamodel information for the preseted archetypes
- */
- public DefaultRmStructureRemover(MetaModels metaModels) {
- this(metaModels, false);
- }
-
/**
* Construct a DefaultRmStructureRemover
- * @param metaModels the metamodels containing metamodel information for the preseted archetypes
+ *
+ * @param metaModels the metamodels containing metamodel information for the preset archetypes
* @param removeEmptyAttributes if true, will remove empty attributes. If false, will not
*/
public DefaultRmStructureRemover(MetaModels metaModels, boolean removeEmptyAttributes) {
@@ -46,35 +37,32 @@ public DefaultRmStructureRemover(MetaModels metaModels, boolean removeEmptyAttri
this.removeEmptyAttributes = removeEmptyAttributes;
}
- public void setRemoveEmptyAttributes(boolean removeEmptyAttributes) {
- this.removeEmptyAttributes = removeEmptyAttributes;
- }
-
public void removeRMDefaults(Archetype archetype) {
this.metaModels.selectModel(archetype);
- if(metaModels.getSelectedModel() == null) {
+ if (metaModels.getSelectedModel() == null) {
throw new IllegalArgumentException("cannot find model for argument, so cannot remove default multiplicity");
}
-
this.constraintImposer = new BMMConstraintImposer(metaModels.getSelectedBmmModel());
removeRMDefaults(archetype.getDefinition());
}
private void removeRMDefaults(CObject object) {
- if(object.getOccurrences() != null) {
+ // Remove occurrences if they are equal to the default occurrences of the object
+ if (object.getOccurrences() != null) {
MultiplicityInterval defaultRMOccurrences = object.getDefaultRMOccurrences(metaModels::referenceModelPropMultiplicity);
- if(defaultRMOccurrences.equals(object.getOccurrences())) {
+ if (defaultRMOccurrences.equals(object.getOccurrences())) {
object.setOccurrences(null);
}
}
- if(object instanceof CComplexObject) {
- CComplexObject complexObject = (CComplexObject) object;
+ // Remove default multiplicities of attributes
+ if (object instanceof CComplexObject) {
+ CComplexObject complexObject = (CComplexObject) object;
List attributesToRemove = new ArrayList<>();
for (CAttribute attribute : object.getAttributes()) {
removeMultiplicities(attribute);
- if(removeEmptyAttributes) {
- //remove all empty attributes. They are 'attribute matches {*}' in ADL 1.4, and should not be present in ADL 2
+ if (removeEmptyAttributes) {
+ // Remove all empty attributes. They are 'attribute matches {*}' in ADL 1.4, and should not be present in ADL 2
if (attribute.getCardinality() == null && attribute.getExistence() == null && (attribute.getChildren() == null || attribute.getChildren().isEmpty())) {
if (!isInTuple(complexObject, attribute)) {
attributesToRemove.add(attribute);
@@ -82,43 +70,43 @@ private void removeRMDefaults(CObject object) {
}
}
}
-
for (CAttribute attributeToRemove : attributesToRemove) {
complexObject.removeAttribute(attributeToRemove);
}
}
-
- }
-
- private boolean isInTuple(CComplexObject complexObject, CAttribute attribute) {
- if(complexObject.getAttributeTuples() == null) {
- return false;
- }
- for(CAttributeTuple tuple:complexObject.getAttributeTuples()) {
- if(tuple.getMember(attribute.getRmAttributeName()) != null) {
- return true;
- }
- }
- return false;
}
private void removeMultiplicities(CAttribute attribute) {
+ // Remove existence and cardinality if they are equal to the default existence and cardinality of the attribute
CAttribute defaultAttribute = constraintImposer.getDefaultAttribute(attribute.getParent().getRmTypeName(), attribute.getRmAttributeName());
- if(attribute.getExistence() != null) {
- if(defaultAttribute != null && defaultAttribute.getExistence() != null && defaultAttribute.getExistence().equals(attribute.getExistence())) {
+ if (attribute.getExistence() != null) {
+ if (defaultAttribute != null && defaultAttribute.getExistence() != null && defaultAttribute.getExistence().equals(attribute.getExistence())) {
attribute.setExistence(null);
}
}
- if(attribute.getCardinality() != null) {
- if(defaultAttribute != null && defaultAttribute.getCardinality() != null) {
- if(defaultAttribute.getCardinality().equals(attribute.getCardinality())) {
+ if (attribute.getCardinality() != null) {
+ if (defaultAttribute != null && defaultAttribute.getCardinality() != null) {
+ if (defaultAttribute.getCardinality().equals(attribute.getCardinality())) {
attribute.setCardinality(null);
}
}
}
- for(CObject child:attribute.getChildren()) {
+
+ // Remove default occurrences of child objects
+ for (CObject child : attribute.getChildren()) {
removeRMDefaults(child);
}
+ }
+ private boolean isInTuple(CComplexObject complexObject, CAttribute attribute) {
+ if (complexObject.getAttributeTuples() == null) {
+ return false;
+ }
+ for (CAttributeTuple tuple : complexObject.getAttributeTuples()) {
+ if (tuple.getMember(attribute.getRmAttributeName()) != null) {
+ return true;
+ }
+ }
+ return false;
}
}
diff --git a/tools/src/main/java/com/nedap/archie/flattener/Flattener.java b/tools/src/main/java/com/nedap/archie/flattener/Flattener.java
index b5d0ccc6a..bec34e4f1 100644
--- a/tools/src/main/java/com/nedap/archie/flattener/Flattener.java
+++ b/tools/src/main/java/com/nedap/archie/flattener/Flattener.java
@@ -2,7 +2,7 @@
import com.nedap.archie.adlparser.modelconstraints.ReflectionConstraintImposer;
import com.nedap.archie.aom.*;
-import com.nedap.archie.aom.utils.ArchetypeParsePostProcesser;
+import com.nedap.archie.aom.utils.ArchetypeParsePostProcessor;
import com.nedap.archie.rminfo.MetaModels;
import com.nedap.archie.rminfo.ReferenceModels;
import org.openehr.bmm.v2.validation.BmmRepository;
@@ -220,7 +220,7 @@ public Archetype flatten(Archetype toFlatten) {
flatOverlay.setDescription(description);
flatOverlay.setOriginalLanguage(result.getOriginalLanguage());
flatOverlay.setTranslationList(result.getTranslationList());
- ArchetypeParsePostProcesser.fixArchetype(flatOverlay);
+ ArchetypeParsePostProcessor.fixArchetype(flatOverlay);
resultTemplate.getTemplateOverlays().add(flatOverlay);
}
}
@@ -230,7 +230,7 @@ public Archetype flatten(Archetype toFlatten) {
result.setDifferential(false);//mark this archetype as being flat
result.setGenerated(true);
- ArchetypeParsePostProcesser.fixArchetype(result);
+ ArchetypeParsePostProcessor.fixArchetype(result);
//set the single/multiple attributes correctly
new ReflectionConstraintImposer(metaModels.getSelectedModel())
diff --git a/tools/src/test/java/com/nedap/archie/json/flat/ArchetypeParsePostProcessorTest.java b/tools/src/test/java/com/nedap/archie/json/flat/ArchetypeParsePostProcessorTest.java
index bb7c04287..9636abb0a 100644
--- a/tools/src/test/java/com/nedap/archie/json/flat/ArchetypeParsePostProcessorTest.java
+++ b/tools/src/test/java/com/nedap/archie/json/flat/ArchetypeParsePostProcessorTest.java
@@ -1,7 +1,7 @@
package com.nedap.archie.json.flat;
import com.nedap.archie.aom.*;
-import com.nedap.archie.aom.utils.ArchetypeParsePostProcesser;
+import com.nedap.archie.aom.utils.ArchetypeParsePostProcessor;
import com.nedap.archie.json.ArchieJacksonConfiguration;
import com.nedap.archie.json.JacksonUtil;
import org.junit.Test;
@@ -16,7 +16,7 @@ public void setTupleParents() throws Exception {
ArchieJacksonConfiguration config = ArchieJacksonConfiguration.createConfigForJavascriptUsage();
try(InputStream stream = getClass().getResourceAsStream("/com/nedap/archie/json/snaq_rc_opt.js")) {
OperationalTemplate template = JacksonUtil.getObjectMapper(config).readValue(stream, OperationalTemplate.class);
- ArchetypeParsePostProcesser.fixArchetype(template);
+ ArchetypeParsePostProcessor.fixArchetype(template);
CComplexObject dvOrdinal = template.itemAtPath("/content[id0.0.100.1]/data[id2]/events[id3]/data[id4]/items[id15]/value[id25]");
CAttributeTuple tuple = dvOrdinal.getAttributeTuples().get(0);
for(CAttribute tupleMember:tuple.getMembers()) {