public ResolvedAttributeSet MergeSet(ResolvedAttributeSet toMerge)
        {
            ResolvedAttributeSet rasResult = this;

            if (toMerge != null)
            {
                foreach (ResolvedAttribute ra in toMerge.Set)
                {
                    // don't pass in the context here
                    ResolvedAttributeSet rasMerged = rasResult.Merge(ra);
                    if (rasMerged != rasResult)
                    {
                        rasResult = rasMerged;
                    }
                    // get the attribute from the merged set, attributes that were already present were merged, not replaced
                    rasResult.ResolvedName2resolvedAttribute.TryGetValue(ra.ResolvedName, out ResolvedAttribute currentRa);
                }
                // merge the ownership map.
                if (toMerge.AttributeOwnershipMap != null)
                {
                    if (this.AttributeOwnershipMap == null)
                    {
                        this.AttributeOwnershipMap = new Dictionary <string, HashSet <string> >();
                    }
                    foreach (var newPair in toMerge.AttributeOwnershipMap)
                    {
                        // always take the new one as the right list, not sure if the constructor for dictionary uses this logic or fails
                        this.AttributeOwnershipMap[newPair.Key] = newPair.Value;
                    }
                }
            }
            return(rasResult);
        }
Exemple #2
0
        public ResolvedAttributeSet Copy()
        {
            ResolvedAttributeSet copy = new ResolvedAttributeSet();

            copy.AttributeContext = this.AttributeContext;
            int l = this.Set.Count;

            // save the mappings to overwrite
            // maps from merge may not be correct
            IDictionary <ResolvedAttribute, HashSet <CdmAttributeContext> > newRa2attCtxSet = new Dictionary <ResolvedAttribute, HashSet <CdmAttributeContext> >();
            IDictionary <CdmAttributeContext, ResolvedAttribute>            newAttCtx2ra    = new Dictionary <CdmAttributeContext, ResolvedAttribute>();

            for (int i = 0; i < l; i++)
            {
                ResolvedAttribute sourceRa = this.Set[i];
                ResolvedAttribute copyRa   = sourceRa.Copy();

                this.CopyAttCtxMappingsInto(newRa2attCtxSet, newAttCtx2ra, sourceRa, copyRa);
                copy.Merge(copyRa);
            }
            // reset mappings to the correct one
            copy.Ra2attCtxSet = newRa2attCtxSet;
            copy.AttCtx2ra    = newAttCtx2ra;

            return(copy);
        }
Exemple #3
0
        public ResolvedAttributeSet Copy()
        {
            ResolvedAttributeSet copy = new ResolvedAttributeSet();

            copy.AttributeContext = this.AttributeContext;
            int l = this.Set.Count;

            // save the mappings to overwrite
            // maps from merge may not be correct
            IDictionary <ResolvedAttribute, HashSet <CdmAttributeContext> > newRa2attCtxSet = new Dictionary <ResolvedAttribute, HashSet <CdmAttributeContext> >();
            IDictionary <CdmAttributeContext, ResolvedAttribute>            newAttCtx2ra    = new Dictionary <CdmAttributeContext, ResolvedAttribute>();

            for (int i = 0; i < l; i++)
            {
                ResolvedAttribute sourceRa = this.Set[i];
                ResolvedAttribute copyRa   = sourceRa.Copy();
                copy.Merge(copyRa);
            }

            // copy the ownership map. new map will point at old att lists, but we never update these lists, only make new ones, so all is well
            if (this.AttributeOwnershipMap != null)
            {
                copy.AttributeOwnershipMap = new Dictionary <string, HashSet <string> >(this.AttributeOwnershipMap);
            }
            copy.DepthTraveled = this.DepthTraveled;

            return(copy);
        }
        public ResolvedAttributeSet MergeSet(ResolvedAttributeSet toMerge)
        {
            ResolvedAttributeSet rasResult = this;

            if (toMerge != null)
            {
                int l = toMerge.Set.Count;
                for (int i = 0; i < l; i++)
                {
                    // don't pass in the context here
                    ResolvedAttributeSet rasMerged = rasResult.Merge(toMerge.Set[i]);
                    if (rasMerged != rasResult)
                    {
                        rasResult = rasMerged;
                    }
                    // copy context here
                    toMerge.CopyAttCtxMappingsInto(rasResult.Ra2attCtxSet, rasResult.AttCtx2ra, toMerge.Set[i]);
                }
            }
            return(rasResult);
        }
