/// <summary>
        /// Executes the paste operation.
        /// </summary>
        /// <param name="rootElement">Root element, on which to paste the current data object's data.</param>
        /// <param name="dataObject">Data to be pasted.</param>
        /// <returns>ValidationResult holding errors, warning or information messages.</returns>
        public static ValidationResult Merge(ModelElement rootElement, IDataObject dataObject)
        {
            if (!CanMerge(rootElement, dataObject))
            {
                return(null);
            }

            ModelProtoGroup       group       = GetModelProtoGroup(dataObject);
            ModelProtoGroupMerger protoMerger = new ModelProtoGroupMerger(group, rootElement);

            return(protoMerger.MergeResult);
        }
Exemple #2
0
        /// <summary>
        /// Moves a proto element to the current element.
        /// </summary>
        /// <param name="protoElement">Proto element representation of the element that is to be added.</param>
        /// <param name="groupMerger">
        /// Group merger class used to track id mapping, merge errors/warnings and
        /// postprocess merging by rebuilding reference relationships.
        /// </param>
        public virtual void ModelMove(ModelProtoElement protoElement, ModelProtoGroupMerger groupMerger)
        {
            if (!ModelIsPasteAllowed(groupMerger.ProtoGroup.Operation))
            {
                // add warning message
                groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergePasteDisallowedId,
                                                                         ModelValidationViolationType.Warning, "Element couldn't be addded to " + this.DomainElementFullName + " because paste is not allowed."));
                return;
            }

            if (protoElement != null)
            {
                DomainClassInfo elementDomainInfo = this.Partition.DomainDataDirectory.GetDomainClass(protoElement.DomainClassId);
                foreach (DomainRoleInfo info in elementDomainInfo.AllDomainRolesPlayed)
                {
                    if (!info.IsSource)
                    {
                        if (info.OppositeDomainRole.RolePlayer.Id == this.GetDomainClassId())
                        {
                            if (this.Store.DomainDataAdvDirectory.IsEmbeddingRelationship(info.DomainRelationship.Id) &&
                                !this.Store.DomainDataAdvDirectory.IsAbstractRelationship(info.DomainRelationship.Id))
                            {
                                ModelElement modelElement = this.Store.ElementDirectory.FindElement(protoElement.ElementId);
                                if (modelElement == null)
                                {
                                    groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergeElementMissingOnMoveId, ModelValidationViolationType.Error, "Element exists although the operation = Move."));
                                    return;
                                }

                                // change parent
                                DomainRoleInfo.SetLinkedElement(modelElement, info.Id, this);
                                return;
                            }
                        }
                    }
                }
            }
        }
 /// <summary>
 /// Finalize merge.
 /// </summary>
 /// <param name="protoElement">Proto element representation of the element that is to be added.</param>
 /// <param name="groupMerger">
 /// Group merger class used to track id mapping, merge errors/warnings and 
 /// postprocess merging by rebuilding reference relationships.
 /// </param>
 public virtual void ModelFinalizeMerge(ModelProtoElement protoElement, ModelProtoGroupMerger groupMerger)
 {
     
 }
        /// <summary>
        /// Moves a proto element to the current element.
        /// </summary>
        /// <param name="protoElement">Proto element representation of the element that is to be added.</param>
        /// <param name="groupMerger">
        /// Group merger class used to track id mapping, merge errors/warnings and 
        /// postprocess merging by rebuilding reference relationships.
        /// </param>
        public virtual void ModelMove(ModelProtoElement protoElement, ModelProtoGroupMerger groupMerger)
        {
            if (!ModelIsPasteAllowed(groupMerger.ProtoGroup.Operation))
            {
                // add warning message
                groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergePasteDisallowedId,
                             ModelValidationViolationType.Warning, "Element couldn't be addded to " + this.DomainElementFullName + " because paste is not allowed."));
                return;
            }

            if (protoElement != null)
            {
                DomainClassInfo elementDomainInfo = this.Partition.DomainDataDirectory.GetDomainClass(protoElement.DomainClassId);
                foreach (DomainRoleInfo info in elementDomainInfo.AllDomainRolesPlayed)
                {
                    if (!info.IsSource)
                        if (info.OppositeDomainRole.RolePlayer.Id == this.GetDomainClassId())
                            if (this.Store.DomainDataAdvDirectory.IsEmbeddingRelationship(info.DomainRelationship.Id) &&
                                !this.Store.DomainDataAdvDirectory.IsAbstractRelationship(info.DomainRelationship.Id))
                            {
                                ModelElement modelElement = this.Store.ElementDirectory.FindElement(protoElement.ElementId);
                                if (modelElement == null)
                                {
                                    groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergeElementMissingOnMoveId, ModelValidationViolationType.Error, "Element exists although the operation = Move."));
                                    return;
                                }

                                // change parent
                                DomainRoleInfo.SetLinkedElement(modelElement, info.Id, this);
                                return;
                            }
                }
            }
        }
        /// <summary>
        /// Adds a proto link to the current element.
        /// </summary>
        /// <param name="protoLink">Proto link representation of the element link that is to be added.</param>
        /// <param name="groupMerger">
        /// Group merger class used to track id mapping, merge errors/warnings and 
        /// postprocess merging by rebuilding reference relationships.
        /// </param>
        public virtual void ModelMerge(ModelProtoLink protoLink, ModelProtoGroupMerger groupMerger)
        {
            if (protoLink.IsTargetIncludedSubmodel && !String.IsNullOrEmpty(protoLink.DomainFilePath))
            {
                // TODO ...
                /*
                string file = protoLink.DomainFilePath;
                IParentModelElement parent = this.GetDomainModelServices().ElementParentProvider.GetParentModelElement(this);
                if (parent == null)
                    throw new System.ArgumentNullException("Parent of element " + this.ToString() + " can not be null");

                string path = parent.DomainFilePath;
                string vModellDirectory = new System.IO.FileInfo(path).DirectoryName;
                string curPath = vModellDirectory + System.IO.Path.DirectorySeparatorChar + path;

                // load model
                using (Transaction transaction = this.Store.TransactionManager.BeginTransaction("Set referenced model"))
                {
                    // TODO load.
                    /*
                    global::Tum.VModellXT.VModellXTDocumentData data = global::Tum.VModellXT.VModellXTDocumentData.Instance as global::Tum.VModellXT.VModellXTDocumentData;
                    global::Tum.VModellXT.VModell referenceModel = data.ModelContextVModellXT.LoadInternal(file) as global::Tum.VModellXT.VModell;
                    model.VModell = referenceModel;
                    */
                /*
                    transaction.Commit();
                }

                return;
                */
                return;
            }

            DomainRelationshipInfo linkDomainInfo = null;
            if (protoLink != null)
            {
                linkDomainInfo = this.Partition.DomainDataDirectory.GetDomainRelationship(protoLink.DomainClassId);
            }
            else
            {
                // try getting the linkDomainInfo from name
                DomainClassInfo elementDomainInfo = this.GetDomainClass();
                foreach (DomainRoleInfo info in elementDomainInfo.AllDomainRolesPlayed)
                {
                    if (info.IsSource)
                        if (!this.Store.DomainDataAdvDirectory.IsEmbeddingRelationship(info.DomainRelationship.Id) &&
                            !this.Store.DomainDataAdvDirectory.IsAbstractRelationship(info.DomainRelationship.Id))
                        {
                            if (protoLink.Name == info.DomainRelationship.Name && linkDomainInfo == null)
                            {
                                linkDomainInfo = this.Partition.DomainDataDirectory.GetDomainRelationship(info.DomainRelationship.Id);
                            }
                        }
                }
            }

            if (linkDomainInfo == null)
            {
                groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergeElementLinkDomainTypeMissingId,
                                 ModelValidationViolationType.Error, "Element link can not be created as the corresponding domain type is missing."));
                return;
            }

            ReferenceRelationshipAdvancedInfo advancedInfo = this.Store.DomainDataAdvDirectory.GetRelationshipInfo(linkDomainInfo.Id) as ReferenceRelationshipAdvancedInfo;
            if (advancedInfo == null)
                throw new InvalidOperationException("Relationship advanced info not found for " + linkDomainInfo.Name);

            // see if this element is taking part in this role
            bool bTakesPart = false;

            ModelProtoRolePlayer sourceRolePlayer = protoLink.GetSourceRolePlayer(this.Store.DefaultPartition);
            ModelProtoElement sourceProtoElement = groupMerger.GetElementById(sourceRolePlayer.RolePlayerId);
            System.Guid mappedSourceIdTP = System.Guid.Empty;
            if (sourceProtoElement != null)
            {
                mappedSourceIdTP = groupMerger.GetIdMapping(sourceRolePlayer.RolePlayerId);
                if (mappedSourceIdTP == this.Id)
                    bTakesPart = true;
            }

            if (advancedInfo.PropagatesCopyOnDeniedElement)
            {
                if (!bTakesPart && mappedSourceIdTP == System.Guid.Empty)
                    if (this.Id == sourceRolePlayer.RolePlayerId)
                        bTakesPart = true;
            }

            if (bTakesPart)
            {
                bool bExists = true;
                if (this.Store.ElementDirectory.FindElement(protoLink.ElementId) == null)
                    bExists = false;

                if (bExists && groupMerger.ProtoGroup.Operation == ModelProtoGroupOperation.Move)
                {
                    groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergeElementLinkExistsOnMoveId,
                         ModelValidationViolationType.Error, "Element link exists although the operation = Move."));
                }

                #region Target
                // see if target element was copied
                ModelProtoRolePlayer targetRolePlayer = protoLink.GetTargetRolePlayer(this.Store.DefaultPartition);
                ModelProtoElement targetProtoElement = groupMerger.GetElementById(targetRolePlayer.RolePlayerId);
                Guid mappedTargetId = Guid.Empty;
                if (targetProtoElement != null)
                {
                    mappedTargetId = groupMerger.GetIdMapping(targetRolePlayer.RolePlayerId);
                }

                if (advancedInfo.PropagatesCopyOnDeniedElement)
                    if (mappedTargetId == System.Guid.Empty)
                    {
                        // try creating relationship to existing element
                        mappedTargetId = targetRolePlayer.RolePlayerId;
                    }

                if (mappedTargetId == System.Guid.Empty)
                {
                    // log warning
                    groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergeLinkElementNotCopiedId,
                         ModelValidationViolationType.Error, "Referenced model element was not copied. Relationship: " + linkDomainInfo.Name));
                }
                else
                {
                    ModelElement targetElement = this.Store.ElementDirectory.FindElement(mappedTargetId);
                    if (targetElement == null)
                    {
                        // log error
                        groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergeLinkElementNotFoundId,
                            ModelValidationViolationType.Error, "Referenced model element was not found. Relationship: " + linkDomainInfo.Name));
                    }
                    else
                    {

                        bool bContinue = true;

                        // check cardinalities, so we don't violate them by additing a new relationship
                        if (advancedInfo.SourceRoleMultiplicity == Multiplicity.One || advancedInfo.SourceRoleMultiplicity == Multiplicity.ZeroOne)
                        {
                            if (DomainRoleInfo.GetLinkedElement(this, advancedInfo.SourceRoleId) != null)
                            {
                                // log warning
                                groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergeLinkCreationViolatesMultiplicityId,
                                    ModelValidationViolationType.Error, "Can not create relationship because one already exists. Relationship: " + linkDomainInfo.Name));

                                bContinue = false;
                            }
                        }

                        if (advancedInfo.TargetRoleMultiplicity == Multiplicity.One || advancedInfo.TargetRoleMultiplicity == Multiplicity.ZeroOne)
                        {
                            if (DomainRoleInfo.GetLinkedElement(this, advancedInfo.TargetRoleId) != null)
                            {
                                // log warning
                                groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergeLinkCreationViolatesMultiplicityId,
                                    ModelValidationViolationType.Error, "Can not create relationship because one already exists. Relationship: " + linkDomainInfo.Name));

                                bContinue = false;
                            }
                        }

                        if (bContinue)
                        {
                            // create property assignments
                            PropertyAssignment[] propertyAssignemnts = protoLink.GetPropertyAssignments(this.Store.DefaultPartition,
                                this.GetDomainModelServices().ElementIdProvider.GenerateNewKey());

                            // create role assignments
                            RoleAssignment[] roleAssignments = new RoleAssignment[2];
                            roleAssignments[0] = new RoleAssignment(advancedInfo.SourceRoleId, this);
                            roleAssignments[1] = new RoleAssignment(advancedInfo.TargetRoleId, targetElement);

                            // create new relationship
                            this.Store.ElementFactory.CreateElementLink(linkDomainInfo, propertyAssignemnts, roleAssignments);
                        }
                    }
                }
                #endregion
            }

        }
        /// <summary>
        /// Adds a proto element to the current element.
        /// </summary>
        /// <param name="protoElement">Proto element representation of the element that is to be added.</param>
        /// <param name="groupMerger">
        /// Group merger class used to track id mapping, merge errors/warnings and 
        /// postprocess merging by rebuilding reference relationships.
        /// </param>
        /// <param name="isRoot">Root element?</param>
        public virtual void ModelMerge(ModelProtoElement protoElement, ModelProtoGroupMerger groupMerger, bool isRoot)
        {
            if (!ModelIsPasteAllowed(groupMerger.ProtoGroup.Operation))
            {
                // add warning message
                groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergePasteDisallowedId,
                             ModelValidationViolationType.Warning, "Element couldn't be addded to " + this.DomainElementFullName + " because paste is not allowed."));
                return;
            }

            if (protoElement != null)
            {
                DomainClassInfo elementDomainInfo = this.Partition.DomainDataDirectory.GetDomainClass(protoElement.DomainClassId);
                foreach (DomainRoleInfo info in elementDomainInfo.AllDomainRolesPlayed)
                {
                    if (!info.IsSource)
                        if (info.OppositeDomainRole.RolePlayer.Id == this.GetDomainClassId())
                            if (this.Store.DomainDataAdvDirectory.IsEmbeddingRelationship(info.DomainRelationship.Id) &&
                                !this.Store.DomainDataAdvDirectory.IsAbstractRelationship(info.DomainRelationship.Id))
                            {
                                // create element id
                                Guid newElementId = this.GetDomainModelServices().ElementIdProvider.GenerateNewKey();

                                // create property assignments
                                PropertyAssignment[] propertyAssignemnts = protoElement.GetPropertyAssignments(this.Store.DefaultPartition, newElementId);

                                // create the actual model element
                                DomainModelElement element = this.Store.ElementFactory.CreateElement(elementDomainInfo, propertyAssignemnts) as DomainModelElement;
                                if (element == null)
                                    throw new System.ArgumentNullException("Element is null in ModelMerge: " + elementDomainInfo.Name);

                                if (!element.ModelIsPasteAllowed(groupMerger.ProtoGroup.Operation))
                                {
                                    // add warning message
                                    groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergePasteDisallowedId,
                                         ModelValidationViolationType.Warning, "Element couldn't be addded to <#= role.RolePlayer.Name #> because paste is not allowed."));

                                    element.Delete();
                                    return;
                                }

                                // set name
                                if (isRoot && groupMerger.ProtoGroup.Operation != ModelProtoGroupOperation.Move)
                                {
                                    if (element.DomainElementHasName)
                                    {
                                        element.GetDomainModelServices().ElementNameProvider.SetName(element, "Copy of " + element.DomainElementName);
                                    }
                                }

                                // update id mapping
                                groupMerger.SetIdMapping(protoElement.ElementId, newElementId);

                                // add child element
                                if (info.OppositeDomainRole.Multiplicity == Multiplicity.One || info.OppositeDomainRole.Multiplicity == Multiplicity.ZeroOne)
                                {
                                    DomainRoleInfo.SetLinkedElement(this, info.OppositeDomainRole.Id, element);
                                }
                                else
                                {
                                    RoleAssignment[] assignments = new RoleAssignment[2];
                                    assignments[0] = new RoleAssignment(info.OppositeDomainRole.Id, this);
                                    assignments[1] = new RoleAssignment(info.Id, element);


                                    this.Store.ElementFactory.CreateElementLink(info.DomainRelationship, assignments);
                                }

                                // continue with child elements (Embedding Relationship)
                                System.Collections.Generic.List<ModelProtoElement> embeddedProtoElements = groupMerger.GetEmbeddedElements(this.Store.DefaultPartition, protoElement);
                                if (embeddedProtoElements.Count > 0)
                                {
                                    foreach (ModelProtoElement p in embeddedProtoElements)
                                        (element as IModelMergeElements).ModelMerge(p, groupMerger, false);
                                }

                                return;
                            }
                }
            }
        }
