/// <summary> /// Adds a proto element to the proto elements collection. /// </summary> /// <param name="protoElement">Proto element to add to the collection.</param> /// <param name="index">Index.</param> public void InsertNewRootElement(ModelProtoElement protoElement, int index) { if (!this.protoRootElements.Contains(protoElement)) { protoRootElements.Insert(index, protoElement); } }
/// <summary> /// Adds a proto element to the proto elements collection. /// </summary> /// <param name="protoElement">Proto element to add to the collection.</param> public void AddNewElement(ModelProtoElement protoElement) { if (!protoElements.Contains(protoElement)) { protoElements.Add(protoElement); } }
/// <summary> /// Get target proto links. /// </summary> /// <param name="partition"></param> /// <param name="protoElement"></param> /// <returns></returns> public List <ModelProtoLink> GetReferenceLinksTarget(Partition partition, ModelProtoElement protoElement) { List <ModelProtoLink> elements; this.referencingMappingTarget.TryGetValue(protoElement.ElementId, out elements); return(elements); }
/// <summary> /// Get all embedded proto elements for the given element. /// </summary> /// <param name="partition">Partition.</param> /// <param name="protoElement">Proto element to get all embedded elements for.</param> /// <returns>List of embedded proto elements.</returns> public List <ModelProtoElement> GetEmbeddedElements(Partition partition, ModelProtoElement protoElement) { List <ModelProtoElement> elements; this.embeddingMapping.TryGetValue(protoElement.ElementId, out elements); return(elements); }
/// <summary> /// Adds a proto element to the proto elements collection. /// </summary> /// <param name="protoElement">Proto element to add to the collection.</param> public void AddNewRootElement(ModelProtoElement protoElement) { if (!this.protoRootElements.Contains(protoElement)) { protoRootElements.Add(protoElement); } }
/// <summary> /// Gets the target proto links. /// </summary> /// <param name="partition"></param> /// <param name="protoElement"></param> /// <returns></returns> public List <ModelProtoLink> GetReferenceLinksTarget(Partition partition, ModelProtoElement protoElement) { if (bNeedsInitialization) { InitDictionaries(partition); } List <ModelProtoLink> elements; this.referencingMappingTarget.TryGetValue(protoElement.ElementId, out elements); return(elements); }
/// <summary> /// Get all embedded proto elements for the given element. /// </summary> /// <param name="partition">Partition.</param> /// <param name="protoElement">Proto element to get all embedded elements for.</param> /// <returns>List of embedded proto elements.</returns> public List <ModelProtoElement> GetEmbeddedElements(Partition partition, ModelProtoElement protoElement) { if (bNeedsInitialization) { InitDictionaries(partition); } List <ModelProtoElement> elements; this.embeddingMapping.TryGetValue(protoElement.ElementId, out elements); return(elements); }
/// <summary> /// Decides whether the element that is represented by the proto element can be pasted or not. /// </summary> /// <param name="protoElement">Proto element representation of the element.</param> /// <param name="protoGroup">Proto group the proto element belongs to.</param> /// <returns>True if the element can be pasted. False otherwise.</returns> public virtual bool ModelCanMerge(ModelProtoElement protoElement, ModelProtoGroup protoGroup) { 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)) { if (info.OppositeDomainRole.Multiplicity == Multiplicity.One || info.OppositeDomainRole.Multiplicity == Multiplicity.ZeroOne) { // Check that creating a link with this path doesn't cause multiplicity overflow if (DomainRoleInfo.GetLinkedElement(this, info.OppositeDomainRole.Id) != null) { return(false); } return(true); } else { if (protoGroup.Operation == ModelProtoGroupOperation.Move) { foreach (ElementLink link in DomainRoleInfo.GetElementLinks <ElementLink>(this, info.OppositeDomainRole.Id)) { if (DomainRoleInfo.GetTargetRolePlayer(link).Id == protoElement.ElementId) { return(false); } } } return(true); } } } } } } return(false); }
private void InitDictionaries(Partition partition) { bNeedsInitialization = false; this.embeddingMapping = new Dictionary <Guid, List <ModelProtoElement> >(); this.referencingMapping = new Dictionary <Guid, List <ModelProtoLink> >(); this.referencingMappingTarget = new Dictionary <Guid, List <ModelProtoLink> >(); this.elementMapping = new Dictionary <Guid, ModelProtoElement>(); foreach (ModelProtoElement element in this.ProtoElements) { embeddingMapping.Add(element.ElementId, new List <ModelProtoElement>()); referencingMapping.Add(element.ElementId, new List <ModelProtoLink>()); referencingMappingTarget.Add(element.ElementId, new List <ModelProtoLink>()); elementMapping.Add(element.ElementId, element); } foreach (ModelProtoLink link in this.ProtoEmbeddingLinks) { ModelProtoRolePlayer rolePlayer = link.GetSourceRolePlayer(partition); ModelProtoElement p = GetElementById(rolePlayer.RolePlayerId); if (p != null) { embeddingMapping[p.ElementId].Add( GetElementById(link.GetTargetRolePlayer(partition).RolePlayerId)); } } foreach (ModelProtoLink link in this.ProtoReferenceLinks) { ModelProtoRolePlayer sourceRP = link.GetSourceRolePlayer(partition); ModelProtoElement p = GetElementById(sourceRP.RolePlayerId); if (p != null) { referencingMapping[p.ElementId].Add(link); } ModelProtoRolePlayer targetRP = link.GetTargetRolePlayer(partition); p = GetElementById(targetRP.RolePlayerId); if (p != null) { referencingMappingTarget[p.ElementId].Add(link); } } }
/// <summary> /// Create a proto element representation of the element, which can be used for paste later. /// </summary> /// <param name="protoGroup">Proto group to add the element to.</param> /// <returns>Proto element representation of the element.</returns> public virtual ModelProtoElement ModelCreateMoveCopy(ModelProtoGroup protoGroup) { if (protoGroup.Operation == ModelProtoGroupOperation.Move) { if (!ModelIsMoveAllowed()) { return(null); } } if (protoGroup.Operation == ModelProtoGroupOperation.Copy) { return(null); } ModelProtoElement protoElement = new ModelProtoElement(this); protoGroup.AddNewElement(protoElement); return(protoElement); }
/// <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> /// 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 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> /// Decides whether the element that is represented by the proto element can be pasted or not. /// </summary> /// <param name="protoElement">Proto element representation of the element.</param> /// <param name="protoGroup">Proto group the proto element belongs to.</param> /// <returns>True if the element can be pasted. False otherwise.</returns> public virtual bool ModelCanMerge(ModelProtoElement protoElement, ModelProtoGroup protoGroup) { 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)) { if (info.OppositeDomainRole.Multiplicity == Multiplicity.One || info.OppositeDomainRole.Multiplicity == Multiplicity.ZeroOne) { // Check that creating a link with this path doesn't cause multiplicity overflow if (DomainRoleInfo.GetLinkedElement(this, info.OppositeDomainRole.Id) != null) return false; return true; } else { if (protoGroup.Operation == ModelProtoGroupOperation.Move) { foreach (ElementLink link in DomainRoleInfo.GetElementLinks<ElementLink>(this, info.OppositeDomainRole.Id)) if (DomainRoleInfo.GetTargetRolePlayer(link).Id == protoElement.ElementId) return false; } return true; } } } } return false; }
/// <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> /// Create a proto element representation of the element, which can be used for paste later. /// </summary> /// <param name="protoGroup">Proto group to add the element to.</param> /// <returns>Proto element representation of the element.</returns> public virtual ModelProtoElement ModelCreateMoveCopy(ModelProtoGroup protoGroup) { if (protoGroup.Operation == ModelProtoGroupOperation.Move) if (!ModelIsMoveAllowed()) return null; if (protoGroup.Operation == ModelProtoGroupOperation.Copy) return null; ModelProtoElement protoElement = new ModelProtoElement(this); protoGroup.AddNewElement(protoElement); return protoElement; }
/// <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> /// 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> /// Get target proto links. /// </summary> /// <param name="partition"></param> /// <param name="protoElement"></param> /// <returns></returns> public List<ModelProtoLink> GetReferenceLinksTarget(Partition partition, ModelProtoElement protoElement) { List<ModelProtoLink> elements; this.referencingMappingTarget.TryGetValue(protoElement.ElementId, out elements); return elements; }
/// <summary> /// Adds a proto element to the proto elements collection. /// </summary> /// <param name="protoElement">Proto element to add to the collection.</param> public void AddNewRootElement(ModelProtoElement protoElement) { if( !this.protoRootElements.Contains(protoElement)) protoRootElements.Add(protoElement); }
/// <summary> /// Gets the target proto links. /// </summary> /// <param name="partition"></param> /// <param name="protoElement"></param> /// <returns></returns> public List<ModelProtoLink> GetReferenceLinksTarget(Partition partition, ModelProtoElement protoElement) { if (bNeedsInitialization) InitDictionaries(partition); List<ModelProtoLink> elements; this.referencingMappingTarget.TryGetValue(protoElement.ElementId, out elements); return elements; }
/// <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> /// Constructor. /// </summary> /// <param name="protoGroup">Proto group to paste/move.</param> /// <param name="rootElement">Element to execute paste/move on.</param> public ModelProtoGroupMerger(ModelProtoGroup protoGroup, ModelElement rootElement) { this.protoGroup = protoGroup; this.validationResult = new ValidationResult(); this.idMapping = new Dictionary <Guid, Guid>(); this.embeddingMapping = new Dictionary <Guid, List <ModelProtoElement> >(); this.referencingMapping = new Dictionary <Guid, List <ModelProtoLink> >(); this.referencingMappingTarget = new Dictionary <Guid, List <ModelProtoLink> >(); this.elementMapping = new Dictionary <Guid, ModelProtoElement>(); if (protoGroup.Operation == ModelProtoGroupOperation.Move) { // move element foreach (ModelProtoElement protoElement in protoGroup.ProtoRootElements) { (rootElement as IModelMergeElements).ModelMove(protoElement, this); } return; } foreach (ModelProtoElement element in protoGroup.ProtoElements) { idMapping.Add(element.ElementId, Guid.Empty); embeddingMapping.Add(element.ElementId, new List <ModelProtoElement>()); referencingMapping.Add(element.ElementId, new List <ModelProtoLink>()); referencingMappingTarget.Add(element.ElementId, new List <ModelProtoLink>()); elementMapping.Add(element.ElementId, element); } foreach (ModelProtoLink link in protoGroup.ProtoEmbeddingLinks) { ModelProtoRolePlayer rolePlayer = link.GetSourceRolePlayer(rootElement.Store.DefaultPartition); ModelProtoElement p = GetElementById(rolePlayer.RolePlayerId); if (p != null) { embeddingMapping[p.ElementId].Add( GetElementById(link.GetTargetRolePlayer(rootElement.Store.DefaultPartition).RolePlayerId)); } } foreach (ModelProtoLink link in protoGroup.ProtoReferenceLinks) { ModelProtoRolePlayer sourceRP = link.GetSourceRolePlayer(rootElement.Store.DefaultPartition); ModelProtoElement p = GetElementById(sourceRP.RolePlayerId); if (p != null) { referencingMapping[p.ElementId].Add(link); } ModelProtoRolePlayer targetRP = link.GetTargetRolePlayer(rootElement.Store.DefaultPartition); p = GetElementById(targetRP.RolePlayerId); if (p != null) { referencingMappingTarget[p.ElementId].Add(link); } } // start merging foreach (ModelProtoElement protoElement in protoGroup.ProtoRootElements) { (rootElement as IModelMergeElements).ModelMerge(protoElement, this, true); } // process reference relationships foreach (ModelProtoLink link in protoGroup.ProtoReferenceLinks) { ModelProtoRolePlayer sourceRP = link.GetSourceRolePlayer(rootElement.Store.DefaultPartition); if (this.idMapping.ContainsKey(sourceRP.RolePlayerId)) { System.Guid id = this.idMapping[sourceRP.RolePlayerId]; if (id != Guid.Empty) { ModelElement copiedModelElement = rootElement.Store.ElementDirectory.FindElement(id); if (copiedModelElement != null) { if (copiedModelElement is IModelMergeElements) { (copiedModelElement as IModelMergeElements).ModelMerge(link, this); } } continue; } } System.Guid elementId = sourceRP.RolePlayerId; ModelElement modelElement = rootElement.Store.ElementDirectory.FindElement(elementId); if (modelElement != null) { if (modelElement is IModelMergeElements) { (modelElement as IModelMergeElements).ModelMerge(link, this); } } } // finalize merging foreach (ModelProtoElement protoElement in protoGroup.ProtoElements) { Guid id = Guid.Empty; try { id = GetIdMapping(protoElement.ElementId); } catch { id = Guid.Empty; continue; } /* * if (id == Guid.Empty) * { * ModelElement m = rootElement.Store.ElementDirectory.FindElement(id); * if (m != null) * id = m.Id; * else * continue; * }*/ ModelElement m = rootElement.Store.ElementDirectory.FindElement(id); if (m != null) { (m as IModelMergeElements).ModelFinalize(protoElement, this); } } // finalize merging foreach (ModelProtoElement protoElement in protoGroup.ProtoRootElements) { (rootElement as IModelMergeElements).ModelFinalizeMerge(protoElement, this); } }
/// <summary> /// Get all embedded proto elements for the given element. /// </summary> /// <param name="partition">Partition.</param> /// <param name="protoElement">Proto element to get all embedded elements for.</param> /// <returns>List of embedded proto elements.</returns> public List<ModelProtoElement> GetEmbeddedElements(Partition partition, ModelProtoElement protoElement) { if (bNeedsInitialization) InitDictionaries(partition); List<ModelProtoElement> elements; this.embeddingMapping.TryGetValue(protoElement.ElementId, out elements); return elements; }
/// <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 element to the proto elements collection. /// </summary> /// <param name="protoElement">Proto element to add to the collection.</param> public void AddNewElement(ModelProtoElement protoElement) { if (!protoElements.Contains(protoElement)) protoElements.Add(protoElement); }
/// <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> /// Adds a proto element to the proto elements collection. /// </summary> /// <param name="protoElement">Proto element to add to the collection.</param> /// <param name="index">Index.</param> public void InsertNewRootElement(ModelProtoElement protoElement, int index) { if (!this.protoRootElements.Contains(protoElement)) protoRootElements.Insert(index, protoElement); }
/// <summary> /// Get all embedded proto elements for the given element. /// </summary> /// <param name="partition">Partition.</param> /// <param name="protoElement">Proto element to get all embedded elements for.</param> /// <returns>List of embedded proto elements.</returns> public List<ModelProtoElement> GetEmbeddedElements(Partition partition, ModelProtoElement protoElement) { List<ModelProtoElement> elements; this.embeddingMapping.TryGetValue(protoElement.ElementId, out elements); return elements; }