Beispiel #1
0
        internal override PropagationMacroCommand PrePropagation()
        {
            PIMGeneralization            g      = Project.TranslateComponent <PIMGeneralization>(deletedGeneralizationGuid);
            IEnumerable <PSMAttribute>   atts   = Project.LatestVersion.PSMSchemas.SelectMany(s => s.PSMAttributes).Where(att => att.UsedGeneralizations.Contains(g));
            IEnumerable <PSMAssociation> assocs = Project.LatestVersion.PSMSchemas.SelectMany(s => s.PSMAssociations).Where(assoc => assoc.UsedGeneralizations.Contains(g));

            PropagationMacroCommand command = new PropagationMacroCommand(Controller);

            command.Report = new CommandReport("Pre-propagation (delete PIM generalization)");

            foreach (PSMAttribute a in atts)
            {
                command.Commands.Add(new cmdDeletePSMAttribute(Controller)
                {
                    AttributeGuid = a
                });
            }

            foreach (PSMAssociation a in assocs)
            {
                command.Commands.Add(new cmdDeletePSMAssociation(Controller)
                {
                    AssociationGuid = a
                });
            }

            return(command);
        }
Beispiel #2
0
        internal override PropagationMacroCommand PrePropagation()
        {
            List <PSMAttribute> list = Project.TranslateComponent <PIMAttribute>(attributeGuid).GetInterpretedComponents().Cast <PSMAttribute>().ToList <PSMAttribute>();

            if (list.Count == 0)
            {
                return(null);
            }

            PropagationMacroCommand command = new PropagationMacroCommand(Controller);

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

            foreach (PSMAttribute a in list)
            {
                cmdDeletePSMAttribute d = new cmdDeletePSMAttribute(Controller)
                {
                    Propagate = false
                };
                d.Set(a);
                command.Commands.Add(d);
            }

            return(command);
        }
Beispiel #3
0
        internal override PropagationMacroCommand PrePropagation()
        {
            PIMClass        pimClass = Project.TranslateComponent <PIMClass>(classGuid);
            List <PSMClass> list     = pimClass.GetInterpretedComponents().Cast <PSMClass>().ToList <PSMClass>();

            if (list.Count == 0)
            {
                return(null);
            }

            PropagationMacroCommand command = new PropagationMacroCommand(Controller);

            command.Report = new CommandReport("Pre-propagation (update PIM class abstract property)");

            foreach (PSMClass psmClass in list)
            {
                acmdUpdatePSMClassAbstract cmd = new acmdUpdatePSMClassAbstract(Controller, psmClass, newAbstract)
                {
                    Propagate = false
                };
                command.Commands.Add(cmd);
            }

            return(command);
        }
        internal override PropagationMacroCommand PrePropagation()
        {
            PIMAttribute        pimAttribute    = Project.TranslateComponent <PIMAttribute>(attributeGuid);
            PIMClass            specialPIMClass = Project.TranslateComponent <PIMClass>(specialClassGuid);
            PIMClass            generalPIMClass = pimAttribute.PIMClass;
            List <PSMAttribute> psmAttributes   = pimAttribute.GetInterpretedComponents().Cast <PSMAttribute>().ToList();

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

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

            foreach (PSMAttribute a in psmAttributes)
            {
                if (a.PSMClass.Interpretation == null)
                {
                    //class without interpretation, maybe including impl.inheritance
                    command.Commands.Add(new cmdMovePSMAttribute(Controller)
                    {
                        AttributeGuid = a, ClassGuid = a.PSMClass.NearestInterpretedClass()
                    });
                }

                IEnumerable <Tuple <PSMClass, IEnumerable <PSMClass> > > paths = a.PSMClass.GetSpecialClassesWithPaths();
                if (paths.Any(p => p.Item1.Interpretation == specialPIMClass))
                //1) there is special PIMClass counterpart -> move there
                {
                    IEnumerable <PSMClass> path = paths.First(p => p.Item1.Interpretation == specialPIMClass).Item2;
                    foreach (PSMClass c in path)
                    {
                        command.Commands.Add(new acmdSpecializePSMAttribute(Controller, a, c));
                    }
                }
                else
                //2) There is none... create. TODO: FIX: multiple attributes in one class => multiple classes
                {
                    Guid newClassGuid = Guid.NewGuid();
                    command.Commands.Add(new acmdNewPSMClass(Controller, a.PSMSchema)
                    {
                        ClassGuid = newClassGuid
                    });
                    command.Commands.Add(new acmdRenameComponent(Controller, newClassGuid, specialPIMClass.Name));
                    command.Commands.Add(new acmdSetPSMClassInterpretation(Controller, newClassGuid, specialPIMClass));
                    command.Commands.Add(new acmdNewPSMGeneralization(Controller, a.PSMClass.NearestInterpretedClass(), newClassGuid, a.PSMSchema));
                    command.Commands.Add(new acmdSpecializePSMAttribute(Controller, a, newClassGuid));
                }
            }

            return(command);
        }
        internal override PropagationMacroCommand PrePropagation()
        {
            PIMGeneralization pimGeneralization  = Project.TranslateComponent <PIMGeneralization>(generalizationGuid);
            PIMClass          newPIMGeneral      = Project.TranslateComponent <PIMClass>(specialClassGuid);
            PIMClass          pimSpecificClass   = pimGeneralization.Specific;
            PIMClass          oldPIMGeneral      = pimGeneralization.General;
            List <PSMClass>   psmSpecificClasses = pimSpecificClass.GetInterpretedComponents().Cast <PSMClass>().ToList();

            if (psmSpecificClasses.Count == 0)
            {
                return(null);
            }

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

            command.Report = new CommandReport("Pre-propagation (specialize PIM generalization)");

            foreach (PSMClass c in psmSpecificClasses)
            {
                if (c.GeneralizationAsSpecific != null)
                {
                    PSMClass oldPSMGeneral = c.GeneralizationAsSpecific.General;
                    if (oldPSMGeneral.Interpretation == oldPIMGeneral)
                    {
                        IEnumerable <PSMClass> rightDescendants = oldPSMGeneral.GeneralizationsAsGeneral.Where(g => g.Specific.Interpretation == newPIMGeneral).Select(g => g.Specific);
                        if (rightDescendants.Count() == 1)
                        //0 - there is no suitable class.. nothing has to happen,
                        //>1 there are more... nothing will happen and it is up to the user (instead of duplicating or SR). Coherence not violated.
                        {
                            PSMClass newPSMGeneral = rightDescendants.Single();
                            command.Commands.Add(new acmdSpecializePSMGeneralization(Controller, c.GeneralizationAsSpecific, newPSMGeneral)
                            {
                                Propagate = false
                            });
                        }
                    }
                }
            }

            return(command);
        }
