diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/analyticsTest.pure b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/analyticsTest.pure index 1df60231c2b..5a1cc6275a3 100644 --- a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/analyticsTest.pure +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/analyticsTest.pure @@ -20,6 +20,11 @@ function meta::analytics::mapping::modelCoverage::test::generateModelCoverageAna meta::analytics::mapping::modelCoverage::analyze($mapping, false, false, false); } +function meta::analytics::mapping::modelCoverage::test::generateModelCoverageAnalyticsWithMappedEntityInfo(mapping: Mapping[1]): MappingModelCoverageAnalysisResult[1] +{ + meta::analytics::mapping::modelCoverage::analyze($mapping, true, false, false); +} + // Relational function <> meta::analytics::mapping::modelCoverage::test::testSimpleRelationalMappingCoverage():Boolean[1] { @@ -111,6 +116,41 @@ function <> meta::analytics::mapping::modelCove assertContains($result.mappedEntities.path, 'meta::analytics::mapping::modelCoverage::test::Target_meta::analytics::mapping::modelCoverage::test::Source_autoMapped_shared'); } + +function <> meta::analytics::mapping::modelCoverage::test::testAutoMappedComplexPropertiesMappingCoverageWithMappedEntityInfo():Boolean[1] +{ + let grammar = 'Class meta::analytics::mapping::modelCoverage::test::Target\n'+ + '{\n'+ + ' tgtId: String[1];\n'+ + ' shared: meta::analytics::mapping::modelCoverage::test::Shared[1];\n'+ + '}\n'+ + 'Class meta::analytics::mapping::modelCoverage::test::Shared\n'+ + '{\n'+ + ' sharedId: String[1];\n'+ + '}\n'+ + 'Class meta::analytics::mapping::modelCoverage::test::Source\n'+ + '{\n'+ + ' srcId: String[1];\n'+ + ' shared: meta::analytics::mapping::modelCoverage::test::Shared[1];\n'+ + '}\n'+ + '###Mapping\n'+ + 'Mapping meta::analytics::mapping::modelCoverage::test::simpleAutoMappedMapping\n'+ + '(\n'+ + ' *meta::analytics::mapping::modelCoverage::test::Target:Pure\n'+ + ' {\n'+ + ' ~src meta::analytics::mapping::modelCoverage::test::Source\n'+ + ' tgtId: $src.srcId,\n'+ + ' shared: $src.shared\n'+ + ' }\n'+ + ')\n'; + let elements = meta::legend::compileLegendGrammar($grammar); + let autoMappedMapping = $elements->filter(e|$e->instanceOf(Mapping))->at(0)->cast(@Mapping); + let result = meta::analytics::mapping::modelCoverage::test::generateModelCoverageAnalyticsWithMappedEntityInfo($autoMappedMapping); + assert($result.mappedEntities->size() == 2); + assertContains($result.mappedEntities.path, 'meta::analytics::mapping::modelCoverage::test::Target_meta::analytics::mapping::modelCoverage::test::Source_autoMapped_shared'); + assert($result.mappedEntities->filter(m |$m.info->isNotEmpty())->size() == 2); +} + function <> meta::analytics::mapping::modelCoverage::test::testCyclicalAutoMappedComplexPropertiesMappingCoverage():Boolean[1] { let grammar = 'Class meta::analytics::mapping::modelCoverage::test::Target\n'+ diff --git a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/mappedEntityBuilder.pure b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/mappedEntityBuilder.pure index 4272359f4aa..387366be166 100644 --- a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/mappedEntityBuilder.pure +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/mappedEntityBuilder.pure @@ -301,9 +301,9 @@ function meta::analytics::mapping::modelCoverage::buildEntity( let srcClassPath = if($pureInstanceSetImplementation.srcClass->isNotEmpty(),|$pureInstanceSetImplementation.srcClass->toOne()->cast(@Class)->elementToPath(),|''); $targetClassPath + '_' + $srcClassPath;, |$pm.targetSetImplementationId); - processAutoMappedPropertyMapping($pm.property->cast(@AbstractProperty), $id + '_autoMapped_', $config, []);); + processAutoMappedPropertyMapping($pm.property->cast(@AbstractProperty), $id + '_autoMapped_', $isRootEntity, $config, []);); let autoMappedPrimitiveProperties = if($setImplementation->instanceOf(PureInstanceSetImplementation), - |buildAutoMappedProperty($class, if($setImplementation->cast(@PureInstanceSetImplementation).srcClass->isEmpty(),|[],|$setImplementation->cast(@PureInstanceSetImplementation).srcClass->cast(@Class)->toOne()), $properties, $config), + |buildAutoMappedProperty($class, if($setImplementation->cast(@PureInstanceSetImplementation).srcClass->isEmpty(),|[],|$setImplementation->cast(@PureInstanceSetImplementation).srcClass->cast(@Class)->toOne()), $properties, $isRootEntity, $config), |[]); buildEntity( $class, @@ -318,6 +318,7 @@ function meta::analytics::mapping::modelCoverage::buildEntity( function meta::analytics::mapping::modelCoverage::processAutoMappedPropertyMapping( property: AbstractProperty[1], prefix: String[1], + isRootEntity: Boolean[1], config: AnalysisConfiguration[1], visited: Pair, String>[*] ): AutoMappedHelperClass[1] @@ -344,8 +345,9 @@ function meta::analytics::mapping::modelCoverage::processAutoMappedPropertyMappi | ^MappedPropertyInfo(type = $property.genericType.rawType->toOne()->mapType(), multiplicity = $property.multiplicity->toOne()), | [])); let newVisited = $visited->concatenate([^Pair, String>(first = $property.genericType.rawType->toOne()->cast(@Class), second = $entityPath)]); - let children = $property.genericType.rawType->toOne()->cast(@Class).properties->map(p | $p->processAutoMappedPropertyMapping($entityPath + '_' , $config, $newVisited)); - let currentMappedEntity = ^MappedEntity(path=$entityPath, properties = $children->map(c|$c.mappedProperties)); + let propertyType = $property.genericType.rawType->toOne()->cast(@Class); + let children = $propertyType.properties->map(p | $p->processAutoMappedPropertyMapping($entityPath + '_' , $isRootEntity, $config, $newVisited)); + let currentMappedEntity = ^MappedEntity(path=$entityPath, properties = $children->map(c|$c.mappedProperties), info = if($config.returnMappedEntityInfo == true, | ^MappedEntityInfo(isRootEntity = $isRootEntity, classPath = $propertyType->elementToPath()), | [])); ^AutoMappedHelperClass(mappedProperties = [$entityMappedProp], mappedEntities=[$currentMappedEntity]->concatenate($children->map(c|$c.mappedEntities))); ); ) @@ -355,6 +357,7 @@ function meta::analytics::mapping::modelCoverage::buildAutoMappedProperty( class:Class[1], srcClass: Class[0..1], mappedProperties: MappedProperty[*], + isRootEntity: Boolean[1], config: AnalysisConfiguration[1] ): MappedProperty[*] {