public bool IsUnderContentGroup(PSMElement element, out PSMElement groupElement) { //Debug.Assert(PSMTreeIterator.ModelsElement(element)); groupElement = null; if (element.ModelsElement() /* && !(element is PSMAttribute) */) { return(false); } PSMTreeIterator it = new PSMTreeIterator(element); while (it.CanGoToParent()) { it.GoToParent(); if (IsContentGroupNode(it.CurrentNode)) { groupElement = it.CurrentNode; return(true); } if (it.CurrentNodeModelsElement()) { return(false); } } return(false); }
/// <summary> /// Marks nodes blue or red if there is a change in the represented /// class/subtree. /// </summary> private void FixStructuralRepresentatives() { PSMTreeIterator.NodeMarker additionalNodeMarker = IsContentGroupNode; foreach (PSMClass sr in Diagram.DiagramElements.Keys.OfType <PSMClass>().Where(c => c.IsStructuralRepresentative)) { foreach (PSMTreeIterator.NodeMarker nodeMarker in new[] { null, additionalNodeMarker }) { PSMElement representedClassSignificantAncestor = PSMTreeIterator.GetSignificantAncestorOrSelf(sr.RepresentedPSMClass, nodeMarker); PSMElement structuralRepresentativeSignificantAncestor = PSMTreeIterator.GetSignificantAncestorOrSelf(sr, nodeMarker); if (redNodes.Contains(representedClassSignificantAncestor)) { redNodes.AddIfNotContained(structuralRepresentativeSignificantAncestor); blueNodes.Remove(structuralRepresentativeSignificantAncestor); greenNodes.Remove(structuralRepresentativeSignificantAncestor); MakeAncestorsBlue(structuralRepresentativeSignificantAncestor, nodeMarker); } else if (blueNodes.Contains(representedClassSignificantAncestor) && !redNodes.Contains(structuralRepresentativeSignificantAncestor)) { blueNodes.AddIfNotContained(structuralRepresentativeSignificantAncestor); greenNodes.Remove(structuralRepresentativeSignificantAncestor); MakeAncestorsBlue(structuralRepresentativeSignificantAncestor, nodeMarker); } } } }
private static IEnumerable <FollowedPath> FollowPath(PSMElement element, FollowedPath followedPath) { List <FollowedPath> result = new List <FollowedPath>(); PSMTreeIterator it = new PSMTreeIterator(element); followedPath.Add(element); while (it.CanGoToParent()) { it.GoToParent(); PSMClass psmClass = it.CurrentNode as PSMClass; if (psmClass != null && psmClass.IsReferencedFromStructuralRepresentative()) { foreach (PSMClass representative in psmClass.Diagram.DiagramElements.Keys.OfType <PSMClass>().Where(rClass => rClass.RepresentedPSMClass == psmClass)) { result.AddRange(FollowPath(representative, followedPath.Copy())); } } followedPath.Add(it.CurrentNode); } if (followedPath.Last() is PSMClass && ((PSMClass)followedPath.Last()).HasElementLabel) { result.Add(followedPath); } return(result); }
/// <summary> /// returns the path to the closest ancestor of <see cref="addedNode"/> /// that existed in the previous version. /// </summary> /// <param name="addedNode">The added node.</param> /// <param name="oldVersion">The old version.</param> /// <returns>xpath expression</returns> private static XPathExpr GetXPathForAddedNode(PSMElement addedNode, Version oldVersion) { PSMTreeIterator it = new PSMTreeIterator(addedNode); PSMElement ancestorOldVersion = null; while (ancestorOldVersion == null) { if (it.CanGoToParent()) { it.GoToParent(); } else { return(null); } it.CurrentNode = it.GetSignificantAncestorOrSelf(); if (it.CurrentNode != null) { ancestorOldVersion = (PSMElement)it.CurrentNode.GetInVersion(oldVersion); } else { break; } } return(ancestorOldVersion != null?ancestorOldVersion.XPathE() : null); }
private void CategorizeSubtree(PSMTreeIterator iterator) { if (iterator.CurrentNodeModelsElement() || IsContentGroupNode(iterator.CurrentNode)) { significantNodes.Add(iterator.CurrentNode); bool isRed = false; if ((changesByTargetSignificantNode.ContainsKey(iterator.CurrentNode) && !changesByTargetSignificantNode[iterator.CurrentNode].All(c => c.Element == iterator.CurrentNode && c is ICanBeIgnoredOnTarget)) || GetState(iterator.CurrentNode) == EContentPlacementState.Added) { redNodes.Add(iterator.CurrentNode); isRed = true; } PSMElement cn = iterator.CurrentNode; foreach (PSMElement child in iterator.GetChildNodes()) { iterator.CurrentNode = child; CategorizeSubtree(iterator); } iterator.CurrentNode = cn; PSMElement firstFoundRedChild = iterator.GetChildNodes().FirstOrDefault(child => (child is PSMAssociation) && redNodes.Contains(((PSMAssociation)child).Child) && IsContentGroupNode(((PSMAssociation)child).Child)); if (!isRed && firstFoundRedChild != null) { isRed = true; int index = redNodes.IndexOf(((PSMAssociation)firstFoundRedChild).Child); redNodes.Insert(index, iterator.CurrentNode); } if (!isRed) { if (iterator.GetChildNodes().Any(child => redNodes.Contains(child) || blueNodes.Contains(child) || insignificantBlueNodes.Contains(child))) { blueNodes.Add(iterator.CurrentNode); } else { greenNodes.Add(iterator.CurrentNode); } } } else { PSMElement cn = iterator.CurrentNode; foreach (PSMElement child in iterator.GetChildNodes()) { iterator.CurrentNode = child; CategorizeSubtree(iterator); } iterator.CurrentNode = cn; if (iterator.GetChildNodes().Any(child => redNodes.Contains(child) || blueNodes.Contains(child) || insignificantBlueNodes.Contains(child))) { insignificantBlueNodes.Add(iterator.CurrentNode); } } }
private void MakeAncestorsBlue(PSMElement node, PSMTreeIterator.NodeMarker nodeMarker) { foreach (PSMElement ancestor in PSMTreeIterator.SignificantAncestors(node, nodeMarker)) { if (!redNodes.Contains(ancestor)) { blueNodes.AddIfNotContained(ancestor); greenNodes.Remove(ancestor); } } }
/// <summary> /// Returns all XPath expressions where PSM element can appear in an XML document. Each structural /// representative in a diagram can contribute with one expression, where an element can appear. /// </summary> /// <param name="element"></param> /// <returns></returns> public static IEnumerable <XPathExpr> PathsWhereElementAppears(PSMElement element) { List <FollowedPath> result = new List <FollowedPath>(); FollowedPath followedPath = new FollowedPath(); result.AddRange(FollowPath(element, followedPath)); return(from p in result where p.Count > 0 && PSMTreeIterator.IsInSignificantSubtree(p.Last()) select p.ToXPath()); }
private PSMElement groupingFuncBySignificantNode(EvolutionChange change) { PSMElement target = (change is ISubelementChange) ? ((ISubelementChange)change).ChangedSubelement : change.Element; if (target.ModelsElement()) { return(target); } else { return(PSMTreeIterator.GetSignificantAncestorOrSelf(target, IsContentGroupNode)); } }
public static List <NodeElementWrapper> GetSubtreeElements(this PSMElement node) { PSMTreeIterator it = new PSMTreeIterator(node); List <NodeElementWrapper> contentList = new List <NodeElementWrapper>(); //if (((PSMClass)node).IsStructuralRepresentative && node.ModelsElement()) //{ // PSMClass representedClass = ((PSMClass)node).RepresentedPSMClass; // contentList.Add(new StructuralRepresentativeElements((PSMClass)node, representedClass)); //} foreach (PSMElement childNode in it.GetChildNodes()) { GetSubtreeContentComponentsInclRoot(childNode, ref contentList); } return(contentList); }
public static string SuggestTemplateName(PSMElement node) { PSMTreeIterator t = new PSMTreeIterator(node); string name = string.Empty; while (t.CanGoToParent()) { string step = t.CurrentNodeModelsElement() ? GetElementNameForSignificantElement(t.CurrentNode) : t.CurrentNode.Name; name = !string.IsNullOrEmpty(step) ? step + "-" + name : name; t.GoToParent(); } if (t.CurrentNode != null) { string step = t.CurrentNodeModelsElement() ? GetElementNameForSignificantElement(t.CurrentNode) : t.CurrentNode.Name; name = step + "-" + name; } return(name.Trim('-') + "-iteration"); }
private void CategorizeNodes() { significantNodes = new List <PSMElement>(); insignificantBlueNodes = new List <PSMElement>(); redNodes = new List <PSMElement>(); blueNodes = new List <PSMElement>(); greenNodes = new List <PSMElement>(); PSMTreeIterator it = new PSMTreeIterator(Diagram); // ReSharper disable MoreSpecificForeachVariableTypeAvailable foreach (PSMSuperordinateComponent root in Diagram.Roots) // ReSharper restore MoreSpecificForeachVariableTypeAvailable { it.CurrentNode = root; CategorizeSubtree(it); } FixStructuralRepresentatives(); Debug.Assert(redNodes.Intersect(blueNodes).Count() == 0); Debug.Assert(blueNodes.Intersect(greenNodes).Count() == 0); Debug.Assert(greenNodes.Intersect(redNodes).Count() == 0); }
public static string GetElementNameForSignificantElement(PSMElement node) { PSMTreeIterator it = new PSMTreeIterator(node); // TODO: prozkoumat //Debug.Assert(it.CurrentNodeModelsElement(), "Node is not correct significant node."); if (node is PSMClass) { Debug.Assert(((PSMClass)node).HasElementLabel); return(((PSMClass)node).ElementName); } if (node is PSMContentContainer) { return(node.Name); } if (node is PSMAttribute) { Debug.Assert(((PSMAttribute)node).AttributeContainer != null); return(((PSMAttribute)node).AliasOrName); } // should never get here... throw new ArgumentException("Node is not correct significant node."); }
private Dictionary <PSMElement, List <EvolutionChange> > GroupByTargetSignificantNode() { Dictionary <PSMElement, List <EvolutionChange> > groupChanges = GroupChanges(groupingFuncBySignificantNode); foreach (EvolutionChange change in this) { List <PSMElement> secondaryTargets = new List <PSMElement>(); if (change is IDoubleTargetChange) { secondaryTargets.Add(((IDoubleTargetChange)change).SecondaryTarget); } else if (change is ISubelementChange) { secondaryTargets.Add(change.Element); } foreach (PSMElement secondaryTarget in secondaryTargets) { if (secondaryTarget == null) { continue; } PSMElement secondaryTargetNV = (PSMElement)secondaryTarget.GetInVersion(change.NewVersion); if (secondaryTargetNV != null) { if (secondaryTargetNV.ModelsElement()) { //secondaryTarget = secondaryTarget; } else { secondaryTargetNV = PSMTreeIterator.GetSignificantAncestorOrSelf(secondaryTargetNV, IsContentGroupNode); } if (secondaryTargetNV != null) { if (!groupChanges.ContainsKey(secondaryTargetNV)) { groupChanges[secondaryTargetNV] = new List <EvolutionChange>(); } if (!groupChanges[secondaryTargetNV].Contains(change)) { groupChanges[secondaryTargetNV].Add(change); } } } } } foreach (KeyValuePair <PSMElement, List <EvolutionChange> > kvp in groupChanges.ToDictionary(pair => pair.Key, pair => pair.Value)) { PSMElement target = kvp.Key; List <EvolutionChange> changeList = kvp.Value; if (IsContentGroupNode(target)) { PSMElement groupParent = PSMTreeIterator.GetSignificantAncestorOrSelf(target); if (groupParent == null) { groupParent = target; } if (!groupChanges.ContainsKey(groupParent)) { groupChanges[groupParent] = new List <EvolutionChange>(); } foreach (EvolutionChange change in changeList) { if (!groupChanges[groupParent].Contains(change)) { groupChanges[groupParent].Add(change); } } } } return(groupChanges); }
/// <summary> /// Adds attributes under a node into <param name="attributeList"/> (when called for a superordinate component, attributes /// from all subordinate PSM classes without element labels are included in the result too) /// </summary> /// <param name="node">node where to search for attributes</param> /// <param name="firstCall">false value indicates recursive call</param> /// <param name="attributeList">list in which attributes are added</param> private static void GetAttributesUnderNode(PSMElement node, bool firstCall, ref List <NodeAttributeWrapper> attributeList) { if (!firstCall && node is PSMClass && !((PSMClass)node).HasElementLabel && ((PSMClass)node).IsStructuralRepresentative) { PSMClass representedClass = ((PSMClass)node).RepresentedPSMClass; attributeList.Add(new StructuralRepresentativeAttributes((PSMClass)node, representedClass)); } { PSMClass psmClass = node as PSMClass; if (psmClass != null) { if (firstCall || (!psmClass.HasElementLabel)) { foreach (PSMAttribute psmAttribute in psmClass.PSMAttributes) { attributeList.Add(new SimpleNodeAttribute(psmAttribute)); } } else { return; } } } if (node is PSMClass || (node is PSMContentContainer && firstCall)) { foreach (PSMSubordinateComponent component in ((PSMSuperordinateComponent)node).Components) { GetAttributesUnderNode(component, false, ref attributeList); } } if (node is PSMClassUnion) { //throw new NotImplementedException("Can't handle unions yet"); } if (node is PSMContentChoice) { PSMContentChoice contentChoice = (PSMContentChoice)node; PSMTreeIterator it = new PSMTreeIterator(contentChoice); List <ChoiceAttributeOption> options = new List <ChoiceAttributeOption>(); foreach (PSMElement childNode in it.GetChildNodes()) { List <NodeAttributeWrapper> choices = new List <NodeAttributeWrapper>(); GetAttributesUnderNode(childNode, false, ref choices); if (choices.Count > 0) { ChoiceAttributeOption option = new ChoiceAttributeOption(); option.Items = choices; options.Add(option); } } if (options.Count > 0) { ChoiceAttributes choiceAttributes = new ChoiceAttributes(contentChoice, options); attributeList.Add(choiceAttributes); } } else if (node is PSMClassUnion) { PSMClassUnion classUnion = (PSMClassUnion)node; PSMTreeIterator it = new PSMTreeIterator(classUnion); List <ChoiceAttributeOption> options = new List <ChoiceAttributeOption>(); foreach (PSMElement childNode in it.GetChildNodes()) { List <NodeAttributeWrapper> choices = new List <NodeAttributeWrapper>(); GetAttributesUnderNode(childNode, false, ref choices); if (choices.Count > 0) { ChoiceAttributeOption option = new ChoiceAttributeOption(); option.Items = choices; options.Add(option); } } if (options.Count > 0) { UnionAttributes choiceAttributes = new UnionAttributes(classUnion, options); attributeList.Add(choiceAttributes); } } if (node is PSMAssociation) { GetAttributesUnderNode(((PSMAssociation)node).Child, false, ref attributeList); } return; }
private static void GetSubtreeContentComponentsInclRoot(PSMElement node, ref List <NodeElementWrapper> e) { List <NodeElementWrapper> contentList = e; bool?group = null; if ((node is PSMClass) || (node is PSMContentContainer)) { if (node.ModelsElement()) { group = false; } else { group = true; } } if (group != null) // i.e. (node is PSMClass) || (node is PSMContentContainer) { if (group == false) // not in group { contentList.Add(new SimpleNodeElement(node)); } else // in group { if (EncompassesContentForParentSignificantNode(node)) { ContentGroup cg = new ContentGroup(); cg.ContainingClass = (PSMClass)node; if (((PSMClass)node).IsStructuralRepresentative && !node.ModelsElement()) { PSMClass representedClass = ((PSMClass)node).RepresentedPSMClass; cg.ContentComponents.Add(new StructuralRepresentativeElements((PSMClass)node, representedClass)); } PSMTreeIterator it = new PSMTreeIterator(node); foreach (PSMElement component in it.GetChildNodes()) { List <NodeElementWrapper> tmp = new List <NodeElementWrapper>(); GetSubtreeContentComponentsInclRoot(component, ref tmp); cg.ContentComponents.AddRange(tmp); } contentList.Add(cg); } } } #region choice and union else if (node is PSMAttributeContainer) { foreach (PSMAttribute psmAttribute in ((PSMAttributeContainer)node).PSMAttributes) { contentList.Add(new SimpleNodeElement(psmAttribute)); } } else if ((node is PSMContentChoice) || (node is PSMClassUnion)) { PSMTreeIterator it = new PSMTreeIterator(node); List <ChoiceElementOption> options = new List <ChoiceElementOption>(); foreach (PSMElement childNode in it.GetChildNodes()) { List <NodeElementWrapper> items = new List <NodeElementWrapper>(); GetSubtreeContentComponentsInclRoot(childNode, ref items); if (items.Count > 0) { ChoiceElementOption option = new ChoiceElementOption(); option.Items = items; options.Add(option); } } if (options.Count > 0) { if (node is PSMContentChoice) { ChoiceElements choiceElements = new ChoiceElements((PSMContentChoice)node, options); contentList.Add(choiceElements); } else { UnionElements unionElements = new UnionElements((PSMClassUnion)node, options); contentList.Add(unionElements); } } } #endregion else if (node is PSMAssociation) { GetSubtreeContentComponentsInclRoot(((PSMAssociation)node).Child, ref contentList); } return; }
/// <summary> /// Performs <see cref="GroupAwareProjectXPath"/> and substitutes steps in the result path according /// to structural representative information. (So the path is relative to the structural representative) /// </summary> /// <param name="context">The generator context.</param> /// <param name="element">The element.</param> /// <param name="structuralRepresentativeReplacement">The structural representative replacement.</param> /// <returns></returns> public static XPathExpr GroupAwareProjectXPathWithSRSubstitution(XsltGeneratorContext context, PSMElement element, IFromStructuralRepresentative structuralRepresentativeReplacement) { XPathExpr expr; if (structuralRepresentativeReplacement != null) { var cp = context.ProcessedPath; //if (PSMTreeIterator.AreInTheSamePSMTree(structuralRepresentativeReplacement.RepresentedPSMClass, structuralRepresentativeReplacement.StructuralRepresentative)) PSMElement representedOldAnc = PSMTreeIterator.GetSignificantAncestorOrSelf((PSMClass)structuralRepresentativeReplacement.RepresentedPSMClass.GetInVersion(context.ChangeSet.OldVersion)); PSMElement structuralRepresentativeOldAnc = PSMTreeIterator.GetSignificantAncestorOrSelf((PSMClass)structuralRepresentativeReplacement.StructuralRepresentative.GetInVersion(context.ChangeSet.OldVersion)); if (representedOldAnc != null) { context.ProcessedPath = GetXPathForNode(representedOldAnc, context.ChangeSet.OldVersion); } else { context.ProcessedPath = new XPathExpr("<virt-root>"); if (context.InGroup) { context.ProcessedPath = context.ProcessedPath.Append("/$cg"); } } string from = representedOldAnc != null?XsltTemplateNameManager.GetElementNameForSignificantElement(representedOldAnc) : null; string to = structuralRepresentativeOldAnc != null?XsltTemplateNameManager.GetElementNameForSignificantElement(structuralRepresentativeOldAnc) : null; XPathExpr e = null; if (from != null && to != null && !(context.ProcessedPath.ToString().EndsWith(from) && cp.ToString().EndsWith(to))) { e = ProjectXPath(cp, context.ProcessedPath, false); if (!XPathExpr.IsNullOrEmpty(e) && !String.IsNullOrEmpty(to) && !String.IsNullOrEmpty(from)) { if (e.ToString().Contains(from)) { e = new XPathExpr(e.ToString().Replace(from, to)); } } } expr = GroupAwareProjectXPath(context, element, context.ChangeSet.OldVersion); if (!XPathExpr.IsNullOrEmpty(e)) { // ReSharper disable PossibleNullReferenceException expr = e.Append("/" + expr); } // ReSharper restore PossibleNullReferenceException context.ProcessedPath = cp; } else { expr = GroupAwareProjectXPath(context, element, context.ChangeSet.OldVersion); } return(expr); }