示例#1
0
        /// <summary>
        /// Recursively Create <see cref="NestedElement"/>s
        /// </summary>
        /// <param name="elementDefinition">
        /// The <see cref="ElementDefinition"/> that contains <see cref="ElementUsage"/>s that
        /// </param>
        /// <param name="rootElement">
        /// The <see cref="ElementDefinition"/> that is the root of the <see cref="NestedElement"/> tree.
        /// </param>
        /// <param name="domainOfExpertise">
        /// The <see cref="DomainOfExpertise"/> for which the <see cref="NestedElement"/> tree needs to be generated. Only the <see cref="Parameter"/>s, <see cref="ParameterOverride"/>s and
        /// <see cref="ParameterSubscription"/>s that are owned by the <see cref="DomainOfExpertise"/> will be taken into account when generating <see cref="NestedParameter"/>s
        /// </param>
        /// <param name="elementUsages">
        /// A <see cref="List{ElementUsage}"/> that contains the <see cref="ElementUsage"/> that define the containment tree
        /// for the <see cref="NestedElement"/>s at the level of the <paramref name="elementDefinition"/>.
        /// </param>
        /// <param name="option">
        /// The <see cref="Option"/> for which the <see cref="NestedElement"/> tree is created. When the <see cref="Option"/>
        /// is null then none of the <see cref="ElementUsage"/>s are filtered.
        /// </param>
        /// <param name="updateOption">
        /// Value indicating whether the <see cref="Option"/> shall be updated with the created <see cref="NestedElement"/>s or not.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable{NestedElement}"/> that have been created.
        /// </returns>
        private IEnumerable <NestedElement> RecursivelyCreateNestedElements(ElementDefinition elementDefinition, ElementDefinition rootElement, DomainOfExpertise domainOfExpertise, List <ElementUsage> elementUsages, Option option, bool updateOption)
        {
            var cache = elementDefinition.Cache;
            var uri   = elementDefinition.IDalUri;

            foreach (var elementUsage in elementDefinition.ContainedElement)
            {
                // comparison is done based on unique identifiers, not on object level. The provided option may be a clone
                if (elementUsage.ExcludeOption.Any(x => x.Iid == option.Iid))
                {
                    Logger.Debug($"ElementUsage {elementUsage.Iid}:{elementUsage.ShortName} is excluded from the Nested Elements.");
                    continue;
                }

                var nestedElement = new NestedElement(Guid.NewGuid(), cache, uri)
                {
                    RootElement = rootElement,
                    IsVolatile  = true
                };

                if (updateOption)
                {
                    option.NestedElement.Add(nestedElement);
                }
                else
                {
                    nestedElement.Container = option;
                }

                var nestedParameters = this.CreateNestedParameters(elementUsage, domainOfExpertise, option);

                foreach (var nestedParameter in nestedParameters)
                {
                    nestedElement.NestedParameter.Add(nestedParameter);
                }

                var containmentUsages = new List <ElementUsage>();

                foreach (var usage in elementUsages)
                {
                    nestedElement.ElementUsage.Add(usage);
                    containmentUsages.Add(usage);
                }

                nestedElement.ElementUsage.Add(elementUsage);
                containmentUsages.Add(elementUsage);

                var referencedElementDefinition = elementUsage.ElementDefinition;

                var nestedElements = this.RecursivelyCreateNestedElements(referencedElementDefinition, rootElement, domainOfExpertise, containmentUsages, option, updateOption);

                foreach (var element in nestedElements)
                {
                    yield return(element);
                }

                yield return(nestedElement);
            }
        }
示例#2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="DataCollectorNode{T}"/> class.
 /// </summary>
 /// <param name="categoryDecompositionHierarchy">
 /// The <see cref="CategoryDecompositionHierarchy"/> associated with this node's subtree.
 /// </param>
 /// <param name="topElement">
 /// The <see cref="CDP4Common.EngineeringModelData.NestedElement"/> associated with this node.
 /// </param>
 /// <param name="parent">
 /// The parent node in the hierarhical tree upon which the data collector is based.
 /// </param>
 public DataCollectorNode(
     CategoryDecompositionHierarchy categoryDecompositionHierarchy,
     NestedElement topElement,
     DataCollectorNode <T> parent = null)
 {
     this.Initialize();
     this.NestedElement = topElement;
     this.parent        = parent;
     this.InitializeCategoryDecompositionHierarchy(categoryDecompositionHierarchy);
 }
