public static IMgaFCO FindTestInjectionTarget( CyPhy.TopLevelSystemUnderTest originalSut, IMgaReference originalTip, CyPhy.TopLevelSystemUnderTest targetSut) { if (originalSut == null) { throw new ArgumentNullException("originalSut"); } if (originalTip == null) { throw new ArgumentNullException("originalTip"); } if (targetSut == null) { throw new ArgumentNullException("targetSut"); } // target that the reference has to be redirected IMgaFCO targetTipByBuilt = null; IMgaFCO targetTipByAbsPath = null; // get tip reference // relative path var relativePath = string.Empty; // ASSUME original SUT is a design container if (originalSut.Referred.DesignContainer == null && targetSut.Referred.ComponentAssembly == null) { throw new NotImplementedException(); } var sutDesignContainer = originalSut.Referred.DesignContainer; var sutComponentAssemblyTarget = targetSut.Referred.ComponentAssembly; // TOOD: Double check this cast CyPhy.DesignEntity originalDesignEntity = null; if (originalTip.Referred.Meta.Name == typeof(CyPhy.DesignContainer).Name) { originalDesignEntity = CyPhyClasses.DesignContainer.Cast(originalTip.Referred); } else if (originalTip.Referred.Meta.Name == typeof(CyPhy.Component).Name) { originalDesignEntity = CyPhyClasses.Component.Cast(originalTip.Referred); } else if (originalTip.Referred.Meta.Name == typeof(CyPhy.ComponentRef).Name) { originalDesignEntity = CyPhyClasses.ComponentRef.Cast(originalTip.Referred); } else if (originalTip.Referred.Meta.Name == typeof(CyPhy.ComponentAssembly).Name) { originalDesignEntity = CyPhyClasses.ComponentAssembly.Cast(originalTip.Referred); } List <CyPhy.DesignEntity> possibleDesignEntities = new List <CyPhy.DesignEntity>(); possibleDesignEntities.Add(originalDesignEntity); // TODO: abspath for component assemblies / Component assembly refs too. Call function recursively if (originalTip.Referred.Meta.Name == typeof(CyPhy.DesignContainer).Name) { var designContainer = CyPhyClasses.DesignContainer.Cast(originalTip.Referred); if (designContainer.Attributes.ContainerType == CyPhyClasses.DesignContainer.AttributesClass.ContainerType_enum.Compound) { // there could be a referece to the compound container // BUG: no tracking of compound containers attempt to get it by AbsPath // this implementation will work as long as // names are unqiue to Compound containes // structure as follows // // == PASS == // | Compound // +-- Compound // | // +-- Compound // // == FAIL 1 == Have no idea how to get the path correctly // | Compound // +-- Alternative // | // +-- Compound // // == FAIL 2 == Have no idea how to get the path correctly // | Compound // +-- Optional // | // +-- Compound // TODO: would be nice to use a regexp or something like that Func <string, string> shortenAbsPath = new Func <string, string>((absPath) => { // Example: // input: /@NewTesting|kind=Testing|relpos=0/@FEA_CompoundTIP_DS|kind=CADTestBench|relpos=0/@DesignContainer|kind=TopLevelSystemUnderTest|relpos=0 // output: /@NewTesting/@FEA_CompoundTIP_DS/@DesignContainer return(string.Join("/", absPath.Split('/').Select(x => string.Join("", x.TakeWhile(y => y != '|'))))); }); var sutPath = shortenAbsPath(originalSut.AllReferred.Impl.AbsPath); var originalTipPath = shortenAbsPath(originalTip.Referred.AbsPath); relativePath = originalTipPath.Substring(sutPath.Length); // TODO: meta base name [kind] can be different if there are no unique path to the object. targetTipByAbsPath = (targetSut.AllReferred.Impl as MgaModel).get_ObjectByPath(relativePath) as MgaFCO; } else { // while optional and alternative containers are not tracked, get all ComponentAssembly, Component, ComponentRef recursively. possibleDesignEntities.AddRange(ExpandInnerOptionalAndAlternativesRecursively(designContainer)); } } Exception ex = null; foreach (var designEntity in possibleDesignEntities) { // Look for a DesignEntityRef, within a CWC, that points to this element in the Design Space. foreach (CyPhy.DesignEntityRef designEntityRef in designEntity.ReferencedBy.DesignEntityRef) { var cwc = CyPhyClasses.CWC.Cast(designEntityRef.ParentContainer.Impl); bool hasMatchingCARoot = false; var caRefs = cwc.DstConnections.Config2CACollection.Select(x => x.DstEnds.ComponentAssemblyRef); foreach (var caRef in caRefs) { if (caRef.AllReferred != null) { if ((caRef.AllReferred.Impl as MgaFCO).RootFCO.ID == (sutComponentAssemblyTarget.Impl as MgaFCO).RootFCO.ID) { hasMatchingCARoot = true; break; } } } if (hasMatchingCARoot == false) { // do not log any messages since they irrelevant. continue; } // TODO: log if design is dirty. // get design entity ref where the refered object is the test injection point reference // // Multiple configuration (1, 2, 3, ...) can have the same design entity refs // // design entity ref ----> DesignSpace element // ^ // | // original test injection --------- // verify root fco do match if ((designEntityRef.Impl as MgaFCO).RootFCO != (sutDesignContainer.Impl as MgaFCO).RootFCO) { // in case user accidentally moves these object in the tree string message = string.Format("Model does not contain traceablity information between the generated configurations and the design space. {0} will not be found in the original design space. Please try to export the configurations again using CAExporter or run the design space exploration tool.", originalTip.Meta.Name); ex = new AnalysisModelTipNotFoundException(message); continue; } // user may have leftovers from running CAExporter then deleting the CA var builts = designEntityRef.DstConnections.BuiltCollection.Where(x => x.DstEnds.BuiltDesignEntityRef.AllReferred != null); var builtConnections = builts.Count(); if (builtConnections == 0) { // no built connection -> not good string message = string.Format("No 'built' connection. Model does not contain traceablity information between the generated configurations and the design space. {0} will not be found in the original design space. Please try to export the configurations again using CAExporter or run the design space exploration tool.", originalTip.Meta.Name); ex = new AnalysisModelTipNotFoundException(message); continue; } if (builtConnections > 1) { // more than one built connection -> not good string message = string.Format("There are more than one 'built' connections traceability is ambiguous. Model has to be fixed first. {0} will not be found in the original design space. Please try to export the configurations again using CAExporter or run the design space exploration tool.", originalTip.Meta.Name); ex = new AnalysisModelTipNotFoundException(message); continue; } // Get the Built connection and then the BuildDesignEntityRef. // The BuildDesignEntityRef will point to our source object within a Component Assembly / configuration. foreach (CyPhy.Built built in builts) { var builtDesignEntityRef = built.DstEnds.BuiltDesignEntityRef; if ((builtDesignEntityRef.AllReferred.Impl as MgaFCO).RootFCO.ID == (sutComponentAssemblyTarget.Impl as MgaFCO).RootFCO.ID) { // verify that the component is inside the target design // TODO: how this would work if it points to a component in a CA which is referred in the design??? targetTipByBuilt = builtDesignEntityRef.AllReferred.Impl as MgaFCO; } } } } if (targetTipByBuilt != null) { // prefer by built return(targetTipByBuilt); } else if (targetTipByAbsPath != null) { // fallback to by abs path return(targetTipByAbsPath); } else if (ex != null) { // not found throw ex; } else { return(null); } }
public static IMgaFCO FindTestInjectionTarget( CyPhy.TopLevelSystemUnderTest originalSut, IMgaReference originalTip, CyPhy.TopLevelSystemUnderTest targetSut) { if (originalSut == null) { throw new ArgumentNullException("originalSut"); } if (originalTip == null) { throw new ArgumentNullException("originalTip"); } if (targetSut == null) { throw new ArgumentNullException("targetSut"); } // target that the reference has to be redirected IMgaFCO targetTipByBuilt = null; IMgaFCO targetTipByAbsPath = null; // get tip reference // relative path var relativePath = string.Empty; // ASSUME original SUT is a design container if (originalSut.Referred.DesignContainer == null && targetSut.Referred.ComponentAssembly == null) { throw new NotImplementedException(); } var sutDesignContainer = originalSut.Referred.DesignContainer; var sutComponentAssemblyTarget = targetSut.Referred.ComponentAssembly; // TOOD: Double check this cast CyPhy.DesignEntity originalDesignEntity = null; if (originalTip.Referred.Meta.Name == typeof(CyPhy.DesignContainer).Name) { originalDesignEntity = CyPhyClasses.DesignContainer.Cast(originalTip.Referred); } else if (originalTip.Referred.Meta.Name == typeof(CyPhy.Component).Name) { originalDesignEntity = CyPhyClasses.Component.Cast(originalTip.Referred); } else if (originalTip.Referred.Meta.Name == typeof(CyPhy.ComponentRef).Name) { originalDesignEntity = CyPhyClasses.ComponentRef.Cast(originalTip.Referred); } else if (originalTip.Referred.Meta.Name == typeof(CyPhy.ComponentAssembly).Name) { originalDesignEntity = CyPhyClasses.ComponentAssembly.Cast(originalTip.Referred); } List<CyPhy.DesignEntity> possibleDesignEntities = new List<CyPhy.DesignEntity>(); possibleDesignEntities.Add(originalDesignEntity); // TODO: abspath for component assemblies / Component assembly refs too. Call function recursively if (originalTip.Referred.Meta.Name == typeof(CyPhy.DesignContainer).Name) { var designContainer = CyPhyClasses.DesignContainer.Cast(originalTip.Referred); if (designContainer.Attributes.ContainerType == CyPhyClasses.DesignContainer.AttributesClass.ContainerType_enum.Compound) { // there could be a referece to the compound container // BUG: no tracking of compound containers attempt to get it by AbsPath // this implementation will work as long as // names are unqiue to Compound containes // structure as follows // // == PASS == // | Compound // +-- Compound // | // +-- Compound // // == FAIL 1 == Have no idea how to get the path correctly // | Compound // +-- Alternative // | // +-- Compound // // == FAIL 2 == Have no idea how to get the path correctly // | Compound // +-- Optional // | // +-- Compound // TODO: would be nice to use a regexp or something like that Func<string, string> shortenAbsPath = new Func<string, string>((absPath) => { // Example: // input: /@NewTesting|kind=Testing|relpos=0/@FEA_CompoundTIP_DS|kind=CADTestBench|relpos=0/@DesignContainer|kind=TopLevelSystemUnderTest|relpos=0 // output: /@NewTesting/@FEA_CompoundTIP_DS/@DesignContainer return string.Join("/", absPath.Split('/').Select(x => string.Join("", x.TakeWhile(y => y != '|')))); }); var sutPath = shortenAbsPath(originalSut.AllReferred.Impl.AbsPath); var originalTipPath = shortenAbsPath(originalTip.Referred.AbsPath); relativePath = originalTipPath.Substring(sutPath.Length); // TODO: meta base name [kind] can be different if there are no unique path to the object. targetTipByAbsPath = (targetSut.AllReferred.Impl as MgaModel).get_ObjectByPath(relativePath) as MgaFCO; } else { // while optional and alternative containers are not tracked, get all ComponentAssembly, Component, ComponentRef recursively. possibleDesignEntities.AddRange(ExpandInnerOptionalAndAlternativesRecursively(designContainer)); } } Exception ex = null; foreach (var designEntity in possibleDesignEntities) { // Look for a DesignEntityRef, within a CWC, that points to this element in the Design Space. foreach (CyPhy.DesignEntityRef designEntityRef in designEntity.ReferencedBy.DesignEntityRef) { var cwc = CyPhyClasses.CWC.Cast(designEntityRef.ParentContainer.Impl); bool hasMatchingCARoot = false; var caRefs = cwc.DstConnections.Config2CACollection.Select(x => x.DstEnds.ComponentAssemblyRef); foreach (var caRef in caRefs) { if (caRef.AllReferred != null) { if ((caRef.AllReferred.Impl as MgaFCO).RootFCO.ID == (sutComponentAssemblyTarget.Impl as MgaFCO).RootFCO.ID) { hasMatchingCARoot = true; break; } } } if (hasMatchingCARoot == false) { // do not log any messages since they irrelevant. continue; } // TODO: log if design is dirty. // get design entity ref where the refered object is the test injection point reference // // Multiple configuration (1, 2, 3, ...) can have the same design entity refs // // design entity ref ----> DesignSpace element // ^ // | // original test injection --------- // verify root fco do match if ((designEntityRef.Impl as MgaFCO).RootFCO != (sutDesignContainer.Impl as MgaFCO).RootFCO) { // in case user accidentally moves these object in the tree string message = string.Format("Model does not contain traceablity information between the generated configurations and the design space. {0} will not be found in the original design space. Please try to export the configurations again using CAExporter or run the design space exploration tool.", originalTip.Meta.Name); ex = new AnalysisModelTipNotFoundException(message); continue; } var builtConnections = designEntityRef.DstConnections.BuiltCollection.Count(); if (builtConnections == 0) { // no built connection -> not good string message = string.Format("No 'built' connection. Model does not contain traceablity information between the generated configurations and the design space. {0} will not be found in the original design space. Please try to export the configurations again using CAExporter or run the design space exploration tool.", originalTip.Meta.Name); ex = new AnalysisModelTipNotFoundException(message); continue; } if (builtConnections > 1) { // more than one built connection -> not good string message = string.Format("There are more than one 'built' connections traceability is ambiguous. Model has to be fixed first. {0} will not be found in the original design space. Please try to export the configurations again using CAExporter or run the design space exploration tool.", originalTip.Meta.Name); ex = new AnalysisModelTipNotFoundException(message); continue; } // Get the Built connection and then the BuildDesignEntityRef. // The BuildDesignEntityRef will point to our source object within a Component Assembly / configuration. foreach (CyPhy.Built built in designEntityRef.DstConnections.BuiltCollection) { var builtDesignEntityRef = built.DstEnds.BuiltDesignEntityRef; if (builtDesignEntityRef.AllReferred == null) { // in case user clears the reference string message = string.Format("Model does not contain traceablity information between the generated configurations and the design space. {0} will not be found in the original design space. Please try to export the configurations again using CAExporter or run the design space exploration tool.", originalTip.Meta.Name); ex = new AnalysisModelTipNotFoundException(message); continue; } if ((builtDesignEntityRef.AllReferred.Impl as MgaFCO).RootFCO.ID == (sutComponentAssemblyTarget.Impl as MgaFCO).RootFCO.ID) { // verify that the component is inside the target design // TODO: how this would work if it points to a component in a CA which is referred in the design??? targetTipByBuilt = builtDesignEntityRef.AllReferred.Impl as MgaFCO; } } } } if (targetTipByBuilt != null) { // prefer by built return targetTipByBuilt; } else if (targetTipByAbsPath != null) { // fallback to by abs path return targetTipByAbsPath; } else if (ex != null) { // not found throw ex; } else { return null; } }