// gets the path down to the set containing the given keyexpression public static List <AccessPathSegment> BuildAccessPath(KeyExpression keyExp, bool requireCanonical) { // grab all the canonical path attributes IEnumerable <ContainmentAttribute> attributes; if (requireCanonical) { attributes = GetContainmentAttributes(keyExp, ca => ca.Canonical); } else { attributes = GetContainmentAttributes(keyExp); } // now we need to link them together, first by getting the SINGLE canonical path attribute with the current // resource container as the child, and moving up List <AccessPathSegment> path = new List <AccessPathSegment>(); ResourceContainer current = keyExp.ResourceContainer; bool done = !attributes.Any(); while (!done) { IEnumerable <ContainmentAttribute> applicable = attributes.Where(ca => ca.ChildContainer == current); if (!applicable.Any()) { done = true; } else { ContainmentAttribute att = applicable.Where(ca => ca.Canonical).FirstOrDefault(); if (att == null) { att = applicable.FirstOrDefault(); } if (att == null || (att.TopLevelAccess && !requireCanonical)) { done = true; } else { AccessPathSegment segment = new AccessPathSegment(); segment.Attribute = att; keyExp = att.GetContainingKey(keyExp); segment.ParentKey = keyExp; path.Add(segment); current = att.ParentContainer; } } } path.Reverse(); return(path); }
public static KeyExpression GetContainingKey(this ContainmentAttribute att, KeyExpression childKey, ResourceType parentType) { return(att.GetContainingKey(childKey, parentType, AbbreviateCanonicalPath)); }
public static KeyExpression GetContainingKey(this ContainmentAttribute att, KeyExpression childKey, bool abbreviate) { return(att.GetContainingKey(childKey, att.ParentContainer.BaseType, abbreviate)); }