protected override ObjectReference FindTargetReference(IGraphNode sourceNode, IGraphNode targetNode, ObjectReference sourceReference)
        {
            if (sourceReference.Index.IsEmpty)
                return targetNode.Content.Reference as ObjectReference;

            // Special case for objects that are identifiable: the object must be linked to the base only if it has the same id
            if (sourceReference.ObjectValue != null)
            {
                if (sourceReference.Index.IsEmpty)
                {
                    return targetNode.Content.Reference.AsObject;
                }

                var sourceAssetNode = (AssetNode)sourceNode;
                if (sourceAssetNode.IsNonIdentifiableCollectionContent)
                    return null;

                // Enumerable reference: we look for an object with the same id
                var targetReference = targetNode.Content.Reference.AsEnumerable;
                var sourceIds = CollectionItemIdHelper.GetCollectionItemIds(sourceNode.Content.Retrieve());
                var targetIds = CollectionItemIdHelper.GetCollectionItemIds(targetNode.Content.Retrieve());
                var itemId = sourceIds[sourceReference.Index.Value];
                var targetKey = targetIds.GetKey(itemId);
                return targetReference.FirstOrDefault(x => Equals(x.Index.Value, targetKey));
            }

            // Not identifiable - default applies
            return base.FindTargetReference(sourceNode, targetNode, sourceReference);
        }
Beispiel #2
0
        internal static IReference CreateReference(object objectValue, Type objectType, object index)
        {
            if (objectValue != null && !objectType.IsInstanceOfType(objectValue)) throw new ArgumentException(@"objectValue type does not match objectType", "objectValue");

            ++creatingReference;

            IReference reference;
            var isCollection = HasCollectionReference(objectValue != null ? objectValue.GetType() : objectType);
            if (objectValue != null && isCollection && index == NotInCollection)
            {
                reference = new ReferenceEnumerable((IEnumerable)objectValue, objectType, index);
            }
            else
            {
                reference = new ObjectReference(objectValue, objectType, index);
            }

            --creatingReference;

            return reference;
        }
            protected override void VisitReference(IGraphNode referencer, ObjectReference reference, GraphNodePath targetPath)
            {
                if (ShouldVisitNode(referencer.Content as MemberContent, reference.TargetNode))
                {
                    if (reference.TargetNode != null)
                    {
                        // Prevent re-entrancy in the same object
                        if (VisitedLinks.ContainsKey(reference.TargetNode))
                            return;

                        IGraphNode targetNode;
                        if (VisitedLinks.TryGetValue(referencer, out targetNode))
                        {
                            ObjectReference targetReference = null;
                            if (targetNode != null)
                                targetReference = linker.FindTargetReference(referencer, targetNode, reference);

                            VisitedLinks.Add(reference.TargetNode, targetReference?.TargetNode);
                        }
                    }
                    base.VisitReference(referencer, reference, targetPath);
                }
            }
Beispiel #4
0
        internal static IReference CreateReference(object objectValue, Type objectType, Index index)
        {
            if (objectValue != null && !objectType.IsInstanceOfType(objectValue)) throw new ArgumentException(@"objectValue type does not match objectType", nameof(objectValue));

            if (!CreatingReference.IsValueCreated)
                CreatingReference.Value = 0;

            ++CreatingReference.Value;

            IReference reference;
            var isCollection = HasCollectionReference(objectValue?.GetType() ?? objectType);
            if (objectValue != null && isCollection && index.IsEmpty)
            {
                reference = new ReferenceEnumerable((IEnumerable)objectValue, objectType, index);
            }
            else
            {
                reference = new ObjectReference(objectValue, objectType, index);
            }

            --CreatingReference.Value;

            return reference;
        }
        private void AddObjectReference(IGraphNode referencer, ObjectReference reference)
        {
            if (reference.TargetNode == null)
                throw new QuantumConsistencyException("A resolved reference", "An unresolved reference", referencer);

            if (referencer.Content.Reference == reference && !Equals(referencer.Content.Value, reference.TargetNode.Content.Value))
                throw new QuantumConsistencyException("Referenced node with same content value that its referencer", "Referenced node with different content value that its referencer", referencer);

            if (reference.TargetGuid != reference.TargetNode.Guid)
                throw new QuantumConsistencyException("Referenced node with same Guid that the reference", "Referenced node with different Guid that the reference", referencer);

            references.Enqueue(reference);
        }
            protected override ObjectReference FindTargetReference(IGraphNode sourceNode, IGraphNode targetNode, ObjectReference sourceReference)
            {
                if (sourceReference.Index.IsEmpty)
                    return base.FindTargetReference(sourceNode, targetNode, sourceReference);

                var matchValue = 0;
                if (sourceReference.TargetNode != null)
                    matchValue = (int)sourceReference.TargetNode.TryGetChild(nameof(SimpleClass.Member1)).Content.Value;

                var targetReference = targetNode.Content.Reference as ReferenceEnumerable;
                return targetReference?.FirstOrDefault(x => (int)x.TargetNode.TryGetChild(nameof(SimpleClass.Member1)).Content.Value == matchValue);

            }
 /// <summary>
 /// Visits an <see cref="ObjectReference"/>.
 /// </summary>
 /// <param name="referencer">The node containing the reference to visit.</param>
 /// <param name="reference">The reference to visit.</param>
 /// <param name="targetPath">The path of the node targeted by this reference.</param>
 protected virtual void VisitReference(IGraphNode referencer, ObjectReference reference, GraphNodePath targetPath)
 {
     if (ShouldVisitNode(referencer.Content as MemberContent, reference.TargetNode))
     {
         VisitNode(reference.TargetNode, targetPath);
     }
 }
        /// <summary>
        /// Finds a reference in a target node to correspond with the given reference from the source node.
        /// </summary>
        /// <param name="sourceNode">The source node that contains the reference.</param>
        /// <param name="targetNode">The target node in which to look for a matching reference.</param>
        /// <param name="sourceReference">The reference in the source node for which to look for a correspondance in the target node.</param>
        /// <returns>A reference of the target node corresponding to the given reference in the source node, or null if there is no match.</returns>
        /// <remarks>
        /// The source reference can either be directly the <see cref="IContent.Reference"/> of the source node if this reference is
        /// an <see cref="ObjectReference"/>, or one of the reference contained inside <see cref="IContent.Reference"/> if this reference
        /// is a <see cref="ReferenceEnumerable"/>. The <see cref="IReference.Index"/> property indicates the index of the reference in this case.
        /// The default implementation returns a reference in the target node that matches the index of the source reference, if available.
        /// </remarks>
        protected virtual ObjectReference FindTargetReference(IGraphNode sourceNode, IGraphNode targetNode, ObjectReference sourceReference)
        {
            if (sourceReference.Index.IsEmpty)
                return targetNode.Content.Reference as ObjectReference;

            var targetReference = targetNode.Content.Reference as ReferenceEnumerable;
            return targetReference != null && targetReference.HasIndex(sourceReference.Index) ? targetReference[sourceReference.Index] : null;
        }
Beispiel #9
0
 public bool ShouldExpandReference(MemberContent member, ObjectReference reference) => true;