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/analytics.pure b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/analytics.pure index cd02a9ecfa0..31cea9cb0e0 100644 --- a/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/analytics.pure +++ b/legend-engine-xts-analytics/legend-engine-xts-analytics-mapping/legend-engine-xt-analytics-mapping-pure/src/main/resources/core_analytics_mapping/modelCoverage/analytics.pure @@ -123,19 +123,20 @@ function meta::analytics::mapping::modelCoverage::analyze( let mapClassMappingsIds = $map->classMappings().id; pair($map, list($classMappings->filter(cm | $cm.id->in($mapClassMappingsIds)))); )); + let propertyFilter = {p:AbstractProperty[1] | true}; let entities = $classMappings->map(cm | $cm->match([ o:OperationSetImplementation[1] | let subTypeMappings = $o->resolveOperation($mapping)->concatenate($operations->filter(op | $op.class->superTypes()->contains($o.class))); - buildInheritanceEntities($o, $o, [], $subTypeMappings, '', $rootClassMappings, $allClasses, $allProperties, $inheritanceMap, $mappingToClassMappings, $o.root, true, $config);, + buildInheritanceEntities($o, $o, [], $subTypeMappings, '', $propertyFilter, $rootClassMappings, $allClasses, $allProperties, $inheritanceMap, $mappingToClassMappings, $o.root, true, $config);, a:meta::pure::mapping::aggregationAware::AggregationAwareSetImplementation[1] | buildEntity( - $a.mainSetImplementation.class, buildEntityName($a.mainSetImplementation), $a.mainSetImplementation, $a.mainSetImplementation->allPropertyMappings(), $rootClassMappings, $allClasses, + $a.mainSetImplementation.class, buildEntityName($a.mainSetImplementation), $a.mainSetImplementation, $a.mainSetImplementation->allPropertyMappings(), $propertyFilter, $rootClassMappings, $allClasses, $allProperties, $inheritanceMap, $mappingToClassMappings, $a.root, $config ), i:InstanceSetImplementation[1] | buildEntity( - $i.class, buildEntityName($i), $i, $i->getPropertyMappings($classMappings), $rootClassMappings, $allClasses, + $i.class, buildEntityName($i), $i, $i->getPropertyMappings($classMappings), $propertyFilter, $rootClassMappings, $allClasses, $allProperties, $inheritanceMap, $mappingToClassMappings, $i.root, $config );, an:Any[1] | [] @@ -150,7 +151,7 @@ function meta::analytics::mapping::modelCoverage::analyze( let superTypes = $operations->filter(o | $o.class->superTypes()->contains($op.class)); let namePrefix = $i.entityPath->split('@')->at(0); let uniqueTypes = $subTypes->concatenate($superTypes)->removeDuplicatesBy(t | $t.class); - buildInheritanceEntities($op, $op, [], $uniqueTypes, $namePrefix, $rootClassMappings, $allClasses, $allProperties, $inheritanceMap, $mappingToClassMappings, false, false, $config); + buildInheritanceEntities($op, $op, [], $uniqueTypes, $namePrefix, $propertyFilter, $rootClassMappings, $allClasses, $allProperties, $inheritanceMap, $mappingToClassMappings, false, false, $config); )->removeDuplicatesBy(x | $x.path); let mappedEntities = $entities->concatenate($inheritanceEntities); if ($returnLightGraph == true, 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 5a1cc6275a3..7587d2197b9 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 @@ -37,15 +37,18 @@ function <> meta::analytics::mapping::modelCove // embedded relational mapping assertContains($mappedEntityForFirm.properties.name, 'employees'); assertContains($result.mappedEntities.path, $mappedEntityForFirm.properties->filter(p|$p.name == 'employees')->toOne()->cast(@EntityMappedProperty).entityPath); + + let mappedEntityForLegalEntity = $result.mappedEntities->filter(mp|$mp.path == 'meta::analytics::mapping::modelCoverage::test::LegalEntity'); + assert($mappedEntityForLegalEntity.properties->size() == 2); } function <> meta::analytics::mapping::modelCoverage::test::testSimpleRelationalInheritanceMappingCoverage():Boolean[1] { let result = meta::analytics::mapping::modelCoverage::test::generateModelCoverageAnalytics(meta::analytics::mapping::modelCoverage::test::sampleRelationalMapping); let mappedEntityForLegalEntity = $result.mappedEntities->filter(mp|$mp.path == 'meta::analytics::mapping::modelCoverage::test::LegalEntity'); - assert($mappedEntityForLegalEntity.properties->size() == 4); + assert($mappedEntityForLegalEntity.properties->size() == 2); assertContains($mappedEntityForLegalEntity.properties->filter(p|$p->instanceOf(EntityMappedProperty))->cast(@EntityMappedProperty).entityPath, '@meta::analytics::mapping::modelCoverage::test::Firm'); - assertContains($mappedEntityForLegalEntity.properties->filter(p|$p->instanceOf(EntityMappedProperty))->cast(@EntityMappedProperty).entityPath, 'meta_analytics_mapping_modelCoverage_test_Firm_employees'); + assertContains($mappedEntityForLegalEntity.properties->filter(p|$p->instanceOf(EntityMappedProperty))->cast(@EntityMappedProperty).entityPath, 'meta::analytics::mapping::modelCoverage::test::Address'); } function <> meta::analytics::mapping::modelCoverage::test::testSimpleRelationalUnionMappingCoverage():Boolean[1] 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 41ac1505720..4956b3fc24c 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 @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +import meta::analytics::class::modelCoverage::utility::*; +import meta::relational::metamodel::*; import meta::relational::mapping::*; import meta::analytics::mapping::modelCoverage::*; import meta::pure::mapping::*; @@ -241,6 +243,7 @@ function meta::analytics::mapping::modelCoverage::buildEntity( target:String[1], setImplementation:SetImplementation[1], propertyMappings:PropertyMapping[*], + propertyFilter:Function<{AbstractProperty[1]->Boolean[1]}>[1], rootClassMappings:SetImplementation[*], classMap:Map, ClassInfo>[1], propertiesMap:Map, PropertyInfo>[1], @@ -259,7 +262,7 @@ function meta::analytics::mapping::modelCoverage::buildEntity( || $pm->match([semi: meta::relational::mapping::SemiStructuredRelationalPropertyMapping[1] | false, rpm:InstanceSetImplementation[1] | true, a: PropertyMapping[1] | false]) // handle SemiStructuredRelationalPropertyMapping manually to take care of automapped properties || $pm.targetSetImplementationId->in($rootClassMappings.id)) - ); + )->filter(pm | $propertyFilter->eval($pm.property)); let properties = $supportedPropertyMappings->processPropertyMappings($rootClassMappings, $inheritanceMap, $propertiesMap, $config); @@ -277,7 +280,8 @@ function meta::analytics::mapping::modelCoverage::buildEntity( && !$p->meta::pure::milestoning::isRangeMilestoningProperty() && ($rootClassMappings.class->contains($returnType) || $returnType == $class - || $returnType->instanceOf(PrimitiveType)); + || $returnType->instanceOf(PrimitiveType)) + && $propertyFilter->eval($p); ) ->map(qp | let qualifiedPropertyType = $qp.genericType.rawType->toOne(); @@ -373,6 +377,7 @@ function <> meta::analytics::mapping::modelCoverage::buildInheri seenInheritanceTypes: Class[*], mappings:SetImplementation[*], namePrefix: String[1], + originalPropertyFilter:Function<{AbstractProperty[1]->Boolean[1]}>[1], rootClassMappings:SetImplementation[*], classMap:Map, ClassInfo>[1], propertiesMap:Map, PropertyInfo>[1], @@ -412,6 +417,14 @@ function <> meta::analytics::mapping::modelCoverage::buildInheri i:InstanceSetImplementation[1] | $i->allPropertyMappings() ]); + let propertyFilter = {a:AbstractProperty[1] | + let ownerClass = $a->ownerClass(); + if ($mapping.class == $baseMapping.class, + | $ownerClass->in($mapping.class->superTypes()->concatenate($mapping.class)), + | $ownerClass == $mapping.class || $ownerClass->in($mapping.class->superTypes(false)->removeAll($seenInheritanceTypes))) + && $originalPropertyFilter->eval($a); + }; + let inheritanceTypes = $mapping->match([ o:OperationSetImplementation[1] | $seenInheritanceTypes->add($o.class), i:InstanceSetImplementation[1] | $seenInheritanceTypes @@ -420,12 +433,12 @@ function <> meta::analytics::mapping::modelCoverage::buildInheri let name = $namePrefix + if ($isBase, | $mapping->buildEntityName(),| $class->createInheritanceName()); let entities = buildEntity($class, $name, $mapping, - $mappedProperties, $rootClassMappings, $classMap, $propertiesMap, $inheritanceMap, $mappingClassMappings, $isRootEntity, $config); + $mappedProperties, $propertyFilter, $rootClassMappings, $classMap, $propertiesMap, $inheritanceMap, $mappingClassMappings, $isRootEntity, $config); let rootEntity = $entities->at(0); let currentMappings = $mappings->filter(m | $m.class->in($specs)); let inheritanceEntities = $currentMappings->map(cm | - $baseMapping->buildInheritanceEntitiesImpl($cm, $inheritanceTypes, $mappings, $namePrefix, $rootClassMappings, $classMap, $propertiesMap, + $baseMapping->buildInheritanceEntitiesImpl($cm, $inheritanceTypes, $mappings, $namePrefix, $originalPropertyFilter, $rootClassMappings, $classMap, $propertiesMap, $inheritanceMap, $mappingClassMappings, false, false, $config); ); @@ -446,6 +459,7 @@ function <> meta::analytics::mapping::modelCoverage::buildInheri seenInheritanceTypes: Class[*], mappings:SetImplementation[*], namePrefix: String[1], + originalPropertyFilter:Function<{AbstractProperty[1]->Boolean[1]}>[1], rootClassMappings:SetImplementation[*], classMap:Map, ClassInfo>[1], propertiesMap:Map, PropertyInfo>[1], @@ -457,7 +471,7 @@ function <> meta::analytics::mapping::modelCoverage::buildInheri ):MappedEntity[*] { let entities = buildInheritanceEntitiesImpl($baseMapping, $mapping, $seenInheritanceTypes, $mappings, - $namePrefix, $rootClassMappings, $classMap, $propertiesMap, $inheritanceMap, $mappingClassMappings, $isRootEntity, $isBase, $config); + $namePrefix, $originalPropertyFilter, $rootClassMappings, $classMap, $propertiesMap, $inheritanceMap, $mappingClassMappings, $isRootEntity, $isBase, $config); $entities->map(e | ^$e(properties = $e.properties->removeDuplicatesBy(x | $x.name))); }