/// <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 override void ModelMerge(DslEditorModeling::ModelProtoLink protoLink, DslEditorModeling::ModelProtoGroupMerger groupMerger) { DslModeling::DomainRelationshipInfo linkDomainInfo = null; if (protoLink != null) { linkDomainInfo = this.Partition.DomainDataDirectory.GetDomainRelationship(protoLink.DomainClassId); } else { // try getting the linkDomainInfo from name if( protoLink.Name == "RelationshipShapeClassReferencesReferenceRelationship" && linkDomainInfo == null) { linkDomainInfo = this.Partition.DomainDataDirectory.GetDomainRelationship(RelationshipShapeClassReferencesReferenceRelationship.DomainClassId); } } if( linkDomainInfo == null ) { groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeElementLinkDomainTypeMissing", DslEditorModeling.ModelValidationViolationType.Error, "Element link can not be created as the corresponding domain type is missing.")); return; } if (linkDomainInfo.IsDerivedFrom(global::Tum.PDE.LanguageDSL.RelationshipShapeClassReferencesReferenceRelationship.DomainClassId)) { // see if this element is taking part in this role bool bTakesPart = false; DslEditorModeling::ModelProtoRolePlayer sourceRolePlayer = protoLink.GetSourceRolePlayer(this.Store.DefaultPartition); DslEditorModeling::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( bTakesPart ) { bool bExists = true; if( this.Store.ElementDirectory.FindElement(protoLink.ElementId) == null ) bExists = false; if( bExists && groupMerger.ProtoGroup.Operation == DslEditorModeling.ModelProtoGroupOperation.Move ) { groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeElementLinkExistsOnMoveId", DslEditorModeling.ModelValidationViolationType.Error, "Element link exists although the operation = Move.")); } #region Target // see if target element was copied DslEditorModeling::ModelProtoRolePlayer targetRolePlayer = protoLink.GetTargetRolePlayer(this.Store.DefaultPartition); DslEditorModeling::ModelProtoElement targetProtoElement = groupMerger.GetElementById(targetRolePlayer.RolePlayerId); System.Guid mappedTargetId = System.Guid.Empty; if( targetProtoElement != null ) { mappedTargetId= groupMerger.GetIdMapping(targetRolePlayer.RolePlayerId); } if( mappedTargetId == System.Guid.Empty ) { // try creating relationship to existing element mappedTargetId = targetRolePlayer.RolePlayerId; } if( mappedTargetId == System.Guid.Empty ) { // try creating relationship to existing element with the same name as the previous element // TODO } if( mappedTargetId == System.Guid.Empty ) { // log warning groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeLinkElementNotCopiedId", DslEditorModeling.ModelValidationViolationType.Error, "Referenced model element was not copied. Relationship: RelationshipShapeClassReferencesReferenceRelationship")); } else { DslModeling::ModelElement targetElement = this.Store.ElementDirectory.FindElement(mappedTargetId); if( targetElement == null ) { // log error groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeLinkElementNotFoundId", DslEditorModeling.ModelValidationViolationType.Error, "Referenced model element was not found. Relationship: RelationshipShapeClassReferencesReferenceRelationship")); } else { bool bContinue = true; // check cardinalities, so we don't violate them by additing a new relationship if( DslModeling::DomainRoleInfo.GetLinkedElement(this, global::Tum.PDE.LanguageDSL.RelationshipShapeClassReferencesReferenceRelationship.RelationshipShapeClassDomainRoleId) != null ) { // log warning groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergeLinkCreationViolatesMultiplicityId", DslEditorModeling.ModelValidationViolationType.Error, "Can not create relationship because one already exists. Relationship: RelationshipShapeClassReferencesReferenceRelationship")); bContinue = false; } if( bContinue ) { // create property assignments DslModeling::PropertyAssignment[] propertyAssignemnts = protoLink.GetPropertyAssignments(this.Store.DefaultPartition, System.Guid.NewGuid()); // create role assignments DslModeling.RoleAssignment[] roleAssignments = new DslModeling.RoleAssignment[2]; roleAssignments[0] = new DslModeling.RoleAssignment(global::Tum.PDE.LanguageDSL.RelationshipShapeClassReferencesReferenceRelationship.RelationshipShapeClassDomainRoleId, this); roleAssignments[1] = new DslModeling.RoleAssignment(global::Tum.PDE.LanguageDSL.RelationshipShapeClassReferencesReferenceRelationship.DomainRelationshipDomainRoleId, targetElement); // create new relationship new global::Tum.PDE.LanguageDSL.RelationshipShapeClassReferencesReferenceRelationship(this.Store, roleAssignments, propertyAssignemnts); } } } #endregion } } base.ModelMerge(protoLink, groupMerger); }
/// <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(DslEditorModeling::ModelProtoElement protoElement, DslEditorModeling::ModelProtoGroupMerger groupMerger, bool isRoot) { if( !ModelIsPasteAllowed(groupMerger.ProtoGroup.Operation) ) { // add warning message groupMerger.MergeResult.AddMessage(new DslEditorModeling::ValidationMessage("ModelMergePasteDisallowedId", DslEditorModeling.ModelValidationViolationType.Warning, "Element couldn't be addded to DiagramClassView because paste is not allowed.")); return; } if (protoElement != null) { DslModeling::DomainClassInfo elementDomainInfo = this.Partition.DomainDataDirectory.GetDomainClass(protoElement.DomainClassId); if (elementDomainInfo.IsDerivedFrom(global::Tum.PDE.LanguageDSL.RootDiagramNode.DomainClassId)) { // get element id System.Guid newElementId = System.Guid.NewGuid(); // create property assignments DslModeling::PropertyAssignment[] propertyAssignemnts = protoElement.GetPropertyAssignments(this.Store.DefaultPartition, newElementId); // create the actual model element global::Tum.PDE.LanguageDSL.RootDiagramNode element = null; if( global::Tum.PDE.LanguageDSL.RootDiagramNode.DomainClassId == elementDomainInfo.Id ) element = new global::Tum.PDE.LanguageDSL.RootDiagramNode(this.Store, propertyAssignemnts); 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 DslEditorModeling.ValidationMessage("ModelMergePasteDisallowedId", DslEditorModeling.ModelValidationViolationType.Warning, "Element couldn't be addded to DiagramClassView because paste is not allowed.")); element.Delete(); return; } if( isRoot && groupMerger.ProtoGroup.Operation != DslEditorModeling.ModelProtoGroupOperation.Move) { //element.Name = "Copy of " + element.Name; } // update id mapping groupMerger.SetIdMapping(protoElement.ElementId, newElementId); // add child element GetRoleCollection<DslModeling::LinkedElementCollection<global::Tum.PDE.LanguageDSL.RootDiagramNode>, global::Tum.PDE.LanguageDSL.RootDiagramNode>(global::Tum.PDE.LanguageDSL.DiagramClassViewHasRootDiagramNodes.DiagramClassViewDomainRoleId).Add(element); // continue with child elements (Embedding Relationship) System.Collections.Generic.List<DslEditorModeling::ModelProtoElement> embeddedProtoElements = groupMerger.GetEmbeddedElements(this.Store.DefaultPartition, protoElement); if( embeddedProtoElements.Count > 0 ) { foreach (DslEditorModeling::ModelProtoElement p in embeddedProtoElements) (element as DslEditorModeling::IModelMergeElements).ModelMerge(p, groupMerger, false); } } } }