/// <summary> /// Add new proto link representing a embedding relationship to this proto group. /// </summary> /// <param name="protoLink">Proto link to add this proto group.</param> public void AddNewEmbeddingLink(ModelProtoLink protoLink) { if (!protoEmbeddingLinks.Contains(protoLink)) protoEmbeddingLinks.Add(protoLink); }
/// <summary> /// Add new proto link representing a reference relationship to this proto group. /// </summary> /// <param name="protoLink">Proto link to add this proto group.</param> public void AddNewReferenceLink(ModelProtoLink protoLink) { if (!protoReferenceLinks.Contains(protoLink)) protoReferenceLinks.Add(protoLink); }
/// <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> /// Processes a proto element representation of the element and adds required proto links. /// This method is called on base classes from derived classes. /// /// Hint: Properties do not need to be added in this method. /// </summary> /// <param name="protoElement">Proto element representation of the element.</param> /// <param name="protoGroup">Proto group the proto element belongs to.</param> public virtual void ModelProcessMergeCopy(ModelProtoElement protoElement, ModelProtoGroup protoGroup) { foreach (ElementLink link in DomainRoleInfo.GetAllElementLinks(this)) if (link is DomainModelLink) { DomainModelLink modelLink = link as DomainModelLink; DomainRelationshipAdvancedInfo info = this.Store.DomainDataAdvDirectory.GetRelationshipInfo(modelLink.GetDomainClassId()); if (info is ReferenceRelationshipAdvancedInfo) { if (DomainRoleInfo.GetSourceRolePlayer(modelLink) == this) { if (!(info as ReferenceRelationshipAdvancedInfo).PropagatesCopyToTarget) continue; } else if (!(info as ReferenceRelationshipAdvancedInfo).PropagatesCopyToSource) continue; ModelProtoLink protoLink = new ModelProtoLink(link); protoGroup.AddNewReferenceLink(protoLink); } else { DomainModelElement child = DomainRoleInfo.GetTargetRolePlayer(link) as DomainModelElement; if (child == this || child == null) continue; if ((info as EmbeddingRelationshipAdvancedInfo).PropagatesCopyToChild) { if (!(info as EmbeddingRelationshipAdvancedInfo).IsTargetIncludedSubmodel) { ModelProtoLink protoLink = new ModelProtoLink(link); protoGroup.AddNewEmbeddingLink(protoLink); child.ModelCreateMergeCopy(protoGroup); } else if( child is IParentModelElement ) { ModelProtoLink protoLink = new ModelProtoLink(link); protoLink.IsTargetIncludedSubmodel = true; protoLink.DomainFilePath = (child as IParentModelElement).DomainFilePath; protoGroup.AddNewReferenceLink(protoLink); } } } } /* // process reference relationships List<ReferenceRelationshipAdvancedInfo> infos = this.Store.DomainDataAdvDirectory.FindDomainClassSourceReferences(this.GetDomainClassId()); if (infos != null) foreach (ReferenceRelationshipAdvancedInfo info in infos) { if (info.PropagatesCopyToTarget) { System.Collections.ObjectModel.ReadOnlyCollection<ElementLink> links = DomainRoleInfo.GetElementLinks<ElementLink>(this, info.SourceRoleId); foreach (ElementLink link in links) { ModelProtoLink protoLink = new ModelProtoLink(link); protoGroup.AddNewReferenceLink(protoLink); } } } infos = this.Store.DomainDataAdvDirectory.FindDomainClassTargetReferences(this.GetDomainClassId()); if (infos != null) foreach (ReferenceRelationshipAdvancedInfo info in infos) { if (info.PropagatesCopyToSource) { System.Collections.ObjectModel.ReadOnlyCollection<ElementLink> links = DomainRoleInfo.GetElementLinks<ElementLink>(this, info.TargetRoleId); foreach (ElementLink link in links) { ModelProtoLink protoLink = new ModelProtoLink(link); protoGroup.AddNewReferenceLink(protoLink); } } } // process embedding relationships List<EmbeddingRelationshipAdvancedInfo> infosEmb = this.Store.DomainDataAdvDirectory.FindDomainClassSourceEmbeddings(this.GetDomainClassId()); if (infosEmb != null) foreach (EmbeddingRelationshipAdvancedInfo info in infosEmb) { if (info.PropagatesCopyToChild) { System.Collections.ObjectModel.ReadOnlyCollection<ElementLink> links = DomainRoleInfo.GetElementLinks<ElementLink>(this, info.SourceRoleId); foreach (ElementLink link in links) { ModelProtoLink protoLink = new ModelProtoLink(link); protoGroup.AddNewEmbeddingLink(protoLink); DomainModelElement child = DomainRoleInfo.GetTargetRolePlayer(link) as DomainModelElement; if( child != null ) child.ModelCreateMergeCopy(protoGroup); } } } */ }
/// <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) { (this.Element as IModelMergeElements).ModelMerge(protoLink, groupMerger); }