/// <summary> /// Creates and adds a port to a node. Also sets the Node property of the port. /// </summary> /// <param name="node">The node to process.</param> /// <param name="link">Link, if linked port is required</param> private static void AddMockPort(INode node, ILink link) { MapPort mapPort = new MapPort(); MapNode mapNode = (MapNode)node; mapPort.Id = mapNode.Id; mapPort.Name = mapNode.Name; //Add port to node mapNode.AddPort(mapPort); //Add node to port mapPort.Node = mapNode; //Linked port is required if (link != null) { mapPort.Links.Add(link); } }
/// <summary> /// This method performs the following logic: /// For each link in the mapdata, it gets the nodes defining the link from its 'path' attributes. /// For each such node, it creates a new synthetic node as a child of the node. /// For each such synthetic node, it creates a port for it. /// It then forms new links between the nodes of the original link and the new ports formed. /// Finally it adds all the new links formed to the mapdata and removes the original link. /// </summary> /// <param name="mapdata">MapData to be processed</param> private void AddNewLinksAndSyntheticNodes(MapData mapdata) { IList <MapLink> linksToDelete = new List <MapLink>(); IList <MapLink> linksToAdd = new List <MapLink>(); foreach (ILink link in mapdata.Links) { MapLink mapLink = (MapLink)link; //Get the path attributes IList <IAttribute> pathAttrs = mapLink.GetAttributesByName(Path); //Preserve the original link if no path attributes are found if (pathAttrs == null || pathAttrs.Count == 0) { continue; } //Get the nodes of the path IList <MapNode> pathNodes = new List <MapNode>(); foreach (IAttribute attr in pathAttrs) { MapAttribute pathAttr = (MapAttribute)attr; if (pathAttr.Type.Equals(AttrTypeInt)) { pathNodes.Add((MapNode)mapdata.GetNodeById(pathAttr.IntValue)); } else if (pathAttr.Type.Equals(AttrTypeString)) { pathNodes.Add((MapNode)mapdata.GetNodeByName(pathAttr.StringValue)); } } //Create the synthetic nodes for each path node. IList <MapNode> syntheticNodes = new List <MapNode>(); foreach (MapNode pathNode in pathNodes) { if (mapdata.Nodes.Contains(pathNode)) { //Get the unique id for the new synthetic node and set it long syntheticNodeId = GetUniqueId(typeof(MapNode), mapdata, 0); MapNode syntheticNode = new MapNode(); syntheticNode.Id = syntheticNodeId; syntheticNode.Name = MapNodeNamePrefix + syntheticNodeId; //Add it as child node of pathNode pathNode.AddOccupant(syntheticNode); syntheticNode.Container = pathNode; //Add it to the mapData mapdata.AddNode(syntheticNode); //Create and add port to synthetic node. long syntheticNodePortId = GetUniqueId(typeof(MapPort), mapdata, 0); MapPort syntheticNodePort = new MapPort(); syntheticNodePort.Id = syntheticNodePortId; syntheticNodePort.Name = MapPortNamePrefix + syntheticNodePortId; syntheticNode.AddPort(syntheticNodePort); //Add synthetic node to the port syntheticNodePort.Node = syntheticNode; //Add created port to the mapdata mapdata.AddPort(syntheticNodePort); //Save it further processing syntheticNodes.Add(syntheticNode); } } //None of the path nodes were found in the mapdata nodes. if (syntheticNodes.Count == 0) { continue; } //Create new links //1)Note that we first get port and then get the node from the port. //See http://forums.topcoder.com/?module=Thread&threadID=592050&start=0&mc=24#885358 //2)Links are guaranteed to have exactly 2 nodes MapPort startPort = (MapPort)mapLink.Ports[0]; MapNode startNode = (MapNode)startPort.Node; MapNode endNode = null; MapPort endPort = null; for (int i = 0; i < syntheticNodes.Count; i++) { endNode = syntheticNodes[i]; endPort = (MapPort)syntheticNodes[i].Ports[0]; //Create link and save it for adding later linksToAdd.Add(CreateNewLink(startNode, endNode, startPort, endPort, mapdata, mapLink, linksToAdd.Count)); startNode = endNode; startPort = endPort; } endPort = (MapPort)mapLink.Ports[1]; endNode = (MapNode)endPort.Node; //Create last link and save it for adding later linksToAdd.Add(CreateNewLink(startNode, endNode, startPort, endPort, mapdata, mapLink, linksToAdd.Count)); //Save original link for deleting it later linksToDelete.Add(mapLink); } //Remove the original links foreach (MapLink linkToDelete in linksToDelete) { //Remove link's attributes from mapdata foreach (IAttribute linkAttr in linkToDelete.Attributes) { mapdata.RemoveAttribute((MapAttribute)linkAttr); } //REmove the link itself from mapdata mapdata.RemoveLink(linkToDelete); } //Add the new links foreach (MapLink linkToAdd in linksToAdd) { mapdata.AddLink(linkToAdd); } }