internal override PropagationMacroCommand PrePropagation()
        {
            PropagationMacroCommand command = new PropagationMacroCommand(Controller);

            command.Report = new CommandReport("Pre-propagation (move PIM attribute)");

            PIMAttribute attribute   = Project.TranslateComponent <PIMAttribute>(attributeGuid);
            PIMClass     targetClass = Project.TranslateComponent <PIMClass>(newClassGuid);
            PIMClass     sourceClass = attribute.PIMClass;

            IEnumerable <PIMAssociation> pimAssociations       = targetClass.GetAssociationsWith(sourceClass);
            IEnumerable <PSMAttribute>   interpretedAttributes = attribute.GetInterpretedComponents().Cast <PSMAttribute>().Where(a => a.ID != PropagateSource);

            foreach (PSMAttribute psmAttribute in interpretedAttributes)
            {
                PSMClass intclass = psmAttribute.PSMClass.NearestInterpretedClass();
                Debug.Assert(intclass.Interpretation == sourceClass, "Intclass != sourceclass");

                bool           found             = false;
                PSMAssociation parentAssociation = intclass.ParentAssociation;

                foreach (PIMAssociation association in pimAssociations)
                {
                    if (parentAssociation != null && parentAssociation.Interpretation == association)
                    {
                        //moving the attribute up in PSM
                        found = true;

                        cmdCreateNewPSMAttribute c2 = new cmdCreateNewPSMAttribute(Controller);
                        Guid attrGuid2 = Guid.NewGuid();
                        c2.AttributeGuid = attrGuid2;
                        c2.Set(intclass, psmAttribute.AttributeType, psmAttribute.Name, psmAttribute.Lower, psmAttribute.Upper, psmAttribute.Element);
                        command.Commands.Add(c2);

                        if (psmAttribute.PSMClass != intclass)
                        {
                            command.Commands.Add(new cmdMovePSMAttribute(Controller)
                            {
                                AttributeGuid = psmAttribute, ClassGuid = intclass, Propagate = false
                            });
                        }

                        acmdSynchroPSMAttributes s2 = new acmdSynchroPSMAttributes(Controller)
                        {
                            Propagate = false
                        };
                        s2.X1.Add(psmAttribute);
                        s2.X2.Add(attrGuid2);
                        command.Commands.Add(s2);

                        if (psmAttribute.PSMClass != intclass)
                        {
                            command.Commands.Add(new cmdMovePSMAttribute(Controller)
                            {
                                AttributeGuid = psmAttribute, ClassGuid = psmAttribute.PSMClass, Propagate = false
                            });
                        }

                        acmdSetInterpretation i2 = new acmdSetPSMAttributeInterpretation(Controller, attrGuid2, attribute);
                        command.Commands.Add(i2);

                        cmdMovePSMAttribute m2 = new cmdMovePSMAttribute(Controller)
                        {
                            Propagate = false
                        };
                        m2.Set(attrGuid2, intclass.NearestInterpretedParentClass());
                        command.Commands.Add(m2);
                    }

                    //select nearest interpreted child PSM classes, whose parent association's interpretation is the PIM association through which we are moving the attribute
                    IEnumerable <PSMClass> children = intclass.InterpretedSubClasses().Where <PSMClass>(pc => pc.Interpretation == targetClass && pc.ParentAssociation.Interpretation == association);
                    foreach (PSMClass child in children)
                    {
                        found = true;
                        cmdCreateNewPSMAttribute c = new cmdCreateNewPSMAttribute(Controller);
                        Guid attrGuid = Guid.NewGuid();
                        c.AttributeGuid = attrGuid;
                        c.Set(intclass, psmAttribute.AttributeType, psmAttribute.Name, psmAttribute.Lower, psmAttribute.Upper, psmAttribute.Element);
                        command.Commands.Add(c);

                        if (psmAttribute.PSMClass != intclass)
                        {
                            command.Commands.Add(new cmdMovePSMAttribute(Controller)
                            {
                                AttributeGuid = psmAttribute, ClassGuid = intclass, Propagate = false
                            });
                        }

                        acmdSynchroPSMAttributes s2 = new acmdSynchroPSMAttributes(Controller)
                        {
                            Propagate = false
                        };
                        s2.X1.Add(psmAttribute);
                        s2.X2.Add(attrGuid);
                        command.Commands.Add(s2);

                        if (psmAttribute.PSMClass != intclass)
                        {
                            command.Commands.Add(new cmdMovePSMAttribute(Controller)
                            {
                                AttributeGuid = psmAttribute, ClassGuid = psmAttribute.PSMClass, Propagate = false
                            });
                        }

                        acmdSetInterpretation i = new acmdSetPSMAttributeInterpretation(Controller, attrGuid, attribute);
                        command.Commands.Add(i);

                        cmdMovePSMAttribute m = new cmdMovePSMAttribute(Controller)
                        {
                            Propagate = false
                        };
                        m.Set(attrGuid, child);
                        command.Commands.Add(m);
                    }

                    if (!found)
                    {
                        cmdCreateNewPSMAttribute c = new cmdCreateNewPSMAttribute(Controller);
                        Guid attrGuid = Guid.NewGuid();
                        c.AttributeGuid = attrGuid;
                        c.Set(/*intclass*/ psmAttribute.PSMClass, psmAttribute.AttributeType, psmAttribute.Name, psmAttribute.Lower, psmAttribute.Upper, psmAttribute.Element);
                        command.Commands.Add(c);

                        /*if (psmAttribute.PSMClass != intclass)
                         * {
                         *  cmdMovePSMAttribute m1 = new cmdMovePSMAttribute(Controller) { Propagate = false };
                         *  m1.Set(psmAttribute, intclass);
                         *  command.Commands.Add(m1);
                         * }*/

                        acmdSynchroPSMAttributes s = new acmdSynchroPSMAttributes(Controller)
                        {
                            Propagate = false
                        };
                        s.X1.Add(psmAttribute);
                        s.X2.Add(attrGuid);
                        command.Commands.Add(s);

                        /*if (psmAttribute.PSMClass != intclass)
                         * {
                         *  cmdMovePSMAttribute m2 = new cmdMovePSMAttribute(Controller) { Propagate = false };
                         *  m2.Set(psmAttribute, psmAttribute.PSMClass);
                         *  command.Commands.Add(m2);
                         * }*/

                        acmdSetInterpretation i = new acmdSetPSMAttributeInterpretation(Controller, attrGuid, attribute);
                        command.Commands.Add(i);

                        //create psmassoc, class
                        Guid            ncGuid = Guid.NewGuid();
                        acmdNewPSMClass nc     = new acmdNewPSMClass(Controller, psmAttribute.PSMSchema)
                        {
                            ClassGuid = ncGuid
                        };
                        command.Commands.Add(nc);

                        acmdRenameComponent rc = new acmdRenameComponent(Controller, ncGuid, targetClass.Name);
                        command.Commands.Add(rc);

                        acmdSetInterpretation ic = new acmdSetPSMClassInterpretation(Controller, ncGuid, targetClass);
                        command.Commands.Add(ic);

                        Guid naGuid = Guid.NewGuid();

                        acmdNewPSMAssociation na = new acmdNewPSMAssociation(Controller, /*intclass*/ psmAttribute.PSMClass, ncGuid, psmAttribute.PSMSchema)
                        {
                            AssociationGuid = naGuid
                        };
                        command.Commands.Add(na);

                        acmdRenameComponent ra = new acmdRenameComponent(Controller, naGuid, association.Name);
                        command.Commands.Add(ra);

                        PIMAssociationEnd e = targetClass.PIMAssociationEnds.Single <PIMAssociationEnd>(aend => aend.PIMAssociation == association);
                        acmdUpdatePSMAssociationCardinality carda = new acmdUpdatePSMAssociationCardinality(Controller, naGuid, e.Lower, e.Upper)
                        {
                            Propagate = false
                        };
                        command.Commands.Add(carda);

                        acmdSetInterpretation ia = new acmdSetPSMAssociationInterpretation(Controller, naGuid, e, association);
                        command.Commands.Add(ia);

                        acmdMovePSMAttribute m = new acmdMovePSMAttribute(Controller, attrGuid, ncGuid)
                        {
                            Propagate = false
                        };
                        command.Commands.Add(m);
                    }
                }
                //delete attribute
                cmdDeletePSMAttribute d = new cmdDeletePSMAttribute(Controller)
                {
                    Propagate = false
                };
                d.Set(psmAttribute);
                command.Commands.Add(d);
            }

            command.CheckFirstOnlyInCanExecute = true;
            return(command);
        }
