/// <inheritdoc />
        internal override ProjectionAttributeStateSet AppendProjectionAttributeState(
            ProjectionContext projCtx,
            ProjectionAttributeStateSet projOutputSet,
            CdmAttributeContext attrCtx)
        {
            // Create a new attribute context for the operation
            AttributeContextParameters attrCtxOpAddAttrGroupParam = new AttributeContextParameters
            {
                under = attrCtx,
                type  = CdmAttributeContextType.OperationAddAttributeGroup,
                Name  = $"operation/index{Index}/{this.GetName()}"
            };
            CdmAttributeContext attrCtxOpAddAttrGroup = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxOpAddAttrGroupParam);

            // Create a new attribute context for the attribute group we will create
            AttributeContextParameters attrCtxAttrGroupParam = new AttributeContextParameters
            {
                under = attrCtxOpAddAttrGroup,
                type  = CdmAttributeContextType.AttributeDefinition,
                Name  = this.AttributeGroupName
            };
            CdmAttributeContext attrCtxAttrGroup = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxAttrGroupParam);

            // Create a new resolve attribute set builder that will be used to combine all the attributes into one set
            ResolvedAttributeSetBuilder rasb = new ResolvedAttributeSetBuilder();

            // Iterate through all the projection attribute states generated from the source's resolved attributes
            // Each projection attribute state contains a resolved attribute that it is corresponding to
            foreach (ProjectionAttributeState currentPAS in projCtx.CurrentAttributeStateSet.States)
            {
                // Create a copy of the resolved attribute
                ResolvedAttribute resolvedAttribute = currentPAS.CurrentResolvedAttribute.Copy();

                // Add the attribute to the resolved attribute set
                rasb.ResolvedAttributeSet.Merge(resolvedAttribute);

                // Add each attribute's attribute context to the resolved attribute set attribute context
                AttributeContextParameters AttrParam = new AttributeContextParameters
                {
                    under = attrCtxAttrGroup,
                    type  = CdmAttributeContextType.AttributeDefinition,
                    Name  = resolvedAttribute.ResolvedName
                };
                resolvedAttribute.AttCtx = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, AttrParam);
                resolvedAttribute.AttCtx.AddLineage(currentPAS.CurrentResolvedAttribute.AttCtx);
            }

            // Create a new resolved attribute that will hold the attribute set containing all the attributes
            ResolvedAttribute resAttrNew = new ResolvedAttribute(projCtx.ProjectionDirective.ResOpt, rasb.ResolvedAttributeSet, this.AttributeGroupName, attrCtxAttrGroup);

            // Create a new projection attribute state pointing to the resolved attribute set that represents the attribute group
            ProjectionAttributeState newPAS = new ProjectionAttributeState(this.Ctx)
            {
                CurrentResolvedAttribute = resAttrNew
            };

            projOutputSet.Add(newPAS);

            return(projOutputSet);
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        /// <inheritdoc />
        internal override ProjectionAttributeStateSet AppendProjectionAttributeState(
            ProjectionContext projCtx,
            ProjectionAttributeStateSet projOutputSet,
            CdmAttributeContext attrCtx)
        {
            // Create a new attribute context for the operation
            AttributeContextParameters attrCtxOpExcludeAttrsParam = new AttributeContextParameters
            {
                under = attrCtx,
                type  = CdmAttributeContextType.OperationExcludeAttributes,
                Name  = $"operation/index{Index}/operationExcludeAttributes"
            };
            CdmAttributeContext attrCtxOpExcludeAttrs = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxOpExcludeAttrsParam);

            // Get the top-level attribute names of the attributes to exclude
            // We use the top-level names because the exclude list may contain a previous name our current resolved attributes had
            Dictionary <string, string> topLevelExcludeAttributeNames = ProjectionResolutionCommonUtil.GetTopList(projCtx, this.ExcludeAttributes);

            // Initialize a projection attribute context tree builder with the created attribute context for the operation
            ProjectionAttributeContextTreeBuilder attrCtxTreeBuilder = new ProjectionAttributeContextTreeBuilder(attrCtxOpExcludeAttrs);

            // Iterate through all the projection attribute states generated from the source's resolved attributes
            // Each projection attribute state contains a resolved attribute that it is corresponding to
            foreach (ProjectionAttributeState currentPAS in projCtx.CurrentAttributeStateSet.States)
            {
                // Check if the current projection attribute state's resolved attribute is in the list of attributes to exclude
                // If this attribute is not in the exclude list, then we are including it in the output
                if (!topLevelExcludeAttributeNames.ContainsKey(currentPAS.CurrentResolvedAttribute.ResolvedName))
                {
                    // Create the attribute context parameters and just store it in the builder for now
                    // We will create the attribute contexts at the end
                    attrCtxTreeBuilder.CreateAndStoreAttributeContextParameters(null, currentPAS, currentPAS.CurrentResolvedAttribute, CdmAttributeContextType.AttributeDefinition);

                    // Create a projection attribute state for the included attribute by creating a copy of the current state
                    // Copy() sets the current state as the previous state for the new one
                    // We only create projection attribute states for attributes that are not in the exclude list
                    ProjectionAttributeState newPAS = currentPAS.Copy();

                    projOutputSet.Add(newPAS);
                }
                else
                {
                    // The current projection attribute state's resolved attribute is in the exclude list

                    // Get the attribute name the way it appears in the exclude list
                    string excludeAttributeName = null;
                    topLevelExcludeAttributeNames.TryGetValue(currentPAS.CurrentResolvedAttribute.ResolvedName, out excludeAttributeName);

                    // Create the attribute context parameters and just store it in the builder for now
                    // We will create the attribute contexts at the end
                    attrCtxTreeBuilder.CreateAndStoreAttributeContextParameters(excludeAttributeName, currentPAS, currentPAS.CurrentResolvedAttribute, CdmAttributeContextType.AttributeDefinition);
                }
            }

            // Create all the attribute contexts and construct the tree
            attrCtxTreeBuilder.ConstructAttributeContextTree(projCtx);

            return(projOutputSet);
        }
