From 02940e237626ea058741cafc8eef80fb72533df9 Mon Sep 17 00:00:00 2001 From: wolandscat Date: Wed, 27 Mar 2024 12:30:53 -0600 Subject: [PATCH 1/3] Support BMM Indexed Container meta-type, enabling Hash structures to be property specified in BMM files. BmmParseRoundTrip tests pass. --- .../openehr/bmm/core/BmmContainerType.java | 7 +- .../bmm/core/BmmIndexedContainerProperty.java | 28 +++ .../bmm/core/BmmIndexedContainerType.java | 26 +++ .../PBmmIndexedContainerProperty.java | 41 ++++ .../persistence/PBmmIndexedContainerType.java | 57 ++++++ .../v2/persistence/jackson/BmmTypeNaming.java | 2 + .../converters/BmmParseRoundtripTest.java | 1 + .../resources/openehr/openehr_base_110.bmm | 186 +++++++++++------- bmm/src/test/resources/testbmm/TestBmm1.bmm | 14 ++ 9 files changed, 287 insertions(+), 75 deletions(-) create mode 100644 bmm/src/main/java/org/openehr/bmm/core/BmmIndexedContainerProperty.java create mode 100644 bmm/src/main/java/org/openehr/bmm/core/BmmIndexedContainerType.java create mode 100644 bmm/src/main/java/org/openehr/bmm/v2/persistence/PBmmIndexedContainerProperty.java create mode 100644 bmm/src/main/java/org/openehr/bmm/v2/persistence/PBmmIndexedContainerType.java diff --git a/bmm/src/main/java/org/openehr/bmm/core/BmmContainerType.java b/bmm/src/main/java/org/openehr/bmm/core/BmmContainerType.java index 57397bfc6..30163e0b4 100644 --- a/bmm/src/main/java/org/openehr/bmm/core/BmmContainerType.java +++ b/bmm/src/main/java/org/openehr/bmm/core/BmmContainerType.java @@ -21,6 +21,8 @@ * Author: Claude Nanjo */ +import org.openehr.bmm.persistence.validation.BmmDefinitions; + import java.util.List; /** @@ -36,7 +38,7 @@ public class BmmContainerType extends BmmType { private BmmGenericClass containerType; /** - * + * The type of the contained item */ private BmmUnitaryType baseType; @@ -90,7 +92,8 @@ public void setBaseType(BmmUnitaryType baseType) { */ @Override public String getTypeName() { - return containerType.getName() + "<" + baseType.getTypeName() + ">"; + return containerType.getName() + + BmmDefinitions.GENERIC_LEFT_DELIMITER + baseType.getTypeName() + BmmDefinitions.GENERIC_RIGHT_DELIMITER; } /** diff --git a/bmm/src/main/java/org/openehr/bmm/core/BmmIndexedContainerProperty.java b/bmm/src/main/java/org/openehr/bmm/core/BmmIndexedContainerProperty.java new file mode 100644 index 000000000..ee5efd995 --- /dev/null +++ b/bmm/src/main/java/org/openehr/bmm/core/BmmIndexedContainerProperty.java @@ -0,0 +1,28 @@ +package org.openehr.bmm.core; + +import com.nedap.archie.base.MultiplicityInterval; + +/** + * Subtype of BMM_CONTAINER_PROPERTY that represents an indexed container type based on one of the inbuilt types + * Hash <>. + */ +public class BmmIndexedContainerProperty extends BmmProperty { + + /** + * We have to replicate cardinality here from BmmContainerProperty since we are inheriting from + * BmmProperty (which creates correct typing of the 'type' property) not BmmContainerProperty + */ + private MultiplicityInterval cardinality; + + public BmmIndexedContainerProperty (String aName, BmmIndexedContainerType aType, String aDocumentation, boolean isMandatoryFlag, boolean isComputedFlag) { + super(aName, aType, aDocumentation, isMandatoryFlag, isComputedFlag); + cardinality = MultiplicityInterval.createOpen(); + } + + public MultiplicityInterval getCardinality() { + return cardinality; + } + public void setCardinality(MultiplicityInterval cardinality) { + this.cardinality = cardinality; + } +} diff --git a/bmm/src/main/java/org/openehr/bmm/core/BmmIndexedContainerType.java b/bmm/src/main/java/org/openehr/bmm/core/BmmIndexedContainerType.java new file mode 100644 index 000000000..6928799b5 --- /dev/null +++ b/bmm/src/main/java/org/openehr/bmm/core/BmmIndexedContainerType.java @@ -0,0 +1,26 @@ +package org.openehr.bmm.core; + +import org.openehr.bmm.persistence.validation.BmmDefinitions; + +public class BmmIndexedContainerType extends BmmContainerType { + + /** + * The type of the index + */ + private BmmSimpleType indexType; + public BmmIndexedContainerType (BmmUnitaryType aBaseType, BmmSimpleType anIndexType, BmmGenericClass aContainerClass) { + super (aBaseType, aContainerClass); + indexType = anIndexType; + } + public BmmSimpleType getIndexType() { return indexType; } + + @Override + public String getTypeName() { + return getContainerType().getName() + + BmmDefinitions.GENERIC_LEFT_DELIMITER + + indexType.getTypeName() + BmmDefinitions.GENERIC_SEPARATOR + + getBaseType().getTypeName() + + BmmDefinitions.GENERIC_RIGHT_DELIMITER; + } + +} diff --git a/bmm/src/main/java/org/openehr/bmm/v2/persistence/PBmmIndexedContainerProperty.java b/bmm/src/main/java/org/openehr/bmm/v2/persistence/PBmmIndexedContainerProperty.java new file mode 100644 index 000000000..2a804bf09 --- /dev/null +++ b/bmm/src/main/java/org/openehr/bmm/v2/persistence/PBmmIndexedContainerProperty.java @@ -0,0 +1,41 @@ +package org.openehr.bmm.v2.persistence; + +import com.nedap.archie.base.Interval; +import com.nedap.archie.base.MultiplicityInterval; +import org.openehr.bmm.core.*; +import org.openehr.bmm.v2.validation.converters.BmmClassProcessor; + +public class PBmmIndexedContainerProperty extends PBmmProperty { + + /** + * We have to replicate cardinality here from PBmmContainerProperty since we are inheriting from + * PBmmProperty (which creates correct typing of typeDef) not PBmmContainerProperty + */ + private Interval cardinality; + + public Interval getCardinality() { + return cardinality; + } + public void setCardinality(Interval cardinality) { + this.cardinality = cardinality; + } + public PBmmIndexedContainerProperty() { + super(); + } + @Override + public BmmIndexedContainerProperty createBmmProperty(BmmClassProcessor classProcessor, BmmClass bmmClass) { + PBmmIndexedContainerType typeRef = getTypeRef(); + if (typeRef != null) { + BmmIndexedContainerType bmmType = (BmmIndexedContainerType) typeRef.createBmmType(classProcessor, bmmClass); + BmmIndexedContainerProperty bmmProperty = new BmmIndexedContainerProperty(getName(), bmmType, getDocumentation(), nullToFalse(isMandatory()), nullToFalse(isComputed())); + if (getCardinality() != null) { + bmmProperty.setCardinality(new MultiplicityInterval(getCardinality())); + } + populateImBooleans(bmmProperty); + return bmmProperty; + } + throw new RuntimeException("BmmTypeCreate failed for type " + typeRef + " of property " + + getName() + " in class " + bmmClass.getName()); + } + +} diff --git a/bmm/src/main/java/org/openehr/bmm/v2/persistence/PBmmIndexedContainerType.java b/bmm/src/main/java/org/openehr/bmm/v2/persistence/PBmmIndexedContainerType.java new file mode 100644 index 000000000..b848c0b0d --- /dev/null +++ b/bmm/src/main/java/org/openehr/bmm/v2/persistence/PBmmIndexedContainerType.java @@ -0,0 +1,57 @@ +package org.openehr.bmm.v2.persistence; + +import org.openehr.bmm.core.*; +import org.openehr.bmm.persistence.validation.BmmDefinitions; +import org.openehr.bmm.v2.validation.converters.BmmClassProcessor; + +import java.util.ArrayList; +import java.util.List; + +public class PBmmIndexedContainerType extends PBmmContainerType { + + private String indexType; + + public String getIndexType() { + return indexType; + } + + public void setIndexType(String indexType) { + this.indexType = indexType; + } + + @Override + public BmmIndexedContainerType createBmmType(BmmClassProcessor processor, BmmClass classDefinition) { + BmmClass containerClassDef = processor.getClassDefinition (getContainerType()); + BmmClass indexClassDef = processor.getClassDefinition (indexType); + PBmmUnitaryType containedType = getTypeRef(); //get the actual typeref for conversion + if (containerClassDef instanceof BmmGenericClass && + indexClassDef instanceof BmmSimpleClass && + containedType != null) + { + BmmType containedBmmType = containedType.createBmmType(processor, classDefinition); + if (containedBmmType instanceof BmmUnitaryType) { + return new BmmIndexedContainerType((BmmUnitaryType) containedBmmType, + ((BmmSimpleClass) indexClassDef).getType(), + (BmmGenericClass) containerClassDef); + } + } + + throw new RuntimeException("BmmClass " + containerClassDef.getName() + " is not defined in this model or not an indexed container type"); + } + @Override + public String asTypeString() { + return getContainerType() + BmmDefinitions.GENERIC_LEFT_DELIMITER + + indexType + BmmDefinitions.GENERIC_SEPARATOR + getTypeRef().asTypeString() + + BmmDefinitions.GENERIC_RIGHT_DELIMITER; + } + @Override + public List flattenedTypeList() { + List result = new ArrayList<>(); + result.add(getContainerType()); + result.add(indexType); + if (getTypeRef() != null) { + result.addAll(getTypeRef().flattenedTypeList()); + } + return result; + } +} diff --git a/bmm/src/main/java/org/openehr/bmm/v2/persistence/jackson/BmmTypeNaming.java b/bmm/src/main/java/org/openehr/bmm/v2/persistence/jackson/BmmTypeNaming.java index d25a5b4b9..2675b2367 100644 --- a/bmm/src/main/java/org/openehr/bmm/v2/persistence/jackson/BmmTypeNaming.java +++ b/bmm/src/main/java/org/openehr/bmm/v2/persistence/jackson/BmmTypeNaming.java @@ -25,6 +25,7 @@ public class BmmTypeNaming extends ClassNameIdResolver { put("BMM_INCLUDE_SPEC", BmmIncludeSpec.class). put("P_BMM_CLASS", PBmmClass.class). put("P_BMM_CONTAINER_PROPERTY", PBmmContainerProperty.class). + put("P_BMM_INDEXED_CONTAINER_PROPERTY", PBmmIndexedContainerProperty.class). put("P_BMM_ENUMERATION", PBmmEnumeration.class). put("P_BMM_ENUMERATION_STRING", PBmmEnumerationString.class). put("P_BMM_ENUMERATION_INTEGER", PBmmEnumerationInteger.class). @@ -33,6 +34,7 @@ public class BmmTypeNaming extends ClassNameIdResolver { put("P_BMM_GENERIC_TYPE", PBmmGenericType.class). put("P_BMM_OPEN_TYPE", PBmmOpenType.class). put("P_BMM_CONTAINER_TYPE", PBmmContainerType.class). + put("P_BMM_INDEXED_CONTAINER_TYPE", PBmmIndexedContainerType.class). put("P_BMM_PACKAGE", PBmmPackage.class). put("P_BMM_PROPERTY", PBmmProperty.class). put("P_BMM_SCHEMA", PBmmSchema.class). diff --git a/bmm/src/test/java/org/openehr/bmm/v2/persistence/converters/BmmParseRoundtripTest.java b/bmm/src/test/java/org/openehr/bmm/v2/persistence/converters/BmmParseRoundtripTest.java index af774f28f..b766dccc8 100644 --- a/bmm/src/test/java/org/openehr/bmm/v2/persistence/converters/BmmParseRoundtripTest.java +++ b/bmm/src/test/java/org/openehr/bmm/v2/persistence/converters/BmmParseRoundtripTest.java @@ -32,6 +32,7 @@ public void parseOpenEHRRoundTrip() throws Exception{ parseRoundTrip("/openehr/openehr_primitive_types_102.bmm"); parseRoundTrip("/openehr/openehr_rm_102.bmm"); parseRoundTrip("/openehr/openehr_structures_102.bmm"); + parseRoundTrip("/openehr/openehr_base_110.bmm"); } public void parseRoundTrip(String name) throws Exception { diff --git a/bmm/src/test/resources/openehr/openehr_base_110.bmm b/bmm/src/test/resources/openehr/openehr_base_110.bmm index 6c19a3dff..a91a81fd7 100644 --- a/bmm/src/test/resources/openehr/openehr_base_110.bmm +++ b/bmm/src/test/resources/openehr/openehr_base_110.bmm @@ -590,28 +590,29 @@ class_definitions = < properties = < ["original_language"] = (P_BMM_SINGLE_PROPERTY) < name = <"original_language"> - type_ref = < - type = <"Terminology_code"> - value_constraint = <"openEHR::languages"> - > + type = <"Terminology_code"> is_mandatory = > ["is_controlled"] = (P_BMM_SINGLE_PROPERTY) < name = <"is_controlled"> type = <"Boolean"> > - ["translations"] = (P_BMM_CONTAINER_PROPERTY) < - name = <"translations"> - type_def = < - container_type = <"List"> - type = <"TRANSLATION_DETAILS"> - > - cardinality = <|>=1|> - > + ["translations"] = (P_BMM_INDEXED_CONTAINER_PROPERTY) < + name = <"translations"> + type_def = < + container_type = <"Hash"> + index_type = <"String"> + type = <"TRANSLATION_DETAILS"> + > + > ["description"] = (P_BMM_SINGLE_PROPERTY) < name = <"description"> type = <"RESOURCE_DESCRIPTION"> > + ["annotations"] = (P_BMM_SINGLE_PROPERTY) < + name = <"annotations"> + type = <"RESOURCE_ANNOTATIONS"> + > > > @@ -621,46 +622,54 @@ class_definitions = < properties = < ["language"] = (P_BMM_SINGLE_PROPERTY) < name = <"language"> - type_ref = < - type = <"Terminology_code"> - value_constraint = <"openEHR::languages"> - > + type = <"Terminology_code"> is_mandatory = > - ["author"] = (P_BMM_GENERIC_PROPERTY) < - name = <"author"> - type_def = < - root_type = <"Hash"> - generic_parameters = <"String", "String"> - > + ["author"] = (P_BMM_INDEXED_CONTAINER_PROPERTY) < + name = <"author"> + type_def = < + container_type = <"Hash"> + index_type = <"String"> + type = <"String"> + > is_mandatory = > ["accreditation"] = (P_BMM_SINGLE_PROPERTY) < name = <"accreditation"> type = <"String"> > - ["other_details"] = (P_BMM_GENERIC_PROPERTY) < - name = <"other_details"> - type_def = < - root_type = <"Hash"> - generic_parameters = <"String", "String"> - > + ["version_last_translated"] = (P_BMM_SINGLE_PROPERTY) < + name = <"version_last_translated"> + type = <"String"> + > + ["other_details"] = (P_BMM_INDEXED_CONTAINER_PROPERTY) < + name = <"other_details"> + type_def = < + container_type = <"Hash"> + index_type = <"String"> + type = <"String"> + > > > > ["RESOURCE_DESCRIPTION"] = < name = <"RESOURCE_DESCRIPTION"> - ancestors = <"Any", ...> + ancestors = <"Any"> properties = < - ["original_author"] = (P_BMM_GENERIC_PROPERTY) < - name = <"original_author"> - type_def = < - root_type = <"Hash"> - generic_parameters = <"String", "String"> - > + ["original_author"] = (P_BMM_INDEXED_CONTAINER_PROPERTY) < + name = <"original_author"> + type_def = < + container_type = <"Hash"> + index_type = <"String"> + type = <"String"> + > is_mandatory = > + ["original_namespace"] = (P_BMM_SINGLE_PROPERTY) < + name = <"original_namespace"> + type = <"String"> + > ["other_contributors"] = (P_BMM_CONTAINER_PROPERTY) < name = <"other_contributors"> type_def = < @@ -669,6 +678,22 @@ class_definitions = < > cardinality = <|>=0|> > + ["custodian_namespace"] = (P_BMM_SINGLE_PROPERTY) < + name = <"custodian_namespace"> + type = <"String"> + > + ["custodian_organisation"] = (P_BMM_SINGLE_PROPERTY) < + name = <"custodian_organisation"> + type = <"String"> + > + ["copyright"] = (P_BMM_SINGLE_PROPERTY) < + name = <"copyright"> + type = <"String"> + > + ["licence"] = (P_BMM_SINGLE_PROPERTY) < + name = <"licence"> + type = <"String"> + > ["lifecycle_state"] = (P_BMM_SINGLE_PROPERTY) < name = <"lifecycle_state"> type = <"String"> @@ -678,26 +703,51 @@ class_definitions = < name = <"resource_package_uri"> type = <"String"> > - ["other_details"] = (P_BMM_GENERIC_PROPERTY) < - name = <"other_details"> - type_def = < - root_type = <"Hash"> - generic_parameters = <"String", "String"> - > + ["ip_acknowledgements"] = (P_BMM_INDEXED_CONTAINER_PROPERTY) < + name = <"ip_acknowledgements"> + type_def = < + container_type = <"Hash"> + index_type = <"String"> + type = <"String"> + > + > + + ["references"] = (P_BMM_INDEXED_CONTAINER_PROPERTY) < + name = <"references"> + type_def = < + container_type = <"Hash"> + index_type = <"String"> + type = <"String"> + > + > + ["conversion_details"] = (P_BMM_INDEXED_CONTAINER_PROPERTY) < + name = <"conversion_details"> + type_def = < + container_type = <"Hash"> + index_type = <"String"> + type = <"String"> + > + > + ["other_details"] = (P_BMM_INDEXED_CONTAINER_PROPERTY) < + name = <"other_details"> + type_def = < + container_type = <"Hash"> + index_type = <"String"> + type = <"String"> + > > ["parent_resource"] = (P_BMM_SINGLE_PROPERTY) < name = <"parent_resource"> type = <"AUTHORED_RESOURCE"> is_mandatory = > - ["details"] = (P_BMM_CONTAINER_PROPERTY) < - name = <"details"> - type_def = < - container_type = <"List"> - type = <"RESOURCE_DESCRIPTION_ITEM"> - > - is_mandatory = - cardinality = <|>=1|> + ["details"] = (P_BMM_INDEXED_CONTAINER_PROPERTY) < + name = <"details"> + type_def = < + container_type = <"Hash"> + index_type = <"String"> + type = <"RESOURCE_DESCRIPTION_ITEM"> + > > > > @@ -708,10 +758,7 @@ class_definitions = < properties = < ["language"] = (P_BMM_SINGLE_PROPERTY) < name = <"language"> - type_ref = < - type = <"Terminology_code"> - value_constraint = <"openEHR::languages"> - > + type = <"Terminology_code"> is_mandatory = > ["purpose"] = (P_BMM_SINGLE_PROPERTY) < @@ -735,28 +782,21 @@ class_definitions = < name = <"misuse"> type = <"String"> > - ["copyright"] = (P_BMM_SINGLE_PROPERTY) < - name = <"copyright"> - type = <"String"> + ["original_resource_uri"] = (P_BMM_INDEXED_CONTAINER_PROPERTY) < + name = <"original_resource_uri"> + type_def = < + container_type = <"Hash"> + index_type = <"String"> + type = <"String"> + > > - ["original_resource_uri"] = (P_BMM_CONTAINER_PROPERTY) < - name = <"original_resource_uri"> - type_def = < - container_type = <"List"> - type_def = (P_BMM_GENERIC_TYPE) < - root_type = <"Hash"> - generic_parameters = <"String", "String"> - > - > - cardinality = <|>=0|> - > - ["other_details"] = (P_BMM_GENERIC_PROPERTY) < + ["other_details"] = (P_BMM_INDEXED_CONTAINER_PROPERTY) < name = <"other_details"> - type_def = < - root_type = <"Hash"> - generic_parameters = <"String", "String"> - > - is_mandatory = + type_def = < + container_type = <"Hash"> + index_type = <"String"> + type = <"String"> + > > > > diff --git a/bmm/src/test/resources/testbmm/TestBmm1.bmm b/bmm/src/test/resources/testbmm/TestBmm1.bmm index 90f690c59..6bc2c8a3b 100644 --- a/bmm/src/test/resources/testbmm/TestBmm1.bmm +++ b/bmm/src/test/resources/testbmm/TestBmm1.bmm @@ -283,6 +283,20 @@ class_definitions = < > > + ["TypeWithHashMap"] = < + name = <"TypeWithHashMap"> + properties = < + ["employees"] = (P_BMM_INDEXED_CONTAINER_PROPERTY) < + name = <"employees"> + type_def = < + container_type = <"Hash"> + index_type = <"String"> + type = <"Party"> + > + > + > + > + ["ProportionKind"] = (P_BMM_ENUMERATION_INTEGER) < name = <"ProportionKind"> ancestors = <"Integer", ...> From b8959cf394cfa875f478045921e4bb9f599a9eff Mon Sep 17 00:00:00 2001 From: wolandscat Date: Thu, 4 Apr 2024 15:20:00 -0600 Subject: [PATCH 2/3] Add tests, correct a failing test for BMM Indexed container type. --- .../bmm/core/BmmIndexedContainerProperty.java | 2 +- .../converters/ConversionTest.java | 52 +++++++++++++++++-- .../resources/openehr/openehr_base_110.bmm | 42 ++++++++++++--- 3 files changed, 85 insertions(+), 11 deletions(-) diff --git a/bmm/src/main/java/org/openehr/bmm/core/BmmIndexedContainerProperty.java b/bmm/src/main/java/org/openehr/bmm/core/BmmIndexedContainerProperty.java index ee5efd995..5a5da747a 100644 --- a/bmm/src/main/java/org/openehr/bmm/core/BmmIndexedContainerProperty.java +++ b/bmm/src/main/java/org/openehr/bmm/core/BmmIndexedContainerProperty.java @@ -10,7 +10,7 @@ public class BmmIndexedContainerProperty extends BmmProperty (which creates correct typing of the 'type' property) not BmmContainerProperty + * BmmProperty <BmmIndexedContainerType> (which creates correct typing of the 'type' property) not BmmContainerProperty */ private MultiplicityInterval cardinality; diff --git a/bmm/src/test/java/org/openehr/bmm/v2/persistence/converters/ConversionTest.java b/bmm/src/test/java/org/openehr/bmm/v2/persistence/converters/ConversionTest.java index 486647e31..edf2ea58c 100644 --- a/bmm/src/test/java/org/openehr/bmm/v2/persistence/converters/ConversionTest.java +++ b/bmm/src/test/java/org/openehr/bmm/v2/persistence/converters/ConversionTest.java @@ -1,9 +1,7 @@ package org.openehr.bmm.v2.persistence.converters; import org.junit.Test; -import org.openehr.bmm.core.BmmClass; -import org.openehr.bmm.core.BmmGenericType; -import org.openehr.bmm.core.BmmModel; +import org.openehr.bmm.core.*; import org.openehr.bmm.v2.persistence.PBmmSchema; import org.openehr.bmm.v2.persistence.odin.BmmOdinParser; import org.openehr.bmm.v2.persistence.odin.BmmOdinSerializer; @@ -58,7 +56,6 @@ public void generateOdinTest() throws Exception { PBmmSchema converted = BmmOdinParser.convert(serialized); } - @Test public void generateGenericParametersTest() throws Exception { BmmRepository repo = new BmmRepository(); @@ -76,6 +73,53 @@ public void generateGenericParametersTest() throws Exception { assertEquals(2, hashContentType.getGenericParameters().size()); assertEquals("Hash", hashContentType.toDisplayString()); } + @Test + public void generateGenericParametersTest2() throws Exception { + BmmRepository repo = new BmmRepository(); + repo.addPersistentSchema(parse("/openehr/openehr_primitive_types_102.bmm")); + repo.addPersistentSchema(parse("/openehr/openehr_basic_types_102.bmm")); + repo.addPersistentSchema(parse("/openehr/openehr_adltest_100.bmm")); + BmmSchemaConverter converter = new BmmSchemaConverter(repo); + converter.validateAndConvertRepository(); + for (BmmValidationResult validationResult:repo.getModels()) { + System.out.println(validationResult.getLogger()); + assertTrue("the OpenEHR ADL test 1.0.0 Base file should pass validation", validationResult.passes()); + } + // SOME_TYPE.qty_interval_attr_1 should be a DV_INTERVAL + BmmModel model = repo.getModel("openehr_adltest_1.0.0").getModel(); + BmmClass aClass = model.getClassDefinition("SOME_TYPE"); + BmmGenericType genericType = (BmmGenericType) aClass.getFlatProperties().get("qty_interval_attr_1").getType().getEffectiveType(); + assertEquals(1, genericType.getGenericParameters().size()); + assertEquals("DV_INTERVAL", genericType.toDisplayString()); + } + + @Test + public void generateIndexedContainerTest() throws Exception { + BmmRepository repo = new BmmRepository(); + repo.addPersistentSchema(parse("/openehr/openehr_primitive_types_102.bmm")); + repo.addPersistentSchema(parse("/openehr/openehr_base_110.bmm")); + BmmSchemaConverter converter = new BmmSchemaConverter(repo); + converter.validateAndConvertRepository(); + for (BmmValidationResult validationResult:repo.getModels()) { + System.out.println(validationResult.getLogger()); + assertTrue("the OpenEHR RM 1.1.0 Base file should pass validation", validationResult.passes()); + } + // RESOURCE_DESCRIPTION_ITEM.other_details should be a HASH + BmmModel baseModel = repo.getModel("openehr_base_1.1.0").getModel(); + BmmClass resourceDescriptionItem = baseModel.getClassDefinition("RESOURCE_DESCRIPTION_ITEM"); + BmmIndexedContainerType hashType = (BmmIndexedContainerType) resourceDescriptionItem.getFlatProperties().get("other_details").getType(); + + BmmSimpleType hashIndexType = hashType.getIndexType(); + assertEquals(hashIndexType.getTypeName(), "String"); + + BmmUnitaryType hashBaseType = hashType.getBaseType(); + assertEquals(hashBaseType.getTypeName(), "String"); + + BmmGenericClass hashContainerclass = hashType.getContainerType(); + assertEquals(hashContainerclass.getName(), "Hash"); + + assertEquals("Hash", hashType.toDisplayString()); + } @Test public void aomParseAndConvertTest() throws Exception { diff --git a/bmm/src/test/resources/openehr/openehr_base_110.bmm b/bmm/src/test/resources/openehr/openehr_base_110.bmm index a91a81fd7..81a5c42d8 100644 --- a/bmm/src/test/resources/openehr/openehr_base_110.bmm +++ b/bmm/src/test/resources/openehr/openehr_base_110.bmm @@ -78,7 +78,7 @@ packages = < > ["resource"] = < name = <"resource"> - classes = <"AUTHORED_RESOURCE", "TRANSLATION_DETAILS", "RESOURCE_DESCRIPTION", "RESOURCE_DESCRIPTION_ITEM"> + classes = <"AUTHORED_RESOURCE", "TRANSLATION_DETAILS", "RESOURCE_DESCRIPTION", "RESOURCE_DESCRIPTION_ITEM", "RESOURCE_ANNOTATIONS"> > > > @@ -782,14 +782,14 @@ class_definitions = < name = <"misuse"> type = <"String"> > - ["original_resource_uri"] = (P_BMM_INDEXED_CONTAINER_PROPERTY) < + ["original_resource_uri"] = (P_BMM_GENERIC_PROPERTY) < name = <"original_resource_uri"> type_def = < - container_type = <"Hash"> - index_type = <"String"> - type = <"String"> + root_type = <"Hash"> + generic_parameters = <"String", "String"> > - > + is_mandatory = + > ["other_details"] = (P_BMM_INDEXED_CONTAINER_PROPERTY) < name = <"other_details"> type_def = < @@ -801,4 +801,34 @@ class_definitions = < > > + ["RESOURCE_ANNOTATIONS"] = < + name = <"RESOURCE_ANNOTATIONS"> + ancestors = <"Any"> + properties = < + ["documentation"] = (P_BMM_GENERIC_PROPERTY) < + name = <"documentation"> + type_def = < + root_type = <"Hash"> + generic_parameter_defs = < + ["K"] = (P_BMM_SIMPLE_TYPE) < + type = <"String"> + > + ["V"] = (P_BMM_GENERIC_TYPE) < + root_type = <"Hash"> + generic_parameter_defs = < + ["K"] = (P_BMM_SIMPLE_TYPE) < + type = <"String"> + > + ["V"] = (P_BMM_GENERIC_TYPE) < + root_type = <"Hash"> + generic_parameters = <"String", "String"> + > + > + > + > + > + is_mandatory = + > + > + > > From 713ad18b5a01c1510fcdbd68cacdd11cbbc1009e Mon Sep 17 00:00:00 2001 From: wolandscat Date: Thu, 4 Apr 2024 17:33:32 -0600 Subject: [PATCH 3/3] Improve test runner structure. --- .../converters/ConversionTest.java | 162 ++++++++++-------- 1 file changed, 94 insertions(+), 68 deletions(-) diff --git a/bmm/src/test/java/org/openehr/bmm/v2/persistence/converters/ConversionTest.java b/bmm/src/test/java/org/openehr/bmm/v2/persistence/converters/ConversionTest.java index edf2ea58c..07acb899b 100644 --- a/bmm/src/test/java/org/openehr/bmm/v2/persistence/converters/ConversionTest.java +++ b/bmm/src/test/java/org/openehr/bmm/v2/persistence/converters/ConversionTest.java @@ -1,5 +1,8 @@ package org.openehr.bmm.v2.persistence.converters; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import org.openehr.bmm.core.*; import org.openehr.bmm.v2.persistence.PBmmSchema; @@ -19,35 +22,59 @@ public class ConversionTest { - @Test - public void testAdlTestSchema() throws Exception { - BmmRepository repo = new BmmRepository(); - repo.addPersistentSchema(parse("/openehr/openehr_primitive_types_102.bmm")); - repo.addPersistentSchema(parse("/openehr/openehr_basic_types_102.bmm")); - repo.addPersistentSchema(parse("/openehr/openehr_adltest_100.bmm")); + private static BmmRepository repo1; + private static BmmRepository repo2; + + @BeforeClass + public static void setup() throws Exception { + BmmSchemaConverter converter; + + repo1 = new BmmRepository(); + repo1.addPersistentSchema(parse("/openehr/openehr_primitive_types_102.bmm")); + repo1.addPersistentSchema(parse("/openehr/openehr_basic_types_102.bmm")); + repo1.addPersistentSchema(parse("/openehr/openehr_adltest_100.bmm")); + repo1.addPersistentSchema(parse("/openehr/openehr_base_110.bmm")); - BmmSchemaConverter converter = new BmmSchemaConverter(repo); + converter = new BmmSchemaConverter(repo1); converter.validateAndConvertRepository(); - for (BmmValidationResult validationResult:repo.getModels()) { + for (BmmValidationResult validationResult:repo1.getModels()) { System.out.println(validationResult.getLogger()); - assertTrue("the OpenEHR ADL Test 1.0.0 BMM files should pass validation", validationResult.passes()); + assertTrue("the OpenEHR schema " + validationResult.getSchemaId() + " should pass validation", validationResult.passes()); } - BmmModel adlTestModel = repo.getModel("openehr_adltest_1.0.0").getModel(); + + repo2 = new BmmRepository(); + repo2.addPersistentSchema(parse("/openehr/openehr_base_for_aom.bmm")); + repo2.addPersistentSchema(parse("/openehr/openEHR_aom_206.bmm")); + converter = new BmmSchemaConverter(repo2); + converter.validateAndConvertRepository(); + for (BmmValidationResult validationResult:repo2.getModels()) { + System.out.println(validationResult.getLogger()); + assertTrue("the OpenEHR schema " + validationResult.getSchemaId() + " should pass validation", validationResult.passes()); + } + } + + @AfterClass + public static void tearDown() { + repo1 = null; + repo2 = null; + } + + @Test + public void testAdlTestSchema() throws Exception { + BmmModel bmmModel = repo1.getModel("openehr_adltest_1.0.0").getModel(); // Descendant relations assertTrue ("\"GENERIC_CHILD_CLOSED\" descendant of \"GENERIC_PARENT\"", - adlTestModel.descendantOf("GENERIC_CHILD_CLOSED", "GENERIC_PARENT")); + bmmModel.descendantOf("GENERIC_CHILD_CLOSED", "GENERIC_PARENT")); // Ancestor relations - List testResult = adlTestModel.getAllAncestorClasses("GENERIC_CHILD_OPEN_T"); + List testResult = bmmModel.getAllAncestorClasses("GENERIC_CHILD_OPEN_T"); // conformance result from ADL Workbench List conformanceResult = Arrays.asList("GENERIC_PARENT"); assertEquals ("\"GENERIC_CHILD_CLOSED\" descendant of \"GENERIC_PARENT\")", testResult, conformanceResult); - } - @Test public void generateOdinTest() throws Exception { PBmmSchema parsed = parse("/openehr/openehr_basic_types_102.bmm"); @@ -56,58 +83,63 @@ public void generateOdinTest() throws Exception { PBmmSchema converted = BmmOdinParser.convert(serialized); } + /* + * This tests the following (old) BMM way of representing a property of type Hash + * that should now be represented using P_BMM_INDEXED_CONTAINER_PROPERTY + * ["original_resource_uri"] = (P_BMM_GENERIC_PROPERTY) < + * name = <"original_resource_uri"> + * type_def = < + * root_type = <"Hash"> + * generic_parameters = <"String", "String"> + * > + * is_mandatory = + * > + */ @Test public void generateGenericParametersTest() throws Exception { - BmmRepository repo = new BmmRepository(); - repo.addPersistentSchema(parse("/openehr/openehr_base_110.bmm")); - BmmSchemaConverter converter = new BmmSchemaConverter(repo); - converter.validateAndConvertRepository(); - for (BmmValidationResult validationResult:repo.getModels()) { - System.out.println(validationResult.getLogger()); - assertTrue("the OpenEHR RM 1.1.0 Base file should pass validation", validationResult.passes()); - } - //RESOURCE_DESCRIPTION_ITEM.original_resource_uri should be a LIST> - BmmModel baseModel = repo.getModel("openehr_base_1.1.0").getModel(); - BmmClass resourceDescriptionItem = baseModel.getClassDefinition("RESOURCE_DESCRIPTION_ITEM"); - BmmGenericType hashContentType = (BmmGenericType) resourceDescriptionItem.getFlatProperties().get("original_resource_uri").getType().getEffectiveType(); + BmmModel bmmModel = repo1.getModel("openehr_base_1.1.0").getModel(); + BmmClass bmmClass = bmmModel.getClassDefinition("RESOURCE_DESCRIPTION_ITEM"); + BmmGenericType hashContentType = (BmmGenericType) bmmClass.getFlatProperties().get("original_resource_uri").getType().getEffectiveType(); assertEquals(2, hashContentType.getGenericParameters().size()); assertEquals("Hash", hashContentType.toDisplayString()); } + + /* + * This tests the BMM way of representing a generic property of type DV_INTERVAL + * ["qty_interval_attr_1"] = (P_BMM_GENERIC_PROPERTY) < + * name = <"qty_interval_attr_1"> + * type_def = < + * root_type = <"DV_INTERVAL"> + * generic_parameters = <"DV_QUANTITY"> + * > + * > + */ @Test public void generateGenericParametersTest2() throws Exception { - BmmRepository repo = new BmmRepository(); - repo.addPersistentSchema(parse("/openehr/openehr_primitive_types_102.bmm")); - repo.addPersistentSchema(parse("/openehr/openehr_basic_types_102.bmm")); - repo.addPersistentSchema(parse("/openehr/openehr_adltest_100.bmm")); - BmmSchemaConverter converter = new BmmSchemaConverter(repo); - converter.validateAndConvertRepository(); - for (BmmValidationResult validationResult:repo.getModels()) { - System.out.println(validationResult.getLogger()); - assertTrue("the OpenEHR ADL test 1.0.0 Base file should pass validation", validationResult.passes()); - } - // SOME_TYPE.qty_interval_attr_1 should be a DV_INTERVAL - BmmModel model = repo.getModel("openehr_adltest_1.0.0").getModel(); - BmmClass aClass = model.getClassDefinition("SOME_TYPE"); - BmmGenericType genericType = (BmmGenericType) aClass.getFlatProperties().get("qty_interval_attr_1").getType().getEffectiveType(); + BmmModel bmmModel = repo1.getModel("openehr_adltest_1.0.0").getModel(); + BmmClass bmmClass = bmmModel.getClassDefinition("SOME_TYPE"); + BmmGenericType genericType = (BmmGenericType) bmmClass.getFlatProperties().get("qty_interval_attr_1").getType().getEffectiveType(); assertEquals(1, genericType.getGenericParameters().size()); assertEquals("DV_INTERVAL", genericType.toDisplayString()); } + /* + * This tests the BMM way of representing a container property of type Hash + * using the P_BMM_INDEXED_CONTAINER_PROPERTY property meta-type. + * ["other_details"] = (P_BMM_INDEXED_CONTAINER_PROPERTY) < + * name = <"other_details"> + * type_def = < + * container_type = <"Hash"> + * index_type = <"String"> + * type = <"String"> + * > + * > + */ @Test public void generateIndexedContainerTest() throws Exception { - BmmRepository repo = new BmmRepository(); - repo.addPersistentSchema(parse("/openehr/openehr_primitive_types_102.bmm")); - repo.addPersistentSchema(parse("/openehr/openehr_base_110.bmm")); - BmmSchemaConverter converter = new BmmSchemaConverter(repo); - converter.validateAndConvertRepository(); - for (BmmValidationResult validationResult:repo.getModels()) { - System.out.println(validationResult.getLogger()); - assertTrue("the OpenEHR RM 1.1.0 Base file should pass validation", validationResult.passes()); - } - // RESOURCE_DESCRIPTION_ITEM.other_details should be a HASH - BmmModel baseModel = repo.getModel("openehr_base_1.1.0").getModel(); - BmmClass resourceDescriptionItem = baseModel.getClassDefinition("RESOURCE_DESCRIPTION_ITEM"); - BmmIndexedContainerType hashType = (BmmIndexedContainerType) resourceDescriptionItem.getFlatProperties().get("other_details").getType(); + BmmModel bmmModel = repo1.getModel("openehr_base_1.1.0").getModel(); + BmmClass bmmClass = bmmModel.getClassDefinition("RESOURCE_DESCRIPTION_ITEM"); + BmmIndexedContainerType hashType = (BmmIndexedContainerType) bmmClass.getFlatProperties().get("other_details").getType(); BmmSimpleType hashIndexType = hashType.getIndexType(); assertEquals(hashIndexType.getTypeName(), "String"); @@ -115,27 +147,21 @@ public void generateIndexedContainerTest() throws Exception { BmmUnitaryType hashBaseType = hashType.getBaseType(); assertEquals(hashBaseType.getTypeName(), "String"); - BmmGenericClass hashContainerclass = hashType.getContainerType(); - assertEquals(hashContainerclass.getName(), "Hash"); + BmmGenericClass hashContainerClass = hashType.getContainerType(); + assertEquals(hashContainerClass.getName(), "Hash"); assertEquals("Hash", hashType.toDisplayString()); } + /* + * RESOURCE_DESCRIPTION_ITEM.original_resource_uri in openehr_aom_2.0.6 + * should be a LIST> + */ @Test public void aomParseAndConvertTest() throws Exception { - BmmRepository repo = new BmmRepository(); - repo.addPersistentSchema(parse("/openehr/openehr_base_for_aom.bmm")); - repo.addPersistentSchema(parse("/openehr/openEHR_aom_206.bmm")); - BmmSchemaConverter converter = new BmmSchemaConverter(repo); - converter.validateAndConvertRepository(); - for (BmmValidationResult validationResult:repo.getModels()) { - System.out.println(validationResult.getLogger()); - assertTrue("the AOM schema must be valid", validationResult.passes()); - } - //RESOURCE_DESCRIPTION_ITEM.original_resource_uri should be a LIST> - BmmModel baseModel = repo.getModel("openehr_aom_2.0.6").getModel(); - BmmClass resourceDescriptionItem = baseModel.getClassDefinition("RESOURCE_DESCRIPTION_ITEM"); - BmmGenericType hashContentType = (BmmGenericType) resourceDescriptionItem.getFlatProperties().get("original_resource_uri").getType().getEffectiveType(); + BmmModel bmmModel = repo2.getModel("openehr_aom_2.0.6").getModel(); + BmmClass bmmClass = bmmModel.getClassDefinition("RESOURCE_DESCRIPTION_ITEM"); + BmmGenericType hashContentType = (BmmGenericType) bmmClass.getFlatProperties().get("original_resource_uri").getType().getEffectiveType(); assertEquals(2, hashContentType.getGenericParameters().size()); assertEquals("Hash", hashContentType.toDisplayString());//this is not according to spec perhaps, but it is how the Archie AOM is implemented, and this is a direct conversion }