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 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); }