Exemple #7
0
 /// <summary>
 /// Finalize merge.
 /// </summary>
 /// <param name="protoElement">Proto element representation of the element that is to be added.</param>
 /// <param name="groupMerger">
 /// Group merger class used to track id mapping, merge errors/warnings and
 /// postprocess merging by rebuilding reference relationships.
 /// </param>
 public virtual void ModelFinalizeMerge(ModelProtoElement protoElement, ModelProtoGroupMerger groupMerger)
 {
 }
Exemple #8
0
        /// <summary>
        /// Adds a proto link to the current element.
        /// </summary>
        /// <param name="protoLink">Proto link representation of the element link that is to be added.</param>
        /// <param name="groupMerger">
        /// Group merger class used to track id mapping, merge errors/warnings and
        /// postprocess merging by rebuilding reference relationships.
        /// </param>
        public virtual void ModelMerge(ModelProtoLink protoLink, ModelProtoGroupMerger groupMerger)
        {
            if (protoLink.IsTargetIncludedSubmodel && !String.IsNullOrEmpty(protoLink.DomainFilePath))
            {
                // TODO ...

                /*
                 * string file = protoLink.DomainFilePath;
                 * IParentModelElement parent = this.GetDomainModelServices().ElementParentProvider.GetParentModelElement(this);
                 * if (parent == null)
                 *  throw new System.ArgumentNullException("Parent of element " + this.ToString() + " can not be null");
                 *
                 * string path = parent.DomainFilePath;
                 * string vModellDirectory = new System.IO.FileInfo(path).DirectoryName;
                 * string curPath = vModellDirectory + System.IO.Path.DirectorySeparatorChar + path;
                 *
                 * // load model
                 * using (Transaction transaction = this.Store.TransactionManager.BeginTransaction("Set referenced model"))
                 * {
                 *  // TODO load.
                 *  /*
                 *  global::Tum.VModellXT.VModellXTDocumentData data = global::Tum.VModellXT.VModellXTDocumentData.Instance as global::Tum.VModellXT.VModellXTDocumentData;
                 *  global::Tum.VModellXT.VModell referenceModel = data.ModelContextVModellXT.LoadInternal(file) as global::Tum.VModellXT.VModell;
                 *  model.VModell = referenceModel;
                 */
                /*
                 *  transaction.Commit();
                 * }
                 *
                 * return;
                 */
                return;
            }

            DomainRelationshipInfo linkDomainInfo = null;

            if (protoLink != null)
            {
                linkDomainInfo = this.Partition.DomainDataDirectory.GetDomainRelationship(protoLink.DomainClassId);
            }
            else
            {
                // try getting the linkDomainInfo from name
                DomainClassInfo elementDomainInfo = this.GetDomainClass();
                foreach (DomainRoleInfo info in elementDomainInfo.AllDomainRolesPlayed)
                {
                    if (info.IsSource)
                    {
                        if (!this.Store.DomainDataAdvDirectory.IsEmbeddingRelationship(info.DomainRelationship.Id) &&
                            !this.Store.DomainDataAdvDirectory.IsAbstractRelationship(info.DomainRelationship.Id))
                        {
                            if (protoLink.Name == info.DomainRelationship.Name && linkDomainInfo == null)
                            {
                                linkDomainInfo = this.Partition.DomainDataDirectory.GetDomainRelationship(info.DomainRelationship.Id);
                            }
                        }
                    }
                }
            }

            if (linkDomainInfo == null)
            {
                groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergeElementLinkDomainTypeMissingId,
                                                                         ModelValidationViolationType.Error, "Element link can not be created as the corresponding domain type is missing."));
                return;
            }

            ReferenceRelationshipAdvancedInfo advancedInfo = this.Store.DomainDataAdvDirectory.GetRelationshipInfo(linkDomainInfo.Id) as ReferenceRelationshipAdvancedInfo;

            if (advancedInfo == null)
            {
                throw new InvalidOperationException("Relationship advanced info not found for " + linkDomainInfo.Name);
            }

            // see if this element is taking part in this role
            bool bTakesPart = false;

            ModelProtoRolePlayer sourceRolePlayer   = protoLink.GetSourceRolePlayer(this.Store.DefaultPartition);
            ModelProtoElement    sourceProtoElement = groupMerger.GetElementById(sourceRolePlayer.RolePlayerId);

            System.Guid mappedSourceIdTP = System.Guid.Empty;
            if (sourceProtoElement != null)
            {
                mappedSourceIdTP = groupMerger.GetIdMapping(sourceRolePlayer.RolePlayerId);
                if (mappedSourceIdTP == this.Id)
                {
                    bTakesPart = true;
                }
            }

            if (advancedInfo.PropagatesCopyOnDeniedElement)
            {
                if (!bTakesPart && mappedSourceIdTP == System.Guid.Empty)
                {
                    if (this.Id == sourceRolePlayer.RolePlayerId)
                    {
                        bTakesPart = true;
                    }
                }
            }

            if (bTakesPart)
            {
                bool bExists = true;
                if (this.Store.ElementDirectory.FindElement(protoLink.ElementId) == null)
                {
                    bExists = false;
                }

                if (bExists && groupMerger.ProtoGroup.Operation == ModelProtoGroupOperation.Move)
                {
                    groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergeElementLinkExistsOnMoveId,
                                                                             ModelValidationViolationType.Error, "Element link exists although the operation = Move."));
                }

                #region Target
                // see if target element was copied
                ModelProtoRolePlayer targetRolePlayer   = protoLink.GetTargetRolePlayer(this.Store.DefaultPartition);
                ModelProtoElement    targetProtoElement = groupMerger.GetElementById(targetRolePlayer.RolePlayerId);
                Guid mappedTargetId = Guid.Empty;
                if (targetProtoElement != null)
                {
                    mappedTargetId = groupMerger.GetIdMapping(targetRolePlayer.RolePlayerId);
                }

                if (advancedInfo.PropagatesCopyOnDeniedElement)
                {
                    if (mappedTargetId == System.Guid.Empty)
                    {
                        // try creating relationship to existing element
                        mappedTargetId = targetRolePlayer.RolePlayerId;
                    }
                }

                if (mappedTargetId == System.Guid.Empty)
                {
                    // log warning
                    groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergeLinkElementNotCopiedId,
                                                                             ModelValidationViolationType.Error, "Referenced model element was not copied. Relationship: " + linkDomainInfo.Name));
                }
                else
                {
                    ModelElement targetElement = this.Store.ElementDirectory.FindElement(mappedTargetId);
                    if (targetElement == null)
                    {
                        // log error
                        groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergeLinkElementNotFoundId,
                                                                                 ModelValidationViolationType.Error, "Referenced model element was not found. Relationship: " + linkDomainInfo.Name));
                    }
                    else
                    {
                        bool bContinue = true;

                        // check cardinalities, so we don't violate them by additing a new relationship
                        if (advancedInfo.SourceRoleMultiplicity == Multiplicity.One || advancedInfo.SourceRoleMultiplicity == Multiplicity.ZeroOne)
                        {
                            if (DomainRoleInfo.GetLinkedElement(this, advancedInfo.SourceRoleId) != null)
                            {
                                // log warning
                                groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergeLinkCreationViolatesMultiplicityId,
                                                                                         ModelValidationViolationType.Error, "Can not create relationship because one already exists. Relationship: " + linkDomainInfo.Name));

                                bContinue = false;
                            }
                        }

                        if (advancedInfo.TargetRoleMultiplicity == Multiplicity.One || advancedInfo.TargetRoleMultiplicity == Multiplicity.ZeroOne)
                        {
                            if (DomainRoleInfo.GetLinkedElement(this, advancedInfo.TargetRoleId) != null)
                            {
                                // log warning
                                groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergeLinkCreationViolatesMultiplicityId,
                                                                                         ModelValidationViolationType.Error, "Can not create relationship because one already exists. Relationship: " + linkDomainInfo.Name));

                                bContinue = false;
                            }
                        }

                        if (bContinue)
                        {
                            // create property assignments
                            PropertyAssignment[] propertyAssignemnts = protoLink.GetPropertyAssignments(this.Store.DefaultPartition,
                                                                                                        this.GetDomainModelServices().ElementIdProvider.GenerateNewKey());

                            // create role assignments
                            RoleAssignment[] roleAssignments = new RoleAssignment[2];
                            roleAssignments[0] = new RoleAssignment(advancedInfo.SourceRoleId, this);
                            roleAssignments[1] = new RoleAssignment(advancedInfo.TargetRoleId, targetElement);

                            // create new relationship
                            this.Store.ElementFactory.CreateElementLink(linkDomainInfo, propertyAssignemnts, roleAssignments);
                        }
                    }
                }
                #endregion
            }
        }