Esempio n. 4
0
        /// <inheritdoc />
        internal override ProjectionAttributeStateSet AppendProjectionAttributeState(
            ProjectionContext projCtx,
            ProjectionAttributeStateSet projOutputSet,
            CdmAttributeContext attrCtx)
        {
            // Pass through all the input projection attribute states if there are any
            foreach (ProjectionAttributeState currentPAS in projCtx.CurrentAttributeStateSet.States)
            {
                projOutputSet.Add(currentPAS);
            }

            // Create a new attribute context for the operation
            AttributeContextParameters attrCtxOpAddSupportingAttrParam = new AttributeContextParameters
            {
                under = attrCtx,
                type  = CdmAttributeContextType.OperationAddSupportingAttribute,
                Name  = $"operation/index{Index}/{this.GetName()}"
            };
            CdmAttributeContext attrCtxOpAddSupportingAttr = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxOpAddSupportingAttrParam);

            // Create a new attribute context for the supporting attribute we will create
            AttributeContextParameters attrCtxTypeAttrParam = new AttributeContextParameters
            {
                under = attrCtxOpAddSupportingAttr,
                type  = CdmAttributeContextType.AddedAttributeSupporting,
                Name  = this.SupportingAttribute.Name
            };
            CdmAttributeContext attrCtxSupportingAttr = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxTypeAttrParam);

            // TODO: this if statement keeps the functionality the same way it works currently in resolution guidance.
            // This should be changed to point to the foreign key attribute instead.
            // There has to be some design decisions about how this will work and will be done in the next release.
            if (projCtx.CurrentAttributeStateSet.States.Count > 0)
            {
                ProjectionAttributeState lastState        = projCtx.CurrentAttributeStateSet.States[projCtx.CurrentAttributeStateSet.States.Count - 1];
                CdmTraitReference        inSupportOfTrait = this.SupportingAttribute.AppliedTraits.Add("is.addedInSupportOf");
                inSupportOfTrait.Arguments.Add("inSupportOf", lastState.CurrentResolvedAttribute.ResolvedName);
            }

            // Create the supporting attribute with the specified "SupportingAttribute" property as its target and apply the trait "is.virtual.attribute" to it
            List <string> addTrait = new List <string>()
            {
                "is.virtual.attribute"
            };
            ResolvedAttribute newResAttr = CreateNewResolvedAttribute(projCtx, attrCtxSupportingAttr, this.SupportingAttribute, addedSimpleRefTraits: addTrait);

            // Create a new projection attribute state for the new supporting attribute and add it to the output set
            // There is no previous state for the newly created supporting attribute
            ProjectionAttributeState newPAS = new ProjectionAttributeState(projOutputSet.Ctx)
            {
                CurrentResolvedAttribute = newResAttr
            };

            projOutputSet.Add(newPAS);

            return(projOutputSet);
        }
        /// <inheritdoc />
        internal override ProjectionAttributeStateSet AppendProjectionAttributeState(
            ProjectionContext projCtx,
            ProjectionAttributeStateSet projOutputSet,
            CdmAttributeContext attrCtx)
        {
            // Create a new attribute context for the operation
            AttributeContextParameters attrCtxOpIncludeAttrsParam = new AttributeContextParameters
            {
                under = attrCtx,
                type  = CdmAttributeContextType.OperationIncludeAttributes,
                Name  = $"operation/index{Index}/operationIncludeAttributes"
            };
            CdmAttributeContext attrCtxOpIncludeAttrs = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxOpIncludeAttrsParam);

            // Get the top-level attribute names for each of the included attributes
            // Since the include operation allows providing either current state resolved attribute names
            //   or the previous state resolved attribute names, we search for the name in the PAS tree
            //   and fetch the top level resolved attribute names.
            Dictionary <string, string> topLevelIncludeAttributeNames = ProjectionResolutionCommonUtil.GetTopList(projCtx, this.IncludeAttributes);

            // Initialize a projection attribute context tree builder with the created attribute context for the operation
            ProjectionAttributeContextTreeBuilder attrCtxTreeBuilder = new ProjectionAttributeContextTreeBuilder(attrCtxOpIncludeAttrs);

            // Iterate through all the PAS in the PASSet generated from the projection source's resolved attributes
            foreach (ProjectionAttributeState currentPAS in projCtx.CurrentAttributeStateSet.States)
            {
                // Check if the current PAS's RA is in the list of attributes to include.
                if (topLevelIncludeAttributeNames.ContainsKey(currentPAS.CurrentResolvedAttribute.ResolvedName))
                {
                    // Get the attribute name the way it appears in the include list
                    string includeAttributeName = null;
                    topLevelIncludeAttributeNames.TryGetValue(currentPAS.CurrentResolvedAttribute.ResolvedName, out includeAttributeName);

                    // Create the attribute context parameters and just store it in the builder for now
                    // We will create the attribute contexts at the end
                    attrCtxTreeBuilder.CreateAndStoreAttributeContextParameters(includeAttributeName, currentPAS, currentPAS.CurrentResolvedAttribute, CdmAttributeContextType.AttributeDefinition);

                    // Create a projection attribute state for the included attribute by creating a copy of the current state
                    // Copy() sets the current state as the previous state for the new one
                    // We only create projection attribute states for attributes in the include list
                    ProjectionAttributeState newPAS = currentPAS.Copy();

                    projOutputSet.Add(newPAS);
                }
                else
                {
                    // Create the attribute context parameters and just store it in the builder for now
                    // We will create the attribute contexts at the end
                    attrCtxTreeBuilder.CreateAndStoreAttributeContextParameters(null, currentPAS, currentPAS.CurrentResolvedAttribute, CdmAttributeContextType.AttributeDefinition);
                }
            }

            // Create all the attribute contexts and construct the tree
            attrCtxTreeBuilder.ConstructAttributeContextTree(projCtx);

            return(projOutputSet);
        }
        /// <summary>
        /// Renames an attribute with the current renameFormat.
        /// </summary>
        /// <param name="projectionOwnerName">The attribute name of projection owner (only available when the owner is an entity attribute or type attribute).</param>
        /// <param name="currentPAS">The attribute state.</param>
        /// <returns></returns>
        private string GetNewAttributeName(string projectionOwnerName, ProjectionAttributeState currentPAS)
        {
            if (string.IsNullOrEmpty(this.RenameFormat))
            {
                Logger.Error((ResolveContext)this.Ctx, Tag, nameof(GetNewAttributeName), this.AtCorpusPath, CdmLogCode.ErrProjRenameFormatIsNotSet);
                return("");
            }

            return(ReplaceWildcardCharacters(this.RenameFormat, projectionOwnerName, currentPAS));
        }
Esempio n. 7
0
        /// <summary>
        /// Get a resolved trait set which contains new resolved traits with placement for wild characters if it's applicable.
        /// </summary>
        /// <param name="projCtx">The current projection context.</param>
        /// <param name="currentPAS">The current attribute state set.</param>
        /// <returns></returns>
        private ResolvedTraitSet ResolvedNewTraits(ProjectionContext projCtx, ProjectionAttributeState currentPAS)
        {
            ResolvedTraitSet resolvedTraitSet    = new ResolvedTraitSet(projCtx.ProjectionDirective.ResOpt);
            string           projectionOwnerName = projCtx.ProjectionDirective.OriginalSourceAttributeName ?? "";

            foreach (var traitRef in this.TraitsToAdd)
            {
                var traitRefCopy = traitRef.FetchResolvedTraits(projCtx.ProjectionDirective.ResOpt).DeepCopy();
                ReplaceWildcardCharacters(projCtx.ProjectionDirective.ResOpt, traitRefCopy, projectionOwnerName, currentPAS);
                resolvedTraitSet = resolvedTraitSet.MergeSet(traitRefCopy);
            }

            return(resolvedTraitSet);
        }