Exemple #5
0
        public ResolvedAttributeSet MergeSet(ResolvedAttributeSet toMerge)
        {
            ResolvedAttributeSet rasResult = this;

            if (toMerge != null)
            {
                foreach (ResolvedAttribute ra in toMerge.Set)
                {
                    // don't pass in the context here
                    ResolvedAttributeSet rasMerged = rasResult.Merge(ra);
                    if (rasMerged != rasResult)
                    {
                        rasResult = rasMerged;
                    }
                    // get the attribute from the merged set, attributes that were already present were merged, not replaced
                    rasResult.ResolvedName2resolvedAttribute.TryGetValue(ra.ResolvedName, out ResolvedAttribute currentRa);
                    // copy context here
                    toMerge.CopyAttCtxMappingsInto(rasResult.Ra2attCtxSet, rasResult.AttCtx2ra, ra, currentRa);
                }
            }
            return(rasResult);
        }
        public ResolvedAttributeSet Copy()
        {
            ResolvedAttributeSet copy = new ResolvedAttributeSet();

            copy.AttributeContext = this.AttributeContext;
            int l = this.Set.Count;

            for (int i = 0; i < l; i++)
            {
                ResolvedAttribute sourceRa = this.Set[i];
                ResolvedAttribute copyRa   = sourceRa.Copy();
                copy.Merge(copyRa);
            }

            // copy the ownership map. new map will point at old att lists, but we never update these lists, only make new ones, so all is well
            if (this.AttributeOwnershipMap != null)
            {
                copy.AttributeOwnershipMap = new Dictionary <string, HashSet <string> >(this.AttributeOwnershipMap);
            }
            copy.DepthTraveled = this.DepthTraveled;

            return(copy);
        }
Exemple #7
0
        public ResolvedAttributeSet FetchAttributesWithTraits(ResolveOptions resOpt, dynamic queryFor)
        {
            // put the input into a standard form
            List <TraitParamSpec> query = new List <TraitParamSpec>();

            if (queryFor.GetType() == typeof(List <TraitParamSpec>))
            {
                int l = queryFor.length;
                for (int i = 0; i < l; i++)
                {
                    dynamic q = queryFor[i];
                    if (q is string)
                    {
                        query.Add(new TraitParamSpec {
                            TraitBaseName = q, Parameters = new Dictionary <string, string>()
                        });
                    }
                    else
                    {
                        query.Add(q);
                    }
                }
            }
            else
            {
                if (queryFor is string)
                {
                    query.Add(new TraitParamSpec {
                        TraitBaseName = queryFor, Parameters = new Dictionary <string, string>()
                    });
                }
                else
                {
                    query.Add(queryFor);
                }
            }

            // if the map isn't in place, make one now. assumption is that this is called as part of a usage pattern where it will get called again.
            if (this.BaseTrait2Attributes == null)
            {
                this.BaseTrait2Attributes = new Dictionary <string, HashSet <ResolvedAttribute> >();
                int l = this.Set.Count;
                for (int i = 0; i < l; i++)
                {
                    // create a map from the name of every trait found in this whole set of attributes to the attributes that have the trait (included base classes of traits)
                    var           resAtt     = this.Set[i];
                    ISet <string> traitNames = resAtt.ResolvedTraits.CollectTraitNames();
                    foreach (string tName in traitNames)
                    {
                        if (!this.BaseTrait2Attributes.ContainsKey(tName))
                        {
                            this.BaseTrait2Attributes.Add(tName, new HashSet <ResolvedAttribute>());
                        }
                        this.BaseTrait2Attributes[tName].Add(resAtt);
                    }
                }
            }
            // for every trait in the query, get the set of attributes.
            // intersect these sets to get the final answer
            HashSet <ResolvedAttribute> finalSet = null;

            for (int i = 0; i < query.Count; i++)
            {
                var q = query[i];
                if (this.BaseTrait2Attributes.ContainsKey(q.TraitBaseName))
                {
                    var subSet = this.BaseTrait2Attributes[q.TraitBaseName];
                    if (q.Parameters?.Count > 0)
                    {
                        // need to check param values, so copy the subset to something we can modify
                        HashSet <ResolvedAttribute> filteredSubSet = new HashSet <ResolvedAttribute>();
                        foreach (var ra in subSet)
                        {
                            ParameterValueSet pvals = ra.ResolvedTraits.Find(resOpt, q.TraitBaseName).ParameterValues;
                            // compare to all query params
                            int lParams = q.Parameters.Count;
                            int iParam  = 0;
                            for (iParam = 0; iParam < lParams; iParam++)
                            {
                                var param = q.Parameters.ElementAt(iParam);
                                var pv    = pvals.FetchParameterValueByName(param.Key);
                                if (pv == null || pv.FetchValueString(resOpt) != param.Value)
                                {
                                    break;
                                }
                            }

                            // stop early means no match
                            if (iParam == lParams)
                            {
                                filteredSubSet.Add(ra);
                            }
                        }

                        subSet = filteredSubSet;
                    }
                    if (subSet != null && subSet.Count > 0)
                    {
                        // got some. either use as starting point for answer or intersect this in
                        if (finalSet == null)
                        {
                            finalSet = subSet;
                        }
                        else
                        {
                            var intersection = new HashSet <ResolvedAttribute>();
                            // intersect the two
                            foreach (var ra in finalSet)
                            {
                                if (subSet.Contains(ra))
                                {
                                    intersection.Add(ra);
                                }
                            }

                            finalSet = intersection;
                        }
                    }
                }
            }

            // collect the final set into a resolvedAttributeSet
            if (finalSet != null && finalSet.Count > 0)
            {
                ResolvedAttributeSet rasResult = new ResolvedAttributeSet();
                foreach (ResolvedAttribute ra in finalSet)
                {
                    rasResult.Merge(ra);
                }
                return(rasResult);
            }

            return(null);
        }