Exemple #9
0
        /// <summary>
        /// Adds a proto element to the current element.
        /// </summary>
        /// <param name="protoElement">Proto element representation of the element that is to be added.</param>
        /// <param name="groupMerger">
        /// Group merger class used to track id mapping, merge errors/warnings and
        /// postprocess merging by rebuilding reference relationships.
        /// </param>
        /// <param name="isRoot">Root element?</param>
        public virtual void ModelMerge(ModelProtoElement protoElement, ModelProtoGroupMerger groupMerger, bool isRoot)
        {
            if (!ModelIsPasteAllowed(groupMerger.ProtoGroup.Operation))
            {
                // add warning message
                groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergePasteDisallowedId,
                                                                         ModelValidationViolationType.Warning, "Element couldn't be addded to " + this.DomainElementFullName + " because paste is not allowed."));
                return;
            }

            if (protoElement != null)
            {
                DomainClassInfo elementDomainInfo = this.Partition.DomainDataDirectory.GetDomainClass(protoElement.DomainClassId);
                foreach (DomainRoleInfo info in elementDomainInfo.AllDomainRolesPlayed)
                {
                    if (!info.IsSource)
                    {
                        if (info.OppositeDomainRole.RolePlayer.Id == this.GetDomainClassId())
                        {
                            if (this.Store.DomainDataAdvDirectory.IsEmbeddingRelationship(info.DomainRelationship.Id) &&
                                !this.Store.DomainDataAdvDirectory.IsAbstractRelationship(info.DomainRelationship.Id))
                            {
                                // create element id
                                Guid newElementId = this.GetDomainModelServices().ElementIdProvider.GenerateNewKey();

                                // create property assignments
                                PropertyAssignment[] propertyAssignemnts = protoElement.GetPropertyAssignments(this.Store.DefaultPartition, newElementId);

                                // create the actual model element
                                DomainModelElement element = this.Store.ElementFactory.CreateElement(elementDomainInfo, propertyAssignemnts) as DomainModelElement;
                                if (element == null)
                                {
                                    throw new System.ArgumentNullException("Element is null in ModelMerge: " + elementDomainInfo.Name);
                                }

                                if (!element.ModelIsPasteAllowed(groupMerger.ProtoGroup.Operation))
                                {
                                    // add warning message
                                    groupMerger.MergeResult.AddMessage(new ValidationMessage(ModelValidationMessageIds.ModelMergePasteDisallowedId,
                                                                                             ModelValidationViolationType.Warning, "Element couldn't be addded to <#= role.RolePlayer.Name #> because paste is not allowed."));

                                    element.Delete();
                                    return;
                                }

                                // set name
                                if (isRoot && groupMerger.ProtoGroup.Operation != ModelProtoGroupOperation.Move)
                                {
                                    if (element.DomainElementHasName)
                                    {
                                        element.GetDomainModelServices().ElementNameProvider.SetName(element, "Copy of " + element.DomainElementName);
                                    }
                                }

                                // update id mapping
                                groupMerger.SetIdMapping(protoElement.ElementId, newElementId);

                                // add child element
                                if (info.OppositeDomainRole.Multiplicity == Multiplicity.One || info.OppositeDomainRole.Multiplicity == Multiplicity.ZeroOne)
                                {
                                    DomainRoleInfo.SetLinkedElement(this, info.OppositeDomainRole.Id, element);
                                }
                                else
                                {
                                    RoleAssignment[] assignments = new RoleAssignment[2];
                                    assignments[0] = new RoleAssignment(info.OppositeDomainRole.Id, this);
                                    assignments[1] = new RoleAssignment(info.Id, element);


                                    this.Store.ElementFactory.CreateElementLink(info.DomainRelationship, assignments);
                                }

                                // continue with child elements (Embedding Relationship)
                                System.Collections.Generic.List <ModelProtoElement> embeddedProtoElements = groupMerger.GetEmbeddedElements(this.Store.DefaultPartition, protoElement);
                                if (embeddedProtoElements.Count > 0)
                                {
                                    foreach (ModelProtoElement p in embeddedProtoElements)
                                    {
                                        (element as IModelMergeElements).ModelMerge(p, groupMerger, false);
                                    }
                                }

                                return;
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Executes the paste operation.
        /// </summary>
        /// <param name="rootElement">Root element, on which to paste the current data object's data.</param>
        /// <param name="dataObject">Data to be pasted.</param>
        /// <returns>ValidationResult holding errors, warning or information messages.</returns>
        public static ValidationResult Merge(ModelElement rootElement, IDataObject dataObject)
        {
            if( !CanMerge(rootElement, dataObject) )
                return null;

            ModelProtoGroup group = GetModelProtoGroup(dataObject);
            ModelProtoGroupMerger protoMerger = new ModelProtoGroupMerger(group, rootElement);

            return protoMerger.MergeResult;
        }