/// <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); }