internal bool IsDerivedFromDef(ResolveOptions resOpt, CdmObjectReference baseCdmObjectRef, string name, string seek) { if (seek == name) { return(true); } CdmObjectDefinition def = baseCdmObjectRef?.FetchObjectDefinition <CdmObjectDefinition>(resOpt); if (def != null) { return(def.IsDerivedFrom(seek, resOpt)); } return(false); }
/// <summary> /// Create a copy of the reference object /// </summary> public static dynamic CopyIdentifierRef(CdmObjectReference objRef, ResolveOptions resOpt, CopyOptions options) { string identifier = objRef.NamedReference; if (options == null || options.StringRefs == null || options.StringRefs == false) { return(identifier); } CdmObjectDefinition resolved = objRef.FetchObjectDefinition <CdmObjectDefinition>(resOpt); if (resolved == null) { return(identifier); } return(new { AtCorpusPath = resolved.AtCorpusPath, Identifier = identifier }); }
internal override ResolvedAttributeSetBuilder ConstructResolvedAttributes(ResolveOptions resOpt, CdmAttributeContext under = null) { // find and cache the complete set of attributes // attributes definitions originate from and then get modified by subsequent re-definitions from (in this order): // an extended entity, traits applied to extended entity, exhibited traits of main entity, the (datatype or entity) used as an attribute, traits applied to that datatype or entity, // the relationsip of the attribute, the attribute definition itself and included attribute groups, dynamic traits applied to the attribute. this.Rasb = new ResolvedAttributeSetBuilder(); this.Rasb.ResolvedAttributeSet.AttributeContext = under; if (this.ExtendsEntity != null) { CdmObjectReference extRef = this.ExtendsEntityRef; CdmAttributeContext extendsRefUnder = null; AttributeContextParameters acpExtEnt = null; if (under != null) { AttributeContextParameters acpExt = new AttributeContextParameters { under = under, type = CdmAttributeContextType.EntityReferenceExtends, Name = "extends", Regarding = null, IncludeTraits = false }; extendsRefUnder = this.Rasb.ResolvedAttributeSet.CreateAttributeContext(resOpt, acpExt); } if (extRef.ExplicitReference != null && extRef.FetchObjectDefinition <CdmObjectDefinition>(resOpt).ObjectType == CdmObjectType.ProjectionDef) { // A Projection CdmObjectDefinition extRefObjDef = extRef.FetchObjectDefinition <CdmObjectDefinition>(resOpt); if (extendsRefUnder != null) { acpExtEnt = new AttributeContextParameters { under = extendsRefUnder, type = CdmAttributeContextType.Projection, Name = extRefObjDef.GetName(), Regarding = extRef, IncludeTraits = false }; } ProjectionDirective projDirective = new ProjectionDirective(resOpt, this, ownerRef: extRef); CdmProjection projDef = (CdmProjection)extRefObjDef; ProjectionContext projCtx = projDef.ConstructProjectionContext(projDirective, extendsRefUnder); this.Rasb.ResolvedAttributeSet = projDef.ExtractResolvedAttributes(projCtx); } else { // An Entity Reference if (extendsRefUnder != null) { // usually the extended entity is a reference to a name. // it is allowed however to just define the entity inline. acpExtEnt = new AttributeContextParameters { under = extendsRefUnder, type = CdmAttributeContextType.Entity, Name = extRef.NamedReference ?? extRef.ExplicitReference.GetName(), Regarding = extRef, IncludeTraits = false }; } // save moniker, extended entity may attach a different moniker that we do not // want to pass along to getting this entities attributes string oldMoniker = resOpt.FromMoniker; this.Rasb.MergeAttributes((this.ExtendsEntityRef as CdmObjectReferenceBase).FetchResolvedAttributes(resOpt, acpExtEnt)); if (!resOpt.CheckAttributeCount(this.Rasb.ResolvedAttributeSet.ResolvedAttributeCount)) { Logger.Error(nameof(CdmEntityDefinition), this.Ctx, $"Maximum number of resolved attributes reached for the entity: {this.EntityName}."); return(null); } if (this.ExtendsEntityResolutionGuidance != null) { // some guidance was given on how to integrate the base attributes into the set. apply that guidance ResolvedTraitSet rtsBase = this.FetchResolvedTraits(resOpt); // this context object holds all of the info about what needs to happen to resolve these attributes. // make a copy and set defaults if needed CdmAttributeResolutionGuidance resGuide = (CdmAttributeResolutionGuidance)this.ExtendsEntityResolutionGuidance.Copy(resOpt); resGuide.UpdateAttributeDefaults(resGuide.FetchObjectDefinitionName()); // holds all the info needed by the resolver code AttributeResolutionContext arc = new AttributeResolutionContext(resOpt, resGuide, rtsBase); this.Rasb.GenerateApplierAttributes(arc, false); // true = apply the prepared traits to new atts } // reset to the old moniker resOpt.FromMoniker = oldMoniker; } } this.Rasb.MarkInherited(); this.Rasb.ResolvedAttributeSet.AttributeContext = under; if (this.Attributes != null) { int l = this.Attributes.Count; for (int i = 0; i < l; i++) { dynamic att = this.Attributes.AllItems[i]; CdmAttributeContext attUnder = under; AttributeContextParameters acpAtt = null; if (under != null) { acpAtt = new AttributeContextParameters { under = under, type = CdmAttributeContextType.AttributeDefinition, Name = att.FetchObjectDefinitionName(), Regarding = att, IncludeTraits = false }; } this.Rasb.MergeAttributes(att.FetchResolvedAttributes(resOpt, acpAtt)); if (!resOpt.CheckAttributeCount(this.Rasb.ResolvedAttributeSet.ResolvedAttributeCount)) { Logger.Error(nameof(CdmEntityDefinition), this.Ctx, $"Maximum number of resolved attributes reached for the entity: {this.EntityName}."); return(null); } } } this.Rasb.MarkOrder(); this.Rasb.ResolvedAttributeSet.AttributeContext = under; // things that need to go away this.Rasb.RemoveRequestedAtts(); return(this.Rasb); }
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); }