Skip to content

Commit

Permalink
Remove annotations of objects that are removed in Flattened archetype (
Browse files Browse the repository at this point in the history
…#615)

* remove annotations when objects are removed because of zero occurrences

* Also remove annotations for objects that are prohibited, but are not removed

* Add test

* add test

* add tests for coverage
  • Loading branch information
VeraPrinsen authored Aug 8, 2024
1 parent 0e79616 commit 148b979
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 11 deletions.
6 changes: 3 additions & 3 deletions tools/src/main/java/com/nedap/archie/flattener/Flattener.java
Original file line number Diff line number Diff line change
Expand Up @@ -253,12 +253,14 @@ private void prohibitZeroOccurrencesConstraints(Archetype archetype) {
CObject object = workList.pop();
for(CAttribute attribute:object.getAttributes()) {
if(attribute.getExistence() != null && attribute.getExistence().getUpper() == 0 && !attribute.getExistence().isUpperUnbounded()) {
//remove children, but do not remove attribute itself to make sure it stays prohibited
// Remove children, but do not remove attribute itself to make sure it stays prohibited
FlattenerUtil.removeAnnotationsForArchetypeConstraints(archetype, attribute.getChildren());
attribute.setChildren(new ArrayList<>());
} else {
List<CObject> objectsToRemove = new ArrayList<>();
for (CObject child : attribute.getChildren()) {
if (!child.isAllowed()) {
FlattenerUtil.removeAnnotationsForArchetypeConstraints(archetype, List.of(child));
if(child instanceof CComplexObject) {
((CComplexObject) child).setAttributes(new ArrayList<>());
}
Expand All @@ -271,9 +273,7 @@ private void prohibitZeroOccurrencesConstraints(Archetype archetype) {
}
attribute.getChildren().removeAll(objectsToRemove);
}

}

}
}

Expand Down
33 changes: 30 additions & 3 deletions tools/src/main/java/com/nedap/archie/flattener/FlattenerUtil.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package com.nedap.archie.flattener;

import com.nedap.archie.aom.CObject;
import com.nedap.archie.aom.Archetype;
import com.nedap.archie.aom.ArchetypeConstraint;
import com.nedap.archie.rules.Assertion;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class FlattenerUtil {



public static List<Assertion> getPossiblyOverridenListValue(List<Assertion> parent, List<Assertion> child) {
if(child != null && !child.isEmpty()) {
return child;
Expand All @@ -22,4 +23,30 @@ public static <T> T getPossiblyOverridenValue(T parent, T specialized) {
}
return parent;
}

/**
* Removes annotations for the objects given, also removes annotations for children underneath the objects.
*/
public static void removeAnnotationsForArchetypeConstraints(Archetype result, List<? extends ArchetypeConstraint> archetypeConstraints) {
if (result.getAnnotations() == null ||
result.getAnnotations().getDocumentation() == null ||
result.getAnnotations().getDocumentation().isEmpty() ||
archetypeConstraints.isEmpty()
) {
return;
}

removeAnnotationsForPaths(result.getAnnotations().getDocumentation(), archetypeConstraints.stream().map(ArchetypeConstraint::getPath).collect(Collectors.toList()));
}

private static void removeAnnotationsForPaths(Map<String, Map<String, Map<String, String>>> annotations, List<String> pathsToRemove) {
for (String pathToRemove : pathsToRemove) {
for (String languageKeys : annotations.keySet()) {
Map<String, Map<String, String>> languageAnnotations = annotations.get(languageKeys);
List<String> toRemove = languageAnnotations.keySet().stream().filter(path -> path.startsWith(pathToRemove)).collect(Collectors.toList());
toRemove.forEach(languageAnnotations::remove);
}

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,12 @@ public void removeZeroOccurrencesConstraints(Archetype archetype) {
}
workList.push(child);
}
FlattenerUtil.removeAnnotationsForArchetypeConstraints(archetype, objectsToRemove);
attribute.getChildren().removeAll(objectsToRemove);
}

}
FlattenerUtil.removeAnnotationsForArchetypeConstraints(archetype, attributesToRemove);
object.getAttributes().removeAll(attributesToRemove);
}
}
Expand Down Expand Up @@ -262,8 +264,4 @@ private void fillArchetypeRoot(CArchetypeRoot root, OperationalTemplate result)
private FlattenerConfiguration getConfig() {
return flattener.getConfiguration();
}




}
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package com.nedap.archie.flattener;

import com.nedap.archie.adlparser.ADLParser;
import com.nedap.archie.aom.Archetype;
import com.nedap.archie.aom.ResourceAnnotations;
import com.nedap.archie.rminfo.ReferenceModels;
import com.nedap.archie.aom.Archetype;
import org.junit.Before;
import org.junit.Test;
import org.openehr.referencemodels.BuiltinReferenceModels;

import java.util.HashMap;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