Beispiel #6
0
        internal override PropagationMacroCommand PostPropagation()
        {
            PSMAttribute psmAttribute = Project.TranslateComponent <PSMAttribute>(attributeGuid);
            PSMClass     oldClass     = Project.TranslateComponent <PSMClass>(oldClassGuid);
            PSMClass     newClass     = Project.TranslateComponent <PSMClass>(newClassGuid);

            if (newClass.RepresentedClass == oldClass || oldClass.RepresentedClass == newClass)
            {
                return(null);
            }
            if (psmAttribute.Interpretation == null)
            {
                return(null);
            }

            PSMClass oldIntContext = oldClass.NearestInterpretedClass();
            PSMClass newIntContext = newClass.NearestInterpretedClass();

            if (oldIntContext == newIntContext)
            {
                return(null);
            }

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

            command.Report = new CommandReport("Post-propagation (move PSM attribute)");

            if (newIntContext == null)
            {
                command.Commands.Add(new acmdSetPSMAttributeInterpretation(Controller, psmAttribute, Guid.Empty));
            }
            else
            {
                command.Commands.Add(new acmdMovePIMAttribute(Controller, psmAttribute.Interpretation, newIntContext.Interpretation)
                {
                    PropagateSource = psmAttribute
                });
            }

            return(command);
        }
Beispiel #7
0
        internal override PropagationMacroCommand PrePropagation()
        {
            PIMClass        pimClass = Project.TranslateComponent <PIMClass>(classGuid);
            List <PSMClass> list     = pimClass.GetInterpretedComponents().Cast <PSMClass>().ToList <PSMClass>();

            if (list.Count == 0)
            {
                return(null);
            }

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

            command.Report = new CommandReport("Pre-propagation (update PIM class final property)");

            foreach (PSMClass c in list)
            {
                if (c.GeneralizationsAsGeneral.Count > 0)
                {
                    foreach (PSMGeneralization g in c.GeneralizationsAsGeneral)
                    {
                        //This should be only in case of:
                        Debug.Assert(g.General.Interpretation == g.Specific.Interpretation);
                        //If not, the PSM class was still involved in a generalization and
                        acmdDeletePSMGeneralization d1 = new acmdDeletePSMGeneralization(Controller, g)
                        {
                            Propagate = false
                        };
                        command.Commands.Add(d1);
                    }
                }

                acmdUpdatePSMClassFinal d = new acmdUpdatePSMClassFinal(Controller, c, newFinal)
                {
                    Propagate = false
                };
                command.Commands.Add(d);
            }

            return(command);
        }
        internal override PropagationMacroCommand PrePropagation()
        {
            List <PSMAssociation> list = Project.TranslateComponent <PIMAssociation>(AssociationGuid).GetInterpretedComponents().Cast <PSMAssociation>().ToList <PSMAssociation>();

            if (list.Count == 0)
            {
                return(null);
            }

            PropagationMacroCommand command = new PropagationMacroCommand(Controller);

            command.Report = new CommandReport("Pre-propagation (delete PIM association)");

            if (list.Count > 0)
            {
                List <PSMAssociation> list2 = new List <PSMAssociation>(list);
                foreach (PSMAssociation a1 in list2)
                {
                    foreach (PSMAssociation a2 in list2)
                    {
                        if (a1.IsDescendantFrom(a2))
                        {
                            list.Remove(a1);
                        }
                    }
                }

                foreach (PSMAssociation a in list)
                {
                    cmdDeletePSMAssociation d = new cmdDeletePSMAssociation(Controller)
                    {
                        Propagate = false
                    };
                    d.Set(a);
                    command.Commands.Add(d);
                }
            }

            return(command);
        }
Beispiel #9
0
        internal override PropagationMacroCommand PrePropagation()
        {
            List <PSMClass> list = Project.TranslateComponent <PIMClass>(deletedClassGuid).GetInterpretedComponents().Cast <PSMClass>().ToList <PSMClass>();

            if (list.Count == 0)
            {
                return(null);
            }

            PropagationMacroCommand command = new PropagationMacroCommand(Controller);

            command.Report = new CommandReport("Pre-propagation (delete PIM class)");

            if (list.Count > 0)
            {
                List <PSMClass> list2 = new List <PSMClass>(list);
                foreach (PSMClass c1 in list2)
                {
                    foreach (PSMClass c2 in list2)
                    {
                        if (c1.IsDescendantFrom(c2))
                        {
                            list.Remove(c1);
                        }
                    }
                }

                foreach (PSMClass c in list)
                {
                    cmdDeletePSMClassAndParent d = new cmdDeletePSMClassAndParent(Controller)
                    {
                        Propagate = false
                    };
                    d.Set(c);
                    command.Commands.Add(d);
                }
            }
            return(command);
        }
Beispiel #10
0
        internal override PropagationMacroCommand PostPropagation()
        {
            PropagationMacroCommand command = new PropagationMacroCommand(Controller)
            {
                CheckFirstOnlyInCanExecute = true
            };
            ExolutioObject component = Project.TranslateComponent(NamedComponentGuid);

            if (component is PIMComponent)
            {
                PIMComponent pimComponent = (PIMComponent)component;
                foreach (PSMComponent psmComponent in pimComponent.GetInterpretedComponents())
                {
                    if (psmComponent.IsNamed && psmComponent.Name == oldname)
                    {
                        command.Commands.Add(new acmdRenameComponent(Controller, psmComponent, NewName));
                    }
                }
            }

            return(command);
        }
        internal override PropagationMacroCommand PrePropagation()
        {
            PIMAttribute        pimAttribute  = Project.TranslateComponent <PIMAttribute>(attributeGuid);
            PIMClass            oldPIMClass   = pimAttribute.PIMClass;
            PIMClass            newPIMClass   = oldPIMClass.GeneralizationAsSpecific.General;
            List <PSMAttribute> psmAttributes = pimAttribute.GetInterpretedComponents().Cast <PSMAttribute>().ToList();

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

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

            foreach (PSMAttribute a in psmAttributes)
            {
                IEnumerable <PSMClass> generals = a.PSMClass.NearestInterpretedClass().GetGeneralClasses();
                if (generals.Any(c => c.Interpretation == newPIMClass))
                {
                    if (a.PSMClass.Interpretation == null)
                    {
                        //class without interpretation, maybe including impl.inheritance
                        command.Commands.Add(new cmdMovePSMAttribute(Controller)
                        {
                            AttributeGuid = a, ClassGuid = a.PSMClass.NearestInterpretedClass()
                        });
                    }

                    //whether the class uses implicit inheritance or not (a.PSMClass.Interpretation == oldPIMClass) we move it to the PSMClass, whose interpretation is newPIMClass
                    command.Commands.Add(new cmdGeneralizePSMAttribute(Controller)
                    {
                        AttributeGuid = a, PSMClassGuid = generals.First(c => c.Interpretation == newPIMClass)
                    });
                }
            }

            return(command);
        }
Beispiel #12
0
        internal override PropagationMacroCommand PostPropagation()
        {
            PSMAssociation association    = Project.TranslateComponent <PSMAssociation>(componentGuid);
            PIMAssociation interpretation = association.Interpretation as PIMAssociation;

            if (interpretation == null)
            {
                return(null);
            }

            PIMAssociationEnd e = ((association.Child as PSMClass).Interpretation as PIMClass).PIMAssociationEnds.First <PIMAssociationEnd>(end => end.PIMAssociation == interpretation);

            PropagationMacroCommand command = new PropagationMacroCommand(Controller);

            acmdUpdatePIMAssociationEndCardinality d = new acmdUpdatePIMAssociationEndCardinality(Controller, e, newLower, newUpper)
            {
                Propagate = true
            };

            command.Commands.Add(d);

            return(command);
        }