Esempio n. 8
0
        /// <inheritdoc />
        internal override ProjectionAttributeStateSet AppendProjectionAttributeState(
            ProjectionContext projCtx,
            ProjectionAttributeStateSet projOutputSet,
            CdmAttributeContext attrCtx)
        {
            // Pass through all the input projection attribute states if there are any
            foreach (ProjectionAttributeState currentPAS in projCtx.CurrentAttributeStateSet.States)
            {
                projOutputSet.Add(currentPAS);
            }

            // Create a new attribute context for the operation
            AttributeContextParameters attrCtxOpAddTypeParam = new AttributeContextParameters
            {
                under = attrCtx,
                type  = CdmAttributeContextType.OperationAddTypeAttribute,
                Name  = $"operation/index{Index}/operationAddTypeAttribute"
            };
            CdmAttributeContext attrCtxOpAddType = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxOpAddTypeParam);

            // Create a new attribute context for the Type attribute we will create
            AttributeContextParameters attrCtxTypeAttrParam = new AttributeContextParameters
            {
                under = attrCtxOpAddType,
                type  = CdmAttributeContextType.AddedAttributeSelectedType,
                Name  = "_selectedEntityName"
            };
            CdmAttributeContext attrCtxTypeAttr = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxTypeAttrParam);

            // Create the Type attribute with the specified "typeAttribute" (from the operation) as its target and apply the trait "is.linkedEntity.name" to it
            List <string> addTrait = new List <string>()
            {
                "is.linkedEntity.name"
            };
            ResolvedAttribute newResAttr = CreateNewResolvedAttribute(projCtx, attrCtxTypeAttr, this.TypeAttribute, addedSimpleRefTraits: addTrait);

            // Create a new projection attribute state for the new Type attribute and add it to the output set
            // There is no previous state for the newly created Type attribute
            ProjectionAttributeState newPAS = new ProjectionAttributeState(projOutputSet.Ctx)
            {
                CurrentResolvedAttribute = newResAttr
            };

            projOutputSet.Add(newPAS);

            return(projOutputSet);
        }
        /// <summary>
        /// Create a new artifact attribute and add it to the projOutputSet.
        /// </summary>
        /// <param name="projCtx">The projection context.</param>
        /// <param name="projOutputSet">The projection attribute state set.</param>
        /// <param name="attrCtx">The attribute context.</param>
        /// <returns></returns>
        private void AddNewArtifactAttributeState(ProjectionContext projCtx, ProjectionAttributeStateSet projOutputSet, CdmAttributeContext attrCtx)
        {
            // Create a new attribute context for the operation
            AttributeContextParameters attrCtxOpAddArtifactAttrParam = new AttributeContextParameters
            {
                under = attrCtx,
                type  = CdmAttributeContextType.OperationAddArtifactAttribute,
                Name  = $"operation/index{Index}/{this.GetName()}"
            };
            CdmAttributeContext attrCtxOpAddArtifactAttr = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxOpAddArtifactAttrParam);

            if (this.NewAttribute is CdmTypeAttributeDefinition)
            {
                // Create a new attribute context for the new artifact attribute we will create
                AttributeContextParameters attrCtxNewAttrParam = new AttributeContextParameters
                {
                    under = attrCtxOpAddArtifactAttr,
                    type  = CdmAttributeContextType.AddedAttributeNewArtifact,
                    Name  = this.NewAttribute.FetchObjectDefinitionName()
                };
                CdmAttributeContext attrCtxNewAttr = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxNewAttrParam);
                ResolvedAttribute   newResAttr     = CreateNewResolvedAttribute(projCtx, attrCtxNewAttr, (CdmAttribute)this.NewAttribute);

                // Create a new projection attribute state for the new artifact attribute and add it to the output set
                // There is no previous state for the newly created attribute
                ProjectionAttributeState newPAS = new ProjectionAttributeState(projOutputSet.Ctx)
                {
                    CurrentResolvedAttribute = newResAttr
                };

                projOutputSet.Add(newPAS);
            }
            else if (this.NewAttribute is CdmEntityAttributeDefinition || this.NewAttribute is CdmAttributeGroupReference)
            {
                var typeStr = this.NewAttribute is CdmEntityAttributeDefinition ? "an entity attribute" : "an attribute group";
                Logger.Warning(this.Ctx, Tag, nameof(AppendProjectionAttributeState), this.AtCorpusPath, CdmLogCode.WarnProjAddArtifactAttrNotSupported, typeStr);
            }
            else
            {
                Logger.Error(this.Ctx, Tag, nameof(AppendProjectionAttributeState), this.AtCorpusPath, CdmLogCode.ErrProjUnsupportedSource, this.NewAttribute.ObjectType.ToString(), this.GetName());
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Renames an attribute with the current renameFormat
        /// </summary>
        /// <param name="attributeState">The attribute state.</param>
        /// <param name="sourceAttributeName">The parent attribute name (if any).</param>
        /// <returns></returns>
        private string RenameAttribute(ProjectionAttributeState attributeState, string sourceAttributeName)
        {
            string currentAttributeName = attributeState.CurrentResolvedAttribute.ResolvedName;
            string ordinal = attributeState.Ordinal != null?attributeState.Ordinal.ToString() : "";

            string format = this.RenameFormat;

            if (string.IsNullOrEmpty(format))
            {
                Logger.Error(TAG, this.Ctx, "RenameFormat should be set for this operation to work.");
                return("");
            }

            string attributeName = StringUtils.Replace(format, 'a', sourceAttributeName);

            attributeName = StringUtils.Replace(attributeName, 'o', ordinal);
            attributeName = StringUtils.Replace(attributeName, 'm', currentAttributeName);

            return(attributeName);
        }
Esempio n. 11
0
        /// <summary>
        /// Renames an attribute with the current renameFormat
        /// </summary>
        /// <param name="attributeState">The attribute state.</param>
        /// <param name="sourceAttributeName">The parent attribute name (if any).</param>
        /// <returns></returns>
        private string GetNewAttributeName(ProjectionAttributeState attributeState, string sourceAttributeName)
        {
            string currentAttributeName = attributeState.CurrentResolvedAttribute.ResolvedName;
            string ordinal = attributeState.Ordinal != null?attributeState.Ordinal.ToString() : "";

            string format = this.RenameFormat;

            if (string.IsNullOrEmpty(format))
            {
                Logger.Error((ResolveContext)this.Ctx, Tag, nameof(GetNewAttributeName), this.AtCorpusPath, CdmLogCode.ErrProjRenameFormatIsNotSet);
                return("");
            }

            string attributeName = StringUtils.Replace(format, 'a', sourceAttributeName);

            attributeName = StringUtils.Replace(attributeName, 'o', ordinal);
            attributeName = StringUtils.Replace(attributeName, 'm', currentAttributeName);

            return(attributeName);
        }
        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);
        }
