private ProjectPlanDto BuildProjectPlanDto() { lock (m_Lock) { return(new ProjectPlanDto() { ProjectStart = ProjectStart, DependentActivities = Activities.Select(x => DtoConverter.ToDto(x)).ToList(), ResourceSettings = ResourceSettingsDto.Copy(), ArrowGraphSettings = ArrowGraphSettingsDto.Copy(), GraphCompilation = DtoConverter.ToDto(GraphCompilation, CyclomaticComplexity.GetValueOrDefault(), Duration.GetValueOrDefault()), ArrowGraph = ArrowGraphDto != null?ArrowGraphDto.Copy() : new ArrowGraphDto() { Edges = new List <ActivityEdgeDto>(), Nodes = new List <EventNodeDto>(), IsStale = false }, HasStaleOutputs = HasStaleOutputs }); } }
private static ArrowGraphData GenerateArrowGraphData(ArrowGraphDto arrowGraph) { if (arrowGraph == null || arrowGraph.Nodes == null || !arrowGraph.Nodes.Any() || arrowGraph.Edges == null || !arrowGraph.Edges.Any()) { return(null); } IList <EventNodeDto> nodeDtos = arrowGraph.Nodes.ToList(); var edgeHeadVertexLookup = new Dictionary <int, ArrowGraphVertex>(); var edgeTailVertexLookup = new Dictionary <int, ArrowGraphVertex>(); var arrowGraphVertices = new List <ArrowGraphVertex>(); foreach (EventNodeDto nodeDto in nodeDtos) { var vertex = new ArrowGraphVertex(nodeDto.Content, nodeDto.NodeType); arrowGraphVertices.Add(vertex); foreach (int edgeId in nodeDto.IncomingEdges) { edgeHeadVertexLookup.Add(edgeId, vertex); } foreach (int edgeId in nodeDto.OutgoingEdges) { edgeTailVertexLookup.Add(edgeId, vertex); } } // Check all edges are used. IList <ActivityEdgeDto> edgeDtos = arrowGraph.Edges.ToList(); IList <int> edgeIds = edgeDtos.Select(x => x.Content.Id).ToList(); if (!edgeIds.OrderBy(x => x).SequenceEqual(edgeHeadVertexLookup.Keys.OrderBy(x => x))) { throw new ArgumentException("List of Edge IDs and Edges referenced by head Nodes do not match"); } if (!edgeIds.OrderBy(x => x).SequenceEqual(edgeTailVertexLookup.Keys.OrderBy(x => x))) { throw new ArgumentException("List of Edge IDs and Edges referenced by tail Nodes do not match"); } // Check all events are used. IEnumerable <long> edgeVertexLookupIds = edgeHeadVertexLookup.Values.Select(x => x.ID) .Union(edgeTailVertexLookup.Values.Select(x => x.ID)); if (!arrowGraphVertices.Select(x => x.ID).OrderBy(x => x).SequenceEqual(edgeVertexLookupIds.OrderBy(x => x))) { throw new ArgumentException("List of Node IDs and Edges referenced by tail Nodes do not match"); } // Check Start and End nodes. IEnumerable <EventNodeDto> startNodes = nodeDtos.Where(x => x.NodeType == NodeType.Start); if (startNodes.Count() != 1) { throw new ArgumentException("Data contain more than one Start node"); } IEnumerable <EventNodeDto> endNodes = nodeDtos.Where(x => x.NodeType == NodeType.End); if (endNodes.Count() != 1) { throw new ArgumentException("Data contain more than one End node"); } // Build the graph data. var graph = new ArrowGraphData(); foreach (ArrowGraphVertex vertex in arrowGraphVertices) { graph.AddVertex(vertex); } foreach (ActivityEdgeDto edgeDto in edgeDtos) { ActivityDto activityDto = edgeDto.Content; var edge = new ArrowGraphEdge( activityDto, edgeTailVertexLookup[activityDto.Id], edgeHeadVertexLookup[activityDto.Id]); graph.AddEdge(edge); } return(graph); }