示例#1
0
        bool CopyNeeded(ResolvedTraitSet traits, CdmAttributeResolutionGuidance resGuide, List <AttributeResolutionApplier> actions)
        {
            if (actions == null || actions.Count == 0)
            {
                return(false);
            }

            // for every attribute in the set, detect if a merge of traits will alter the traits. if so, need to copy the attribute set to avoid overwrite
            int l = this.Set.Count;

            for (int i = 0; i < l; i++)
            {
                ResolvedAttribute resAtt = this.Set[i];
                foreach (var currentTraitAction in actions)
                {
                    ApplierContext ctx = new ApplierContext {
                        ResOpt = traits.ResOpt, ResAttSource = resAtt, ResGuide = resGuide
                    };
                    if (currentTraitAction.WillAttributeModify(ctx))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
        public static AttributeResolutionGuidance ToData(CdmAttributeResolutionGuidance instance, ResolveOptions resOpt, CopyOptions options)
        {
            AttributeResolutionGuidance obj = new AttributeResolutionGuidance
            {
                removeAttribute        = instance.removeAttribute,
                imposedDirectives      = instance.imposedDirectives,
                removedDirectives      = instance.removedDirectives,
                addSupportingAttribute = Utils.JsonForm(instance.addSupportingAttribute, resOpt, options),
                cardinality            = instance.cardinality,
                renameFormat           = instance.renameFormat
            };

            if (instance.expansion != null)
            {
                obj.expansion = new AttributeResolutionGuidance.Expansion()
                {
                    startingOrdinal  = instance.expansion.startingOrdinal,
                    maximumExpansion = instance.expansion.maximumExpansion,
                    countAttribute   = Utils.JsonForm(instance.expansion.countAttribute, resOpt, options)
                };
            }
            if (instance.entityByReference != null)
            {
                obj.entityByReference = new AttributeResolutionGuidance.CdmAttributeResolutionGuidance_EntityByReference()
                {
                    alwaysIncludeForeignKey = instance.entityByReference.alwaysIncludeForeignKey,
                    referenceOnlyAfterDepth = instance.entityByReference.referenceOnlyAfterDepth,
                    allowReference          = instance.entityByReference.allowReference,
                    foreignKeyAttribute     = Utils.JsonForm(instance.entityByReference.foreignKeyAttribute, resOpt, options)
                };
            }
            if (instance.selectsSubAttribute != null)
            {
                obj.selectsSubAttribute = new AttributeResolutionGuidance.CdmAttributeResolutionGuidance_SelectsSubAttribute()
                {
                    selects = instance.selectsSubAttribute.selects,
                    selectedTypeAttribute = Utils.JsonForm(instance.selectsSubAttribute.selectedTypeAttribute, resOpt, options),
                    selectsSomeTakeNames  = instance.selectsSubAttribute.selectsSomeTakeNames,
                    selectsSomeAvoidNames = instance.selectsSubAttribute.selectsSomeAvoidNames
                };
            }
            return(obj);
        }
        public void TestResolutionGuidanceCopy()
        {
            var corpus             = new CdmCorpusDefinition();
            var resolutionGuidance = new CdmAttributeResolutionGuidance(corpus.Ctx)
            {
                expansion           = new CdmAttributeResolutionGuidance.Expansion(),
                entityByReference   = new CdmAttributeResolutionGuidance.CdmAttributeResolutionGuidance_EntityByReference(),
                selectsSubAttribute = new CdmAttributeResolutionGuidance.CdmAttributeResolutionGuidance_SelectsSubAttribute(),
                imposedDirectives   = new List <string>(),
                removedDirectives   = new List <string>()
            };

            var resolutionGuidanceCopy = resolutionGuidance.Copy() as CdmAttributeResolutionGuidance;

            Assert.IsFalse(Object.ReferenceEquals(resolutionGuidance.expansion, resolutionGuidanceCopy.expansion));
            Assert.IsFalse(Object.ReferenceEquals(resolutionGuidance.entityByReference, resolutionGuidanceCopy.entityByReference));
            Assert.IsFalse(Object.ReferenceEquals(resolutionGuidance.selectsSubAttribute, resolutionGuidanceCopy.selectsSubAttribute));
            Assert.IsFalse(Object.ReferenceEquals(resolutionGuidance.imposedDirectives, resolutionGuidanceCopy.imposedDirectives));
            Assert.IsFalse(Object.ReferenceEquals(resolutionGuidance.removedDirectives, resolutionGuidanceCopy.removedDirectives));
        }
示例#4
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        //  traits that change attributes
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        internal ResolvedAttributeSet ApplyTraits(ResolvedTraitSet traits, CdmAttributeResolutionGuidance resGuide, List <AttributeResolutionApplier> actions)
        {
            ResolvedAttributeSet rasResult = this;
            ResolvedAttributeSet rasApplied;

            if (this.RefCnt > 1 && rasResult.CopyNeeded(traits, resGuide, actions))
            {
                rasResult = rasResult.Copy();
            }
            rasApplied = rasResult.Apply(traits, resGuide, actions);

            // now we are that
            rasResult.ResolvedName2resolvedAttribute = rasApplied.ResolvedName2resolvedAttribute;
            rasResult.BaseTrait2Attributes           = null;
            rasResult.Set          = rasApplied.Set;
            rasResult.Ra2attCtxSet = rasApplied.Ra2attCtxSet;
            rasResult.AttCtx2ra    = rasApplied.AttCtx2ra;

            return(rasResult);
        }
示例#5
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);
        }
        internal AttributeResolutionContext(ResolveOptions resOpt, CdmAttributeResolutionGuidance resGuide, ResolvedTraitSet traits)
        {
            // collect a set of appliers for all traits
            this.TraitsToApply = traits;
            this.ResGuide      = resGuide;
            this.ResOpt        = resOpt;

            this.ActionsModify       = new List <AttributeResolutionApplier>();
            this.ActionsGroupAdd     = new List <AttributeResolutionApplier>();
            this.ActionsRoundAdd     = new List <AttributeResolutionApplier>();
            this.ActionsAttributeAdd = new List <AttributeResolutionApplier>();
            this.ActionsRemove       = new List <AttributeResolutionApplier>();
            this.ApplierCaps         = null;

            this.ResOpt = resOpt.Copy();

            if (resGuide != null)
            {
                if (this.ApplierCaps == null)
                {
                    this.ApplierCaps = new AttributeResolutionApplierCapabilities()
                    {
                        CanAlterDirectives = false,
                        CanCreateContext   = false,
                        CanRemove          = false,
                        CanAttributeModify = false,
                        CanGroupAdd        = false,
                        CanRoundAdd        = false,
                        CanAttributeAdd    = false
                    }
                }
                ;
                Func <AttributeResolutionApplier, bool> addApplier = (AttributeResolutionApplier apl) =>
                {
                    // Collect the code that will perform the right action.
                    // Associate with the resolved trait and get the priority
                    if (apl.WillAttributeModify != null && apl.DoAttributeModify != null)
                    {
                        this.ActionsModify.Add(apl);
                        this.ApplierCaps.CanAttributeModify = true;
                    }
                    if (apl.WillAttributeAdd != null && apl.DoAttributeAdd != null)
                    {
                        this.ActionsAttributeAdd.Add(apl);
                        this.ApplierCaps.CanAttributeAdd = true;
                    }
                    if (apl.WillGroupAdd != null && apl.DoGroupAdd != null)
                    {
                        this.ActionsGroupAdd.Add(apl);
                        this.ApplierCaps.CanGroupAdd = true;
                    }
                    if (apl.WillRoundAdd != null && apl.DoRoundAdd != null)
                    {
                        this.ActionsRoundAdd.Add(apl);
                        this.ApplierCaps.CanRoundAdd = true;
                    }
                    if (apl.WillAlterDirectives != null && apl.DoAlterDirectives != null)
                    {
                        this.ApplierCaps.CanAlterDirectives = true;
                        apl.DoAlterDirectives(this.ResOpt, resGuide);
                    }
                    if (apl.WillCreateContext != null && apl.DoCreateContext != null)
                    {
                        this.ApplierCaps.CanCreateContext = true;
                    }
                    if (apl.WillRemove != null)
                    {
                        this.ActionsRemove.Add(apl);
                        this.ApplierCaps.CanRemove = true;
                    }
                    return(true);
                };

                if (resGuide.removeAttribute == true)
                {
                    addApplier(PrimitiveAppliers.isRemoved);
                }
                if (resGuide.imposedDirectives != null)
                {
                    addApplier(PrimitiveAppliers.doesImposeDirectives);
                }
                if (resGuide.removedDirectives != null)
                {
                    addApplier(PrimitiveAppliers.doesRemoveDirectives);
                }
                if (resGuide.addSupportingAttribute != null)
                {
                    addApplier(PrimitiveAppliers.doesAddSupportingAttribute);
                }
                if (resGuide.renameFormat != null)
                {
                    addApplier(PrimitiveAppliers.doesDisambiguateNames);
                }
                if (resGuide.cardinality == "many")
                {
                    addApplier(PrimitiveAppliers.doesExplainArray);
                }
                if (resGuide.entityByReference != null)
                {
                    addApplier(PrimitiveAppliers.doesReferenceEntityVia);
                }

                if (resGuide.selectsSubAttribute != null && resGuide.selectsSubAttribute.selects == "one")
                {
                    addApplier(PrimitiveAppliers.doesSelectAttributes);
                }

                // sorted by priority
                this.ActionsModify.Sort((l, r) => l.Priority - r.Priority);
                this.ActionsGroupAdd.Sort((l, r) => l.Priority - r.Priority);
                this.ActionsRoundAdd.Sort((l, r) => l.Priority - r.Priority);
                this.ActionsAttributeAdd.Sort((l, r) => l.Priority - r.Priority);
            }
        }
    }