示例#3
0
        /// <summary>
        /// Serialize the <see cref="NestedElement"/>
        /// </summary>
        /// <param name="nestedElement">The <see cref="NestedElement"/> to serialize</param>
        /// <returns>The <see cref="JObject"/></returns>
        private JObject Serialize(NestedElement nestedElement)
        {
            var jsonObject = new JObject();

            jsonObject.Add("classKind", this.PropertySerializerMap["classKind"](Enum.GetName(typeof(CDP4Common.CommonData.ClassKind), nestedElement.ClassKind)));
            jsonObject.Add("elementUsage", this.PropertySerializerMap["elementUsage"](nestedElement.ElementUsage.OrderBy(x => x, this.orderedItemComparer)));
            jsonObject.Add("excludedDomain", this.PropertySerializerMap["excludedDomain"](nestedElement.ExcludedDomain.OrderBy(x => x, this.guidComparer)));
            jsonObject.Add("excludedPerson", this.PropertySerializerMap["excludedPerson"](nestedElement.ExcludedPerson.OrderBy(x => x, this.guidComparer)));
            jsonObject.Add("iid", this.PropertySerializerMap["iid"](nestedElement.Iid));
            jsonObject.Add("isVolatile", this.PropertySerializerMap["isVolatile"](nestedElement.IsVolatile));
            jsonObject.Add("modifiedOn", this.PropertySerializerMap["modifiedOn"](nestedElement.ModifiedOn));
            jsonObject.Add("nestedParameter", this.PropertySerializerMap["nestedParameter"](nestedElement.NestedParameter.OrderBy(x => x, this.guidComparer)));
            jsonObject.Add("revisionNumber", this.PropertySerializerMap["revisionNumber"](nestedElement.RevisionNumber));
            jsonObject.Add("rootElement", this.PropertySerializerMap["rootElement"](nestedElement.RootElement));
            jsonObject.Add("thingPreference", this.PropertySerializerMap["thingPreference"](nestedElement.ThingPreference));
            return(jsonObject);
        }
示例#4
0
        /// <summary>
        /// Gets the tree of <see cref="DataCollectorNode{T}"/>s. This method can call itself recursively.
        /// </summary>
        /// <param name="nestedElement">
        /// The <see cref="NestedElement"/>
        /// </param>
        /// <param name="categoryDecompositionHierarchy">
        /// The <see cref="CategoryDecompositionHierarchy"/> used for filtering the considered <see cref="NestedElement"/> items.
        /// </param>
        /// <param name="nestedElements">
        /// The <see cref="List{NestedElement}"/>s
        /// </param>
        /// <param name="parentNode">
        /// The <see cref=" DataCollectorNode{T}"/> that is the parent of new nodes.
        /// </param>
        /// <returns>
        /// An <see cref="IEnumerable{T}"/> of <see cref="DataCollectorNode{T}"/>
        /// </returns>
        private IEnumerable <DataCollectorNode <T> > GetDataCollectorNodes(NestedElement nestedElement, CategoryDecompositionHierarchy categoryDecompositionHierarchy, List <NestedElement> nestedElements, DataCollectorNode <T> parentNode)
        {
            var resultNodes = new List <DataCollectorNode <T> >();
            DataCollectorNode <T> newNode = null;
            var searchCategory            = categoryDecompositionHierarchy;

            if (categoryDecompositionHierarchy.Child != null && parentNode?.CountCategoryRecursionLevel(categoryDecompositionHierarchy.Category) > 0 && nestedElement.IsMemberOfCategory(categoryDecompositionHierarchy.Child.Category))
            {
                searchCategory = categoryDecompositionHierarchy.Child;

                newNode = new DataCollectorNode <T>(searchCategory, nestedElement, parentNode);
                parentNode.Children.Add(newNode);
                resultNodes.Add(newNode);
            }
            else if (nestedElement.IsMemberOfCategory(categoryDecompositionHierarchy.Category))
            {
                newNode = new DataCollectorNode <T>(categoryDecompositionHierarchy, nestedElement, parentNode);
                parentNode?.Children.Add(newNode);
                resultNodes.Add(newNode);
            }
            else if (!(categoryDecompositionHierarchy.Child?.AllowSkipUnknownCategories ?? true))
            {
                return(resultNodes);
            }

            var children = nestedElement.GetChildren(nestedElements).ToList();

            foreach (var child in children)
            {
                var nodes = this.GetDataCollectorNodes(child, searchCategory, nestedElements, newNode ?? parentNode).ToArray();

                if (newNode == null && nodes.Any())
                {
                    resultNodes = resultNodes.Concat(nodes).ToList();
                }
            }

            return(resultNodes);
        }
        /// <summary>
        /// Persist the <see cref="NestedElement"/> containment tree to the ORM layer. Update if it already exists.
        /// This is typically used during the import of existing data to the Database.
        /// </summary>
        /// <param name="transaction">
        /// The current <see cref="NpgsqlTransaction"/> to the database.
        /// </param>
        /// <param name="partition">
        /// The database partition (schema) where the requested resource will be stored.
        /// </param>
        /// <param name="nestedElement">
        /// The <see cref="NestedElement"/> instance to persist.
        /// </param>
        /// <returns>
        /// True if the persistence was successful.
        /// </returns>
        private bool UpsertContainment(NpgsqlTransaction transaction, string partition, NestedElement nestedElement)
        {
            var results = new List <bool>();

            foreach (var nestedParameter in this.ResolveFromRequestCache(nestedElement.NestedParameter))
            {
                results.Add(this.NestedParameterService.UpsertConcept(transaction, partition, nestedParameter, nestedElement));
            }

            return(results.All(x => x));
        }
