private static ProjectionAttributeStateSet CreateNewProjectionAttributeStateSet( ProjectionContext projCtx, ProjectionAttributeStateSet projOutputSet, ResolvedAttribute newResAttrFK, string refAttrName) { List <ProjectionAttributeState> pasList = ProjectionResolutionCommonUtil.GetLeafList(projCtx, refAttrName); if (pasList != null) { // update the new foreign key resolved attribute with trait param with reference details ResolvedTrait reqdTrait = newResAttrFK.ResolvedTraits.Find(projCtx.ProjectionDirective.ResOpt, "is.linkedEntity.identifier"); if (reqdTrait != null) { CdmEntityReference traitParamEntRef = ProjectionResolutionCommonUtil.CreateForeignKeyLinkedEntityIdentifierTraitParameter(projCtx.ProjectionDirective, projOutputSet.Ctx.Corpus, pasList); reqdTrait.ParameterValues.SetParameterValue(projCtx.ProjectionDirective.ResOpt, "entityReferences", traitParamEntRef); } // Create new output projection attribute state set for FK and add prevPas as previous state set ProjectionAttributeState newProjAttrStateFK = new ProjectionAttributeState(projOutputSet.Ctx) { CurrentResolvedAttribute = newResAttrFK, PreviousStateList = pasList }; projOutputSet.Add(newProjAttrStateFK); } else { // Log error & return projOutputSet without any change Logger.Error(TAG, projOutputSet.Ctx, $"Unable to locate state for reference attribute \"{refAttrName}\".", nameof(CreateNewProjectionAttributeStateSet)); } return(projOutputSet); }
private static ProjectionAttributeStateSet CreateNewProjectionAttributeStateSet( ProjectionContext projCtx, ProjectionAttributeStateSet projOutputSet, ResolvedAttribute newResAttrFK, string refAttrName) { List <ProjectionAttributeState> pasList = ProjectionResolutionCommonUtil.GetLeafList(projCtx, refAttrName); string sourceEntity = projCtx.ProjectionDirective.OriginalSourceAttributeName; if (sourceEntity == null) { Logger.Warning(projOutputSet.Ctx, Tag, nameof(CreateNewProjectionAttributeStateSet), null, CdmLogCode.WarnProjFKWithoutSourceEntity, refAttrName); } if (pasList != null) { // update the new foreign key resolved attribute with trait param with reference details ResolvedTrait reqdTrait = newResAttrFK.ResolvedTraits.Find(projCtx.ProjectionDirective.ResOpt, "is.linkedEntity.identifier"); if (reqdTrait != null && sourceEntity != null) { CdmEntityReference traitParamEntRef = ProjectionResolutionCommonUtil.CreateForeignKeyLinkedEntityIdentifierTraitParameter(projCtx.ProjectionDirective, projOutputSet.Ctx.Corpus, pasList); reqdTrait.ParameterValues.SetParameterValue(projCtx.ProjectionDirective.ResOpt, "entityReferences", traitParamEntRef); } // Create new output projection attribute state set for FK and add prevPas as previous state set ProjectionAttributeState newProjAttrStateFK = new ProjectionAttributeState(projOutputSet.Ctx) { CurrentResolvedAttribute = newResAttrFK, PreviousStateList = pasList }; projOutputSet.Add(newProjAttrStateFK); } else { // Log error & return projOutputSet without any change Logger.Error(projOutputSet.Ctx, Tag, nameof(CreateNewProjectionAttributeStateSet), null, CdmLogCode.ErrProjRefAttrStateFailure, refAttrName); } return(projOutputSet); }
/// <inheritdoc /> internal override ProjectionAttributeStateSet AppendProjectionAttributeState( ProjectionContext projCtx, ProjectionAttributeStateSet projOutputSet, CdmAttributeContext attrCtx) { // Create a new attribute context for the operation AttributeContextParameters attrCtxOpCombineAttrsParam = new AttributeContextParameters { under = attrCtx, type = CdmAttributeContextType.OperationCombineAttributes, Name = $"operation/index{Index}/operationCombineAttributes" }; CdmAttributeContext attrCtxOpCombineAttrs = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxOpCombineAttrsParam); // Initialize a projection attribute context tree builder with the created attribute context for the operation ProjectionAttributeContextTreeBuilder attrCtxTreeBuilder = new ProjectionAttributeContextTreeBuilder(attrCtxOpCombineAttrs); // Get all the leaf level PAS nodes from the tree for each selected attribute and cache to a dictionary Dictionary <string, List <ProjectionAttributeState> > leafLevelCombineAttributeNames = new Dictionary <string, List <ProjectionAttributeState> >(); // Also, create a single list of leaf level PAS List <ProjectionAttributeState> leafLevelMergePASList = new List <ProjectionAttributeState>(); foreach (string select in this.Select) { List <ProjectionAttributeState> leafLevelListForCurrentSelect = ProjectionResolutionCommonUtil.GetLeafList(projCtx, select); if (leafLevelListForCurrentSelect != null && leafLevelListForCurrentSelect.Count > 0 && !leafLevelCombineAttributeNames.ContainsKey(select)) { leafLevelCombineAttributeNames.Add(select, leafLevelListForCurrentSelect); leafLevelMergePASList.AddRange(leafLevelListForCurrentSelect); } } // Create a List of top-level PAS objects that will be get merged based on the selected attributes List <ProjectionAttributeState> pasMergeList = new List <ProjectionAttributeState>(); // Run through the top-level PAS objects foreach (ProjectionAttributeState currentPAS in projCtx.CurrentAttributeStateSet.States) { if (leafLevelCombineAttributeNames.ContainsKey(currentPAS.CurrentResolvedAttribute.ResolvedName)) { // Attribute to Merge if (!pasMergeList.Contains(currentPAS)) { pasMergeList.Add(currentPAS); } } else { // Attribute to Pass Through // Create a projection attribute state for the non-selected / pass-through attribute by creating a copy of the current state // Copy() sets the current state as the previous state for the new one ProjectionAttributeState newPAS = currentPAS.Copy(); projOutputSet.Add(newPAS); } } if (pasMergeList.Count > 0) { CdmTypeAttributeDefinition mergeIntoAttribute = this.MergeInto as CdmTypeAttributeDefinition; // the merged attribute needs one new place to live, so here it is AttributeContextParameters mergedAttrCtxParam = new AttributeContextParameters { under = attrCtxOpCombineAttrs, type = CdmAttributeContextType.AttributeDefinition, Name = mergeIntoAttribute.GetName() }; CdmAttributeContext mergedAttrCtx = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, mergedAttrCtxParam); // Create new resolved attribute, set the new attribute as target ResolvedAttribute raNewMergeInto = CreateNewResolvedAttribute(projCtx, mergedAttrCtx, mergeIntoAttribute, null); // Create new output projection attribute state set ProjectionAttributeState newMergeIntoPAS = new ProjectionAttributeState(projOutputSet.Ctx) { CurrentResolvedAttribute = raNewMergeInto, PreviousStateList = pasMergeList }; // Create the attribute context parameters and just store it in the builder for now // We will create the attribute contexts at the end foreach (string select in leafLevelCombineAttributeNames.Keys) { if (leafLevelCombineAttributeNames.ContainsKey(select) && leafLevelCombineAttributeNames[select] != null && leafLevelCombineAttributeNames[select].Count > 0) { foreach (ProjectionAttributeState leafLevelForSelect in leafLevelCombineAttributeNames[select]) { attrCtxTreeBuilder.CreateAndStoreAttributeContextParameters(select, leafLevelForSelect, newMergeIntoPAS.CurrentResolvedAttribute, CdmAttributeContextType.AttributeDefinition, leafLevelForSelect.CurrentResolvedAttribute.AttCtx, // lineage is the source att newMergeIntoPAS.CurrentResolvedAttribute.AttCtx); // merge into points back here } } } projOutputSet.Add(newMergeIntoPAS); } // Create all the attribute contexts and construct the tree attrCtxTreeBuilder.ConstructAttributeContextTree(projCtx); return(projOutputSet); }