public class AnnotationsFlattenerTest {

Expand Down Expand Up @@ -105,4 +108,68 @@ public void flattenUsedArchetypeWithAnnotations() throws Exception {
assertEquals("this is a design note on intelerance", annotations.getDocumentation().get("en").get("/data[id2]/events[id3]/data[id4]/items[id6]").get("design note"));
assertEquals("this is a design note for a cluster", annotations.getDocumentation().get("en").get("/data[id2]/events[id3]/data[id4]/items[id8]/items[id3]/value[id4]").get("design note"));
}

@Test
public void flattenArchetypeWithZeroOccurrencesObject() throws Exception {
Archetype childWithExcluded = new ADLParser().parse(FlattenerTest.class.getResourceAsStream("openEHR-EHR-OBSERVATION.to_flatten_child_with_annotations_exclude_object.v1.adls"));
repository.addArchetype(childWithExcluded);

flattener = new Flattener(repository, models).createOperationalTemplate(false);

Archetype flattened = flattener.flatten(childWithExcluded);
assertNull(flattened.getAnnotations().getDocumentation().get("en").get("/data[id2]/events[id3]/data[id4]/items[id6]"));
}

@Test
public void flattenArchetypeWithZeroOccurrencesObjectOPT() throws Exception {
Archetype childWithExcluded = new ADLParser().parse(FlattenerTest.class.getResourceAsStream("openEHR-EHR-OBSERVATION.to_flatten_child_with_annotations_exclude_object.v1.adls"));
repository.addArchetype(childWithExcluded);

flattener = new Flattener(repository, models).createOperationalTemplate(true);

Archetype flattened = flattener.flatten(childWithExcluded);
assertNull(flattened.getAnnotations().getDocumentation().get("en").get("/data[id2]/events[id3]/data[id4]/items[id6]"));
}

@Test
public void flattenArchetypeWithNoAnnotations() throws Exception {
parent.setAnnotations(null);
repository.addArchetype(parent);
Archetype childWithExcluded = new ADLParser().parse(FlattenerTest.class.getResourceAsStream("openEHR-EHR-OBSERVATION.to_flatten_child_with_annotations_exclude_object.v1.adls"));
childWithExcluded.setAnnotations(null);
repository.addArchetype(childWithExcluded);

flattener = new Flattener(repository, models).createOperationalTemplate(true);

Archetype flattened = flattener.flatten(childWithExcluded);
assertNull(flattened.getAnnotations());
}

@Test
public void flattenArchetypeWithNoDocumentation() throws Exception {
parent.setAnnotations(new ResourceAnnotations());
repository.addArchetype(parent);
Archetype childWithExcluded = new ADLParser().parse(FlattenerTest.class.getResourceAsStream("openEHR-EHR-OBSERVATION.to_flatten_child_with_annotations_exclude_object.v1.adls"));
childWithExcluded.setAnnotations(new ResourceAnnotations());
repository.addArchetype(childWithExcluded);

flattener = new Flattener(repository, models).createOperationalTemplate(true);

Archetype flattened = flattener.flatten(childWithExcluded);
assertNull(flattened.getAnnotations().getDocumentation());
}

@Test
public void flattenArchetypeWithEmptyDocumentation() throws Exception {
parent.getAnnotations().setDocumentation(new HashMap<>());
repository.addArchetype(parent);
Archetype childWithExcluded = new ADLParser().parse(FlattenerTest.class.getResourceAsStream("openEHR-EHR-OBSERVATION.to_flatten_child_with_annotations_exclude_object.v1.adls"));
childWithExcluded.getAnnotations().setDocumentation(new HashMap<>());
repository.addArchetype(childWithExcluded);

flattener = new Flattener(repository, models).createOperationalTemplate(true);

Archetype flattened = flattener.flatten(childWithExcluded);
assertEquals(0, flattened.getAnnotations().getDocumentation().size());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
archetype (adl_version=2.0.5; rm_release=1.0.2; generated)
openEHR-EHR-OBSERVATION.to_flatten_child.v1.0.0

specialize
openEHR-EHR-OBSERVATION.to_flatten_parent.v1

language
original_language = <[ISO_639-1::en]>
translations = <
["ar-sy"] = <
language = <[ISO_639-1::ar-sy]>
author = <
["name"] = <"Mona Saleh">
>
>
>

description
lifecycle_state = <"unmanaged">
original_author = <
["name"] = <"Heather Leslie">
["organisation"] = <"Ocean Informatics">
["email"] = <"[email protected]">
["date"] = <"2012-12-11">
>
copyright = <"none">
details = <
["en"] = <
language = <[ISO_639-1::en]>
purpose = <"specialized rules test">
use = <"testing specialized rules">
keywords = <"test">
misuse = <"">
>
>

definition
OBSERVATION[id1.1] matches { -- blood pressure
/data[id2]/events[id3]/data[id4]/items matches {
ELEMENT[id6] occurrences matches {0}
}
}

terminology
term_definitions = <
["en"] = <
["id1.1"] = <
text = <"blood pressure observation">
description = <"blood pressure observation">
>
>
>

annotations
documentation = <
["en"] = <
["/subject"] = <
["design note"] = <"xxxxxx">
>
["/data[id2]/events[id3]/data[id4]/items[id5]"] = <
["design note"] = <"this is a design note on allergic reaction, with some extra information">
["requirements note"] = <"this is a requirements note on allergic reaction">
["medline ref"] = <"this is a medline ref on allergic reaction">
>
["/data[id2]/events[id3]/data[id4]/items[id7]"] = <
["design note"] = <"this is also a design note on intelerance">
["requirements note"] = <"this is a requirements note on intolerance">
["national data dictionary"] = <"NDD ref for intolerance">
>
>
>

0 comments on commit 148b979

Please sign in to comment.