示例#6
0
 /// <summary>
 /// Add an Nested Element row view model to the list of <see cref="NestedElement"/>
 /// </summary>
 /// <param name="nestedElement">
 /// The <see cref="NestedElement"/> that is to be added
 /// </param>
 private NestedElementRowViewModel AddNestedElementRowViewModel(NestedElement nestedElement)
 {
     return(new NestedElementRowViewModel(nestedElement, this.Session, this));
 }
示例#7
0
        /// <summary>
        /// Creates The <see cref="NestedElement"/> and contained <see cref="NestedParameter"/> that represents the <paramref name="rootElement"/>
        /// </summary>
        /// <param name="rootElement">
        /// The <see cref="ElementDefinition"/> that is the root of the <see cref="NestedElement"/> tree.
        /// </param>
        /// <param name="domainOfExpertise">
        /// The <see cref="DomainOfExpertise"/> for which the <see cref="NestedElement"/> tree needs to be generated. Only the <see cref="Parameter"/>s, <see cref="ParameterOverride"/>s and
        /// <see cref="ParameterSubscription"/>s that are owned by the <see cref="DomainOfExpertise"/> will be taken into account when generating <see cref="NestedParameter"/>s
        /// </param>
        /// <param name="option">
        /// The <see cref="Option"/> for which the <see cref="NestedElement"/> tree is created. When the <see cref="Option"/>
        /// is null then none of the <see cref="ElementUsage"/>s are filtered.
        /// </param>
        /// <param name="updateOption">
        /// Value indicating whether the <see cref="Option"/> shall be updated with the created <see cref="NestedElement"/>s or not.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable{NestedElement}"/> that have been created.
        /// </returns>
        private NestedElement CreateNestedElementAndNestedParametersForRootElement(ElementDefinition rootElement, DomainOfExpertise domainOfExpertise, Option option, bool updateOption)
        {
            var nestedElement = new NestedElement(Guid.NewGuid(), rootElement.Cache, rootElement.IDalUri)
            {
                RootElement   = rootElement,
                IsVolatile    = true,
                IsRootElement = true
            };

            if (updateOption)
            {
                option.NestedElement.Add(nestedElement);
            }
            else
            {
                nestedElement.Container = option;
            }

            foreach (var parameter in rootElement.Parameter)
            {
                var compoundParameterType = parameter.ParameterType as CompoundParameterType;

                if (domainOfExpertise == null || parameter.Owner == domainOfExpertise)
                {
                    var valueSets = parameter.IsOptionDependent ? parameter.ValueSet.Where(vs => vs.ActualOption == option).ToList() : parameter.ValueSet;

                    foreach (var parameterValueSet in valueSets)
                    {
                        if (compoundParameterType == null)
                        {
                            var nestedParameter = this.CreatedNestedParameter(parameter, null, parameterValueSet, option);
                            nestedElement.NestedParameter.Add(nestedParameter);
                        }
                        else
                        {
                            foreach (var component in compoundParameterType.Component)
                            {
                                var comp            = (ParameterTypeComponent)component;
                                var nestedParameter = this.CreatedNestedParameter(parameter, comp, parameterValueSet, option);
                                nestedElement.NestedParameter.Add(nestedParameter);
                            }
                        }
                    }
                }
                else
                {
                    var subscription = parameter.ParameterSubscription.SingleOrDefault(ps => ps.Owner == domainOfExpertise);

                    if (subscription != null)
                    {
                        var nestedParameters = this.CreatedNestedParameters(subscription, option, compoundParameterType);

                        foreach (var nestedParameter in nestedParameters)
                        {
                            nestedElement.NestedParameter.Add(nestedParameter);
                        }
                    }
                }
            }

            return(nestedElement);
        }