Exemple #8
0
        public ResolvedAttributeSet RemoveRequestedAtts(Marker marker)
        {
            int countIndex = marker.CountIndex;
            int markIndex  = marker.MarkIndex;

            // for every attribute in the set run any attribute removers on the traits they have
            ResolvedAttributeSet appliedAttSet = new ResolvedAttributeSet();
            int l = this.Set.Count;

            for (int iAtt = 0; iAtt < l; iAtt++)
            {
                ResolvedAttribute resAtt = this.Set[iAtt];
                // possible for another set to be in this set
                ResolvedAttributeSet subSet = resAtt.Target as ResolvedAttributeSet;
                if (subSet?.Set != null)
                {
                    // well, that happened. so now we go around again on this same function and get rid of things from this group
                    marker.CountIndex = countIndex;
                    marker.MarkIndex  = markIndex;
                    ResolvedAttributeSet newSubSet = subSet.RemoveRequestedAtts(marker);
                    countIndex = marker.CountIndex;
                    markIndex  = marker.MarkIndex;
                    // replace the set with the new one that came back
                    resAtt.Target = newSubSet;
                    // if everything went away, then remove this group
                    if (newSubSet?.Set == null || newSubSet.Set.Count == 0)
                    {
                        resAtt = null;
                    }
                    else
                    {
                        // don't count this as an attribute (later)
                        countIndex--;
                    }
                }
                else
                {
                    // this is a good time to make the resolved names final
                    resAtt.previousResolvedName = resAtt.ResolvedName;
                    if (resAtt.Arc != null && resAtt.Arc.ApplierCaps != null && resAtt.Arc.ApplierCaps.CanRemove)
                    {
                        foreach (AttributeResolutionApplier apl in resAtt.Arc.ActionsRemove)
                        {
                            // this should look like the applier context when the att was created
                            ApplierContext ctx = new ApplierContext()
                            {
                                ResOpt = resAtt.Arc.ResOpt, ResAttSource = resAtt, ResGuide = resAtt.Arc.ResGuide
                            };
                            if (apl.WillRemove(ctx))
                            {
                                resAtt = null;
                                break;
                            }
                        }
                    }
                }
                if (resAtt != null)
                {
                    // attribute remains
                    // are we building a new set?
                    if (appliedAttSet != null)
                    {
                        this.CopyAttCtxMappingsInto(appliedAttSet.Ra2attCtxSet, appliedAttSet.AttCtx2ra, resAtt);
                        appliedAttSet.Merge(resAtt);
                    }
                    countIndex++;
                }
                else
                {
                    // remove the att
                    // if this is the first removed attribute, then make a copy of the set now
                    // after this point, the rest of the loop logic keeps the copy going as needed
                    if (appliedAttSet == null)
                    {
                        appliedAttSet = new ResolvedAttributeSet();
                        for (int iCopy = 0; iCopy < iAtt; iCopy++)
                        {
                            this.CopyAttCtxMappingsInto(appliedAttSet.Ra2attCtxSet, appliedAttSet.AttCtx2ra, this.Set[iCopy]);
                            appliedAttSet.Merge(this.Set[iCopy]);
                        }
                    }
                    // track deletes under the mark (move the mark up)
                    if (countIndex < markIndex)
                    {
                        markIndex--;
                    }
                }
            }

            marker.CountIndex = countIndex;
            marker.MarkIndex  = markIndex;

            // now we are that (or a copy)
            ResolvedAttributeSet rasResult = this;

            if (appliedAttSet != null && appliedAttSet.Size != rasResult.Size)
            {
                rasResult = appliedAttSet;
                rasResult.BaseTrait2Attributes = null;
                rasResult.AttributeContext     = this.AttributeContext;
            }

            return(rasResult);
        }
