Esempio n. 1
0
        public virtual void FillCopy(Element copyElement, Model targetModel, ElementCopiesMap createdCopies)
        {
            PSMDiagramReference copyReference = (PSMDiagramReference)copyElement;

            copyReference.SchemaLocation  = this.SchemaLocation;
            copyReference.Local           = this.Local;
            copyReference.Namespace       = this.Namespace;
            copyReference.Name            = this.Name;
            copyReference.NamespacePrefix = this.NamespacePrefix;
        }
Esempio n. 2
0
        public Project BranchProject(Project project, IEnumerable <Type> PIMElementsOrder, bool initialBranch)
        {
            Project branchProject = new Project(project.Caption);
            Model   sourceModel   = project.Schema.Model;
            Model   targetModel   = branchProject.Schema.Model;

            branchProject.FilePath            = project.FilePath;
            branchProject.Schema.XMLNamespace = project.Schema.XMLNamespace;
            // TODO: remove these names
            project.Schema.Name       = "OLD SCHEMA";
            branchProject.Schema.Name = "NEW SCHEMA";

            targetModel.Name = sourceModel.Name;

            ElementCopiesMap createdCopies = new ElementCopiesMap();
            Dictionary <Diagram, Diagram> createdDiagrams = new Dictionary <Diagram, Diagram>();

            createdCopies[sourceModel] = targetModel;
            List <Package> packages = new List <Package> {
                sourceModel
            };

            #region packages structure

            {
                int index = 0;
                while (packages.Count > index)
                {
                    Package sourcePackage = packages[index];
                    if (sourcePackage != sourceModel)
                    {
                        Package copyPackage = (Package)sourcePackage.CreateCopy(targetModel, createdCopies);
                        createdCopies[sourcePackage] = copyPackage;
                    }

                    packages.AddRange(sourcePackage.NestedPackages);
                    index++;
                }
            }

            #endregion

            #region primitive types

            branchProject.TemplateIdTable = new Serialization.SerializatorIdTable();
            foreach (SimpleDataType primitiveType in project.Schema.PrimitiveTypes)
            {
                SimpleDataType copyPrimitiveType = (SimpleDataType)primitiveType.CreateCopy(targetModel, createdCopies);
                createdCopies[primitiveType] = copyPrimitiveType;
                branchProject.TemplateIdTable[copyPrimitiveType] = project.TemplateIdTable[primitiveType];
            }

            #endregion

            #region profiles

            foreach (Profile profile in project.Schema.Profiles)
            {
                Profile copyProfile = branchProject.Schema.AddProfile();
                profile.FillCopy(copyProfile, targetModel, createdCopies);
                if (profile.Name == "XSem")
                {
                    createdCopies.SubElements.Clear();
                    createdCopies.Remove(profile);
                }
            }

            #endregion

            #region classes (not association classes!)

            List <AssociationClass> associationClasses = new List <AssociationClass>();

            foreach (Package package in packages)
            {
                foreach (PIMClass pimClass in package.Classes)
                {
                    if (pimClass is AssociationClass)
                    {
                        associationClasses.Add((AssociationClass)pimClass);
                    }
                    else
                    {
                        Element copyClass = pimClass.CreateCopy(targetModel, createdCopies);
                        createdCopies[pimClass] = copyClass;
                    }
                }
            }

            #endregion

            #region pim comments

            // in PIM diagrams
            foreach (PIMDiagram diagram in project.PIMDiagrams)
            {
                foreach (Comment comment in diagram.DiagramElements.Keys.OfType <Comment>())
                {
                    Element copyComment = comment.CreateCopy(targetModel, createdCopies);
                    createdCopies[comment] = copyComment;
                }
            }

            // in model
            foreach (Comment comment in project.Schema.Model.Comments)
            {
                Element copyComment = comment.CreateCopy(targetModel, createdCopies);
                createdCopies[comment] = copyComment;
            }

            #endregion

            #region AssociationClasses

            {
                // try to copy association classes, if not all ends are ready yet, skip the class for now.
                bool canContinue = associationClasses.Count > 0;
                int  index       = 0;
                while (index <= associationClasses.Count - 1)
                {
                    AssociationClass associationClass = associationClasses[index];
                    if (associationClass.Ends.All(end => createdCopies.ContainsKey(end.Class)))
                    {
                        Element copyAssociationClass = associationClass.CreateCopy(targetModel, createdCopies);
                        createdCopies[associationClass] = copyAssociationClass;
                        associationClasses.RemoveAt(index);
                        canContinue = true;
                    }
                    else
                    {
                        index++;
                    }
                    if (index == associationClasses.Count && canContinue)
                    {
                        index       = 0;
                        canContinue = false;
                    }
                }
                if (associationClasses.Count != 0)
                {
                    throw new InvalidOperationException("Failed to branch association classes. ");
                }
            }

            #endregion

            #region PIM generalizations

            foreach (Generalization generalization in sourceModel.Generalizations)
            {
                if (!(generalization.General is PSMClass))
                {
                    Element copyGeneralization = generalization.CreateCopy(targetModel, createdCopies);

                    createdCopies[generalization] = copyGeneralization;
                }
            }


            #endregion

            #region associations (without association classes)

            foreach (Association association in sourceModel.Associations.Where(association => !(association is AssociationClass)))
            {
                Element copyAssociation = association.CreateCopy(targetModel, createdCopies);

                createdCopies[association] = copyAssociation;
            }

            #endregion

            #region create PIM diagrams

            {
                foreach (PIMDiagram pimDiagram in project.PIMDiagrams)
                {
                    PIMDiagram pimDiagramCopy = (PIMDiagram)pimDiagram.Clone();

                    Dictionary <Element, ViewHelper> viewHelperCopies = new Dictionary <Element, ViewHelper>();

                    /* Elements in PIM diagram are loaded in the order of their LoadPriority in registration set */
                    foreach (Type ModelElementType in PIMElementsOrder)
                    {
                        foreach (KeyValuePair <Element, ViewHelper> pair in pimDiagram.DiagramElements)
                        {
                            Element    element    = pair.Key;
                            ViewHelper viewHelper = pair.Value;

                            if (!viewHelperCopies.ContainsKey(element) && ModelElementType.IsInstanceOfType(element))
                            {
                                ViewHelper copiedViewHelper = viewHelper.CreateCopy(pimDiagramCopy, createdCopies);
                                viewHelperCopies.Add(element, copiedViewHelper);

                                pimDiagramCopy.AddModelElement(createdCopies[element], copiedViewHelper);
                            }
                        }
                    }

                    branchProject.AddPIMDiagram(pimDiagramCopy);
                    createdDiagrams[pimDiagram] = pimDiagramCopy;
                }
            }

            #endregion

            #region create PSM diagrams

            {
                foreach (PSMDiagram psmDiagram in project.PSMDiagrams)
                {
                    PSMDiagram psmDiagramCopy = (PSMDiagram)psmDiagram.Clone();

                    IList <Element> ordered;

                    // order
                    PSMTree.ReturnElementsInPSMOrder((psmDiagram).Roots.Cast <Element>(), out ordered, true);

                    // clone PSM elements
                    foreach (Element element in ordered)
                    {
                        Element copy = element.CreateCopy(targetModel, createdCopies);
                        createdCopies[element] = copy;

                        foreach (Comment comment in element.Comments)
                        {
                            Element copyComment = comment.CreateCopy(targetModel, createdCopies);
                            createdCopies[comment] = copyComment;
                        }
                    }

                    // clone comments
                    foreach (Comment comment in psmDiagram.DiagramElements.Keys.OfType <Comment>())
                    {
                        Element copyComment = comment.CreateCopy(targetModel, createdCopies);
                        createdCopies[comment] = copyComment;
                    }

                    // clone references
                    foreach (PSMDiagramReference psmDiagramReference in psmDiagram.DiagramReferences)
                    {
                        PSMDiagramReference copyReference = (PSMDiagramReference)psmDiagramReference.CreateCopy(targetModel, createdCopies);
                        copyReference.ReferencingDiagram   = psmDiagramCopy;
                        createdCopies[psmDiagramReference] = copyReference;
                    }

                    // representants must be handled separately after all copies are created
                    PSMTree.CopyRepresentantsRelations(createdCopies);

                    // clone viewhelpers
                    Dictionary <Element, ViewHelper> createdViewHelpers = new Dictionary <Element, ViewHelper>();

                    foreach (Element element in ordered)
                    {
                        ViewHelper viewHelper       = psmDiagram.DiagramElements[element];
                        ViewHelper copiedViewHelper = viewHelper.CreateCopy(psmDiagramCopy, createdCopies);

                        createdViewHelpers.Add(element, copiedViewHelper);

                        foreach (Comment comment in element.Comments)
                        {
                            ViewHelper commentViewHelper       = psmDiagram.DiagramElements[comment];
                            ViewHelper copiedCommentViewHelper = commentViewHelper.CreateCopy(psmDiagramCopy, createdCopies);
                            createdViewHelpers.Add(comment, copiedCommentViewHelper);
                        }
                    }

                    foreach (PSMDiagramReference psmDiagramReference in psmDiagram.DiagramReferences)
                    {
                        ViewHelper referenceViewHelper       = psmDiagram.DiagramElements[psmDiagramReference];
                        ViewHelper copiedReferenceViewHelper = referenceViewHelper.CreateCopy(psmDiagramCopy, createdCopies);
                        createdViewHelpers.Add(psmDiagramReference, copiedReferenceViewHelper);
                    }

                    foreach (Comment comment in psmDiagram.DiagramElements.Keys.OfType <Comment>())
                    {
                        ViewHelper commentViewHelper       = psmDiagram.DiagramElements[comment];
                        ViewHelper copiedCommentViewHelper = commentViewHelper.CreateCopy(psmDiagramCopy, createdCopies);
                        createdViewHelpers.Add(comment, copiedCommentViewHelper);
                    }

                    psmDiagram.FillCopy(psmDiagramCopy, targetModel, createdCopies, createdViewHelpers);

                    branchProject.AddPSMDiagram(psmDiagramCopy);
                    createdDiagrams[psmDiagram] = psmDiagramCopy;
                }

                foreach (PSMDiagram psmDiagram in project.PSMDiagrams)
                {
                    foreach (PSMDiagramReference psmDiagramReference in psmDiagram.DiagramReferences)
                    {
                        PSMDiagramReference copyReference = (PSMDiagramReference)createdCopies[psmDiagramReference];
                        copyReference.ReferencedDiagram = (PSMDiagram)createdDiagrams[psmDiagramReference.ReferencedDiagram];
                    }
                }
            }

            #endregion

            #region comments

            // there may be some comments that are not part of any diagram and they are copied now.

            foreach (KeyValuePair <Element, Element> kvp in createdCopies)
            {
                Element source = kvp.Key;

                foreach (Comment comment in source.Comments)
                {
                    if (!createdCopies.ContainsKey(comment))
                    {
                        comment.CreateCopy(targetModel, createdCopies);
                    }
                }
            }

            #endregion

            int next;

            Version firstVersion;
            if (initialBranch)
            {
                firstVersion = new Version {
                    Number = 1
                };
                versions.Add(firstVersion);
                versionedProjects[firstVersion] = project;
                SetAsFirstVersion(project, firstVersion);
                next = 2;
            }
            else
            {
                next         = versions.Max(version => version.Number) + 1;
                firstVersion = project.FirstVersion.Version;
            }

            Version newVersion = new Version {
                Number = next, CreatedFrom = project.Version
            };
            versions.Add(newVersion);

            RegisterBranch(sourceModel, targetModel, newVersion, initialBranch, firstVersion);
            RegisterBranch(project, branchProject, newVersion, initialBranch, firstVersion);

            Versions.InvokeCollectionChanged();

            #region register element branches

            foreach (KeyValuePair <Element, Element> keyValuePair in createdCopies)
            {
                IVersionedElement sourceVersion   = keyValuePair.Key;
                IVersionedElement branchedVersion = keyValuePair.Value;

                RegisterBranch(sourceVersion, branchedVersion, newVersion, initialBranch, firstVersion);
            }

            foreach (KeyValuePair <Diagram, Diagram> keyValuePair in createdDiagrams)
            {
                IVersionedElement sourceVersion   = keyValuePair.Key;
                IVersionedElement branchedVersion = keyValuePair.Value;

                RegisterBranch(sourceVersion, branchedVersion, newVersion, initialBranch, firstVersion);
            }

            foreach (SubElementCopiesMap subElementCopiesMap in createdCopies.SubElements.Values)
            {
                foreach (KeyValuePair <Element, Element> keyValuePair in subElementCopiesMap)
                {
                    IVersionedElement sourceVersion   = keyValuePair.Key;
                    IVersionedElement branchedVersion = keyValuePair.Value;

                    RegisterBranch(sourceVersion, branchedVersion, newVersion, initialBranch, firstVersion);
                }
            }

            #endregion

            versionedProjects[newVersion] = branchProject;

            return(branchProject);
        }