Beispiel #13
0
        internal override PropagationMacroCommand PrePropagation()
        {
            List <PSMAssociation> list = Project.TranslateComponent <PIMAssociationEnd>(ComponentGuid).PIMAssociation.GetInterpretedComponents().Cast <PSMAssociation>().ToList <PSMAssociation>();

            if (list.Count == 0)
            {
                return(null);
            }

            PropagationMacroCommand command = new PropagationMacroCommand(Controller);

            command.Report = new CommandReport("Pre-propagation (update PIM association end cardinality)");

            foreach (PSMAssociation a in list)
            {
                acmdUpdatePSMAssociationCardinality d = new acmdUpdatePSMAssociationCardinality(Controller, a, newLower, newUpper)
                {
                    Propagate = false
                };
                command.Commands.Add(d);
            }

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

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

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

            command.Report = new CommandReport("Pre-propagation (synchronize PIM association sets)");
            PIMClass pimClass1 = aX2.First().PIMClasses.First();
            PIMClass pimClass2 = aX2.First().PIMClasses.Last();

            //Twice... X1 => X2, X2 => X1
            for (int i = 0; i < 2; i++)
            {
                IEnumerable <PSMClass> allPSMClasses = pimClass1.GetInterpretedComponents().Union(pimClass2.GetInterpretedComponents()).Cast <PSMClass>();
                //Selects psmClasses affected by the synchronization (those which have aX1 counterpart present)
                List <PSMClass> psmClasses = new List <PSMClass>();
                foreach (PSMClass c in allPSMClasses)
                {
                    IEnumerable <PSMAssociation> assocs = c.GetContextPSMAssociations();
                    if (assocs.Union(c.ParentAssociation == null
                                ? Enumerable.Empty <PSMAssociation>()
                                : Enumerable.Repeat(c.ParentAssociation, 1))
                        .Where(a => a.Interpretation != null)
                        .Select(psma => psma.Interpretation as PIMAssociation)
                        .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.GetContextPSMAssociations(true)
                            .Union(psmClass.ParentAssociation == null
                                        ? Enumerable.Empty <PSMAssociation>()
                                        : Enumerable.Repeat(psmClass.ParentAssociation, 1))
                            .Where(a => a.Interpretation != null)
                            .Select(psma => psma.Interpretation as PIMAssociation)
                            .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 <PSMAssociation> parentEnum =
                        psmClass.ParentAssociation == null
                        ? Enumerable.Empty <PSMAssociation>()
                        : Enumerable.Repeat(psmClass.ParentAssociation, 1);

                    IEnumerable <Tuple <PSMAssociation, IEnumerable <ModelIterator.MoveStep> > > associationsAndPaths = psmClass.GetContextPSMAssociationsWithPaths();
                    IEnumerable <PSMAssociation> associations            = associationsAndPaths.Select(t => t.Item1).Union(parentEnum);
                    IEnumerable <PSMAssociation> interpretedAssociations = associations.Where(a => a.Interpretation != null);
                    IEnumerable <PSMAssociation> responsibleAssociations = interpretedAssociations.Where(a => aX1.Contains(a.Interpretation as PIMAssociation));
                    IEnumerable <PIMAssociation> interpretations         = interpretedAssociations.Select(a => a.Interpretation as PIMAssociation);
                    IEnumerable <PIMAssociation> associationsToPropagate = aX2.Where(a => !interpretations.Contains(a));

                    IEnumerable <PSMAssociation> psmAssociationsToMoveList = interpretedAssociations.Where(a => a.Parent != psmClass && a.Child != psmClass && aX1.Contains((PIMAssociation)a.Interpretation) || aX2.Contains((PIMAssociation)a.Interpretation));
                    Dictionary <PSMAssociation, IEnumerable <ModelIterator.MoveStep> > psmAssociationsToMove = new Dictionary <PSMAssociation, IEnumerable <ModelIterator.MoveStep> >();
                    foreach (PSMAssociation t in psmAssociationsToMoveList)
                    {
                        Tuple <PSMAssociation, IEnumerable <ModelIterator.MoveStep> > tuple = associationsAndPaths.Single(tup => tup.Item1 == t);
                        psmAssociationsToMove.Add(tuple.Item1, tuple.Item2);
                    }

                    List <Guid> newAssociationsGuid = new List <Guid>();
                    foreach (PIMAssociation a in associationsToPropagate)
                    {
                        Guid classGuid = Guid.NewGuid();
                        command.Commands.Add(new acmdNewPSMClass(Controller, psmClass.PSMSchema)
                        {
                            ClassGuid = classGuid
                        });
                        command.Commands.Add(new acmdRenameComponent(Controller, classGuid, psmClass.Interpretation == pimClass1 ? pimClass2.Name : pimClass1.Name));
                        command.Commands.Add(new acmdSetPSMClassInterpretation(Controller, classGuid, psmClass.Interpretation == pimClass1 ? pimClass2 : pimClass1));

                        Guid assocGuid = Guid.NewGuid();
                        command.Commands.Add(new acmdNewPSMAssociation(Controller, psmClass, classGuid, psmClass.PSMSchema)
                        {
                            AssociationGuid = assocGuid
                        });
                        command.Commands.Add(new acmdRenameComponent(Controller, assocGuid, a.Name));
                        PIMAssociationEnd e = a.PIMAssociationEnds.First(ae => ae.PIMClass != psmClass.Interpretation);
                        command.Commands.Add(new acmdUpdatePSMAssociationCardinality(Controller, assocGuid, e.Lower, e.Upper));
                        command.Commands.Add(new acmdSetPSMAssociationInterpretation(Controller, assocGuid, e, a));
                        newAssociationsGuid.Add(assocGuid);
                    }

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

                    IEnumerable <Guid> synchroGroup1 = responsibleAssociations.Select <PSMAssociation, Guid>(a => a);
                    IEnumerable <Guid> synchroGroup2 = associations.Where(a => aX2.Contains((PIMAssociation)a.Interpretation)).Select <PSMAssociation, Guid>(a => a).Union(newAssociationsGuid);

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

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

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

            return(command);
        }
Beispiel #15
0
        internal override PropagationMacroCommand PrePropagation()
        {
            PIMGeneralization pimGeneralization  = Project.TranslateComponent <PIMGeneralization>(generalizationGuid);
            PIMClass          pimSpecificClass   = pimGeneralization.Specific;
            PIMClass          oldPIMGeneral      = pimGeneralization.General;
            PIMClass          newPIMGeneral      = oldPIMGeneral.GeneralizationAsSpecific.General;
            List <PSMClass>   classesToCheck     = pimSpecificClass.GetSpecificClasses(true).SelectMany(c => c.GetInterpretedComponents().Cast <PSMClass>()).ToList();
            List <PSMClass>   psmSpecificClasses = pimSpecificClass.GetInterpretedComponents().Cast <PSMClass>().ToList();

            /* ALTERNATIVE SOLUTION - TO BE THOUGHT THROUGH - MOVE AS MANY ATTS AND ASSOCS AS POSSIBLE - DOES IT MAKE SENSE?
             * What about those in inheritance subtree??? Must go through every PSM class that has interpretation in the inheritance hierarchy subtree
             *
             *
             * 1) Is there a need to move atts and assocs? No - OK
             *  1a) Yes - where? Is there the "old general class"?
             *   1aa) Yes - There
             *   1ab) No - Is there superparent?
             *    1aba) Yes - Create old parent and there and specialize the subtree under it
             *    1abb) No - create parent, move "bad" atts and assocs, delete generalization.
             * 2) Now assocs and attrs are OK. Has inh. parent same interpretation or is there no generalization? Yes - nothing
             *  2a) No - is it old parent? Yes - generalize
             *   2aa) No - Nothing - the generalization does not affect the current PSM class.
             */

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

            command.Report = new CommandReport("Pre-propagation (generalize PIM generalization)");

            //DELETE ATTS AND ASSOCS THAT VIOLATE INTERPRETATION AFTER GEN PIM GEN
            foreach (PSMClass c in classesToCheck)
            {
                //parent association (just check it...), it should not be involved...
                Debug.Assert(c.ParentAssociation == null || c.ParentAssociation.Interpretation == null || c.Interpretation == (c.ParentAssociation.Interpretation as PIMAssociation)
                             .PIMAssociationEnds
                             .Single(e => e != c.ParentAssociation.InterpretedAssociationEnd));

                List <PSMAttribute> attributesLost = c.GetContextPSMAttributes(true).Where
                                                         (a => a.Interpretation != null && (a.Interpretation as PIMAttribute).PIMClass == pimGeneralization.General).ToList();

                List <PSMAssociation> associationsLost = c.GetContextPSMAssociations(true).Where
                                                             (a => a.Interpretation != null && a.InterpretedAssociationEnd.PIMClass == pimGeneralization.General).ToList();

                foreach (PSMAttribute att in attributesLost)
                {
                    if (att.PSMClass != c)
                    {
                        command.Commands.Add(new cmdMovePSMAttribute(Controller)
                        {
                            AttributeGuid = att, ClassGuid = c
                        });
                    }
                    command.Commands.Add(new cmdDeletePSMAttribute(Controller)
                    {
                        AttributeGuid = att
                    });
                }

                foreach (PSMAssociation assoc in associationsLost)
                {
                    if (assoc.Parent != c)
                    {
                        command.Commands.Add(new cmdReconnectPSMAssociation(Controller)
                        {
                            AssociationGuid = assoc, NewParentGuid = c
                        });
                    }
                    command.Commands.Add(new cmdDeletePSMAssociation(Controller)
                    {
                        AssociationGuid = assoc
                    });
                }
            }

            foreach (PSMClass c in psmSpecificClasses)
            {
                if (c.GeneralizationAsSpecific != null && c.GeneralizationAsSpecific.General.Interpretation != c.Interpretation)
                {
                    if (c.GeneralizationAsSpecific.General.Interpretation == oldPIMGeneral)
                    {
                        command.Commands.Add(new acmdGeneralizePSMGeneralization(Controller, c.GeneralizationAsSpecific)
                        {
                            Propagate = false
                        });
                    }
                }
            }

            return(command);
        }
        internal override PropagationMacroCommand PostPropagation()
        {
            ReadOnlyCollection <PSMAssociation> aX1 = Project.TranslateComponentCollection <PSMAssociation>(X1);
            ReadOnlyCollection <PSMAssociation> aX2 = Project.TranslateComponentCollection <PSMAssociation>(X2);
            PSMAssociationMember C1_;
            PIMClass             C1;
            PIMClass             C2;

            if (aX1.Count == 0 || aX2.Count == 0 || aX1.Union(aX2).Count() == 1)
            {
                return(null);
            }
            if (!getAmAndInterpretation(aX1, aX2, out C2, out C1_))
            {
                return(null);
            }
            if (aX1.Any(assoc => assoc.Interpretation == null) && aX2.Any(assoc => assoc.Interpretation == null))
            {
                return(null);
            }
            //Here we assume that C1_ is in fact an interpreted PSMClass. If it was a PSMSchemaClass or uninterpreted class, it would have been filtered above.
            C1 = C1_.Interpretation as PIMClass;

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

            command.Report = new CommandReport("Post-propagation (synchronize PSM association sets)");

            //Twice... X1 => X2, X2 => X1
            for (int i = 0; i < 2; i++)
            {
                if (aX1.All(assoc => assoc.Interpretation != null))
                {
                    IEnumerable <PIMAssociation> interpretations1        = aX1.Select <PSMAssociation, PIMAssociation>(a => a.Interpretation as PIMAssociation);
                    IEnumerable <PIMAssociation> interpretations2        = aX2.Where(a => a.Interpretation != null).Select <PSMAssociation, PIMAssociation>(a => a.Interpretation as PIMAssociation);
                    IEnumerable <PSMAssociation> associationsToPropagate = aX2.Where(a => a.Interpretation == null);
                    List <Guid> newAssociations = new List <Guid>();

                    foreach (PSMAssociation a in associationsToPropagate)
                    {
                        PSMClass C2_ = a.Parent.Interpretation == C1 ? a.Child as PSMClass : a.Parent as PSMClass;

                        Guid pimClassGuid = C2;
                        if (C2_.Interpretation == null)
                        {
                            pimClassGuid = Guid.NewGuid();
                            cmdCreateNewPIMClass c = new cmdCreateNewPIMClass(Controller)
                            {
                                ClassGuid = pimClassGuid
                            };
                            c.Set(C2_.Name, C1.PIMSchema);
                            command.Commands.Add(c);

                            acmdSetInterpretation cmdi = new acmdSetPSMClassInterpretation(Controller, C2_, pimClassGuid);
                            command.Commands.Add(cmdi);
                        }

                        //else - but all C2 should be the same class

                        Guid assocGuid     = Guid.NewGuid();
                        Guid assocEnd1Guid = Guid.NewGuid();
                        Guid assocEnd2Guid = Guid.NewGuid();

                        command.Commands.Add(new acmdNewPIMAssociation(Controller, C1, assocEnd1Guid, pimClassGuid, assocEnd2Guid, C1.PIMSchema)
                        {
                            AssociationGuid = assocGuid
                        });
                        foreach (PIMDiagram d in Project.SingleVersion.PIMDiagrams.Where(d => d.PIMComponents.Contains(C1)))
                        {
                            command.Commands.Add(new acmdAddComponentToDiagram(Controller, assocGuid, d));
                        }

                        command.Commands.Add(new acmdRenameComponent(Controller, assocGuid, a.Name));
                        command.Commands.Add(new acmdUpdatePIMAssociationEndCardinality(Controller, assocEnd2Guid, a.Lower, a.Upper));
                        command.Commands.Add(new acmdSetPSMAssociationInterpretation(Controller, a, assocEnd2Guid, assocGuid));
                        newAssociations.Add(assocGuid);
                    }

                    IEnumerable <PIMAssociation> associations  = C1.GetAssociationsWith(C2);
                    IEnumerable <Guid>           synchroGroup1 = associations.Where(a => interpretations1.Contains(a)).Select <PIMAssociation, Guid>(g => g);
                    IEnumerable <Guid>           synchroGroup2 = associations.Where(a => interpretations2.Contains(a)).Select <PIMAssociation, Guid>(g => g).Union(newAssociations);

                    //We could somehow add PropagateSource here...
                    command.Commands.Add(new acmdSynchroPIMAssociations(Controller)
                    {
                        X1 = synchroGroup1.ToList(), X2 = synchroGroup2.ToList()
                    });
                }
                //Swap the two lists and do it again
                ReadOnlyCollection <PSMAssociation> temp = aX1;
                aX1 = aX2;
                aX2 = temp;
            }
            return(command);
        }
Beispiel #17
0
        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);
        }
        internal override PropagationMacroCommand PostPropagation()
        {
            ReadOnlyCollection <PSMAttribute> aX1 = Project.TranslateComponentCollection <PSMAttribute>(X1);
            ReadOnlyCollection <PSMAttribute> aX2 = Project.TranslateComponentCollection <PSMAttribute>(X2);

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

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

            command.Report = new CommandReport("Post-propagation (synchronize PSM attribute sets)");
            PSMClass psmClass = aX2.First().PSMClass;

            if (aX1.Any(att => att.Interpretation == null) && aX2.Any(att => att.Interpretation == null))
            {
                return(command);
            }

            //Twice... X1 => X2, X2 => X1
            for (int i = 0; i < 2; i++)
            {
                if (aX1.All(att => att.Interpretation != null))
                {
                    PIMClass pimClass = (aX1.First().Interpretation as PIMAttribute).PIMClass;
                    IEnumerable <PIMAttribute> interpretations1      = aX1.Select <PSMAttribute, PIMAttribute>(a => a.Interpretation as PIMAttribute);
                    IEnumerable <PIMAttribute> interpretations2      = aX2.Where(a => a.Interpretation != null).Select <PSMAttribute, PIMAttribute>(a => a.Interpretation as PIMAttribute);
                    IEnumerable <PSMAttribute> attributesToPropagate = aX2.Where(a => a.Interpretation == null);

                    List <Guid> newAttributes = new List <Guid>();
                    foreach (PSMAttribute a in attributesToPropagate)
                    {
                        cmdCreateNewPIMAttribute c = new cmdCreateNewPIMAttribute(Controller);
                        Guid attrGuid = Guid.NewGuid();
                        c.AttributeGuid = attrGuid;
                        c.Set(pimClass, a.AttributeType, a.Name, a.Lower, a.Upper, a.DefaultValue);
                        command.Commands.Add(c);

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

                        newAttributes.Add(attrGuid);
                    }

                    IEnumerable <Guid> synchroGroup1 = pimClass.PIMAttributes.Where(a => interpretations1.Contains(a)).Select <PIMAttribute, Guid>(g => g);
                    IEnumerable <Guid> synchroGroup2 = pimClass.PIMAttributes.Where(a => interpretations2.Contains(a)).Select <PIMAttribute, Guid>(g => g).Union(newAttributes);

                    //We could somehow add PropagateSource here...
                    command.Commands.Add(new acmdSynchroPIMAttributes(Controller)
                    {
                        X1 = synchroGroup1.ToList(), X2 = synchroGroup2.ToList()
                    });
                }
                //Swap the two lists and do it again
                ReadOnlyCollection <PSMAttribute> temp = aX1;
                aX1 = aX2;
                aX2 = temp;
            }
            return(command);
        }
        internal override PropagationMacroCommand PrePropagation()
        {
            PropagationMacroCommand command = new PropagationMacroCommand(Controller);

            command.Report = new CommandReport("Pre-propagation (reconnect PIM association end)");

            PIMAssociationEnd assocEnd    = Project.TranslateComponent <PIMAssociationEnd>(associationEndGuid);
            PIMClass          targetClass = Project.TranslateComponent <PIMClass>(newClassGuid);
            PIMClass          sourceClass = assocEnd.PIMClass;

            IEnumerable <PIMAssociation> pimAssociations         = targetClass.GetAssociationsWith(sourceClass);
            IEnumerable <PSMAssociation> interpretedAssociations = assocEnd.PIMAssociation.GetInterpretedComponents().Cast <PSMAssociation>().Where(a => a.ID != PropagateSource);

            foreach (PSMAssociation psmAssociation in interpretedAssociations)
            {
                if (psmAssociation.NearestInterpretedClass().Interpretation == sourceClass)
                // C1 => C2, C1 (intclass) source, C2 (its descendant) target //I(R')=R^(E2)
                {
                    //C'u
                    PSMClass intclass = psmAssociation.NearestInterpretedClass();

                    //C', it is a PSMClass because psmAssociation has interpretation
                    PSMClass child = psmAssociation.Child as PSMClass;

                    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 association up in PSM
                            found = true;

                            Guid classGuid2 = Guid.NewGuid();
                            Guid assocGuid2 = Guid.NewGuid();

                            command.Commands.Add(new acmdNewPSMClass(Controller, psmAssociation.Schema)
                            {
                                ClassGuid = classGuid2
                            });
                            command.Commands.Add(new acmdRenameComponent(Controller, classGuid2, child.Name));
                            command.Commands.Add(new acmdSetPSMClassInterpretation(Controller, classGuid2, child.Interpretation));
                            command.Commands.Add(new acmdSetRepresentedClass(Controller, classGuid2, child));
                            command.Commands.Add(new acmdNewPSMAssociation(Controller, intclass, classGuid2, psmAssociation.Schema)
                            {
                                AssociationGuid = assocGuid2
                            });
                            command.Commands.Add(new acmdRenameComponent(Controller, assocGuid2, psmAssociation.Interpretation.Name)
                            {
                                Propagate = false
                            });
                            command.Commands.Add(new acmdUpdatePSMAssociationCardinality(Controller, assocGuid2, psmAssociation.Lower, psmAssociation.Upper)
                            {
                                Propagate = false
                            });
                            command.Commands.Add(new acmdSetPSMAssociationInterpretation(Controller, assocGuid2, psmAssociation.InterpretedAssociationEnd, psmAssociation.Interpretation)
                            {
                                ForceExecute = true
                            });

                            if (psmAssociation.Parent != intclass)
                            {
                                command.Commands.Add(new cmdReconnectPSMAssociation(Controller)
                                {
                                    AssociationGuid = psmAssociation, NewParentGuid = intclass, Propagate = false
                                });
                            }

                            acmdSynchroPSMAssociations s = new acmdSynchroPSMAssociations(Controller)
                            {
                                Propagate = false
                            };
                            s.X1.Add(psmAssociation);
                            s.X2.Add(assocGuid2);
                            command.Commands.Add(s);

                            if (psmAssociation.Parent != intclass)
                            {
                                command.Commands.Add(new cmdReconnectPSMAssociation(Controller)
                                {
                                    AssociationGuid = psmAssociation, NewParentGuid = psmAssociation.Parent, Propagate = false
                                });
                            }

                            cmdReconnectPSMAssociation r = new cmdReconnectPSMAssociation(Controller)
                            {
                                Propagate = false
                            };
                            r.Set(assocGuid2, parentAssociation.NearestInterpretedClass());
                            command.Commands.Add(r);
                        }

                        //select nearest interpreted child PSM classes, whose parent association's interpretation is the PIM association through which we are moving the association
                        IEnumerable <PSMClass> children = intclass.InterpretedSubClasses().Where(pc => pc.Interpretation == targetClass && pc.ParentAssociation.Interpretation == association);
                        foreach (PSMClass childClass in children)
                        {
                            found = true;
                            Guid classGuid2 = Guid.NewGuid();
                            Guid assocGuid2 = Guid.NewGuid();

                            command.Commands.Add(new acmdNewPSMClass(Controller, psmAssociation.Schema)
                            {
                                ClassGuid = classGuid2
                            });
                            command.Commands.Add(new acmdRenameComponent(Controller, classGuid2, child.Name)
                            {
                                Propagate = false
                            });
                            command.Commands.Add(new acmdSetPSMClassInterpretation(Controller, classGuid2, child.Interpretation));
                            command.Commands.Add(new acmdSetRepresentedClass(Controller, classGuid2, child));
                            command.Commands.Add(new acmdNewPSMAssociation(Controller, intclass, classGuid2, psmAssociation.Schema)
                            {
                                AssociationGuid = assocGuid2
                            });
                            command.Commands.Add(new acmdRenameComponent(Controller, assocGuid2, psmAssociation.Interpretation.Name)
                            {
                                Propagate = false
                            });
                            command.Commands.Add(new acmdUpdatePSMAssociationCardinality(Controller, assocGuid2, psmAssociation.Lower, psmAssociation.Upper)
                            {
                                Propagate = false
                            });
                            command.Commands.Add(new acmdSetPSMAssociationInterpretation(Controller, assocGuid2, psmAssociation.InterpretedAssociationEnd, psmAssociation.Interpretation)
                            {
                                ForceExecute = true
                            });

                            if (psmAssociation.Parent != intclass)
                            {
                                command.Commands.Add(new cmdReconnectPSMAssociation(Controller)
                                {
                                    AssociationGuid = psmAssociation, NewParentGuid = intclass, Propagate = false
                                });
                            }

                            acmdSynchroPSMAssociations s = new acmdSynchroPSMAssociations(Controller)
                            {
                                Propagate = false
                            };
                            s.X1.Add(psmAssociation);
                            s.X2.Add(assocGuid2);
                            command.Commands.Add(s);

                            if (psmAssociation.Parent != intclass)
                            {
                                command.Commands.Add(new cmdReconnectPSMAssociation(Controller)
                                {
                                    AssociationGuid = psmAssociation, NewParentGuid = psmAssociation.Parent, Propagate = false
                                });
                            }

                            cmdReconnectPSMAssociation r = new cmdReconnectPSMAssociation(Controller)
                            {
                                Propagate = false
                            };
                            r.Set(assocGuid2, childClass);
                            command.Commands.Add(r);
                        }

                        if (!found)
                        {
                            Guid classGuid = Guid.NewGuid();
                            Guid assocGuid = Guid.NewGuid();

                            command.Commands.Add(new acmdNewPSMClass(Controller, psmAssociation.Schema)
                            {
                                ClassGuid = classGuid
                            });
                            command.Commands.Add(new acmdRenameComponent(Controller, classGuid, targetClass.Name)
                            {
                                Propagate = false
                            });
                            command.Commands.Add(new acmdSetPSMClassInterpretation(Controller, classGuid, targetClass));
                            command.Commands.Add(new acmdNewPSMAssociation(Controller, intclass, classGuid, psmAssociation.Schema)
                            {
                                AssociationGuid = assocGuid
                            });
                            command.Commands.Add(new acmdRenameComponent(Controller, assocGuid, association.Name)
                            {
                                Propagate = false
                            });
                            PIMAssociationEnd e = targetClass.PIMAssociationEnds.Single <PIMAssociationEnd>(aend => aend.PIMAssociation == association);
                            command.Commands.Add(new acmdUpdatePSMAssociationCardinality(Controller, assocGuid, e.Lower, e.Upper)
                            {
                                Propagate = false
                            });
                            command.Commands.Add(new acmdSetPSMAssociationInterpretation(Controller, assocGuid, e, association)
                            {
                                ForceExecute = true
                            });

                            Guid classGuid2 = Guid.NewGuid();
                            Guid assocGuid2 = Guid.NewGuid();

                            command.Commands.Add(new acmdNewPSMClass(Controller, psmAssociation.Schema)
                            {
                                ClassGuid = classGuid2
                            });
                            command.Commands.Add(new acmdRenameComponent(Controller, classGuid2, child.Name)
                            {
                                Propagate = false
                            });
                            command.Commands.Add(new acmdSetPSMClassInterpretation(Controller, classGuid2, child.Interpretation));
                            command.Commands.Add(new acmdSetRepresentedClass(Controller, classGuid2, child));
                            command.Commands.Add(new acmdNewPSMAssociation(Controller, intclass, classGuid2, psmAssociation.Schema)
                            {
                                AssociationGuid = assocGuid2
                            });
                            command.Commands.Add(new acmdRenameComponent(Controller, assocGuid2, psmAssociation.Interpretation.Name)
                            {
                                Propagate = false
                            });
                            command.Commands.Add(new acmdUpdatePSMAssociationCardinality(Controller, assocGuid2, psmAssociation.Lower, psmAssociation.Upper)
                            {
                                Propagate = false
                            });
                            command.Commands.Add(new acmdSetPSMAssociationInterpretation(Controller, assocGuid2, psmAssociation.InterpretedAssociationEnd, psmAssociation.Interpretation)
                            {
                                ForceExecute = true
                            });

                            if (psmAssociation.Parent != intclass)
                            {
                                command.Commands.Add(new cmdReconnectPSMAssociation(Controller)
                                {
                                    AssociationGuid = psmAssociation, NewParentGuid = intclass, Propagate = false
                                });
                            }

                            acmdSynchroPSMAssociations s = new acmdSynchroPSMAssociations(Controller)
                            {
                                Propagate = false
                            };
                            s.X1.Add(psmAssociation);
                            s.X2.Add(assocGuid2);
                            command.Commands.Add(s);

                            if (psmAssociation.Parent != intclass)
                            {
                                command.Commands.Add(new cmdReconnectPSMAssociation(Controller)
                                {
                                    AssociationGuid = psmAssociation, NewParentGuid = psmAssociation.Parent, Propagate = false
                                });
                            }

                            cmdReconnectPSMAssociation r = new cmdReconnectPSMAssociation(Controller)
                            {
                                Propagate = false
                            };
                            r.Set(assocGuid2, classGuid);
                            command.Commands.Add(r);
                        }
                    }
                    //delete association
                    cmdDeletePSMAssociation d = new cmdDeletePSMAssociation(Controller)
                    {
                        Propagate = false
                    };
                    d.Set(psmAssociation);
                    command.Commands.Add(d);
                }
                else
                // C1 => C2, C2 source, C1 target
                {
                    //C'
                    PSMClass intclass = psmAssociation.NearestInterpretedClass();

                    //C'u, it is a PSMClass because psmAssociation has interpretation
                    PSMClass child = psmAssociation.Child as PSMClass;

                    Debug.Assert(child.Interpretation == sourceClass, "Child != sourceclass");

                    foreach (PIMAssociation association in pimAssociations)
                    {
                        //The case that C'v would be an ancestor of intclass does not apply here

                        //select nearest interpreted child PSM classes, whose parent association's interpretation is the PIM association through which we are moving the association
                        Dictionary <Guid, Guid> children = new Dictionary <Guid, Guid>();
                        foreach (PSMClass ch in intclass.InterpretedSubClasses().Where(pc => pc.Interpretation == sourceClass && pc.ParentAssociation.Interpretation == association))
                        {
                            children.Add(ch, ch.ParentAssociation);
                        }
                        if (children.Count() == 0)
                        {
                            Guid classGuid = Guid.NewGuid();
                            Guid assocGuid = Guid.NewGuid();

                            command.Commands.Add(new acmdNewPSMClass(Controller, psmAssociation.Schema)
                            {
                                ClassGuid = classGuid
                            });
                            command.Commands.Add(new acmdRenameComponent(Controller, classGuid, targetClass.Name)
                            {
                                Propagate = false
                            });
                            command.Commands.Add(new acmdSetPSMClassInterpretation(Controller, classGuid, targetClass));
                            command.Commands.Add(new acmdNewPSMAssociation(Controller, psmAssociation.Child, classGuid, psmAssociation.Schema)
                            {
                                AssociationGuid = assocGuid
                            });
                            command.Commands.Add(new acmdRenameComponent(Controller, assocGuid, association.Name)
                            {
                                Propagate = false
                            });
                            PIMAssociationEnd e = targetClass.PIMAssociationEnds.Single(aend => aend.PIMAssociation == association);
                            command.Commands.Add(new acmdUpdatePSMAssociationCardinality(Controller, assocGuid, e.Lower, e.Upper)
                            {
                                Propagate = false
                            });
                            command.Commands.Add(new acmdSetPSMAssociationInterpretation(Controller, assocGuid, e, association)
                            {
                                ForceExecute = true
                            });
                            children.Add(classGuid, assocGuid);
                        }

                        foreach (KeyValuePair <Guid, Guid> p in children)
                        {
                            Guid classGuid = Guid.NewGuid();
                            Guid assocGuid = Guid.NewGuid();

                            //C'_
                            command.Commands.Add(new acmdNewPSMClass(Controller, psmAssociation.Schema)
                            {
                                ClassGuid = classGuid
                            });
                            command.Commands.Add(new acmdRenameComponent(Controller, classGuid, intclass.Name)
                            {
                                Propagate = false
                            });
                            command.Commands.Add(new acmdSetPSMClassInterpretation(Controller, classGuid, intclass.Interpretation));
                            //command.Commands.Add(new acmdSetRepresentedClass(Controller, classGuid, intclass));
                            //R'_
                            command.Commands.Add(new acmdNewPSMAssociation(Controller, child, classGuid, psmAssociation.Schema)
                            {
                                AssociationGuid = assocGuid
                            });
                            command.Commands.Add(new acmdRenameComponent(Controller, assocGuid, psmAssociation.Interpretation.Name)
                            {
                                Propagate = false
                            });
                            PIMAssociationEnd e1 = (psmAssociation.Interpretation as PIMAssociation).PIMAssociationEnds.Single(aend => aend.PIMClass == intclass.Interpretation);
                            command.Commands.Add(new acmdUpdatePSMAssociationCardinality(Controller, assocGuid, e1.Lower, e1.Upper)
                            {
                                Propagate = false
                            });
                            command.Commands.Add(new acmdSetPSMAssociationInterpretation(Controller, assocGuid, e1, psmAssociation.Interpretation)
                            {
                                ForceExecute = true
                            });
                            acmdSynchroPSMAssociations s = new acmdSynchroPSMAssociations(Controller)
                            {
                                Propagate = false, ForceExecute = true
                            };
                            s.X1.Add(psmAssociation);
                            s.X2.Add(assocGuid);
                            command.Commands.Add(s);

                            cmdReconnectPSMAssociation r = new cmdReconnectPSMAssociation(Controller)
                            {
                                Propagate = false
                            };
                            r.Set(assocGuid, p.Key);
                            command.Commands.Add(r);

                            Guid classGuid3 = Guid.NewGuid();
                            Guid assocGuid3 = Guid.NewGuid();

                            //Cu'^_
                            command.Commands.Add(new acmdNewPSMClass(Controller, psmAssociation.Schema)
                            {
                                ClassGuid = classGuid3
                            });
                            command.Commands.Add(new acmdRenameComponent(Controller, classGuid3, child.Name)
                            {
                                Propagate = false
                            });
                            command.Commands.Add(new acmdSetPSMClassInterpretation(Controller, classGuid3, child.Interpretation));
                            command.Commands.Add(new acmdSetRepresentedClass(Controller, classGuid3, child)
                            {
                                Propagate = false
                            });

                            //Rx'^_
                            command.Commands.Add(new acmdNewPSMAssociation(Controller, p.Key, classGuid3, psmAssociation.PSMSchema)
                            {
                                AssociationGuid = assocGuid3
                            });
                            command.Commands.Add(new acmdRenameComponent(Controller, assocGuid3, association.Name)
                            {
                                Propagate = false
                            });
                            PIMAssociationEnd e2 = association.PIMAssociationEnds.Single(aend => aend.PIMClass == sourceClass);
                            command.Commands.Add(new acmdUpdatePSMAssociationCardinality(Controller, assocGuid3, e2.Lower, e2.Upper)
                            {
                                Propagate = false
                            });
                            command.Commands.Add(new acmdSetPSMAssociationInterpretation(Controller, assocGuid3, e2, association)
                            {
                                ForceExecute = true
                            });

                            acmdSynchroPSMAssociations s2 = new acmdSynchroPSMAssociations(Controller)
                            {
                                Propagate = false
                            };
                            s2.X1.Add(p.Value);
                            s2.X2.Add(assocGuid3);
                            command.Commands.Add(s2);

                            cmdDeletePSMAssociation d0 = new cmdDeletePSMAssociation(Controller)
                            {
                                Propagate = false
                            };
                            d0.Set(p.Value);
                            command.Commands.Add(d0);

                            //R'^_
                            Guid assocGuid4 = Guid.NewGuid();
                            command.Commands.Add(new acmdNewPSMAssociation(Controller, psmAssociation.Parent, p.Key, psmAssociation.PSMSchema)
                            {
                                AssociationGuid = assocGuid4
                            });
                            command.Commands.Add(new acmdRenameComponent(Controller, assocGuid4, psmAssociation.Interpretation.Name)
                            {
                                Propagate = false
                            });
                            command.Commands.Add(new acmdUpdatePSMAssociationCardinality(Controller, assocGuid4, assocEnd.Lower, assocEnd.Upper)
                            {
                                Propagate = false
                            });
                            command.Commands.Add(new acmdSetPSMAssociationInterpretation(Controller, assocGuid4, assocEnd, psmAssociation.Interpretation)
                            {
                                ForceExecute = true
                            });

                            acmdSynchroPSMAssociations s3 = new acmdSynchroPSMAssociations(Controller)
                            {
                                Propagate = false
                            };
                            s3.X1.Add(assocGuid);
                            s3.X2.Add(assocGuid4);
                            command.Commands.Add(s3);

                            cmdDeletePSMAssociation d2 = new cmdDeletePSMAssociation(Controller)
                            {
                                Propagate = false
                            };
                            d2.Set(assocGuid);
                            command.Commands.Add(d2);

                            cmdDeleteRootPSMClass d3 = new cmdDeleteRootPSMClass(Controller)
                            {
                                Propagate = false
                            };
                            d3.Set(classGuid);
                            command.Commands.Add(d3);
                        }
                    }
                    //delete association
                    cmdDeletePSMAssociation d = new cmdDeletePSMAssociation(Controller)
                    {
                        Propagate = false
                    };
                    d.Set(psmAssociation);
                    command.Commands.Add(d);
                }
            }

            command.CheckFirstOnlyInCanExecute = true;
            return(command);
        }
        internal override PropagationMacroCommand PrePropagation()
        {
            PIMAssociationEnd pimAssociationEnd = Project.TranslateComponent <PIMAssociationEnd>(associationEndGuid);
            PIMClass          oldPIMClass       = pimAssociationEnd.PIMClass;
            PIMClass          newPIMClass       = oldPIMClass.GeneralizationAsSpecific.General;

            //TODO: what about psm associations in the other direction? Create inheritance?
            IEnumerable <PSMAssociation> psmAssociations = pimAssociationEnd.PIMAssociation.GetInterpretedComponents().Cast <PSMAssociation>();
            List <PSMAssociation>        psmAssociationsNormalDirection   = psmAssociations.Where(a => a.InterpretedAssociationEnd != pimAssociationEnd).ToList();
            List <PSMAssociation>        psmAssociationsOppositeDirection = psmAssociations.Where(a => a.InterpretedAssociationEnd == pimAssociationEnd).ToList();

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

            command.Report = new CommandReport("Pre-propagation (generalize PIM association end)");

            foreach (PSMAssociation a in psmAssociationsNormalDirection)
            {
                IEnumerable <PSMClass> generals = a.Parent.NearestInterpretedClass().GetGeneralClasses();
                if (generals.Any(c => c.Interpretation == newPIMClass))
                {
                    if (a.Parent.Interpretation == null)
                    {
                        //classa neinterpret, mozna i s impl.inheritance
                        command.Commands.Add(new cmdReconnectPSMAssociation(Controller)
                        {
                            AssociationGuid = a, NewParentGuid = a.Parent.NearestInterpretedClass()
                        });
                    }

                    //whether the class uses implicit inheritance or not (a.PSMClass.Interpretation == oldPIMClass) we move it to the PSMClass, whose interpretation is newPIMClass
                    command.Commands.Add(new cmdGeneralizePSMAssociation(Controller)
                    {
                        AssociationGuid = a, PSMClassGuid = generals.First(c => c.Interpretation == newPIMClass)
                    });
                }
            }

            foreach (PSMAssociation a in psmAssociationsOppositeDirection)
            {
                Guid newPSMClassGuid       = Guid.NewGuid();
                Guid newPSMAssociationGuid = Guid.NewGuid();

                command.Commands.Add(new acmdNewPSMClass(Controller, a.PSMSchema)
                {
                    ClassGuid = newPSMClassGuid
                });
                command.Commands.Add(new acmdRenameComponent(Controller, newPSMClassGuid, newPIMClass.Name));
                command.Commands.Add(new acmdSetPSMClassInterpretation(Controller, newPSMClassGuid, newPIMClass));
                command.Commands.Add(new acmdNewPSMAssociation(Controller, a.Parent, newPSMClassGuid, a.PSMSchema)
                {
                    AssociationGuid = newPSMAssociationGuid
                });
                command.Commands.Add(new acmdSetPSMAssociationInterpretation(Controller, newPSMAssociationGuid, a.InterpretedAssociationEnd, a.Interpretation)
                {
                    ForceExecute = true
                });

                command.Commands.Add(new cmdUpdatePSMAssociation(Controller)
                {
                    AssociationGuid = newPSMAssociationGuid, Name = a.Name, Lower = a.Lower, Upper = a.Upper
                });
                command.Commands.Add(new cmdDeletePSMAssociation(Controller)
                {
                    AssociationGuid = a
                });
                if ((a.Child as PSMClass).GeneralizationAsSpecific != null)
                {
                    command.Commands.Add(new acmdNewPSMGeneralization(Controller, (a.Child as PSMClass).GeneralizationAsSpecific.General, newPSMClassGuid, a.PSMSchema));
                    command.Commands.Add(new acmdDeletePSMGeneralization(Controller, (a.Child as PSMClass).GeneralizationAsSpecific));
                }
                command.Commands.Add(new acmdNewPSMGeneralization(Controller, newPSMClassGuid, a.Child, a.PSMSchema));
            }

            return(command);
        }
