Exemplo n.º 1
0
        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;
            }
        }