Beispiel #2
0
        internal override PropagationMacroCommand PrePropagation()
        {
            IEnumerable <PIMAttribute> aX1 = Project.TranslateComponentCollection <PIMAttribute>(X1);
            IEnumerable <PIMAttribute> aX2 = Project.TranslateComponentCollection <PIMAttribute>(X2);

            if (aX1.Count() == 0 || aX2.Count() == 0)
            {
                return(null);
            }

            PropagationMacroCommand command = new PropagationMacroCommand(Controller)
            {
                CheckFirstOnlyInCanExecute = true
            };

            command.Report = new CommandReport("Pre-propagation (synchronize PIM attribute sets)");
            PIMClass pimClass = aX2.First().PIMClass;

            //Twice... X1 => X2, X2 => X1
            for (int i = 0; i < 2; i++)
            {
                IEnumerable <PSMClass> allPSMClasses = pimClass.GetInterpretedComponents().Cast <PSMClass>();
                List <PSMClass>        psmClasses    = new List <PSMClass>();
                foreach (PSMClass c in allPSMClasses)
                {
                    IEnumerable <PSMAttribute> atts = c.GetContextPSMAttributes();
                    if (atts.Where(a => a.Interpretation != null)
                        .Select(psma => psma.Interpretation as PIMAttribute)
                        .Intersect(aX1)
                        .OrderBy(k => k.ID)
                        .SequenceEqual(aX1.OrderBy(j => j.ID)))
                    {
                        psmClasses.Add(c);
                    }
                }

                //Elimination of SRs where C is affected and SR is a SR of C
                bool found = true;
                while (found)
                {
                    found = false;
                    List <PSMClass> list = new List <PSMClass>();
                    foreach (PSMClass psmClass in psmClasses)
                    {
                        if (psmClass.RepresentedClass != null &&
                            psmClasses.Contains(psmClass.RepresentedClass) &&
                            !psmClass.GetContextPSMAttributes(true)
                            .Where(a => a.Interpretation != null)
                            .Select(psma => psma.Interpretation as PIMAttribute)
                            .Intersect(aX1)
                            .OrderBy(k => k.ID)
                            .SequenceEqual(aX1.OrderBy(j => j.ID)))
                        {
                            found = true;
                        }
                        else
                        {
                            list.Add(psmClass);
                        }
                    }
                    psmClasses = list;
                }

                foreach (PSMClass psmClass in psmClasses)
                {
                    IEnumerable <Tuple <PSMAttribute, IEnumerable <ModelIterator.MoveStep> > > attributesAndPaths = psmClass.GetContextPSMAttributesWithPaths();
                    IEnumerable <PSMAttribute> attributes            = attributesAndPaths.Select(t => t.Item1);
                    IEnumerable <PSMAttribute> interpretedAttributes = attributes.Where(a => a.Interpretation != null);
                    IEnumerable <PSMAttribute> responsibleAttributes = interpretedAttributes.Where(a => aX1.Contains(a.Interpretation as PIMAttribute));
                    IEnumerable <PIMAttribute> interpretations       = interpretedAttributes.Select(a => a.Interpretation as PIMAttribute);
                    IEnumerable <PIMAttribute> attributesToPropagate = aX2.Where(a => !interpretations.Contains(a));

                    IEnumerable <PSMAttribute> attributesToMoveList = interpretedAttributes.Where(a => a.PSMClass != psmClass && (aX1.Contains((PIMAttribute)a.Interpretation) || aX2.Contains((PIMAttribute)a.Interpretation)));
                    Dictionary <PSMAttribute, IEnumerable <ModelIterator.MoveStep> > psmAttributesToMove = new Dictionary <PSMAttribute, IEnumerable <ModelIterator.MoveStep> >();
                    foreach (PSMAttribute t in attributesToMoveList)
                    {
                        Tuple <PSMAttribute, IEnumerable <ModelIterator.MoveStep> > tuple = attributesAndPaths.Single(tup => tup.Item1 == t);
                        psmAttributesToMove.Add(tuple.Item1, tuple.Item2);
                    }

                    List <Guid> newAttributesGuid = new List <Guid>();
                    foreach (PIMAttribute a in attributesToPropagate)
                    {
                        cmdCreateNewPSMAttribute c = new cmdCreateNewPSMAttribute(Controller);
                        Guid attrGuid = Guid.NewGuid();
                        c.AttributeGuid = attrGuid;
                        c.Set(psmClass, a.AttributeType, a.Name, a.Lower, a.Upper, responsibleAttributes.First().Element);
                        command.Commands.Add(c);
                        newAttributesGuid.Add(attrGuid);

                        acmdSetInterpretation cmdi = new acmdSetPSMAttributeInterpretation(Controller, attrGuid, a);
                        command.Commands.Add(cmdi);
                    }

                    foreach (KeyValuePair <PSMAttribute, IEnumerable <ModelIterator.MoveStep> > kvp in psmAttributesToMove)
                    {
                        foreach (ModelIterator.MoveStep s in kvp.Value)
                        {
                            if (s.StepType == ModelIterator.MoveStep.MoveStepType.None)
                            {
                                continue;
                            }
                            command.Commands.Add(new acmdMovePSMAttribute(Controller, kvp.Key, s.StepTarget)
                            {
                                Propagate = false
                            });
                        }
                    }

                    IEnumerable <Guid> synchroGroup1 = responsibleAttributes.Select <PSMAttribute, Guid>(a => a);
                    IEnumerable <Guid> synchroGroup2 = attributes.Where(a => aX2.Contains((PIMAttribute)a.Interpretation)).Select <PSMAttribute, Guid>(a => a).Union(newAttributesGuid);

                    command.Commands.Add(new acmdSynchroPSMAttributes(Controller)
                    {
                        X1 = synchroGroup1.ToList(), X2 = synchroGroup2.ToList(), Propagate = false
                    });

                    foreach (KeyValuePair <PSMAttribute, IEnumerable <ModelIterator.MoveStep> > kvp in psmAttributesToMove)
                    {
                        bool first = true;
                        foreach (ModelIterator.MoveStep s in kvp.Value.Reverse <ModelIterator.MoveStep>())
                        {
                            if (first)
                            {
                                first = false;
                            }
                            else
                            {
                                command.Commands.Add(new acmdMovePSMAttribute(Controller, kvp.Key, s.StepTarget)
                                {
                                    Propagate = false
                                });
                            }
                        }
                    }
                }

                //Swap the two lists and do it again
                IEnumerable <PIMAttribute> temp = aX1;
                aX1 = aX2;
                aX2 = temp;
            }

            return(command);
        }