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); }
/// <summary> /// Given a container, find all ConnectorComposition connections, and make /// new connections between the new "standalone" ports that have been created. /// </summary> /// <param name="container"></param> private void ExpandConnectorCompositionChildren(MgaModel container) { Logger.WriteDebug("ExpandConnectorCompositionChildren: {0}", container.AbsPath); // Find PortComposition role for this parent type GME.MGA.Meta.MgaMetaRole role = null; foreach (GME.MGA.Meta.MgaMetaRole roleItem in (container.Meta as GME.MGA.Meta.MgaMetaModel).Roles) { if (roleItem.Name == "PortComposition") { role = roleItem; break; } } // For each ConnectorComposition, create new connections between the new "standalone" ports. // Since we did depth-first recursion in modifying the connectors, they should all be "expanded" // and ready to go. foreach (MgaSimpleConnection connectorComposition in container.GetChildrenOfKind("ConnectorComposition")) { MgaModel connector1 = connectorComposition.Src as MgaModel; MgaModel connector2 = connectorComposition.Dst as MgaModel; var portsConn1 = ConnectorToStandalonePortMap[connector1]; var portsConn2 = ConnectorToStandalonePortMap[connector2]; // For each port, find the analogue from the other connector. foreach (var port1 in portsConn1) { var kindPort1 = port1.SourcePort.MetaBase.Name; // Try to match by role & kind. var port2 = portsConn2.FirstOrDefault(p2 => p2.SourcePortRole == port1.SourcePortRole && p2.SourcePort.MetaBase.Name == kindPort1); // Nominal match case failed. Try alternatives. if (port2 == null) { // If we failed to match by the methods above, we'll try another method. // Try to see if each port's kind is unique to its connector (e.g.: They are the only ModelicaConnectors in their parent Connectors). // If so, then we will go ahead and match them, but yield a warning. Boolean port1KindIsUnique = portsConn1.Where(pc => kindPort1 == pc.SourcePort.MetaBase.Name).Count() == 1; var port2KindMatches = portsConn2.Where(pc => kindPort1 == pc.SourcePort.MetaBase.Name); Boolean port2KindIsUnique = port2KindMatches.Count() == 1; if (port1KindIsUnique && port2KindIsUnique) { // Match anyway based on unique kinds. port2 = port2KindMatches.First(); Logger.WriteWarning("Non-name match: " + "Port {0} in Connector {1} and Port {2} in Connector {3}", TraceabilityExtensions.ToMgaHyperLink(port1.SourcePort, Traceability), TraceabilityExtensions.ToMgaHyperLink(port1.SourceConnector, Traceability), TraceabilityExtensions.ToMgaHyperLink(port2.SourcePort, Traceability), TraceabilityExtensions.ToMgaHyperLink(port2.SourceConnector, Traceability)); } else { // Kinds were not unique, so we can't guess. Logger.WriteWarning("NO MATCH found for Port {0} of Connector {1} with any Port within Connector {2}", TraceabilityExtensions.ToMgaHyperLink(port1.SourcePort, Traceability), TraceabilityExtensions.ToMgaHyperLink(port1.SourceConnector, Traceability), TraceabilityExtensions.ToMgaHyperLink(connector2, Traceability)); continue; } } var conn = container.CreateChildObject(role) as MgaSimpleConnection; conn.SetSrc(EmptyArray, port1.StandalonePort); conn.SetDst(EmptyArray, port2.StandalonePort); } } }