/// <summary> /// Verifies if a paste operation can be executed in the current context. /// </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>True if paste can be executed. False otherwise.</returns> public static bool CanMerge(ModelElement rootElement, IDataObject dataObject) { if (rootElement is IModelMergeElements) { ModelProtoGroup group = GetModelProtoGroup(dataObject); if (group == null) { return(false); } if (group.ProtoRootElements.Count == 0) { return(false); } foreach (ModelProtoElement p in group.ProtoRootElements) { if (!(rootElement as IModelMergeElements).ModelCanMerge(p, group)) { return(false); } } return(true); } return(false); }
/// <summary> /// Executes the paste operation on the given element. /// </summary> /// <param name="modelElement">Element.</param> /// <returns>Validation result, indicating problems during the paste operation.</returns> public static ValidationResult ExecutePaste(ModelElement modelElement) { System.Windows.IDataObject idataObject = System.Windows.Clipboard.GetDataObject(); ValidationResult result = null; using (Transaction transaction = modelElement.Store.TransactionManager.BeginTransaction("Paste")) { result = ModelElementOperations.Merge(modelElement, idataObject); transaction.Commit(); } ModelProtoGroup group = ModelElementOperations.GetModelProtoGroup(idataObject); if (group != null) { if (group.Operation == ModelProtoGroupOperation.Move) { System.Windows.Clipboard.Clear(); ElementsInMoveMode.Clear(); } } return(result); }
/// <summary> /// Copies the given elements to the dataObject for the move operation. /// </summary> /// <param name="elements">Elements to copy.</param> /// <param name="dataObject">DataObject to add the data to.</param> /// <returns>DataObjects with the added data.</returns> public static IDataObject CopyToMove(ICollection <ModelElement> elements, IDataObject dataObject) { ModelProtoGroup protoGroup = new ModelProtoGroup(elements, ModelProtoGroupOperation.Move); dataObject.SetData(ModelProtoGroup.DefaultDataFormatName, protoGroup); dataObject.SetData(ModelProtoGroup.DefaultDataIdentifierName, Guid.NewGuid()); return(dataObject); }
/// <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); }
/// <summary> /// Helper method of the cut opeation. /// </summary> /// <param name="eventManager">Event manager.</param> /// <param name="idataObject">Data object.</param> public static void ProcessMoveMode(System.Windows.IDataObject idataObject) { bool isInMoveMode = false; if (idataObject != null) { ModelProtoGroup group = ModelElementOperations.GetModelProtoGroup(idataObject); if (group != null) { if (group.Operation == ModelProtoGroupOperation.Move) { isInMoveMode = true; List <System.Guid> guids = new List <System.Guid>(); foreach (ModelProtoElement root in group.ProtoRootElements) { guids.Add(root.ElementId); } foreach (System.Guid id in guids) { if (!ElementsInMoveMode.Contains(id)) { //eventManager.GetEvent<ModelElementCustomEvent<bool>>().Publish(true, ModelElementCustomEventNames.ModelElementMoveModeStatus, id); ElementsInMoveMode.Add(id); } } for (int i = ElementsInMoveMode.Count - 1; i >= 0; i--) { if (!guids.Contains(ElementsInMoveMode[i])) { //eventManager.GetEvent<ModelElementCustomEvent<bool>>().Publish(false, ModelElementCustomEventNames.ModelElementMoveModeStatus, ElementsInMoveMode[i]); ElementsInMoveMode.RemoveAt(i); } } } } } if (!isInMoveMode) { // remove all elements from the current list and notify them to change status //foreach (System.Guid id in ElementsInMoveMode) // eventManager.GetEvent<ModelElementCustomEvent<bool>>().Publish(false, ModelElementCustomEventNames.ModelElementMoveModeStatus, id); } }
/// <summary> /// Deserialize. /// </summary> public void OnDeserialization(object sender) { elementId = (Guid)serializationInfo.GetValue("elementId", typeof(Guid)); domainClassId = (Guid)serializationInfo.GetValue("domainClassId", typeof(Guid)); properties = (System.Collections.ArrayList)serializationInfo.GetValue("properties", typeof(System.Collections.ArrayList)); name = (string)serializationInfo.GetValue("name", typeof(string)); try { customChildGroup = (ModelProtoGroup)serializationInfo.GetValue("customChildGroup", typeof(ModelProtoGroup)); } catch { } try { CustomArguments = serializationInfo.GetValue("customArguments", typeof(IModelMergeCustomArguments)) as IModelMergeCustomArguments; } catch { } }
/// <summary> /// Retrieves a model proto group from the given data object if one exists. /// </summary> /// <param name="dataObject">Data objects to retrieve a model proto group from.</param> /// <returns>ModelProtoGroup instance or null.</returns> public static ModelProtoGroup GetModelProtoGroup(IDataObject dataObject) { ModelProtoGroup group = null; if (dataObject.GetDataPresent(ModelProtoGroup.DefaultDataFormatName)) { Guid guid = Guid.Empty; if (dataObject.GetDataPresent(ModelProtoGroup.DefaultDataIdentifierName)) { guid = (System.Guid)dataObject.GetData(ModelProtoGroup.DefaultDataIdentifierName); } if ((cachedPrototype != null) && guid == cachedPrototype.InstanceId) { return(cachedPrototype.Prototype); } object obj = dataObject.GetData(ModelProtoGroup.DefaultDataFormatName); group = obj as ModelProtoGroup; cachedPrototype = new CachedModelProtoGroup(guid, group); } return(group); }
public override void ModelProcessMergeCopy(CopyPaste.ModelProtoElement protoElement, CopyPaste.ModelProtoGroup protoGroup) { base.ModelProcessMergeCopy(protoElement, protoGroup); // copy rs and target elements if required if (CopyPaste.CopyAndPasteOperations.Operation == CopyPaste.CopyAndPasteOperation.CopyEmbeddingTree || CopyPaste.CopyAndPasteOperations.Operation == CopyPaste.CopyAndPasteOperation.CopyAllTree || CopyPaste.CopyAndPasteOperations.Operation == CopyPaste.CopyAndPasteOperation.CopyReferenceTree) { foreach (DomainRole role in this.RolesPlayed) { if (role.Relationship is EmbeddingRelationship && role.Relationship.Source == role) { if (CopyPaste.CopyAndPasteOperations.Operation == CopyPaste.CopyAndPasteOperation.CopyEmbeddingTree || CopyPaste.CopyAndPasteOperations.Operation == CopyPaste.CopyAndPasteOperation.CopyAllTree) { ModelProtoElement e = (role.Relationship as IModelMergeElements).ModelCreateMergeCopy(protoGroup); protoGroup.AddNewRootElement(e); // continue with target element if (ImmutabilityExtensionMethods.GetLocks(role.Relationship.Target.RolePlayer) == Locks.None) { if (!protoGroup.HasProtoElementFor(role.Relationship.Target.RolePlayer.Id, this.Partition)) { ModelProtoElement d = (role.Relationship.Target.RolePlayer as IModelMergeElements).ModelCreateMergeCopy(protoGroup); protoGroup.InsertNewRootElement(d, 0); } } } } else if (role.Relationship is ReferenceRelationship && role.Relationship.Source == role) { if (CopyPaste.CopyAndPasteOperations.Operation == CopyPaste.CopyAndPasteOperation.CopyAllTree || CopyPaste.CopyAndPasteOperations.Operation == CopyPaste.CopyAndPasteOperation.CopyReferenceTree) { ModelProtoElement e = (role.Relationship as IModelMergeElements).ModelCreateMergeCopy(protoGroup); protoGroup.AddNewRootElement(e); } } } // sort proto elements: bring domain classes to the top protoGroup.SortProtoElements(SortProtoElements); } // copy order of attributes and children DomainClassSerializationInfo info = new DomainClassSerializationInfo( this.SerializedDomainClass.Children.Count, this.SerializedDomainClass.Attributes.Count); for (int i = 0; i < this.SerializedDomainClass.Attributes.Count; i++) { SerializationAttributeElement aatr = this.SerializedDomainClass.Attributes[i]; if (aatr is SerializedDomainProperty) { SerializedDomainProperty sP = aatr as SerializedDomainProperty; ElementSerializationInfo sInfo = new ElementSerializationInfo( sP.DomainProperty.Name, sP.DomainProperty.Id); if (sP.OmitProperty) { sInfo.OmitElement = true; } info.AttributesOrder.Add(sInfo); } else if (aatr is SerializedIdProperty) { SerializedIdProperty sI = aatr as SerializedIdProperty; ElementSerializationInfo sInfo = new ElementSerializationInfo("SerializedIdProperty", Guid.Empty); if (sI.OmitIdProperty) { sInfo.OmitElement = true; } info.AttributesOrder.Add(sInfo); } } for (int i = 0; i < this.SerializedDomainClass.Children.Count; i++) { SerializationElement sE = this.SerializedDomainClass.Children[i]; if (sE is SerializedReferenceRelationship) { SerializedReferenceRelationship sDomainRel = sE as SerializedReferenceRelationship; ElementSerializationInfo sInfo = new ElementSerializationInfo( sDomainRel.ReferenceRelationship.Name, sDomainRel.ReferenceRelationship.Id); if (sDomainRel.OmitRelationship) { sInfo.OmitElement = true; } info.ChildrenOrder.Add(sInfo); } else if (sE is SerializedEmbeddingRelationship) { SerializedEmbeddingRelationship sDomainRel = sE as SerializedEmbeddingRelationship; ElementSerializationInfo sInfo = new ElementSerializationInfo( sDomainRel.EmbeddingRelationship.Name, sDomainRel.EmbeddingRelationship.Id); if (sDomainRel.OmitRelationship) { sInfo.OmitElement = true; } info.ChildrenOrder.Add(sInfo); } else if (sE is SerializedDomainProperty) { SerializedDomainProperty sP = sE as SerializedDomainProperty; ElementSerializationInfo sInfo = new ElementSerializationInfo( sP.DomainProperty.Name, sP.DomainProperty.Id); if (sP.OmitProperty) { sInfo.OmitElement = true; } info.ChildrenOrder.Add(sInfo); } } protoElement.CustomArguments = info; }
/// <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> /// 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); } }
public override bool ModelCanMerge(CopyPaste.ModelProtoElement protoElement, CopyPaste.ModelProtoGroup protoGroup) { if (protoElement != null) { DomainClassInfo elementDomainInfo = this.Partition.DomainDataDirectory.GetDomainClass(protoElement.DomainClassId); if (elementDomainInfo.IsDerivedFrom(global::Tum.PDE.LanguageDSL.DomainClass.DomainClassId)) { if (protoGroup.Operation == ModelProtoGroupOperation.Move) { foreach (global::Tum.PDE.LanguageDSL.LibraryModelContextHasClasses link in DomainRoleInfo.GetElementLinks <global::Tum.PDE.LanguageDSL.LibraryModelContextHasClasses>(this, global::Tum.PDE.LanguageDSL.LibraryModelContextHasClasses.LibraryModelContextDomainRoleId)) { if (link.DomainClass.Id == protoElement.ElementId) { return(false); } } } return(true); } else if (elementDomainInfo.IsDerivedFrom(global::Tum.PDE.LanguageDSL.DomainRelationship.DomainClassId)) { if (protoGroup.Operation == ModelProtoGroupOperation.Move) { foreach (global::Tum.PDE.LanguageDSL.LibraryModelContextHasRelationships link in DomainRoleInfo.GetElementLinks <global::Tum.PDE.LanguageDSL.LibraryModelContextHasRelationships>(this, global::Tum.PDE.LanguageDSL.LibraryModelContextHasRelationships.LibraryModelContextDomainRoleId)) { if (link.DomainRelationship.Id == protoElement.ElementId) { return(false); } } } // see if source and target domain classes are copied here List <ModelProtoElement> elements = protoGroup.GetEmbeddedElements(this.Partition, protoElement); for (int i = 0; i < elements.Count; i++) { if (elements[i].Name == "DomainRole") { List <ModelProtoLink> links = protoGroup.GetReferenceLinks(this.Partition, elements[i]); foreach (ModelProtoLink link in links) { if (link.Name == "DomainRoleReferencesRolePlayer") { ModelProtoRolePlayer rP = link.GetTargetRolePlayer(this.Partition); // see if the target element is beeing copied or is already in the model if (!protoGroup.HasProtoElementFor(rP.RolePlayerId, this.Partition)) { ModelElement m = this.Store.ElementDirectory.FindElement(rP.RolePlayerId); if (m == null) { if (!this.MetaModel.HasElement(rP.ElementName)) { return(false); } } } } } } } return(true); } } return(false); }
/// <summary> /// Constructor. /// </summary> /// <param name="instanceID"></param> /// <param name="prototype"></param> public CachedModelProtoGroup(Guid instanceID, ModelProtoGroup prototype) { this.instanceID = instanceID; this.prototype = prototype; }
public override void ModelProcessMergeCopy(ModelProtoElement protoElement, ModelProtoGroup protoGroup) { base.ModelProcessMergeCopy(protoElement, protoGroup); bool isInFull = false; bool isTargetInc = false; SerializationClass sClass; if (this is ReferenceRelationship) { sClass = (this as ReferenceRelationship).SerializedReferenceRelationship; isInFull = (this as ReferenceRelationship).SerializedReferenceRelationship.IsInFullSerialization; } else { sClass = (this as EmbeddingRelationship).SerializedEmbeddingRelationship; isInFull = (this as EmbeddingRelationship).SerializedEmbeddingRelationship.IsInFullSerialization; isTargetInc = (this as EmbeddingRelationship).SerializedEmbeddingRelationship.IsTargetIncludedSubmodel; } // copy order of attributes and children DomainRelationshipSerializationInfo info = new DomainRelationshipSerializationInfo( sClass.Children.Count, sClass.Attributes.Count); info.IsInFullSerialization = isInFull; info.IsTargetIncludedSubmodel = isTargetInc; for (int i = 0; i < sClass.Attributes.Count; i++) { SerializationAttributeElement aatr = sClass.Attributes[i]; if (aatr is SerializedDomainProperty) { SerializedDomainProperty sP = aatr as SerializedDomainProperty; ElementSerializationInfo sInfo = new ElementSerializationInfo( sP.DomainProperty.Name, sP.DomainProperty.Id); if (sP.OmitProperty) sInfo.OmitElement = true; info.AttributesOrder.Add(sInfo); } else if (aatr is SerializedIdProperty) { SerializedIdProperty sI = aatr as SerializedIdProperty; ElementSerializationInfo sInfo = new ElementSerializationInfo("SerializedIdProperty", Guid.Empty); if (sI.OmitIdProperty) sInfo.OmitElement = true; info.AttributesOrder.Add(sInfo); } } for (int i = 0; i < sClass.Children.Count; i++) { SerializationElement sE = sClass.Children[i]; if (sE is SerializedDomainProperty) { SerializedDomainProperty sP = sE as SerializedDomainProperty; ElementSerializationInfo sInfo = new ElementSerializationInfo( sP.DomainProperty.Name, sP.DomainProperty.Id); if (sP.OmitProperty) sInfo.OmitElement = true; info.ChildrenOrder.Add(sInfo); } } protoElement.CustomArguments = info; }