Beispiel #1
0
        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);
        }
Beispiel #2
0
 /// <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);
             }
         }
     }
 }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        /// <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);
        }
Beispiel #5
0
        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);
                }
            }
        }
Beispiel #6
0
 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);
         }
     }
 }
Beispiel #7
0
        /// <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());
        }
Beispiel #8
0
        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));
            }
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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");
        }
Beispiel #11
0
        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);
        }
Beispiel #12
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.");
        }
Beispiel #13
0
        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);
        }
Beispiel #14
0
        /// <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;
        }
Beispiel #15
0
        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;
        }
Beispiel #16
0
        /// <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);
        }