public object GraphNodeToObject(IGraphNode node, Type type) { var seq = (ISequenceGraphNode) node; Type elemType = null; if (type.IsArray) elemType = type.GetElementType(); else if (TypeTools.IsAssignableToGenericType(type, typeof(IList<>))) elemType = TypeTools.GetGenericArguments(type)[0]; var elements = seq.Select(n => n?.RebuildObject(elemType)); if (type.IsArray) { var a = Array.CreateInstance(elemType, seq.Length); int i = 0; foreach (var e in elements) a.SetValue(e, i++); return a; } var instance = (IList)Activator.CreateInstance(type); foreach (var e in elements) instance.Add(e); return instance; }
private IDictionary<LibraryDescription, ISet<LibraryDescription>> FindImmediateDependent(IGraphNode<LibraryDescription> root) { var result = new Dictionary<LibraryDescription, ISet<LibraryDescription>>(); root.DepthFirstPreOrderWalk( visitNode: (node, ancestors) => { ISet<LibraryDescription> slot; if (!result.TryGetValue(node.Item, out slot)) { slot = new HashSet<LibraryDescription>(); result.Add(node.Item, slot); } // first item in the path is the immediate parent if (ancestors.Any()) { slot.Add(ancestors.First().Item); } return true; }); // removing the root package result.Remove(root.Item); return result; }
private static void PrintHierarchyInternal(IGraphNode node, int indentation, StringBuilder builder) { PrintIndentation(indentation, builder); builder.Append(node.Guid + " "); PrintIndentation(indentation, builder); builder.Append(node.Name ?? "<untitled>"); builder.Append(": ["); builder.Append(node.Content.GetType().Name); builder.Append("] = "); if (node.Content.IsReference) { if (node.Content.Value != null) { builder.Append(node.Content.Value.ToString().Replace(Environment.NewLine, " ")); builder.Append(" > "); } builder.Append("Reference -> "); builder.Append(node.Content.Reference); } else if (node.Content.Value == null) { builder.Append("(null)"); } else { builder.Append(node.Content.Value.ToString().Replace(Environment.NewLine, " ")); } builder.AppendLine(); foreach (var child in node.Children) { PrintHierarchyInternal(child, indentation + 4, builder); } }
public void Render(IGraphNode<LibraryDependency> root) { // tuples of <Library Name, Requested Version, Actual Version> var results = new HashSet<Tuple<string, string, string>>(); root.DepthFirstPreOrderWalk( (node, ancestors) => { var dependency = node.Item; if (IsLibraryMismatch(dependency)) { results.Add(Tuple.Create( dependency.Library.Identity.Name, dependency.LibraryRange.VersionRange?.MinVersion.ToString(), dependency.Library.Identity.Version?.ToString())); } return true; }); if (results.Any()) { var format = GetFormat(results, padding: 2); RenderTitle(format); RenderMismatches(format, results); } }
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); }
protected virtual void UnregisterNode(IGraphNode node) { node.Content.PrepareChange += ContentPrepareChange; node.Content.FinalizeChange += ContentFinalizeChange; node.Content.Changing -= ContentChanging; node.Content.Changed -= ContentChanged; }
public void Walk(IGraphNode<LibraryDescription> root) { _assemblyFilePaths = new HashSet<string>(StringComparer.Ordinal); _dependencyAssemblySources = new Dictionary<string, HashSet<string>>(StringComparer.Ordinal); _dependencyPackageSources = new Dictionary<string, HashSet<string>>(StringComparer.Ordinal); var libraries = new HashSet<LibraryDescription>(); root.DepthFirstPreOrderWalk(visitNode: (node, _) => VisitLibrary(node, _, libraries)); _reports.Information.WriteLine("\n[Target framework {0} ({1})]\n", _framework.ToString(), VersionUtility.GetShortFrameworkName(_framework)); foreach (var assemblyFilePath in _assemblyFilePaths.OrderBy(assemblyName => assemblyName)) { _reports.Information.WriteLine(assemblyFilePath); if (_showDetails) { var assemblyName = Path.GetFileNameWithoutExtension(assemblyFilePath); HashSet<string> packagesSources; if (_dependencyPackageSources.TryGetValue(assemblyName, out packagesSources) && packagesSources.Any()) { _reports.Information.WriteLine(" by package: {0}", string.Join(", ", packagesSources)); } HashSet<string> assemblySources; if (_dependencyAssemblySources.TryGetValue(assemblyName, out assemblySources) && assemblySources.Any()) { _reports.Information.WriteLine(" by assembly: {0}", string.Join(", ", assemblySources)); } } } }
public object GraphNodeToObject(IGraphNode node, Type objectType) { var n = node as IStringGraphNode; if (n != null) return Name.BuildName(n.Value); return Name.BuildName(((IPrimitiveGraphNode)node).Value); }
/// <summary> /// Returns true if graph node is cyclic. /// </summary> /// <param name="node">Graph node.</param> /// <param name="path">Path from a graph node to this <paramref name="graph node"/>.</param> /// <param name="acyclicNodes">Nodes from which a cycle does not exist.</param> /// <returns>Returns true if graph node is cyclic.</returns> private static bool IsCyclic(IGraphNode node, ISet<string> path, ISet<string> acyclicNodes) { node.ThrowIfArgumentNull(nameof(node)); node.Id.ThrowIfArgumentNull(nameof(node.Id)); node.Neighbors.ThrowIfArgumentNull(nameof(node.Neighbors)); if (acyclicNodes.Contains(node.Id)) { return false; } if (path.Contains(node.Id)) { return true; } path.Add(node.Id); foreach (var neighbor in node.Neighbors) { if (IsCyclic(neighbor, path, acyclicNodes)) { return true; } } path.Remove(node.Id); acyclicNodes.Add(node.Id); return false; }
private static IEnumerable<IGraphNode> GetAllChildNodes(IGraphNode graphNode) { var processedNodes = new HashSet<IGraphNode>(); var nodeStack = new Stack<IGraphNode>(); nodeStack.Push(graphNode); while (nodeStack.Count > 0) { var node = nodeStack.Pop(); processedNodes.Add(node); // We don't want to include the initial node if (node != graphNode) yield return node; // Add child nodes node.Children.ForEach(x => nodeStack.Push(x)); // Add object reference target node var objectReference = node.Content.Reference as ObjectReference; if (objectReference?.TargetNode != null) nodeStack.Push(objectReference.TargetNode); // Add enumerable reference target nodes var enumerableReference = node.Content.Reference as ReferenceEnumerable; enumerableReference?.Select(x => x.TargetNode).NotNull().ForEach(x => nodeStack.Push(x)); } }
/// <summary> /// Tests the validity of a node that is an object that is a collection /// </summary> /// <param name="node">The node to validate.</param> /// <param name="obj">The value represented by this node.</param> /// <param name="isReference">Indicate whether the node is expected to contain an enumerable reference to the collection items.</param> public static void TestCollectionObjectContentNode(IGraphNode node, object obj, bool isReference) { if (node == null) throw new ArgumentNullException(nameof(node)); if (obj == null) throw new ArgumentNullException(nameof(obj)); // Check that the content is of the expected type. Assert.IsInstanceOf<ObjectContent>(node.Content); // Check that the content is properly referencing its node. Assert.AreEqual(node, node.Content.OwnerNode); // A node with an ObjectContent should have the same name that the type of its content. Assert.AreEqual(obj.GetType().Name, node.Name); // A node with an ObjectContent should be a root node. Assert.IsNull(node.Parent); // A node with an ObjectContent should have the related object as value of its content. Assert.AreEqual(obj, node.Content.Retrieve()); if (isReference) { // A node with an ObjectContent representing a collection of reference types should contain an enumerable reference. Assert.AreEqual(true, node.Content.IsReference); Assert.IsInstanceOf<ReferenceEnumerable>(node.Content.Reference); } else { // A node with an ObjectContent representing a collection of primitive or struct types should not contain a refernce. Assert.AreEqual(false, node.Content.IsReference); } // A node with an ObjectContent representing a collection should not have any child. Assert.AreEqual(0, node.Children.Count); }
/// <summary> /// Initializes a new instance of the QuantumConsistencyException class. /// </summary> /// <param name="expected">A string representing the expected result.</param> /// <param name="observed">A string representing the observed result.</param> /// <param name="node">The node that is related to this error.</param> public QuantumConsistencyException(string expected, string observed, IGraphNode node) : base(GetMessage(expected, observed)) { Expected = expected ?? "(NullMessage)"; Observed = observed ?? "(NullMessage)"; Node = node; }
public IEnumerable<string> GetRenderContent(IGraphNode<LibraryDescription> root) { var dict = FindImmediateDependent(root); var libraries = dict.Keys.OrderBy(description => description.Identity.Name); var results = new List<string>(); var gacOrFrameworkReferences = libraries.Where(library => library.Identity.IsGacOrFrameworkReference); if (gacOrFrameworkReferences.Any()) { results.Add("Framework references:"); RenderLibraries(gacOrFrameworkReferences, dict, results); results.Add(string.Empty); } var otherReferences = libraries.Where(library => !library.Identity.IsGacOrFrameworkReference); var referencesGroups = otherReferences.GroupBy(reference => reference.Type); foreach (var group in referencesGroups) { results.Add(string.Format("{0} references:", group.Key)); RenderLibraries(group, dict, results); results.Add(string.Empty); } return results; }
/// <summary> /// Initializes a new instance of the <see cref="ObservableModelNode"/> class. /// </summary> /// <param name="ownerViewModel">The <see cref="ObservableViewModel"/> that owns the new <see cref="ObservableModelNode"/>.</param> /// <param name="baseName">The base name of this node. Can be null if <see cref="index"/> is not. If so a name will be automatically generated from the index.</param> /// <param name="isPrimitive">Indicate whether this node should be considered as a primitive node.</param> /// <param name="modelNode">The model node bound to the new <see cref="ObservableModelNode"/>.</param> /// <param name="graphNodePath">The <see cref="GraphNodePath"/> corresponding to the given <see cref="modelNode"/>.</param> /// <param name="index">The index of this content in the model node, when this node represent an item of a collection. <c>null</c> must be passed otherwise</param> protected ObservableModelNode(ObservableViewModel ownerViewModel, string baseName, bool isPrimitive, IGraphNode modelNode, GraphNodePath graphNodePath, object index = null) : base(ownerViewModel, baseName, index) { if (modelNode == null) throw new ArgumentNullException(nameof(modelNode)); if (baseName == null && index == null) throw new ArgumentException("baseName and index can't be both null."); this.isPrimitive = isPrimitive; SourceNode = modelNode; // By default we will always combine items of list of primitive items. CombineMode = index != null && isPrimitive ? CombineMode.AlwaysCombine : CombineMode.CombineOnlyForAll; SourceNodePath = graphNodePath; // Override display name if available var memberDescriptor = GetMemberDescriptor() as MemberDescriptorBase; if (memberDescriptor != null) { if (index == null) { var displayAttribute = TypeDescriptorFactory.Default.AttributeRegistry.GetAttribute<DisplayAttribute>(memberDescriptor.MemberInfo); if (!string.IsNullOrEmpty(displayAttribute?.Name)) { DisplayName = displayAttribute.Name; } IsReadOnly = !memberDescriptor.HasSet; } } }
protected override void VisitNode(IGraphNode node, GraphNodePath currentPath) { var targetNode = linker.FindTarget(node); // Override the target node, in case FindTarget returned a different one. VisitedLinks[node] = targetNode; linker.LinkNodes(node, targetNode); base.VisitNode(node, currentPath); }
public ISet<string> Walk(IGraphNode<Library> root) { var assemblies = new HashSet<string>(); var libraries = new HashSet<Library>(); root.DepthFirstPreOrderWalk(visitNode: (node, _) => VisitLibrary(node, _, libraries, assemblies)); return assemblies; }
/// <summary> /// Initializes a new instance of the <see cref="ObservableViewModel"/> class. /// </summary> /// <param name="serviceProvider">A service provider that can provide a <see cref="IDispatcherService"/> and an <see cref="ObservableViewModelService"/> to use for this view model.</param> /// <param name="nodeContainer">A <see cref="NodeContainer"/> to use to build view model nodes.</param> /// <param name="modelNode">The root model node of the view model to generate.</param> /// <param name="dirtiables">The list of <see cref="IDirtiable"/> objects linked to this view model.</param> public ObservableViewModel(IViewModelServiceProvider serviceProvider, NodeContainer nodeContainer, IGraphNode modelNode, IEnumerable<IDirtiable> dirtiables) : this(serviceProvider, nodeContainer, dirtiables.SafeArgument("dirtiables").ToList()) { if (modelNode == null) throw new ArgumentNullException(nameof(modelNode)); var node = ObservableViewModelService.ObservableNodeFactory(this, "Root", modelNode.Content.IsPrimitive, modelNode, new GraphNodePath(modelNode), modelNode.Content.Type, null); node.Initialize(); RootNode = node; node.CheckConsistency(); }
protected override bool ShouldReconcileItem(MemberContent member, IGraphNode targetNode, object localValue, object baseValue, bool isReference) { // Always reconcile referenced parts if (isReference && IsReferencedPart(member, targetNode)) { return true; } return base.ShouldReconcileItem(member, targetNode, localValue, baseValue, isReference); }
/// <summary> /// Initializes a new instance of the <see cref="GraphNodeChangeListener"/> class. /// </summary> /// <param name="rootNode">The root node for which to track referenced node changes.</param> public GraphNodeChangeListener(IGraphNode rootNode) { this.rootNode = rootNode; foreach (var node in GetAllChildNodes(rootNode)) { node.Content.Changing += ContentChanging; node.Content.Changed += ContentChanged; } }
public void Render(IGraphNode<Library> root) { var dict = FindImmediateDependent(root); foreach (var key in dict.Keys.OrderBy(library => library.Name)) { _output.WriteLine(key.ToString().White().Bold()); _output.WriteLine(" -> {0}", string.Join(", ", dict[key].Select(lib => lib.ToString()).OrderBy(s => s))); } }
public VirtualNodeCommandWrapper(IViewModelServiceProvider serviceProvider, INodeCommand nodeCommand, IGraphNode node, Index index) : base(serviceProvider) { if (nodeCommand == null) throw new ArgumentNullException(nameof(nodeCommand)); if (node == null) throw new ArgumentNullException(nameof(node)); this.node = node; this.index = index; NodeCommand = nodeCommand; Service = serviceProvider.Get<ObservableViewModelService>(); }
/// <summary> /// Visits a hierarchy of node, starting by the given root node. /// </summary> /// <param name="node">The root node of the visit</param> /// <param name="initialPath">The initial path of the root node, if this visit occurs in the context of a sub-hierarchy. Can be null.</param> public virtual void Visit(IGraphNode node, GraphNodePath initialPath = null) { var path = initialPath ?? new GraphNodePath(node); RootNode = node; if (ShouldVisitNode(null, node)) { VisitNode(node, path); } RootNode = null; }
/// <summary>Retrieves the index for the given node.</summary> /// <param name="candidate">The candidate node.</param> /// <returns>An index that is used for referencing the candidate node in various /// arrays.</returns> private int GetParticipatingNodeIndex(IGraphNode candidate) { int participatingNodesCount = _participatingNodes.Length; for (int result = 0; result < participatingNodesCount; result++) { if (object.ReferenceEquals(_participatingNodes[result], candidate)) { return result; } } throw new ArgumentException(); }
/// <summary> /// Initializes a new instance of the <see cref="ObservableViewModel"/> class. /// </summary> /// <param name="serviceProvider">A service provider that can provide a <see cref="IDispatcherService"/> and an <see cref="ObservableViewModelService"/> to use for this view model.</param> /// <param name="propertyProvider">The object providing properties to display</param> /// <param name="graphNode">The root node of the view model to generate.</param> private ObservableViewModel(IViewModelServiceProvider serviceProvider, IPropertiesProviderViewModel propertyProvider, IGraphNode graphNode) : this(serviceProvider) { if (graphNode == null) throw new ArgumentNullException(nameof(graphNode)); PropertiesProvider = propertyProvider; var node = ObservableViewModelService.ObservableNodeFactory(this, "Root", graphNode.Content.IsPrimitive, graphNode, new GraphNodePath(graphNode), graphNode.Content.Type, Index.Empty); node.Initialize(); RootNode = node; node.CheckConsistency(); }
/// <summary> /// Visits the children of the given node. /// </summary> /// <param name="node">The node being visited.</param> /// <param name="currentPath">The path of the node being visited.</param> protected virtual void VisitChildren(IGraphNode node, GraphNodePath currentPath) { foreach (var child in node.Children) { var childPath = currentPath.PushMember(child.Name); if (ShouldVisitNode(child.Content as MemberContent, child)) { VisitNode(child, childPath); } } }
protected virtual void UnregisterNode(IGraphNode node, GraphNodePath path) { if (!registeredNodes.ContainsKey(node)) throw new InvalidOperationException("Node not registered"); registeredNodes.Remove(node); node.Content.PrepareChange -= ContentPrepareChange; node.Content.FinalizeChange -= ContentFinalizeChange; node.Content.Changing -= ContentChanging; node.Content.Changed -= ContentChanged; }
public IEnumerable<string> GetRenderContent(IGraphNode<Library> root) { var dict = FindImmediateDependent(root); var libraries = dict.Keys.OrderBy(library => library.Name); var results = new List<string>(); RenderLibraries(libraries.Where(library => library.IsGacOrFrameworkReference), dict, results); RenderLibraries(libraries.Where(library => !library.IsGacOrFrameworkReference), dict, results); return results; }
/// <summary> /// Visits a single node. /// </summary> /// <param name="node">The node being visited.</param> /// <param name="currentPath">The path of the node being visited.</param> /// <remarks>This method is in charge of pursuing the visit with the children and references of the given node, as well as raising the <see cref="Visiting"/> event.</remarks> protected virtual void VisitNode(IGraphNode node, GraphNodePath currentPath) { visitedNodes.Add(node); if (node != RootNode || !SkipRootNode) { Visiting?.Invoke(node, currentPath); } VisitChildren(node, currentPath); VisitSingleTarget(node, currentPath); VisitEnumerableTargets(node, currentPath); visitedNodes.Remove(node); }
protected virtual void RegisterNode(IGraphNode node, GraphNodePath path) { if (registeredNodes.ContainsKey(node)) throw new InvalidOperationException("Node already registered"); registeredNodes.Add(node, path); node.Content.PrepareChange += ContentPrepareChange; node.Content.FinalizeChange += ContentFinalizeChange; node.Content.Changing += ContentChanging; node.Content.Changed += ContentChanged; }
protected virtual bool UnregisterNode(IGraphNode node) { if (RegisteredNodes.Remove(node)) { node.Content.PrepareChange -= ContentPrepareChange; node.Content.FinalizeChange -= ContentFinalizeChange; node.Content.Changing -= ContentChanging; node.Content.Changed -= ContentChanged; return true; } return false; }
public void UnjoinFrom(IGraphNode <T> other) { Peers.Remove(other); other.Peers.Remove(this); }
protected virtual bool ShouldTerminate(IGraphNode <T> node) { return(false); }
public int CompareTo(IGraphNode <T> other) { return(Id.CompareTo(other.Id)); }
protected IDictionary <IGraphNode <T>, IGraphEdge <T> > RelaxEdges(IGraph <T> graph, IGraphNode <T> node, float initialCost = 0) { PriorityQueue <QueueType> openNodes = new PriorityQueue <QueueType>(graph.NodeCount); IDictionary <IGraphNode <T>, QueueType> priorityQueueLocator = new Dictionary <IGraphNode <T>, QueueType>(); IDictionary <IGraphNode <T>, IGraphEdge <T> > parents = new Dictionary <IGraphNode <T>, IGraphEdge <T> >(); HashSet <IGraphNode <T> > closedNodes = new HashSet <IGraphNode <T> >(); QueueType nodePair = new QueueType(initialCost, node); openNodes.Add(nodePair); priorityQueueLocator[node] = nodePair; while (openNodes.Count > 0) { nodePair = openNodes.Pop(); float baseCost = nodePair.First; node = nodePair.Second; if (ShouldTerminate(node)) { break; } foreach (IGraphEdge <T> edge in graph.GetEdges(node)) { if (closedNodes.Contains(edge.node2)) { continue; } float cost = GetCost(baseCost, edge); IGraphEdge <T> currentEdge; if (!parents.TryGetValue(edge.node2, out currentEdge) || cost < currentEdge.weight) { parents[edge.node2] = edge; nodePair = new QueueType(cost, edge.node2); QueueType oldPair; if (priorityQueueLocator.TryGetValue(edge.node2, out oldPair) && openNodes.Contains(oldPair)) { openNodes.UpdatePosition(oldPair, nodePair); } else { openNodes.Add(nodePair); } priorityQueueLocator[edge.node2] = nodePair; } } closedNodes.Add(node); } return(parents); }
public QueueType(float first, IGraphNode <T> second) : base(first, second) { }