public static uint GetLowerMultiplicityOfContentElement(PSMElement node) { { PSMAssociationChild c = node as PSMAssociationChild; if (c != null) { if (c.ParentUnion != null) { return(1); } if (c.ParentAssociation != null) { Debug.Assert(c.ParentAssociation.Lower != null); return(c.ParentAssociation.Lower.Value); } else { return(1); // root class } } } if (node is PSMContentContainer) { return(1); } if (node is PSMAttribute) { Debug.Assert(((PSMAttribute)node).Lower != null); return(((PSMAttribute)node).Lower.Value); } // should never get here... throw new ArgumentException(); }
private void TranslateClassUnion(PSMClassUnion classUnion, DataGeneratorContext context) { PSMAssociationChild selectedPath = classUnion.Components.ChooseOneRandomly(); TranslateComments(classUnion, context); TranslateAssociationChild(selectedPath, context); }
protected override void TranslateAssociationChild(PSMAssociationChild associationChild, DataGeneratorContext context) { int count = 1; if (associationChild.ParentAssociation != null) { count = ChooseMultiplicity(associationChild.ParentAssociation); } for (int i = 0; i < count; i++) { if (associationChild is PSMClass) { PSMClass psmClass = (PSMClass)associationChild; if (!psmClass.HasElementLabel) { if (GenerateComments) { XmlComment xmlComment = context.Document.CreateComment(string.Format("Content group {0} {1}", psmClass.Name, i)); context.CurrentElement.AppendChild(xmlComment); } } TranslateClass(psmClass, context); } else { TranslateClassUnion((PSMClassUnion)associationChild, context); } } }
public static int ComponentIndex(this PSMAssociationChild associationChild) { if (associationChild.ParentUnion == null) { return(-1); } return(associationChild.ParentUnion.Components.IndexOf(associationChild)); }
protected override void TranslateAssociationChild(PSMAssociationChild associationChild, ChangesDetectorContext context) { if (associationChild is PSMClass) { TranslateClass((PSMClass)associationChild, context); } else { TranslateClassUnion((PSMClassUnion)associationChild, context); } }
internal static Element GetComponentAndCollection(ISelectable selectedItem, PSMDiagram diagram, out IList <PSMSuperordinateComponent> rootsCollection, out IList <PSMAssociationChild> associationChildCollection, out IList <PSMSubordinateComponent> subordinateComponentCollection) { rootsCollection = null; associationChildCollection = null; subordinateComponentCollection = null; if (selectedItem is IPSMSubordinateComponentRepresentant) { PSMSubordinateComponent subordinateComponent = ((IPSMSubordinateComponentRepresentant)selectedItem).ModelSubordinateComponent; if (subordinateComponent.Parent != null) { subordinateComponentCollection = subordinateComponent.Parent.Components; return(subordinateComponent); } } PSMAssociationChild associationChild = null; if (selectedItem is PSM_Class) { associationChild = ((PSM_Class)selectedItem).PSMClass; PSMClass psmClass = (PSMClass)associationChild; if (diagram.Roots.Contains(psmClass)) { rootsCollection = diagram.Roots; return(psmClass); } } if (selectedItem is PSM_ClassUnion) { associationChild = ((PSM_ClassUnion)selectedItem).ClassUnion; } if (associationChild != null) { if (associationChild.ParentAssociation != null && associationChild.ParentAssociation.Parent != null) { subordinateComponentCollection = associationChild.ParentAssociation.Parent.Components; return(associationChild.ParentAssociation); } else if (associationChild.ParentUnion != null) { associationChildCollection = associationChild.ParentUnion.Components; return(associationChild); } } return(null); }
/// <summary> /// Checks whether <paramref name="items"/> are all children of a common parent, that is a <see cref="PSMSuperordinateComponent"/> and all /// items are <see cref="PSMSubordinateComponent"/>s. /// </summary> /// <param name="items">list of selectable items</param> /// <param name="parent">common parent for <paramref name="items"/> (if found)</param> /// <param name="components"><see cref="PSMSubordinateComponent"/>s that are represented by <paramref name="items"/></param> /// <returns>true if <paramref name="items"/> are all components of a common parent, false otherwise</returns> public static bool AreComponentsOfCommonParent(IEnumerable<IModelElementRepresentant> items, out PSMSuperordinateComponent parent, out IList<PSMSubordinateComponent> components) { parent = null; List<PSMSubordinateComponent> result = new List<PSMSubordinateComponent>(); components = null; foreach (IModelElementRepresentant item in items) { if (!(item is IPSMSubordinateComponentRepresentant) && !(item is Controls.PSM_Class)) { return false; } else { PSMSubordinateComponent component = null; if (item is Controls.PSM_Class) { PSMAssociationChild associationChild = (item as Controls.PSM_Class).ClassController.Class; if (associationChild != null && associationChild.ParentAssociation != null) component = associationChild.ParentAssociation; } else { component = ((IPSMSubordinateComponentRepresentant)item).ModelSubordinateComponent; } if (component == null) { return false; } PSMSuperordinateComponent itemParent = component.Parent; if (parent == null) parent = itemParent; else { if (parent != itemParent) { return false; } } if (!result.Contains(component)) result.Add(component); } } components = result; return true; }
public static IList <EvolutionChange> Detect(Version v1, Version v2, PSMAssociationChild associationChild) { List <EvolutionChange> result = new List <EvolutionChange>(); PSMAssociationChild associationChildOldVersion = (PSMAssociationChild)associationChild.GetInVersion(v2); if (associationChild.ParentUnion != null && associationChildOldVersion.ParentUnion != null && associationChild.ParentUnion.GetInVersion(v1) == associationChildOldVersion.ParentUnion && associationChild.ComponentIndex() != associationChildOldVersion.ComponentIndex()) { AssociationChildClassUnionIndexChange change = new AssociationChildClassUnionIndexChange(associationChild) { OldVersion = v1, NewVersion = v2 }; result.Add(change); } return(result); }
public static IList <EvolutionChange> Detect(Version v1, Version v2, PSMAssociationChild associationChild) { List <EvolutionChange> result = new List <EvolutionChange>(); PSMAssociationChild associationChildOldVersion = (PSMAssociationChild)associationChild.GetInVersion(v2); Debug.Assert(associationChildOldVersion != null); if ((associationChild.ParentAssociation != null || (associationChild.ParentAssociation == null && associationChild.ParentUnion == null)) && associationChildOldVersion.ParentUnion != null) { result.Add(new AssociationChildReturnedFromUnionChange(associationChild) { OldVersion = v1, NewVersion = v2 }); } return(result); }
public static Element GetParentOfElement(Element element) { if (element is PSMSubordinateComponent) { return(((PSMSubordinateComponent)element).Parent); } PSMAssociationChild associationChild = element as PSMAssociationChild; if (associationChild != null && associationChild.ParentAssociation != null) { return(associationChild.ParentAssociation); } if (associationChild != null && associationChild.ParentUnion != null) { return(associationChild.ParentUnion); } PSMClass psmClass = element as PSMClass; if (psmClass != null) { if (psmClass.ParentUnion != null) { return(psmClass.ParentUnion); } if (psmClass.Generalizations.Count() > 0) { return(psmClass.Generalizations.First()); } } Generalization generalization = element as Generalization; if (generalization != null) { return(generalization.General); } return(null); }
/// <summary> /// Sets this command for execution /// </summary> /// <param name="Parent">Parent element of the association</param> /// <param name="Child">Child element of the association</param> /// <param name="createdAssociation">Holder that will contain the newly created association - can be null</param> /// <param name="index">Index at which to insert the association into parents components (null = default)</param> public void Set(PSMSuperordinateComponent Parent, PSMAssociationChild Child, ElementHolder <PSMAssociation> createdAssociation, int?index) { ParentHolder = new ElementHolder <PSMSuperordinateComponent>() { Element = Parent }; ChildHolder = new ElementHolder <PSMAssociationChild>() { Element = Child }; Index = index; if (createdAssociation == null) { CreatedAssociation = new ElementHolder <PSMAssociation>(); } else { CreatedAssociation = createdAssociation; } }
/// <summary> /// Gets the root of the PSM tree that contains the given item (if any). /// </summary> /// <param name="item">Reference to the item being searched</param> /// <returns>Reference to the root of the tree that contains item or null if no such exists</returns> public static PSMSuperordinateComponent GetRootOf(object item) { if (item is PSMSubordinateComponent) { PSMSubordinateComponent comp = item as PSMSubordinateComponent; if (comp.Parent == null) { return(item as PSMSuperordinateComponent); } else { return(GetRootOf(comp.Parent)); } } if (item is PSMAssociationChild) { PSMAssociationChild child = item as PSMAssociationChild; if (child.ParentAssociation != null) { return(GetRootOf(child.ParentAssociation)); } if (child.ParentUnion != null) { return(GetRootOf(child.ParentUnion)); } return(item as PSMSuperordinateComponent); } if (item is PSMAttribute) { return(GetRootOf((item as PSMAttribute).Class)); } return(null); }
/// <summary> /// Returns PSM associations between an two nodes (they must be part of a path in the PSM tree). /// (assocations are returned in root to leafes order. /// </summary> /// <param name="ancestor">ancestor node</param> /// <param name="descendant">descendant node</param> public static IEnumerable <PSMAssociation> GetAssociationsBetweenNodes(PSMElement ancestor, PSMElement descendant) { List <PSMAssociation> associations = new List <PSMAssociation>(); PSMTreeIterator it = new PSMTreeIterator(descendant); while (it.CurrentNode != ancestor) { { PSMAssociationChild associationChild = it.CurrentNode as PSMAssociationChild; if (associationChild != null && associationChild.ParentAssociation != null) { associations.Insert(0, associationChild.ParentAssociation); } } if (!it.CanGoToParent()) { throw new ArgumentException("Nodes are not valid ancestor-descendant pair"); } it.GoToParent(); } return(associations); }
public AssociationChildMovedToUnionChange(PSMAssociationChild associationChild) : base(associationChild) { }
public AssociationChildClassUnionIndexChange(PSMAssociationChild associationChild) : base(associationChild) { }
private EvoX.Model.PSM.PSMAssociation CreateLeadingAssociationForUnionComponents(PSMAssociationChild associationChild, PSMAssociationMember childAssociationMember) { PSMAssociationMember parent = (PSMAssociationMember)translatedElements[associationChild.ParentUnion]; EvoX.Model.PSM.PSMAssociation psmAssociation = new EvoX.Model.PSM.PSMAssociation( evoxProject, parent, childAssociationMember, psmSchema); PSMClass psmClass = associationChild as PSMClass; if (psmClass != null && psmClass.HasElementLabel) { psmAssociation.Name = psmClass.ElementName; } else { psmAssociation.Name = null; } associationOrder[psmAssociation] = associationChild.ComponentIndex(); return(psmAssociation); }
/// <summary> /// Translates the association child. /// </summary> /// <remarks> /// The <see cref="PSMAssociationChild"/> can be /// either <see cref="PSMClass"/> or <see cref="PSMClassUnion"/>. If the child is /// <see cref="PSMClass"/>, <see cref="TranslateClass"/> could be used. /// </remarks> /// <param name="associationChild">The association child.</param> /// <param name="context">The translation context.</param> protected virtual void TranslateAssociationChild(PSMAssociationChild associationChild, Context context) { }
/// <summary> /// Returns the elements of subtrees of roots in an order in which they can be /// added to a PSM diagram. /// </summary> /// <param name="roots">The roots.</param> /// <param name="ordered">The ordered.</param> /// <param name="addMetElements">if set to <c>true</c> method adds any elements met /// during the execution (subelements of the elements in <paramref name="roots"/>).</param> /// <returns></returns> public static bool ReturnElementsInPSMOrder(IEnumerable <Element> roots, out IList <Element> ordered, bool addMetElements) { /* PSM diagram elements must be loaded from root to leaves, * following code is BFS implementation */ Queue <Element> elementsToDo = new Queue <Element>(); List <Element> alreadyProcessed = new List <Element>(); List <Element> delayedElements = new List <Element>(); List <Element> _roots = roots.ToList(); _roots.Sort(CompareByRootPositionsDesc); foreach (Element root in _roots) { elementsToDo.Enqueue(root); } List <Element> needed = new List <Element>(); while (elementsToDo.Count > 0) { Element node = elementsToDo.Dequeue(); if (!alreadyProcessed.Contains(node)) { if (node is PSMSuperordinateComponent) { foreach (PSMSubordinateComponent component in ((PSMSuperordinateComponent)node).Components.Where(i => !alreadyProcessed.Contains(i) && !elementsToDo.Contains(i))) { elementsToDo.Enqueue(component); } } if (node is PSMClassUnion) { foreach (PSMAssociationChild component in ((PSMClassUnion)node).Components.Where(i => !alreadyProcessed.Contains(i) && !elementsToDo.Contains(i))) { elementsToDo.Enqueue(component); } } PSMClass psmClass = node as PSMClass; if (psmClass != null) { foreach (Generalization specification in psmClass.Specifications.Where(i => !alreadyProcessed.Contains(i) && !elementsToDo.Contains(i))) { elementsToDo.Enqueue(specification); } } PSMAssociation a = node as PSMAssociation; Generalization g = node as Generalization; PSMSubordinateComponent sub = node as PSMSubordinateComponent; PSMAssociationChild child = node as PSMAssociationChild; /* * association can be loaded only after the child is already loaded too. * otherwise it is postponed, * * generalizations can be loaded after both * general and specific class are loaded * * component can be loaded after parent is loaded */ needed.Clear(); if (a != null) { if (elementsToDo.Contains(a.Parent)) { needed.Add(a.Parent); } needed.Add(a.Child); } if (g != null) { if (elementsToDo.Contains(g.General)) { needed.Add(g.General); } needed.Add(g.Specific); } if (sub != null) { if (elementsToDo.Contains(sub.Parent)) { needed.Add(sub.Parent); } //IList<PSMSubordinateComponent> components = sub.Parent.Components; //int index = components.IndexOf(sub); //needed.AddRange(components.Where(component => components.IndexOf(component) < index).Cast<Element>()); } if (child != null && child.ParentUnion != null) { if (elementsToDo.Contains(child.ParentUnion)) { needed.Add(child.ParentUnion); } //IList<PSMAssociationChild> components = child.ParentUnion.Components; //int index = components.IndexOf(child); //needed.AddRange(components.Where(component => components.IndexOf(component) < index).Cast<Element>()); } //if (child != null && child.ParentAssociation != null) //{ // if (elementsToDo.Contains(child.ParentAssociation)) // needed.Add(child.ParentAssociation); // //IList<PSMAssociationChild> components = child.ParentAssociation.Components; // //int index = components.IndexOf(child); // //needed.AddRange(components.Where(component => components.IndexOf(component) < index).Cast<Element>()); //} if (needed.All(alreadyProcessed.Contains)) { if (!alreadyProcessed.Contains(node)) { alreadyProcessed.Add(node); } } else { if (delayedElements.Contains(node)) { /* * association/generalization was already delayed once, * now it is clear that it will never be loaded correctly, * algortithm is stopped to avoid infinite cycle. */ ordered = null; return(false); } else { /* wait untill the association child is loaded */ foreach (Element element in needed.Where(i => !alreadyProcessed.Contains(i) && !elementsToDo.Contains(i))) { elementsToDo.Enqueue(element); } elementsToDo.Enqueue(node); delayedElements.Add(node); } } } } if (!addMetElements) { alreadyProcessed.RemoveAll(element => !roots.Contains(element)); } ordered = alreadyProcessed; return(true); }
public AssociationChildReturnedFromUnionChange(PSMAssociationChild associationChild) : base(associationChild) { }
protected AssociationChildChange(PSMAssociationChild associationChild) { Element = associationChild; }
internal override void CommandOperation() { // The context of each new association includes the entire context of the previous // created association + Parent path of the nesting join of the previous association // Therefore we progressively cumulate it in this collection. List <PIMPath> context = new List <PIMPath>(); for (int i = 0; i < Associations.Count; ++i) { // Get a reference to Ai and Ai+1 if defined. PSMAssociation association = Associations[i]; PSMAssociation nextAssociation = null; if (i < Associations.Count - 1) { nextAssociation = Associations[i + 1]; } // Remove Ai from the model DeleteFromPSMDiagramCommand cmdDel = DeleteFromPSMDiagramCommandFactory.Factory().Create(Controller) as DeleteFromPSMDiagramCommand; cmdDel.DeletedElements = new List <Element>(); cmdDel.DeletedElements.Add(association); cmdDel.CommandOperation(); deletedAssociations.Add(cmdDel); // Create a new PSM association A'i NewPSMAssociationCommand cmdNew = NewPSMAssociationCommandFactory.Factory().Create( Controller.ModelController) as NewPSMAssociationCommand; PSMAssociationChild child = (nextAssociation == null ? GroupedClass : nextAssociation.Child); cmdNew.Set((PSMClass)association.Child, child, null, null); cmdNew.CommandOperation(); PSMAssociation newAssociation = cmdNew.CreatedAssociation.Element; createdAssociations.Add(cmdNew); // Create a nesting join for the new association A'i, all the nesting joins // of the associations A1..n will have the GroupedClass as their CoreClass. NestingJoin nj = newAssociation.AddNestingJoin(GroupedClass.RepresentedClass); // Copy the parent path of the nesting join of Ai to the parent // path of A'i and reverse it. IEnumerable <PIMStep> revPath = association.NestingJoins[0].Parent.Steps.Reverse(); foreach (PIMStep step in revPath) { nj.Parent.AddStep(step.End, step.Start, step.Association); } // If Ai+1 is defined then copy its Parent path to the Child path of A'i // and reverse it. Set the A'i ending to the child of Ai+1. // Thus, the A'i association will look as follows // - A'i: Ai.Child -> Ai+1.Child // - Nesting join: GroupedClass[Ai.ParentPath(reversed) -> Ai+1.ParentPath(reversed)] // // If Ai+1 is not defined, A'i will end at the GroupedClass and will look as follows // - A'i: Ai.Child -> GroupedClass // - Nesting join: GroupedClass[Ai.ParentPath(reversed) -> .] if (nextAssociation != null) { revPath = nextAssociation.NestingJoins[0].Parent.Steps.Reverse(); foreach (PIMStep step in revPath) { nj.Child.AddStep(step.End, step.Start, step.Association); } } // Set the context of A'i as a collection of all the parent paths of A'1 .. A'i-1 foreach (PIMPath path in context) { PIMPath newPath = nj.AddContextPath(); foreach (PIMStep step in path.Steps) { newPath.AddStep(step.Start, step.End, step.Association); } } // Add the parent path of A'i to the temporal collection to enable it for A'i+1 context.Add(nj.Parent); // Put A'i on the diagram ElementToDiagramCommand <PSMAssociation, PSMAssociationViewHelper> cmdToDiag = ElementToDiagramCommandFactory <PSMAssociation, PSMAssociationViewHelper> .Factory().Create(Controller) as ElementToDiagramCommand <PSMAssociation, PSMAssociationViewHelper>; cmdToDiag.IncludedElement = new Helpers.ElementHolder <PSMAssociation>(newAssociation); cmdToDiag.CommandOperation(); visualizedAssociations.Add(cmdToDiag); } // If the grouped class was previously a root of the PSM diagram // replace it with the topmost grouping class. rootIndex = GroupedClass.Diagram.Roots.IndexOf(GroupedClass); if (rootIndex != -1) { newRoot = Associations[0].Child as PSMClass; GroupedClass.Diagram.Roots[rootIndex] = newRoot; } }