Esempio n. 13
0
        /// <inheritdoc />
        internal override ProjectionAttributeStateSet AppendProjectionAttributeState(
            ProjectionContext projCtx,
            ProjectionAttributeStateSet projOutputSet,
            CdmAttributeContext attrCtx)
        {
            // Create a new attribute context for the operation
            AttributeContextParameters attrCtxOpAlterTraitsParam = new AttributeContextParameters
            {
                under = attrCtx,
                type  = CdmAttributeContextType.OperationAlterTraits,
                Name  = $"operation/index{Index}/{this.GetName()}"
            };
            CdmAttributeContext attrCtxOpAlterTraits = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxOpAlterTraitsParam);

            // Get the top-level attribute names of the selected attributes to apply
            // We use the top-level names because the applyTo list may contain a previous name our current resolved attributes had
            Dictionary <string, string> topLevelSelectedAttributeNames = this.ApplyTo != null?ProjectionResolutionCommonUtil.GetTopList(projCtx, this.ApplyTo) : null;

            foreach (ProjectionAttributeState currentPAS in projCtx.CurrentAttributeStateSet.States)
            {
                // Check if the current projection attribute state's resolved attribute is in the list of selected attributes
                // If this attribute is not in the list, then we are including it in the output without changes
                if (topLevelSelectedAttributeNames == null || topLevelSelectedAttributeNames.ContainsKey(currentPAS.CurrentResolvedAttribute.ResolvedName))
                {
                    // Create a new attribute context for the new attribute we will create
                    AttributeContextParameters attrCtxNewAttrParam = new AttributeContextParameters
                    {
                        under = attrCtxOpAlterTraits,
                        type  = CdmAttributeContextType.AttributeDefinition,
                        Name  = currentPAS.CurrentResolvedAttribute.ResolvedName
                    };
                    CdmAttributeContext attrCtxNewAttr = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxNewAttrParam);

                    ResolvedAttribute newResAttr = null;

                    if (currentPAS.CurrentResolvedAttribute.Target is ResolvedAttributeSet)
                    {
                        // Attribute group
                        // Create a copy of resolved attribute set
                        ResolvedAttributeSet resAttrNewCopy = ((ResolvedAttributeSet)currentPAS.CurrentResolvedAttribute.Target).Copy();
                        newResAttr = new ResolvedAttribute(projCtx.ProjectionDirective.ResOpt, resAttrNewCopy, currentPAS.CurrentResolvedAttribute.ResolvedName, attrCtxNewAttr);

                        // the resolved attribute group obtained from previous projection operation may have a different set of traits comparing to the resolved attribute target.
                        // We would want to take the set of traits from the resolved attribute.
                        newResAttr.ResolvedTraits = currentPAS.CurrentResolvedAttribute.ResolvedTraits.DeepCopy();
                    }
                    else if (currentPAS.CurrentResolvedAttribute.Target is CdmAttribute)
                    {
                        // Entity Attribute or Type Attribute
                        newResAttr = CreateNewResolvedAttribute(projCtx, attrCtxNewAttr, currentPAS.CurrentResolvedAttribute, currentPAS.CurrentResolvedAttribute.ResolvedName);
                    }
                    else
                    {
                        Logger.Error(this.Ctx, Tag, nameof(AppendProjectionAttributeState), this.AtCorpusPath, CdmLogCode.ErrProjUnsupportedSource, currentPAS.CurrentResolvedAttribute.Target.ObjectType.ToString(), this.GetName());
                        // Add the attribute without changes
                        projOutputSet.Add(currentPAS);
                        break;
                    }

                    newResAttr.ResolvedTraits = newResAttr.ResolvedTraits.MergeSet(this.ResolvedNewTraits(projCtx, currentPAS));
                    this.RemoveTraitsInNewAttribute(projCtx.ProjectionDirective.ResOpt, newResAttr);

                    // Create a projection attribute state for the new attribute with new applied traits 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();

                    // Update the resolved attribute to be the new attribute we created
                    newPAS.CurrentResolvedAttribute = newResAttr;

                    projOutputSet.Add(newPAS);
                }
                else
                {
                    // Pass through
                    projOutputSet.Add(currentPAS);
                }
            }

            return(projOutputSet);
        }
Esempio n. 14
0
        /// <inheritdoc />
        internal override ProjectionAttributeStateSet AppendProjectionAttributeState(
            ProjectionContext projCtx,
            ProjectionAttributeStateSet projOutputSet,
            CdmAttributeContext attrCtx)
        {
            // Create a new attribute context for the operation
            AttributeContextParameters attrCtxOpIncludeAttrsParam = new AttributeContextParameters
            {
                under = attrCtx,
                type  = CdmAttributeContextType.OperationIncludeAttributes,
                Name  = $"operation/index{Index}/operationIncludeAttributes"
            };
            CdmAttributeContext attrCtxOpIncludeAttrs = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxOpIncludeAttrsParam);

            // Get the top-level attribute names for each of the included attributes
            // Since the include operation allows providing either current state resolved attribute names
            //   or the previous state resolved attribute names, we search for the name in the PAS tree
            //   and fetch the top level resolved attribute names.
            Dictionary <string, string> topLevelIncludeAttributeNames = ProjectionResolutionCommonUtil.GetTopList(projCtx, this.IncludeAttributes);

            // Initialize a projection attribute context tree builder with the created attribute context for the operation
            ProjectionAttributeContextTreeBuilder attrCtxTreeBuilder = new ProjectionAttributeContextTreeBuilder(attrCtxOpIncludeAttrs);

            // Index that holds the current attribute name as the key and the attribute as value
            Dictionary <string, ProjectionAttributeState> topLevelIncludeAttribute = new Dictionary <string, ProjectionAttributeState>();

            // List of attributes that were not included on the final attribute list
            List <ProjectionAttributeState> removedAttributes = new List <ProjectionAttributeState>();

            // Iterate through all the PAS in the PASSet generated from the projection source's resolved attributes
            foreach (ProjectionAttributeState currentPAS in projCtx.CurrentAttributeStateSet.States)
            {
                // Check if the current PAS's RA is in the list of attributes to include.
                if (topLevelIncludeAttributeNames.ContainsKey(currentPAS.CurrentResolvedAttribute.ResolvedName))
                {
                    topLevelIncludeAttribute.Add(currentPAS.CurrentResolvedAttribute.ResolvedName, currentPAS);
                }
                else
                {
                    removedAttributes.Add(currentPAS);
                }
            }

            // Loop through the list of attributes in the same order that was specified by the user
            foreach (KeyValuePair <string, string> entry in topLevelIncludeAttributeNames)
            {
                // Get the attribute state
                ProjectionAttributeState currentPAS = topLevelIncludeAttribute[entry.Key];

                // Get the attribute name the way it appears in the include list
                string includeAttributeName = entry.Value;

                // Create the attribute context parameters and just store it in the builder for now
                // We will create the attribute contexts at the end
                attrCtxTreeBuilder.CreateAndStoreAttributeContextParameters(includeAttributeName, currentPAS, currentPAS.CurrentResolvedAttribute,
                                                                            CdmAttributeContextType.AttributeDefinition,
                                                                            currentPAS.CurrentResolvedAttribute.AttCtx, // lineage is the included attribute
                                                                            null);                                      // don't know who will point here yet

                // Create a projection attribute state for the included attribute by creating a copy of the current state
                // Copy() sets the current state as the previous state for the new one
                // We only create projection attribute states for attributes in the include list
                ProjectionAttributeState newPAS = currentPAS.Copy();

                projOutputSet.Add(newPAS);
            }

            // Generate attribute context nodes for the attributes that were not included
            foreach (ProjectionAttributeState currentPAS in removedAttributes)
            {
                // Create the attribute context parameters and just store it in the builder for now
                // We will create the attribute contexts at the end
                attrCtxTreeBuilder.CreateAndStoreAttributeContextParameters(null, currentPAS, currentPAS.CurrentResolvedAttribute,
                                                                            CdmAttributeContextType.AttributeExcluded,
                                                                            currentPAS.CurrentResolvedAttribute.AttCtx, // lineage is the included attribute
                                                                            null);                                      // don't know who will point here yet
            }

            // Create all the attribute contexts and construct the tree
            attrCtxTreeBuilder.ConstructAttributeContextTree(projCtx);

            return(projOutputSet);
        }