示例#8
0
        public virtual void Setup()
        {
            this.Assembler = new Assembler(this.Uri);

            this.Domain = new DomainOfExpertise(Guid.NewGuid(), this.Assembler.Cache, this.Uri)
            {
                ShortName = "test"
            };

            this.Person = new Person(Guid.NewGuid(), this.Assembler.Cache, this.Uri)
            {
                DefaultDomain = this.Domain
            };

            this.Participant = new Participant(Guid.NewGuid(), this.Assembler.Cache, this.Uri);

            this.Option = new Option(Guid.NewGuid(), this.Assembler.Cache, this.Uri)
            {
                Name = "TestOption",
            };

            this.SetupElements();

            this.ElementUsage = new ElementUsage(Guid.NewGuid(), this.Assembler.Cache, this.Uri)
            {
                Name              = "testName",
                ShortName         = "testShortName",
                Owner             = this.Domain,
                ElementDefinition = this.ElementDefinition1,
                Category          = new List <Category>()
                {
                    new Category(Guid.NewGuid(), this.Assembler.Cache, this.Uri)
                    {
                        ShortName = "Test"
                    }
                }
            };

            this.NestedElement = new NestedElement(Guid.NewGuid(), this.Assembler.Cache, this.Uri)
            {
                RootElement  = this.TopElement,
                Container    = this.Option,
                ElementUsage = new OrderedItemList <ElementUsage>(null)
                {
                    this.ElementUsage1
                }
            };

            this.EngineeringModelSetup = new EngineeringModelSetup(Guid.NewGuid(), this.Assembler.Cache, this.Uri)
            {
                Name        = "test",
                Participant = { new Participant(Guid.NewGuid(), this.Assembler.Cache, this.Uri)
                                {
                                    Person = this.Person
                                } }
            };

            this.EngineeringModel = new EngineeringModel(Guid.NewGuid(), this.Assembler.Cache, this.Uri)
            {
                EngineeringModelSetup = this.EngineeringModelSetup
            };

            this.IterationSetup = new IterationSetup(Guid.NewGuid(), this.Assembler.Cache, this.Uri)
            {
                IterationNumber = int.MaxValue
            };

            this.Iteration = new Iteration(Guid.NewGuid(), this.Assembler.Cache, this.Uri)
            {
                IterationSetup = this.IterationSetup,
                TopElement     = this.TopElement, DefaultOption = this.Option
            };

            this.Iteration.Option.Add(this.Option);
            this.AddThingsToTheCache();
            this.EngineeringModel.Iteration.Add(this.Iteration);
            this.Session = new Mock <ISession>();
            this.Session.Setup(x => x.Assembler).Returns(this.Assembler);
            this.Session.Setup(x => x.ActivePerson).Returns(this.Person);
            this.Session.Setup(x => x.QuerySelectedDomainOfExpertise(this.Iteration)).Returns(this.Domain);
        }
        public void Setup()
        {
            this.cache = new ConcurrentDictionary <CacheKey, Lazy <Thing> >();

            this.iteration = new Iteration(Guid.NewGuid(), this.cache, this.uri);
            this.option    = new Option(Guid.NewGuid(), this.cache, this.uri)
            {
                Container = this.iteration
            };

            this.iteration.Option.Add(this.option);

            this.nestedElement  = new NestedElement(Guid.NewGuid(), this.cache, this.uri);
            this.rootElementDef = new ElementDefinition(Guid.NewGuid(), this.cache, this.uri)
            {
                Name = "ElementDef", ShortName = "Def", Container = this.iteration
            };
            this.elementDef1 = new ElementDefinition(Guid.NewGuid(), this.cache, this.uri)
            {
                Name = "ElementDef1", ShortName = "Def1", Container = this.iteration
            };
            this.elementDef2 = new ElementDefinition(Guid.NewGuid(), this.cache, this.uri)
            {
                Name = "ElementDef2", ShortName = "Def2", Container = this.iteration
            };
            this.elementDef3 = new ElementDefinition(Guid.NewGuid(), this.cache, this.uri)
            {
                Name = "ElementDef3", ShortName = "Def3", Container = this.iteration
            };
            this.elementDef4 = new ElementDefinition(Guid.NewGuid(), this.cache, this.uri)
            {
                Name = "ElementDef4", ShortName = "Def4", Container = this.iteration
            };
            this.elementUsage1 = new ElementUsage(Guid.NewGuid(), this.cache, this.uri)
            {
                Name = "ElementUsage", ShortName = "Use1", ElementDefinition = this.elementDef1
            };
            this.elementUsage2 = new ElementUsage(Guid.NewGuid(), this.cache, this.uri)
            {
                Name = "ElementUsage2", ShortName = "Use2", ElementDefinition = this.elementDef2
            };
            this.elementUsage3_1 = new ElementUsage(Guid.NewGuid(), this.cache, this.uri)
            {
                Name = "ElementUsage3_1", ShortName = "Use3_1", ElementDefinition = this.elementDef3
            };
            this.elementUsage3_2 = new ElementUsage(Guid.NewGuid(), this.cache, this.uri)
            {
                Name = "ElementUsage3_2", ShortName = "Use3_2", ElementDefinition = this.elementDef3
            };
            this.elementUsage4 = new ElementUsage(Guid.NewGuid(), this.cache, this.uri)
            {
                Name = "ElementUsage4", ShortName = "Use4", ElementDefinition = this.elementDef4
            };

            this.iteration.TopElement = this.rootElementDef;
            this.rootElementDef.ContainedElement.Add(this.elementUsage1);
            this.elementDef1.ContainedElement.Add(this.elementUsage2);
            this.elementDef1.ContainedElement.Add(this.elementUsage3_1);
            this.elementDef1.ContainedElement.Add(this.elementUsage3_2);
            this.elementDef3.ContainedElement.Add(this.elementUsage4);

            this.domain  = new DomainOfExpertise(Guid.NewGuid(), this.cache, this.uri);
            this.domain2 = new DomainOfExpertise(Guid.NewGuid(), this.cache, this.uri);

            this.elementUsage1.Owner             = this.domain2;
            this.elementUsage2.Owner             = this.domain2;
            this.elementUsage2.ElementDefinition = this.elementDef2;
            this.elementUsage3_1.Owner           = this.domain2;
            this.elementUsage3_2.Owner           = this.domain2;
            this.elementUsage4.Owner             = this.domain2;
            this.rootElementDef.Owner            = this.domain;

            this.nestedElement.RootElement = this.rootElementDef;
            this.nestedElement.ElementUsage.Add(this.elementUsage1);
            this.nestedElement.ElementUsage.Add(this.elementUsage2);

            this.category = new Category(Guid.NewGuid(), this.cache, this.uri)
            {
                Name = "Category", ShortName = "Cat"
            };

            var lazyCategory = new Lazy <Thing>(() => this.category);

            this.cache.TryAdd(new CacheKey(this.category.Iid, null), lazyCategory);

            var iterationSetup = new IterationSetup(Guid.NewGuid(), this.cache, this.uri);

            this.iteration.IterationSetup = iterationSetup;

            var engineeringModelSetup = new EngineeringModelSetup(Guid.NewGuid(), this.cache, this.uri);

            engineeringModelSetup.IterationSetup.Add(iterationSetup);

            var modelReferenceLibrary = new ModelReferenceDataLibrary(Guid.NewGuid(), this.cache, this.uri);

            modelReferenceLibrary.DefinedCategory.Add(this.category);
            engineeringModelSetup.RequiredRdl.Add(modelReferenceLibrary);
        }