Exemple #9
0
        ResolvedAttributeSet Apply(ResolvedTraitSet traits, ResolveOptions resOpt, CdmAttributeResolutionGuidance resGuide, List <AttributeResolutionApplier> actions)
        {
            if (traits == null && actions.Count == 0)
            {
                // nothing can change
                return(this);
            }

            // for every attribute in the set run any attribute appliers
            ResolvedAttributeSet appliedAttSet = new ResolvedAttributeSet();
            int l = this.Set.Count;

            appliedAttSet.AttributeContext = this.AttributeContext;

            // check to see if we need to make a copy of the attributes
            // do this when building an attribute context and when we will modify the attributes (beyond traits)
            // see if any of the appliers want to modify
            bool makingCopy = false;

            if (l > 0 && appliedAttSet.AttributeContext != null && actions != null && actions.Count > 0)
            {
                ResolvedAttribute resAttTest = this.Set[0];
                foreach (AttributeResolutionApplier traitAction in actions)
                {
                    ApplierContext ctx = new ApplierContext {
                        ResOpt = resOpt, ResAttSource = resAttTest, ResGuide = resGuide
                    };
                    if (traitAction.WillAttributeModify(ctx) == true)
                    {
                        makingCopy = true;
                        break;
                    }
                }
            }

            if (makingCopy)
            {
                // fake up a generation round for these copies that are about to happen
                AttributeContextParameters acp = new AttributeContextParameters
                {
                    under = appliedAttSet.AttributeContext,
                    type  = Enums.CdmAttributeContextType.GeneratedSet,
                    Name  = "_generatedAttributeSet"
                };
                appliedAttSet.AttributeContext = CdmAttributeContext.CreateChildUnder(traits.ResOpt, acp);
                acp = new AttributeContextParameters
                {
                    under = appliedAttSet.AttributeContext,
                    type  = Enums.CdmAttributeContextType.GeneratedRound,
                    Name  = "_generatedAttributeRound0"
                };
                appliedAttSet.AttributeContext = CdmAttributeContext.CreateChildUnder(traits.ResOpt, acp);
            }
            for (int i = 0; i < l; i++)
            {
                ResolvedAttribute   resAtt        = this.Set[i];
                CdmAttributeContext attCtxToMerge = null;
                if (resAtt.Target is ResolvedAttributeSet subSet)
                {
                    if (makingCopy)
                    {
                        resAtt = resAtt.Copy();
                        // making a copy of a subset (att group) also bring along the context tree for that whole group
                        attCtxToMerge = resAtt.AttCtx;
                    }
                    // the set contains another set. process those
                    resAtt.Target = subSet.Apply(traits, resOpt, resGuide, actions);
                }
                else
                {
                    ResolvedTraitSet rtsMerge = resAtt.ResolvedTraits.MergeSet(traits);
                    resAtt.ResolvedTraits = rtsMerge;
                    if (actions != null)
                    {
                        foreach (AttributeResolutionApplier traitAction in actions)
                        {
                            ApplierContext ctx = new ApplierContext {
                                ResOpt = traits.ResOpt, ResAttSource = resAtt, ResGuide = resGuide
                            };
                            if (traitAction.WillAttributeModify(ctx) == true)
                            {
                                // make a context for this new copy
                                if (makingCopy)
                                {
                                    AttributeContextParameters acp = new AttributeContextParameters
                                    {
                                        under     = appliedAttSet.AttributeContext,
                                        type      = Enums.CdmAttributeContextType.AttributeDefinition,
                                        Name      = resAtt.ResolvedName,
                                        Regarding = resAtt.Target
                                    };
                                    ctx.AttCtx    = CdmAttributeContext.CreateChildUnder(traits.ResOpt, acp);
                                    attCtxToMerge = ctx.AttCtx as CdmAttributeContext;
                                }

                                // make a copy of the resolved att
                                if (makingCopy)
                                {
                                    resAtt = resAtt.Copy();
                                }

                                ctx.ResAttSource = resAtt;
                                // modify it
                                traitAction.DoAttributeModify(ctx);
                            }
                        }
                    }
                }
                appliedAttSet.Merge(resAtt, attCtxToMerge);
            }

            appliedAttSet.AttributeContext = this.AttributeContext;

            if (!makingCopy)
            {
                // didn't copy the attributes or make any new context, so just take the old ones
                appliedAttSet.Ra2attCtxSet = this.Ra2attCtxSet;
                appliedAttSet.AttCtx2ra    = this.AttCtx2ra;
            }

            return(appliedAttSet);
        }
        public void GenerateApplierAttributes(AttributeResolutionContext arc, bool applyTraitsToNew)
        {
            if (arc == null || arc.ApplierCaps == null)
            {
                return;
            }
            if (this.ResolvedAttributeSet == null)
            {
                this.TakeReference(new ResolvedAttributeSet());
            }

            // make sure all of the 'source' attributes know about this context
            List <ResolvedAttribute> set = this.ResolvedAttributeSet.Set;

            if (set != null)
            {
                int l = set.Count;
                for (int i = 0; i < l; i++)
                {
                    set[i].Arc = arc;
                }

                // the resolution guidance may be asking for a one time 'take' or avoid of attributes from the source
                // this also can re-order the attributes
                //
                if (arc.ResGuide != null && arc.ResGuide.selectsSubAttribute != null &&
                    arc.ResGuide.selectsSubAttribute.selects == "some" &&
                    (arc.ResGuide.selectsSubAttribute.selectsSomeTakeNames != null || arc.ResGuide.selectsSubAttribute.selectsSomeAvoidNames != null))
                {
                    // we will make a new resolved attribute set from the 'take' list
                    List <ResolvedAttribute> takeSet = new List <ResolvedAttribute>();
                    List <string>            selectsSomeTakeNames  = arc.ResGuide.selectsSubAttribute.selectsSomeTakeNames;
                    List <string>            selectsSomeAvoidNames = arc.ResGuide.selectsSubAttribute.selectsSomeAvoidNames;

                    if (selectsSomeTakeNames != null && selectsSomeAvoidNames == null)
                    {
                        // make an index that goes from name to insertion order
                        Dictionary <string, int> inverted = new Dictionary <string, int>();
                        for (int iOrder = 0; iOrder < l; iOrder++)
                        {
                            inverted.Add(set[iOrder].ResolvedName, iOrder);
                        }

                        for (int iTake = 0; iTake < selectsSomeTakeNames.Count; iTake++)
                        {
                            // if in the original set of attributes, take it in the new order
                            int iOriginalOrder;
                            if (inverted.TryGetValue(selectsSomeTakeNames[iTake], out iOriginalOrder))
                            {
                                takeSet.Add(set[iOriginalOrder]);
                            }
                        }
                    }
                    if (selectsSomeAvoidNames != null)
                    {
                        // make a quick look up of avoid names
                        HashSet <string> avoid = new HashSet <string>();
                        foreach (string avoidName in selectsSomeAvoidNames)
                        {
                            avoid.Add(avoidName);
                        }

                        for (int iAtt = 0; iAtt < l; iAtt++)
                        {
                            // only take the ones not in avoid the list given
                            if (!avoid.Contains(set[iAtt].ResolvedName))
                            {
                                takeSet.Add(set[iAtt]);
                            }
                        }
                    }

                    // replace the guts of the resolvedAttributeSet with this
                    this.ResolvedAttributeSet.AlterSetOrderAndScope(takeSet);
                }
            }


            // get the new atts and then add them one at a time into this set
            List <ResolvedAttribute> newAtts = GetApplierGeneratedAttributes(arc, true, applyTraitsToNew);

            if (newAtts != null)
            {
                ResolvedAttributeSet ras = this.ResolvedAttributeSet;
                for (int i = 0; i < newAtts.Count; i++)
                {
                    ras = ras.Merge(newAtts[i]);
                }
                this.TakeReference(ras);
            }
        }