Esempio n. 15
0
        /// <inheritdoc />
        internal override ProjectionAttributeStateSet AppendProjectionAttributeState(
            ProjectionContext projCtx,
            ProjectionAttributeStateSet projOutputSet,
            CdmAttributeContext attrCtx)
        {
            // Create a new attribute context for the operation
            AttributeContextParameters attrCtxOpExcludeAttrsParam = new AttributeContextParameters
            {
                under = attrCtx,
                type  = CdmAttributeContextType.OperationExcludeAttributes,
                Name  = $"operation/index{Index}/operationExcludeAttributes"
            };
            CdmAttributeContext attrCtxOpExcludeAttrs = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxOpExcludeAttrsParam);

            // Get the top-level attribute names of the attributes to exclude
            // We use the top-level names because the exclude list may contain a previous name our current resolved attributes had
            Dictionary <string, string> topLevelExcludeAttributeNames = ProjectionResolutionCommonUtil.GetTopList(projCtx, this.ExcludeAttributes);

            // Iterate through all the projection attribute states generated from the source's resolved attributes
            // Each projection attribute state contains a resolved attribute that it is corresponding to
            foreach (ProjectionAttributeState currentPAS in projCtx.CurrentAttributeStateSet.Values)
            {
                // Check if the current projection attribute state's resolved attribute is in the list of attributes to exclude
                // If this attribute is not in the exclude list, then we are including it in the output
                if (!topLevelExcludeAttributeNames.ContainsKey(currentPAS.CurrentResolvedAttribute.ResolvedName))
                {
                    // Create a new attribute context for the attribute that we are including
                    AttributeContextParameters attrCtxAddedAttrParam = new AttributeContextParameters
                    {
                        under = attrCtx,
                        type  = CdmAttributeContextType.AttributeDefinition,
                        Name  = currentPAS.CurrentResolvedAttribute.ResolvedName
                    };
                    CdmAttributeContext attrCtxAddedAttr = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxAddedAttrParam);

                    // Create a projection attribute state for the included attribute
                    // We only create projection attribute states for attributes that are not in the exclude list
                    // Add the current projection attribute state as the previous state of the new projection attribute state
                    ProjectionAttributeState newPAS = new ProjectionAttributeState(projOutputSet.Ctx)
                    {
                        CurrentResolvedAttribute = currentPAS.CurrentResolvedAttribute,
                        PreviousStateList        = new List <ProjectionAttributeState> {
                            currentPAS
                        }
                    };

                    projOutputSet.Add(newPAS);
                }
                else
                {
                    // The current projection attribute state's resolved attribute is in the exclude list

                    // Get the attribute name the way it appears in the exclude list
                    // For our attribute context, we want to use the attribute name the attribute has in the exclude list rather than its current name
                    string excludeAttributeName = null;
                    topLevelExcludeAttributeNames.TryGetValue(currentPAS.CurrentResolvedAttribute.ResolvedName, out excludeAttributeName);

                    // Create a new attribute context for the excluded attribute
                    AttributeContextParameters attrCtxExcludedAttrParam = new AttributeContextParameters
                    {
                        under = attrCtxOpExcludeAttrs,
                        type  = CdmAttributeContextType.AttributeDefinition,
                        Name  = excludeAttributeName
                    };
                    CdmAttributeContext attrCtxExcludedAttr = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxExcludedAttrParam);
                }
            }

            return(projOutputSet);
        }
Esempio n. 16
0
        private ProjectionContext BuildFakeTree(CdmCorpusDefinition corpus)
        {
            ProjectionDirective projDir = new ProjectionDirective(new ResolveOptions()
            {
            }, null);
            ProjectionContext pc = new ProjectionContext(projDir, null);

            {
                ProjectionAttributeState p1 = new ProjectionAttributeState(corpus.Ctx);
                p1.CurrentResolvedAttribute = new ResolvedAttribute(projDir.ResOpt, "1", "1", null);
                ProjectionAttributeState p2 = new ProjectionAttributeState(corpus.Ctx);
                p2.CurrentResolvedAttribute = new ResolvedAttribute(projDir.ResOpt, "2", "2", null);
                ProjectionAttributeState p4 = new ProjectionAttributeState(corpus.Ctx);
                p4.CurrentResolvedAttribute = new ResolvedAttribute(projDir.ResOpt, "4", "4", null);
                ProjectionAttributeState p5 = new ProjectionAttributeState(corpus.Ctx);
                p5.CurrentResolvedAttribute = new ResolvedAttribute(projDir.ResOpt, "5", "5", null);
                ProjectionAttributeState p6 = new ProjectionAttributeState(corpus.Ctx);
                p6.CurrentResolvedAttribute = new ResolvedAttribute(projDir.ResOpt, "6", "6", null);
                ProjectionAttributeState p7 = new ProjectionAttributeState(corpus.Ctx);
                p7.CurrentResolvedAttribute = new ResolvedAttribute(projDir.ResOpt, "7", "7", null);
                ProjectionAttributeState p8 = new ProjectionAttributeState(corpus.Ctx);
                p8.CurrentResolvedAttribute = new ResolvedAttribute(projDir.ResOpt, "8", "8", null);
                ProjectionAttributeState p9 = new ProjectionAttributeState(corpus.Ctx);
                p9.CurrentResolvedAttribute = new ResolvedAttribute(projDir.ResOpt, "9", "9", null);
                ProjectionAttributeState p10 = new ProjectionAttributeState(corpus.Ctx);
                p10.CurrentResolvedAttribute = new ResolvedAttribute(projDir.ResOpt, "10", "10", null);
                ProjectionAttributeState p11 = new ProjectionAttributeState(corpus.Ctx);
                p11.CurrentResolvedAttribute = new ResolvedAttribute(projDir.ResOpt, "11", "11", null);
                ProjectionAttributeState p12 = new ProjectionAttributeState(corpus.Ctx);
                p12.CurrentResolvedAttribute = new ResolvedAttribute(projDir.ResOpt, "12", "12", null);
                ProjectionAttributeState p13 = new ProjectionAttributeState(corpus.Ctx);
                p13.CurrentResolvedAttribute = new ResolvedAttribute(projDir.ResOpt, "13", "13", null);
                ProjectionAttributeState p14 = new ProjectionAttributeState(corpus.Ctx);
                p14.CurrentResolvedAttribute = new ResolvedAttribute(projDir.ResOpt, "14", "14", null);
                ProjectionAttributeState p15 = new ProjectionAttributeState(corpus.Ctx);
                p15.CurrentResolvedAttribute = new ResolvedAttribute(projDir.ResOpt, "15", "15", null);
                ProjectionAttributeState p16 = new ProjectionAttributeState(corpus.Ctx);
                p16.CurrentResolvedAttribute = new ResolvedAttribute(projDir.ResOpt, "16", "16", null);
                ProjectionAttributeState p17 = new ProjectionAttributeState(corpus.Ctx);
                p17.CurrentResolvedAttribute = new ResolvedAttribute(projDir.ResOpt, "17", "17", null);

                p1.PreviousStateList  = new List <ProjectionAttributeState>();
                p2.PreviousStateList  = new List <ProjectionAttributeState>();
                p4.PreviousStateList  = new List <ProjectionAttributeState>();
                p5.PreviousStateList  = new List <ProjectionAttributeState>();
                p6.PreviousStateList  = new List <ProjectionAttributeState>();
                p7.PreviousStateList  = new List <ProjectionAttributeState>();
                p8.PreviousStateList  = new List <ProjectionAttributeState>();
                p9.PreviousStateList  = new List <ProjectionAttributeState>();
                p10.PreviousStateList = new List <ProjectionAttributeState>();
                p11.PreviousStateList = new List <ProjectionAttributeState>();
                p12.PreviousStateList = new List <ProjectionAttributeState>();
                p13.PreviousStateList = new List <ProjectionAttributeState>();
                p14.PreviousStateList = new List <ProjectionAttributeState>();
                p15.PreviousStateList = new List <ProjectionAttributeState>();
                p16.PreviousStateList = new List <ProjectionAttributeState>();
                p17.PreviousStateList = new List <ProjectionAttributeState>();

                p11.PreviousStateList.Add(p7);
                p7.PreviousStateList.Add(p2);
                p2.PreviousStateList.Add(p1);
                p12.PreviousStateList.Add(p8);
                p8.PreviousStateList.Add(p1);
                p13.PreviousStateList.Add(p9);
                p9.PreviousStateList.Add(p4);
                p9.PreviousStateList.Add(p5);
                p13.PreviousStateList.Add(p10);
                p10.PreviousStateList.Add(p6);
                p14.PreviousStateList.Add(p16);
                p16.PreviousStateList.Add(p1);
                p15.PreviousStateList.Add(p7);
                p17.PreviousStateList.Add(p8);

                pc.CurrentAttributeStateSet.Add(p11);
                pc.CurrentAttributeStateSet.Add(p12);
                pc.CurrentAttributeStateSet.Add(p13);
                pc.CurrentAttributeStateSet.Add(p14);
                pc.CurrentAttributeStateSet.Add(p15);
                pc.CurrentAttributeStateSet.Add(p17);
            }

            return(pc);
        }
