Beispiel #1
0
        public ResolvedEntityReferenceSet FetchResolvedEntityReferences(ResolveOptions resOpt = null)
        {
            bool wasPreviouslyResolving = this.Ctx.Corpus.isCurrentlyResolving;

            this.Ctx.Corpus.isCurrentlyResolving = true;
            if (resOpt == null)
            {
                resOpt = new ResolveOptions(this, this.Ctx.Corpus.DefaultResolutionDirectives);
            }

            // this whole resolved entity ref goo will go away when resolved documents are done.
            // for now, it breaks if structured att sets get made.
            resOpt            = CdmObjectBase.CopyResolveOptions(resOpt);
            resOpt.Directives = new AttributeResolutionDirectiveSet(new HashSet <string> {
                "normalized", "referenceOnly"
            });

            ResolveContext             ctx            = this.Ctx as ResolveContext; // what it actually is
            ResolvedEntityReferenceSet entRefSetCache = ctx.FetchCache(this, resOpt, "entRefSet") as ResolvedEntityReferenceSet;

            if (entRefSetCache == null)
            {
                entRefSetCache = new ResolvedEntityReferenceSet(resOpt);
                if (resolvingEntityReferences == false)
                {
                    resolvingEntityReferences = true;
                    // get from dynamic base public class and then 'fix' those to point here instead.
                    CdmObjectReference extRef = this.ExtendsEntityRef;
                    if (extRef != null)
                    {
                        var extDef = extRef.FetchObjectDefinition <CdmEntityDefinition>(resOpt);
                        if (extDef != null)
                        {
                            if (extDef == this)
                            {
                                extDef = extRef.FetchObjectDefinition <CdmEntityDefinition>(resOpt);
                            }
                            ResolvedEntityReferenceSet inherited = extDef.FetchResolvedEntityReferences(resOpt);
                            if (inherited != null)
                            {
                                foreach (var res in inherited.Set)
                                {
                                    ResolvedEntityReference resolvedEntityReference = res.Copy();
                                    resolvedEntityReference.Referencing.Entity = this;
                                    entRefSetCache.Set.Add(resolvedEntityReference);
                                }
                            }
                        }
                    }
                    if (this.Attributes != null)
                    {
                        for (int i = 0; i < this.Attributes.Count; i++)
                        {
                            // if dynamic refs come back from attributes, they don't know who we are, so they don't set the entity
                            dynamic sub = this.Attributes.AllItems[i].FetchResolvedEntityReferences(resOpt);
                            if (sub != null)
                            {
                                foreach (var res in sub.Set)
                                {
                                    res.Referencing.Entity = this;
                                }
                                entRefSetCache.Add(sub);
                            }
                        }
                    }
                    ctx.UpdateCache(this, resOpt, "entRefSet", entRefSetCache);
                    this.resolvingEntityReferences = false;
                }
            }
            this.Ctx.Corpus.isCurrentlyResolving = wasPreviouslyResolving;
            return(entRefSetCache);
        }
        // the only thing we need this code for is testing!!!
        public override ResolvedEntityReferenceSet FetchResolvedEntityReferences(ResolveOptions resOpt = null)
        {
            if (resOpt == null)
            {
                resOpt = new ResolveOptions(this);
            }

            ResolvedTraitSet rtsThisAtt = this.FetchResolvedTraits(resOpt);
            CdmAttributeResolutionGuidance resGuide = (CdmAttributeResolutionGuidance)this.ResolutionGuidance;

            // this context object holds all of the info about what needs to happen to resolve these attributes
            AttributeResolutionContext arc = new AttributeResolutionContext(resOpt, resGuide, rtsThisAtt);

            RelationshipInfo relInfo = this.GetRelationshipInfo(resOpt, arc);
            if (relInfo.IsByRef && !relInfo.IsArray)
            {
                {
                    // only place this is used, so logic here instead of encapsulated. 
                    // make a set and the one ref it will hold
                    ResolvedEntityReferenceSet rers = new ResolvedEntityReferenceSet(resOpt);
                    ResolvedEntityReference rer = new ResolvedEntityReference();
                    // referencing attribute(s) come from this attribute
                    rer.Referencing.ResolvedAttributeSetBuilder.MergeAttributes(this.FetchResolvedAttributes(resOpt, null));
                    Func<CdmEntityReference, ResolvedEntityReferenceSide> resolveSide = entRef =>
                    {
                        ResolvedEntityReferenceSide sideOther = new ResolvedEntityReferenceSide(null, null);
                        if (entRef != null)
                        {
                            // reference to the other entity, hard part is the attribue name.
                            // by convention, this is held in a trait that identifies the key
                            sideOther.Entity = entRef.FetchObjectDefinition<CdmEntityDefinition>(resOpt);
                            if (sideOther.Entity != null)
                            {
                                CdmAttribute otherAttribute;
                                ResolveOptions otherOpts = new ResolveOptions { WrtDoc = resOpt.WrtDoc, Directives = resOpt.Directives };
                                ResolvedTrait t = entRef.FetchResolvedTraits(otherOpts).Find(otherOpts, "is.identifiedBy");
                                if (t?.ParameterValues?.Length > 0)
                                {
                                    dynamic otherRef = (t.ParameterValues.FetchParameterValueByName("attribute").Value);
                                    if (typeof(CdmObject).IsAssignableFrom(otherRef?.GetType()))
                                    {
                                        otherAttribute = (otherRef as CdmObject).FetchObjectDefinition<CdmObjectDefinition>(otherOpts) as CdmAttribute;
                                        if (otherAttribute != null)
                                        {
                                            sideOther.ResolvedAttributeSetBuilder.OwnOne(sideOther.Entity.FetchResolvedAttributes(otherOpts).Get(otherAttribute.GetName()).Copy());
                                        }
                                    }
                                }
                            }
                        }

                        return sideOther;
                    };

                    // either several or one entity
                    // for now, a sub for the 'select one' idea
                    if ((this.Entity as CdmEntityReference).ExplicitReference != null)
                    {
                        CdmEntityDefinition entPickFrom = (this.Entity as CdmEntityReference).FetchObjectDefinition<CdmEntityDefinition>(resOpt);
                        CdmCollection<CdmAttributeItem> attsPick = entPickFrom.GetAttributeDefinitions();
                        if (attsPick != null && attsPick != null)
                        {
                            for (int i = 0; i < attsPick.Count; i++)
                            {
                                if (attsPick.AllItems[i].ObjectType == CdmObjectType.EntityAttributeDef)
                                {
                                    CdmEntityReference er = (attsPick.AllItems[i] as CdmEntityAttributeDefinition).Entity;
                                    rer.Referenced.Add(resolveSide(er));
                                }
                            }
                        }
                    }
                    else
                    {
                        rer.Referenced.Add(resolveSide(this.Entity as CdmEntityReference));
                    }

                    rers.Set.Add(rer);
                    return rers;
                }
            }
            return null;
        }