private MgaFCO ClonePort(MgaModel parent, MgaFCO oldPort) { Logger.WriteDebug("ClonePort: {0}", oldPort.AbsPath); GME.MGA.Meta.MgaMetaRole role = null; foreach (GME.MGA.Meta.MgaMetaRole roleItem in (parent.Meta as GME.MGA.Meta.MgaMetaModel).Roles) { if (roleItem.Kind.MetaRef == oldPort.MetaBase.MetaRef) { role = roleItem; break; } } var newPortFCO = parent.CopyFCODisp(oldPort, role); String lastGood = oldPort.ID; String iter = null; while (Traceability.TryGetMappedObject(lastGood, out iter) && lastGood != iter) { lastGood = iter; } Traceability.AddItem(newPortFCO.ID, lastGood); return(newPortFCO); }
// What do we have to do here now? // Well, if this connector has instances, we need to add port maps for those things too. // Then those connectors need to be visited to connections can be adjusted. private void VisitConnector(MgaModel connector) { #region Check arguments if (connector == null) { throw new ArgumentNullException("connector"); } if (connector.MetaBase.MetaRef != MetaRef["Connector"]) { throw new ArgumentException("Input parameter was not a connector.", "connector"); } if (ConnectorsProcessed.Contains(connector)) { return; } #endregion Logger.WriteDebug("VisitConnector: {0}", connector.AbsPath); ConnectorToStandalonePortMap.Add(connector, new List <PortWrapper>()); var parent = connector.ParentModel; Boolean connectorIsArchetype = (connector.ArcheType == null); Boolean parentIsArchetype = (parent.ArcheType == null); if (parentIsArchetype) { Logger.WriteDebug("VisitConnector: Processing with parent as Archetype"); if (connectorIsArchetype) { Logger.WriteDebug("VisitConnector: Processing connector as Archetype"); } else { Logger.WriteDebug("VisitConnector: Processing connector as Derived"); Logger.WriteDebug("VisitConnector: Setting connector's local attributes and detaching"); SetAttributesLocally(connector as MgaFCO); connector.DetachFromArcheType(); } // I'm an archetype. // Go through each supported port, clone it, and create a wrapper. // Add it to traceability. // Redirect connections to constituent ports. foreach (MgaFCO port in connector.ChildFCOs) { if (false == SupportedPortTypesMeta.Contains(port.MetaBase.MetaRef)) { Logger.WriteDebug("VisitConnector: Skipping unsupported port {0}", port.AbsPath); continue; } var newPort = ClonePort(parent, port); newPort.Name = String.Format("{0}__{1}", connector.Name, port.Name); var wrapper = new PortWrapper() { SourceConnector = connector, SourcePortRole = port.Name, SourcePort = port, StandalonePort = newPort }; ConnectorToStandalonePortMap[connector].Add(wrapper); // See if the derived guy is itself in the Traceability. String lastGood = port.ID; String iter = null; while (Traceability.TryGetMappedObject(lastGood, out iter) && lastGood != iter) { lastGood = iter; } Traceability.AddItem(newPort.ID, lastGood); } RedirectConnectionsToConstituentPorts(connector); } else { Logger.WriteDebug("VisitConnector: Processing as Derived"); var connectorArchetype = connector.ArcheType as MgaModel; // I'm derived. What we need to do is go through each // port, and create a new wrapper for each one. foreach (MgaFCO derivedPort in connector.ChildFCOs) { if (false == SupportedPortTypesMeta.Contains(derivedPort.MetaBase.MetaRef)) { Logger.WriteDebug("VisitConnector: Skipping unsupported derived port {0}", derivedPort.AbsPath); continue; } // Find the wrapper for these guys var orgWrapper = ConnectorToStandalonePortMap[connectorArchetype] .FirstOrDefault(w => w.SourceConnector == connectorArchetype && w.SourcePort == derivedPort.ArcheType); if (orgWrapper == null) { Logger.WriteDebug("VisitConnector: orgWrapper is null for {0}", derivedPort.AbsPath); throw new ArgumentNullException("orgWrapper is null for " + derivedPort.AbsPath); } // Now guess at the standalone port. MgaFCO standalonePort = null; foreach (MgaFCO brokenOutPort in parent.ChildFCOs) { if (brokenOutPort.ArcheType != null && brokenOutPort.ArcheType == orgWrapper.StandalonePort) { standalonePort = brokenOutPort; break; } } if (standalonePort == null) { Logger.WriteDebug("VisitConnector: standalonePort is null for {0}", derivedPort.AbsPath); throw new ArgumentNullException("standalonePort is null for " + derivedPort.AbsPath); } var wrapper = new PortWrapper() { SourceConnector = connector, SourcePortRole = derivedPort.Name, SourcePort = derivedPort, StandalonePort = standalonePort }; ConnectorToStandalonePortMap[connector].Add(wrapper); // See if the derived guy is itself in the Traceability. String lastGood = derivedPort.ID; String iter = null; while (Traceability.TryGetMappedObject(lastGood, out iter) && lastGood != iter) { lastGood = iter; } Traceability.AddItem(standalonePort.ID, lastGood); } } foreach (MgaModel derivedConnector in connector.DerivedObjects) { Logger.WriteDebug("VisitConnector: Visiting derived connector {0}", derivedConnector.AbsPath); VisitConnector(derivedConnector); } ConnectorsProcessed.Add(connector); }