Esempio n. 17
0
        /// <summary>
        /// Creates the attribute context parameters for the searchFor, found, and action nodes and then stores them in different maps.
        /// The maps are used when constructing the actual attribute context tree.
        /// </summary>
        /// <param name="searchFor">The "search for" string</param>
        /// <param name="found">The projection attribute state that contains the "found" attribute</param>
        /// <param name="resAttrFromAction">The resolved attribute that resulted from the action</param>
        /// <param name="attrCtxType">The attribute context type to give the "action" attribute context parameter</param>
        internal void CreateAndStoreAttributeContextParameters(string searchFor, ProjectionAttributeState found, ResolvedAttribute resAttrFromAction, CdmAttributeContextType attrCtxType)
        {
            // searchFor is null when we have to construct attribute contexts for the excluded attributes in Include or the included attributes in Exclude,
            // as these attributes weren't searched for with a searchFor name.
            // If searchFor is null, just set it to have the same name as found so that it'll collapse in the final tree.
            if (searchFor == null)
            {
                searchFor = found.CurrentResolvedAttribute.ResolvedName;
            }

            // Create the attribute context parameter for the searchFor node and store it in the map as [searchFor name]:[attribute context parameter]
            AttributeContextParameters searchForAttrCtxParam = null;

            if (!searchForToSearchForAttrCtxParam.ContainsKey(searchFor))
            {
                searchForAttrCtxParam = new AttributeContextParameters
                {
                    under = root,
                    type  = CdmAttributeContextType.AttributeDefinition,
                    Name  = searchFor
                };

                searchForToSearchForAttrCtxParam.Add(searchFor, searchForAttrCtxParam);
            }
            else
            {
                searchForToSearchForAttrCtxParam.TryGetValue(searchFor, out searchForAttrCtxParam);
            }

            // Create the attribute context parameter for the found node
            AttributeContextParameters foundAttrCtxParam = new AttributeContextParameters
            {
                under = root, // Set this to be under the root for now, as we may end up collapsing this node
                type  = CdmAttributeContextType.AttributeDefinition,
                Name  = $"{found.CurrentResolvedAttribute.ResolvedName}{(found.Ordinal != null ? "@" + found.Ordinal : "")}"
            };

            // Store this in the map as [searchFor attribute context parameter]:[found attribute context parameters]
            // We store it this way so that we can create the found nodes under their corresponding searchFor nodes.
            if (!searchForAttrCtxParamToFoundAttrCtxParam.ContainsKey(searchForAttrCtxParam))
            {
                searchForAttrCtxParamToFoundAttrCtxParam.Add(searchForAttrCtxParam, new List <AttributeContextParameters> {
                    foundAttrCtxParam
                });
            }
            else
            {
                List <AttributeContextParameters> foundAttrCtxParams = null;
                searchForAttrCtxParamToFoundAttrCtxParam.TryGetValue(searchForAttrCtxParam, out foundAttrCtxParams);
                foundAttrCtxParams.Add(foundAttrCtxParam);
                searchForAttrCtxParamToFoundAttrCtxParam[searchForAttrCtxParam] = foundAttrCtxParams;
            }

            // Create the attribute context parameter for the action node
            AttributeContextParameters actionAttrCtxParam = new AttributeContextParameters
            {
                under = root,        // Set this to be under the root for now, as we may end up collapsing this node
                type  = attrCtxType, // This type will be updated once we implement the new attribute context types
                Name  = resAttrFromAction.ResolvedName
            };

            // Store this in the map as [found attribute context parameter]:[action attribute context parameter]
            // We store it this way so that we can create the action nodes under their corresponding found nodes.
            foundAttrCtxParamToActionAttrCtxParam[foundAttrCtxParam] = actionAttrCtxParam;

            // Store the action attribute context parameter with the resolved attribute resulting out of the action.
            // This is so that we can point the action attribute context to the correct resolved attribute once the attribute context is created.
            actionAttrCtxParamToResAttr[actionAttrCtxParam] = resAttrFromAction;
        }
