/// <summary> /// Resolve the route of a <see cref="Thing"/> from a <see cref="IEnumerable{Thing}"/> that contains all its containers /// </summary> /// <param name="thing">The <see cref="Thing"/> to resolve</param> /// <param name="dtolist">The <see cref="IEnumerable{Thing}"/> that shall contain</param> /// <param name="session">The <see cref="ISession"/> associated to the <see cref="Thing"/></param> /// <exception cref="ArgumentNullException">The arguments cannot be null</exception> /// <exception cref="InstanceNotFoundException">If the container cannot be found</exception> /// <exception cref="InvalidOperationException">If the multiple containers are found for one thing</exception> /// <exception cref="NullReferenceException">The containement tree is broken for a <see cref="Poco"/> currently in the <see cref="ISession"/></exception> public static void ResolveRoute(this Thing thing, IEnumerable <Thing> dtolist, ISession session) { if (dtolist == null) { throw new ArgumentNullException("dtolist"); } if (session == null) { throw new ArgumentNullException("session"); } if (thing is TopContainer) { return; } var dtos = dtolist.ToList(); Thing container = dtos.SingleOrDefault(dto => dto.Contains(thing)); if (container == null) { // the container is not in the list of dtos, search in the current ISession Lazy <Poco> lazyThing; var res = session.Assembler.Cache.TryGetValue(new CacheKey(thing.Iid, thing.IterationContainerId), out lazyThing); if (!res) { throw new InstanceNotFoundException(string.Format("The {0} with id {1} could not be found", thing.ClassKind, thing.Iid)); } // Build the complete containement tree thing.AddContainerCompleteTree(lazyThing.Value); return; } // the container is in the list of dtos thing.AddContainer(container.ClassKind, container.Iid); while (!(container is TopContainer)) { var previousContainer = container; container = dtos.SingleOrDefault(dto => dto.Contains(container)); if (container != null) { thing.AddContainer(container.ClassKind, container.Iid); continue; } // one of the container nnot be found in the list of dto => search in the current ISession and build the partial tree up to the topcontainer Lazy <Poco> lazyThing; var res = session.Assembler.Cache.TryGetValue(new CacheKey(previousContainer.Iid, previousContainer.IterationContainerId), out lazyThing); if (!res) { throw new InstanceNotFoundException(string.Format("The {0} with id {1} could not be found", previousContainer.ClassKind, previousContainer.Iid)); } thing.AddContainerPartialTree(lazyThing.Value); break; } }
/// <summary> /// Build the full containment tree for a <see cref="Thing"/> from its associated <see cref="Poco"/> /// </summary> /// <param name="thing">The <see cref="Thing"/> which containment tree is computed</param> /// <param name="cachedThing">Its associated <see cref="Poco"/> in the current <see cref="ISession"/></param> private static void AddContainerCompleteTree(this Thing thing, Poco cachedThing) { var container = cachedThing.Container; if (container == null) { throw new NullReferenceException(string.Format("The container of the {0} with id {1} is null.", thing.ClassKind, thing.Iid)); } thing.AddContainer(container.ClassKind, container.Iid); while (!(container is CDP4Common.CommonData.TopContainer)) { container = container.Container; if (container == null) { throw new NullReferenceException(string.Format("The containment tree is broken for the {0} with id {1}.", thing.ClassKind, thing.Iid)); } thing.AddContainer(container.ClassKind, container.Iid); } }
/// <summary> /// Build the partial containment tree of a <see cref="Thing"/> starting from one of its container /// </summary> /// <param name="thing">The <see cref="Thing"/> which containment tree is computed</param> /// <param name="container">One of its container in the containment tree in the current <see cref="ISession"/></param> private static void AddContainerPartialTree(this Thing thing, Poco container) { var tmpContainer = container; while (!(tmpContainer is CDP4Common.CommonData.TopContainer)) { tmpContainer = tmpContainer.Container; if (tmpContainer == null) { throw new NullReferenceException(string.Format("The containment tree is broken for the {0} with id {1}.", thing.ClassKind, thing.Iid)); } thing.AddContainer(tmpContainer.ClassKind, tmpContainer.Iid); } }