Beispiel #21
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);
        }
Beispiel #22
0
        internal override PropagationMacroCommand PostPropagation()
        {
            PSMAssociation       psmAssociation = Project.TranslateComponent <PSMAssociation>(associationGuid);
            PSMAssociationMember source         = Project.TranslateComponent <PSMAssociationMember>(oldParentGuid);
            PSMAssociationMember target         = Project.TranslateComponent <PSMAssociationMember>(newParentGuid);

            PSMClass oldIntContext = (source is PSMClass && (source as PSMClass).Interpretation != null)? (source as PSMClass) : source.NearestInterpretedParentClass();
            PSMClass newIntContext = (target is PSMClass && (target as PSMClass).Interpretation != null) ? (target as PSMClass) : target.NearestInterpretedParentClass();

            if (oldIntContext == null)
            {
                return(null);
            }
            if (newIntContext != null && oldIntContext.Interpretation == newIntContext.Interpretation)
            {
                return(null);
            }

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

            command.Report = new CommandReport("Post-propagation (reconnect parent PSM association end)");

            if (newIntContext == null)
            {
                foreach (PSMAttribute a in psmAssociation.Child.UnInterpretedSubClasses(true)
                         .SelectMany <PSMClass, PSMAttribute>(c => c.PSMAttributes)
                         .Where(a => a.Interpretation != null))
                {
                    command.Commands.Add(new acmdSetPSMAttributeInterpretation(Controller, a, Guid.Empty));
                }
                foreach (PSMAssociation a in psmAssociation.Child.UnInterpretedSubClasses(true)
                         .SelectMany <PSMClass, PSMAssociation>(c => c.ChildPSMAssociations)
                         .Where(a => a.Interpretation != null))
                {
                    command.Commands.Add(new acmdSetPSMAssociationInterpretation(Controller, a, Guid.Empty, Guid.Empty));
                }
            }
            if (psmAssociation.Interpretation == null)
            {
                foreach (PSMAttribute a in psmAssociation.Child.UnInterpretedSubClasses(true)
                         .SelectMany <PSMClass, PSMAttribute>(c => c.PSMAttributes)
                         .Where(a => a.Interpretation != null))
                {
                    command.Commands.Add(new acmdMovePIMAttribute(Controller, a.Interpretation, newIntContext.Interpretation)
                    {
                        PropagateSource = a
                    });
                }
                foreach (PSMAssociation a in psmAssociation.Child.UnInterpretedSubClasses(true)
                         .SelectMany <PSMClass, PSMAssociation>(c => c.ChildPSMAssociations)
                         .Where(a => a.Interpretation != null))
                {
                    PIMAssociationEnd e = (a.Interpretation as PIMAssociation).PIMAssociationEnds.First(ae => ae.PIMClass == oldIntContext.Interpretation);
                    command.Commands.Add(new acmdMoveAssociationEnd(Controller, e, newIntContext.Interpretation)
                    {
                        PropagateSource = a
                    });
                }
            }
            else
            {
                if (newIntContext == null)
                {
                    command.Commands.Add(new acmdSetPSMAssociationInterpretation(Controller, psmAssociation, Guid.Empty, Guid.Empty));
                }
                else
                {
                    PIMAssociationEnd e = (psmAssociation.Interpretation as PIMAssociation).PIMAssociationEnds.First(ae => ae.PIMClass == oldIntContext.Interpretation);
                    command.Commands.Add(new acmdMoveAssociationEnd(Controller, e, newIntContext.Interpretation)
                    {
                        PropagateSource = psmAssociation
                    });
                }
            }

            return(command);
        }