Esempio n. 18
0
        /// <inheritdoc />
        internal override ProjectionAttributeStateSet AppendProjectionAttributeState(
            ProjectionContext projCtx,
            ProjectionAttributeStateSet projOutputSet,
            CdmAttributeContext attrCtx)
        {
            // Create a new attribute context for the operation
            AttributeContextParameters attrCtxOpArrayExpansionParam = new AttributeContextParameters
            {
                under = attrCtx,
                type  = CdmAttributeContextType.OperationArrayExpansion,
                Name  = $"operation/index{Index}/operationArrayExpansion"
            };
            CdmAttributeContext attrCtxOpArrayExpansion = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxOpArrayExpansionParam);

            // Expansion steps start at round 0
            int round = 0;
            List <ProjectionAttributeState> projAttrStatesFromRounds = new List <ProjectionAttributeState>();

            // Ordinal validation
            if (this.StartOrdinal > this.EndOrdinal)
            {
                Logger.Warning(TAG, this.Ctx, $"startOrdinal {this.StartOrdinal} should not be greater than endOrdinal {this.EndOrdinal}", nameof(AppendProjectionAttributeState));
            }
            else
            {
                // Ordinals should start at startOrdinal or 0, whichever is larger.
                int startingOrdinal = Math.Max(0, (int)this.StartOrdinal);

                // Ordinals should end at endOrdinal or the maximum ordinal allowed (set in resolve options), whichever is smaller.
                if (this.EndOrdinal > projCtx.ProjectionDirective.ResOpt.MaxOrdinalForArrayExpansion)
                {
                    Logger.Warning(TAG, this.Ctx, $"endOrdinal {this.EndOrdinal} is greater than the maximum allowed ordinal of {projCtx.ProjectionDirective.ResOpt.MaxOrdinalForArrayExpansion}. Using the maximum allowed ordinal instead.", nameof(AppendProjectionAttributeState));
                }
                int endingOrdinal = Math.Min(projCtx.ProjectionDirective.ResOpt.MaxOrdinalForArrayExpansion, (int)this.EndOrdinal);

                // For each ordinal, create a copy of the input resolved attribute
                for (int i = startingOrdinal; i <= endingOrdinal; i++)
                {
                    // Create a new attribute context for the round
                    AttributeContextParameters attrCtxRoundParam = new AttributeContextParameters
                    {
                        under = attrCtxOpArrayExpansion,
                        type  = CdmAttributeContextType.GeneratedRound,
                        Name  = $"_generatedAttributeRound{round}"
                    };
                    CdmAttributeContext attrCtxRound = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxRoundParam);

                    // Iterate through all the projection attribute states generated from the source's resolved attributes
                    // Each projection attribute state contains a resolved attribute that it is corresponding to
                    foreach (ProjectionAttributeState currentPAS in projCtx.CurrentAttributeStateSet.States)
                    {
                        // Create a new attribute context for the expanded attribute with the current ordinal
                        AttributeContextParameters attrCtxExpandedAttrParam = new AttributeContextParameters
                        {
                            under = attrCtxRound,
                            type  = CdmAttributeContextType.AttributeDefinition,
                            Name  = $"{currentPAS.CurrentResolvedAttribute.ResolvedName}@{i}"
                        };
                        CdmAttributeContext attrCtxExpandedAttr = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxExpandedAttrParam);

                        if (currentPAS.CurrentResolvedAttribute.Target is ResolvedAttributeSet)
                        {
                            Logger.Error(TAG, this.Ctx, "Array expansion operation does not support attribute groups.");
                            projAttrStatesFromRounds.Clear();
                            break;
                        }

                        // Create a new resolved attribute for the expanded attribute
                        ResolvedAttribute newResAttr = CreateNewResolvedAttribute(projCtx, attrCtxExpandedAttr, currentPAS.CurrentResolvedAttribute.Target, currentPAS.CurrentResolvedAttribute.ResolvedName);
                        newResAttr.AttCtx.AddLineage(currentPAS.CurrentResolvedAttribute.AttCtx);

                        // Create a projection attribute state for the expanded attribute
                        ProjectionAttributeState newPAS = new ProjectionAttributeState(projOutputSet.Ctx)
                        {
                            CurrentResolvedAttribute = newResAttr,
                            PreviousStateList        = new List <ProjectionAttributeState> {
                                currentPAS
                            },
                            Ordinal = i
                        };

                        projAttrStatesFromRounds.Add(newPAS);
                    }

                    if (i == endingOrdinal)
                    {
                        break;
                    }

                    // Increment the round
                    round++;
                }
            }

            if (projAttrStatesFromRounds.Count == 0)
            {
                // No rounds were produced from the array expansion - input passes through
                foreach (ProjectionAttributeState pas in projCtx.CurrentAttributeStateSet.States)
                {
                    projOutputSet.Add(pas);
                }
            }
            else
            {
                // Add all the projection attribute states containing the expanded attributes to the output
                foreach (ProjectionAttributeState pas in projAttrStatesFromRounds)
                {
                    projOutputSet.Add(pas);
                }
            }

            return(projOutputSet);
        }
Esempio n. 19
0
 /// <summary>
 /// Replace wild characters in the arguments if argumentsContainWildcards is true.
 /// </summary>
 /// <param name="resOpt">The resolve options.</param>
 /// <param name="resolvedTraitSet">The current attribute state set.</param>
 /// <param name="projectionOwnerName">The attribute name of projection owner (only available when the owner is an entity attribute or type attribute).</param>
 /// <param name="currentPAS">The attribute state.</param>
 private void ReplaceWildcardCharacters(ResolveOptions resOpt, ResolvedTraitSet resolvedTraitSet, string projectionOwnerName, ProjectionAttributeState currentPAS)
 {
     if (this.ArgumentsContainWildcards.HasValue && this.ArgumentsContainWildcards.Value == true)
     {
         foreach (ResolvedTrait resolvedTrait in resolvedTraitSet.Set)
         {
             var parameterValueSet = resolvedTrait.ParameterValues;
             for (int i = 0; i < parameterValueSet.Length; ++i)
             {
                 var value = parameterValueSet.FetchValue(i);
                 if (value is string v)
                 {
                     var newVal = ReplaceWildcardCharacters(v, projectionOwnerName, currentPAS);
                     if (newVal != value)
                     {
                         parameterValueSet.SetParameterValue(resOpt, parameterValueSet.FetchParameterAtIndex(i).GetName(), newVal);
                     }
                 }
             }
         }
     }
 }
Esempio n. 20
0
        /// <summary>
        /// Replace the wildcard character. {a/A} will be replaced with the current attribute name. {m/M} will be replaced with the entity attribute name. {o} will be replaced with the index of the attribute after an array expansion
        /// </summary>
        /// <param name="format">The original text.</param>
        /// <param name="projectionOwnerName">The attribute name of projection owner (only available when the owner is an entity attribute or type attribute).</param>
        /// <param name="currentPAS">The attribute state.</param>
        /// <returns></returns>
        internal static string ReplaceWildcardCharacters(string format, string projectionOwnerName, ProjectionAttributeState currentPAS)
        {
            if (string.IsNullOrEmpty(format))
            {
                return("");
            }

            string ordinal = currentPAS.Ordinal != null?currentPAS.Ordinal.ToString() : "";

            string originalMemberAttributeName = (currentPAS.CurrentResolvedAttribute.Target as CdmAttribute)?.Name ?? "";
            string resolvedMemberAttributeName = currentPAS.CurrentResolvedAttribute.ResolvedName ?? "";


            string value = StringUtils.Replace(format, "a", projectionOwnerName);

            value = StringUtils.Replace(value, "o", ordinal);
            value = StringUtils.Replace(value, "mo", originalMemberAttributeName);
            value = StringUtils.Replace(value, "m", resolvedMemberAttributeName);

            return(value);
        }
