public override void Reset()
 {
     contextStack.Clear();
     rootNode = null;
     references.Clear();
     checkedNodes.Clear();
     base.Reset();
 }
示例#2
0
 /// <summary>
 /// Reset the visitor in order to use it to generate another model.
 /// </summary>
 public override void Reset()
 {
     rootNode = null;
     rootGuid = Guid.Empty;
     contextStack.Clear();
     referenceContents.Clear();
     base.Reset();
 }
示例#3
0
        /// <summary>
        /// Add a child to this node. The node must not have been sealed yet.
        /// </summary>
        /// <param name="child">The child node to add.</param>
        /// <param name="allowIfReference">if set to <c>false</c> throw an exception if <see cref="IContent.Reference"/> is not null.</param>
        public void AddChild(GraphNode child, bool allowIfReference = false)
        {
            if (isSealed)
                throw new InvalidOperationException("Unable to add a child to a GraphNode that has been sealed");

            if (child.Parent != null)
                throw new ArgumentException(@"This node has already been registered to a different parent", nameof(child));

            if (Content.Reference != null && !allowIfReference)
                throw new InvalidOperationException("A GraphNode cannot have children when its content hold a reference.");

            child.Parent = this;
            children.Add(child);
        }
        public void Check(GraphNode node, object obj, Type type, bool checkReferences)
        {
            Reset();

            if (node.Content.Value != obj)
                throw new QuantumConsistencyException("The node content value [{0}]", obj.ToStringSafe(), "The node content value [{0}]", node.Content.Value.ToStringSafe(), node);
            if (node.Content.Type != type)
                throw new QuantumConsistencyException("The node content type [{0}]", type.Name, "The node content value [{0}]", node.Content.Type.Name, node);

            rootNode = node;

            while (rootNode != null)
            {
                if (rootNode.Parent != null)
                    throw new QuantumConsistencyException("A root node", "A node with a parent", rootNode);

                if (rootNode.Content.Value != null)
                {
                    var typeDescriptor = TypeDescriptorFactory.Find(rootNode.Content.Type);
                    PushContextNode(rootNode);
                    VisitObject(rootNode.Content.Value, typeDescriptor as ObjectDescriptor, true);
                    PopContextNode();
                }
                checkedNodes.Add(rootNode);
                rootNode = null;

                if (checkReferences)
                {
                    while (references.Count > 0)
                    {
                        var reference = references.Dequeue();
                        if (!checkedNodes.Contains(reference.TargetNode))
                        {
                            rootNode = (GraphNode)reference.TargetNode;
                            break;
                        }
                    }
                }
            }
        }
 private void PushContextNode(GraphNode node)
 {
     contextStack.Push(node);
 }
示例#6
0
        /// <inheritdoc/>
        public override void VisitObject(object obj, ObjectDescriptor descriptor, bool visitMembers)
        {
            ITypeDescriptor currentDescriptor = descriptor;

            bool isRootNode = contextStack.Count == 0;
            if (isRootNode)
            {
                bool shouldProcessReference;
                if (!NotifyNodeConstructing(descriptor, out shouldProcessReference))
                    return;

                // If we are in the case of a collection of collections, we might have a root node that is actually an enumerable reference
                // This would be the case for each collection within the base collection.
                IContent content = descriptor.Type.IsStruct() ? ContentFactory.CreateBoxedContent(this, obj, descriptor, IsPrimitiveType(descriptor.Type))
                                                : ContentFactory.CreateObjectContent(this, obj, descriptor, IsPrimitiveType(descriptor.Type), shouldProcessReference);
                currentDescriptor = content.Descriptor;
                rootNode = (GraphNode)NodeFactory(currentDescriptor.Type.Name, content, rootGuid);
                if (content.IsReference && currentDescriptor.Type.IsStruct())
                    throw new QuantumConsistencyException("A collection type", "A structure type", rootNode);

                if (content.IsReference)
                    referenceContents.Add(content);

                AvailableCommands.Where(x => x.CanAttach(currentDescriptor, null)).ForEach(rootNode.AddCommand);
                NotifyNodeConstructed(content);

                if (obj == null)
                {
                    rootNode.Seal();
                    return;
                }
                PushContextNode(rootNode);
            }

            if (!IsPrimitiveType(currentDescriptor.Type))
            {
                base.VisitObject(obj, descriptor, true);
            }

            if (isRootNode)
            {
                PopContextNode();
                rootNode.Seal();
            }
        }
示例#7
0
 private void PushContextNode(GraphNode node)
 {
     contextStack.Push(node);
 }