Esempio n. 21
0
        /// <inheritdoc />
        internal override ProjectionAttributeStateSet AppendProjectionAttributeState(
            ProjectionContext projCtx,
            ProjectionAttributeStateSet projOutputSet,
            CdmAttributeContext attrCtx)
        {
            // Create a new attribute context for the operation
            AttributeContextParameters attrCtxOpRenameAttrsParam = new AttributeContextParameters
            {
                under = attrCtx,
                type  = CdmAttributeContextType.OperationRenameAttributes,
                Name  = $"operation/index{Index}/operationRenameAttributes"
            };
            CdmAttributeContext attrCtxOpRenameAttrs = CdmAttributeContext.CreateChildUnder(projCtx.ProjectionDirective.ResOpt, attrCtxOpRenameAttrsParam);

            // Get the list of attributes that will be renamed
            List <string> renameAttributes;

            if (this.ApplyTo != null)
            {
                renameAttributes = this.ApplyTo;
            }
            else
            {
                renameAttributes = new List <string>();
                foreach (ProjectionAttributeState currentPAS in projCtx.CurrentAttributeStateSet.States)
                {
                    renameAttributes.Add(currentPAS.CurrentResolvedAttribute.ResolvedName);
                }
            }

            // Get the top-level attribute names of the attributes to rename
            // We use the top-level names because the rename list may contain a previous name our current resolved attributes had
            Dictionary <string, string> topLevelRenameAttributeNames = ProjectionResolutionCommonUtil.GetTopList(projCtx, renameAttributes);

            string sourceAttributeName = projCtx.ProjectionDirective.OriginalSourceEntityAttributeName;

            // Initialize a projection attribute context tree builder with the created attribute context for the operation
            ProjectionAttributeContextTreeBuilder attrCtxTreeBuilder = new ProjectionAttributeContextTreeBuilder(attrCtxOpRenameAttrs);

            // Iterate through all the projection attribute states generated from the source's resolved attributes
            // Each projection attribute state contains a resolved attribute that it is corresponding to
            foreach (ProjectionAttributeState currentPAS in projCtx.CurrentAttributeStateSet.States)
            {
                // Check if the current projection attribute state's resolved attribute is in the list of attributes to rename
                // If this attribute is not in the rename list, then we are including it in the output without changes
                if (topLevelRenameAttributeNames.ContainsKey(currentPAS.CurrentResolvedAttribute.ResolvedName))
                {
                    if (currentPAS.CurrentResolvedAttribute.Target is CdmAttribute)
                    {
                        // The current attribute should be renamed

                        string newAttributeName = GetNewAttributeName(currentPAS, sourceAttributeName);

                        // Create new resolved attribute with the new name, set the new attribute as target
                        ResolvedAttribute resAttrNew = CreateNewResolvedAttribute(projCtx, null, currentPAS.CurrentResolvedAttribute.Target, newAttributeName);

                        // Get the attribute name the way it appears in the applyTo list
                        string applyToName = topLevelRenameAttributeNames[currentPAS.CurrentResolvedAttribute.ResolvedName];

                        // Create the attribute context parameters and just store it in the builder for now
                        // We will create the attribute contexts at the end
                        attrCtxTreeBuilder.CreateAndStoreAttributeContextParameters(applyToName, currentPAS, resAttrNew,
                                                                                    CdmAttributeContextType.AttributeDefinition,
                                                                                    currentPAS.CurrentResolvedAttribute.AttCtx, // lineage is the original attribute
                                                                                    null);                                      // don't know who will point here yet

                        // Create a projection attribute state for the renamed attribute by creating a copy of the current state
                        // Copy() sets the current state as the previous state for the new one
                        // We only create projection attribute states for attributes that are in the rename list
                        ProjectionAttributeState newPAS = currentPAS.Copy();

                        // Update the resolved attribute to be the new renamed attribute we created
                        newPAS.CurrentResolvedAttribute = resAttrNew;

                        projOutputSet.Add(newPAS);
                    }
                    else
                    {
                        Logger.Warning(this.Ctx, Tag, nameof(AppendProjectionAttributeState), this.AtCorpusPath, CdmLogCode.WarnProjRenameAttrNotSupported);
                        // Add the attribute without changes
                        projOutputSet.Add(currentPAS);
                    }
                }
                else
                {
                    // Pass through
                    projOutputSet.Add(currentPAS);
                }
            }

            // Create all the attribute contexts and construct the tree
            attrCtxTreeBuilder.ConstructAttributeContextTree(projCtx);

            return(projOutputSet);
        }
Esempio n. 22
0
        /// <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);
        }
        /// <summary>
        /// Creates the attribute context parameters for the searchFor, found, and action nodes and then stores them in different maps.
        /// The maps are used when constructing the actual attribute context tree.
        /// </summary>
        /// <param name="searchFor">The "search for" string</param>
        /// <param name="found">The projection attribute state that contains the "found" attribute</param>
        /// <param name="resAttrFromAction">The resolved attribute that resulted from the action</param>
        /// <param name="attrCtxType">The attribute context type to give the "action" attribute context parameter</param>
        /// <param name="lineageOut">normally lineage goes from new context to the found. false means don't and maybe even flip it</param>
        /// <param name="lineageIn"></param>
        internal void CreateAndStoreAttributeContextParameters(string searchFor, ProjectionAttributeState found, ResolvedAttribute resAttrFromAction,
                                                               CdmAttributeContextType attrCtxType, CdmAttributeContext lineageOut, CdmAttributeContext lineageIn)
        {
            // searchFor is null when we have to construct attribute contexts for the excluded attributes in Include or the included attributes in Exclude,
            // as these attributes weren't searched for with a searchFor name.
            // If searchFor is null, just set it to have the same name as found so that it'll collapse in the final tree.
            if (searchFor == null)
            {
                searchFor = found.CurrentResolvedAttribute.ResolvedName;
            }

            // Create the attribute context parameter for the searchFor node and store it in the map as [searchFor name]:[attribute context parameter]
            AttributeContextParameters searchForAttrCtxParam = null;

            if (!searchForToSearchForAttrCtxParam.ContainsKey(searchFor))
            {
                searchForAttrCtxParam = new AttributeContextParameters
                {
                    under = root,
                    type  = CdmAttributeContextType.AttributeDefinition,
                    Name  = searchFor
                };

                searchForToSearchForAttrCtxParam.Add(searchFor, searchForAttrCtxParam);
            }
            else
            {
                searchForToSearchForAttrCtxParam.TryGetValue(searchFor, out searchForAttrCtxParam);
            }

            // Create the attribute context parameter for the found node
            AttributeContextParameters foundAttrCtxParam = new AttributeContextParameters
            {
                under = root, // Set this to be under the root for now, as we may end up collapsing this node
                type  = CdmAttributeContextType.AttributeDefinition,
                Name  = $"{found.CurrentResolvedAttribute.ResolvedName}{(found.Ordinal != null ? "@" + found.Ordinal : "")}"
            };

            // Store this in the map as [searchFor attribute context parameter]:[found attribute context parameters]
            // We store it this way so that we can create the found nodes under their corresponding searchFor nodes.
            if (!searchForAttrCtxParamToFoundAttrCtxParam.ContainsKey(searchForAttrCtxParam))
            {
                searchForAttrCtxParamToFoundAttrCtxParam.Add(searchForAttrCtxParam, new List <AttributeContextParameters>());
            }

            List <AttributeContextParameters> foundAttrCtxParams = searchForAttrCtxParamToFoundAttrCtxParam[searchForAttrCtxParam];

            foundAttrCtxParams.Add(foundAttrCtxParam);

            // Create the attribute context parameter for the action node
            AttributeContextParameters actionAttrCtxParam = new AttributeContextParameters
            {
                under = root,        // Set this to be under the root for now, as we may end up collapsing this node
                type  = attrCtxType, // This type will be updated once we implement the new attribute context types
                Name  = resAttrFromAction.ResolvedName
            };

            // Store this in the map as [found attribute context parameter]:[action attribute context parameter]
            // We store it this way so that we can create the action nodes under their corresponding found nodes.
            foundAttrCtxParamToActionAttrCtxParam[foundAttrCtxParam] = actionAttrCtxParam;

            // Store the action attribute context parameter with the resolved attribute resulting out of the action.
            // This is so that we can point the action attribute context to the correct resolved attribute once the attribute context is created.
            actionAttrCtxParamToResAttr[actionAttrCtxParam] = resAttrFromAction;

            // store the current resAtt as the lineage of the new one
            // of note, if no lineage is stored AND the resolved Att associated above holds an existing context? we will
            // flip the lineage when we make a new context and point 'back' to this new node. this means this new node should
            // point 'back' to the context of the source attribute
            if (lineageOut != null)
            {
                actionAttrCtxParamToLineageOut[actionAttrCtxParam] = lineageOut;
            }
            if (lineageIn != null)
            {
                actionAttrCtxParamToLineageIn[actionAttrCtxParam] = lineageIn;
            }
        }