private static Dictionary <IMigrationFileAttachment, List <IMigrationAction> > GroupAttachmentByMetadata(ChangeGroup attachmentChangeGroup) { var metadataComparer = new BasicFileAttachmentComparer(); Dictionary <IMigrationFileAttachment, List <IMigrationAction> > perAttachmentChangeActions = new Dictionary <IMigrationFileAttachment, List <IMigrationAction> >(new BasicFileAttachmentComparer()); foreach (IMigrationAction migrationAction in attachmentChangeGroup.Actions) { if (IsAttachmentSpecificChangeAction(migrationAction.Action)) { FileAttachmentMetadata attchMetadata = FileAttachmentMetadata.Create(migrationAction.MigrationActionDescription); if (null != attchMetadata) { IMigrationFileAttachment existingKey = null; foreach (IMigrationFileAttachment key in perAttachmentChangeActions.Keys) { if (metadataComparer.Equals(key, attchMetadata)) { existingKey = key; break; } } if (null == existingKey) { existingKey = attchMetadata; perAttachmentChangeActions.Add(existingKey, new List <IMigrationAction>()); } perAttachmentChangeActions[existingKey].Add(migrationAction); } } } return(perAttachmentChangeActions); }
private bool AttachmentsMatch(IMigrationFileAttachment attachment1, IMigrationFileAttachment attachment2, out WitDiffAttachment diffAttachment) { if (!string.Equals(attachment1.Name, attachment2.Name, StringComparison.Ordinal)) { diffAttachment = new WitDiffAttachment(attachment1.Name, "Name", attachment1.Name, attachment2.Name); return(false); } if (!string.Equals(attachment1.Comment, attachment2.Comment, StringComparison.Ordinal)) { diffAttachment = new WitDiffAttachment(attachment1.Name, "Comment", attachment1.Comment, attachment2.Comment); return(false); } if (attachment1.Length != attachment2.Length) { diffAttachment = new WitDiffAttachment(attachment1.Name, "Length", attachment1.Length.ToString(), attachment2.Length.ToString()); return(false); } diffAttachment = null; return(true); }
private string GetAttachmentId(IMigrationFileAttachment fileAttachment) { return(fileAttachment.Name + ";" + fileAttachment.Length.ToString(CultureInfo.InvariantCulture)); }
private void FlattenDeltaTable( List <string> outMappedWorkItemUpdates, Dictionary <string, List <MigrationAction> > outMappedAttachmentUpdates, bool getSourceSideCopyInMigrationInstructionTable) { Guid sourceId = getSourceSideCopyInMigrationInstructionTable ? SourceSystemId : TargetSystemId; Guid targetId = getSourceSideCopyInMigrationInstructionTable ? TargetSystemId : SourceSystemId; int pageNumber = 0; int pageSize = 50; IEnumerable <ChangeGroup> changeGroups = null; do { changeGroups = getSourceSideCopyInMigrationInstructionTable ? TargetChangeGroupService.NextMigrationInstructionTablePage(pageNumber++, pageSize, true, true) : TargetChangeGroupService.NextDeltaTablePage(pageNumber++, pageSize, true); foreach (ChangeGroup changeGroupEntry in changeGroups) { foreach (MigrationAction action in changeGroupEntry.Actions) { if (action.Action.Equals(WellKnownChangeActionId.SyncContext)) { continue; } else if (action.Action == WellKnownChangeActionId.Add) { // do nothing for adding item, be it created by sync engine or not continue; } else if (action.Action == WellKnownChangeActionId.Edit) { string sourceSideItemId = GetSourceWorkItemIdFromActionDescription(action.MigrationActionDescription); string targetWorkItemId = TryGetTargetWorkItemId( action.MigrationActionDescription, sourceId, getSourceSideCopyInMigrationInstructionTable); if (string.IsNullOrEmpty(targetWorkItemId)) { // the source work item has never been migrated yet continue; } if (getSourceSideCopyInMigrationInstructionTable) { if (ConflictManager.IsItemInBacklog(sourceId, targetId, sourceSideItemId)) { // previous revision of the work item has conflict, push this revision to backlog as well string conflictDetails = ChainOnBackloggedItemConflictType.CreateConflictDetails(sourceSideItemId, action.Version); string scopeHint = ChainOnBackloggedItemConflictType.CreateScopeHint(sourceSideItemId); if (changeGroupEntry.ReflectedChangeGroupId.HasValue) { // we reactivate the original delta entry and discard this migration instruction entry // and then backlog the delta entry, to preserve correct order of the revisions ChangeGroup deltaChangeGroupEntry = TargetChangeGroupService.ReactivateDeltaEntry(changeGroupEntry); if (null != deltaChangeGroupEntry) { MigrationConflict chainedConflict = new ChainOnBackloggedItemConflictType().CreateConflict( conflictDetails, scopeHint, deltaChangeGroupEntry.Actions.First()); ConflictManager.BacklogUnresolvedConflict(ConflictManager.SourceId, chainedConflict, false); break; } } // if we can't find the original delta entry successfully, we block this migration instruction entry MigrationConflict conflict = new ChainOnBackloggedItemConflictType().CreateConflict( conflictDetails, scopeHint, action); ConflictManager.BacklogUnresolvedConflict(ConflictManager.SourceId, conflict, false); if (!m_conflictedWorkItems[targetId].Contains(targetWorkItemId)) { // record the target-side work item to be in conflict m_conflictedWorkItems[targetId].Add(targetWorkItemId); } break; } if (!m_perMappedItemEdits.ContainsKey(m_targetToSourceWorkItemIdMapping[targetWorkItemId])) { m_perMappedItemEdits.Add(m_targetToSourceWorkItemIdMapping[targetWorkItemId], new List <MigrationAction>()); } m_perMappedItemEdits[m_targetToSourceWorkItemIdMapping[targetWorkItemId]].Add(action); } else { // check if the revision is a sync copy from the other side if (TranslationService.IsSyncGeneratedAction(action, sourceId)) { continue; } if (m_conflictedWorkItems[sourceId].Contains(sourceSideItemId)) { string conflictDetails = ChainOnBackloggedItemConflictType.CreateConflictDetails(sourceSideItemId, action.Version); string scopeHint = ChainOnBackloggedItemConflictType.CreateScopeHint(sourceSideItemId); MigrationConflict conflict = new ChainOnBackloggedItemConflictType().CreateConflict( conflictDetails, scopeHint, action); ConflictManager.BacklogUnresolvedConflict(TargetSystemId, conflict, false); break; } if (!m_perMappedItemEditsTargetDelta.ContainsKey(targetWorkItemId)) { m_perMappedItemEditsTargetDelta.Add(targetWorkItemId, new List <MigrationAction>()); } m_perMappedItemEditsTargetDelta[targetWorkItemId].Add(action); } // item is mapped to an item on target system if (!outMappedWorkItemUpdates.Contains(targetWorkItemId)) { outMappedWorkItemUpdates.Add(targetWorkItemId); } } else if (action.Action == WellKnownChangeActionId.AddAttachment) { string targetWorkItemId = TryGetTargetWorkItemId( action.MigrationActionDescription, sourceId, getSourceSideCopyInMigrationInstructionTable); if (string.IsNullOrEmpty(targetWorkItemId)) { continue; } if (!outMappedAttachmentUpdates.ContainsKey(targetWorkItemId)) { outMappedAttachmentUpdates.Add(targetWorkItemId, new List <MigrationAction>()); } List <MigrationAction> attachmentList = outMappedAttachmentUpdates[targetWorkItemId]; IMigrationFileAttachment sourceItem = action.SourceItem as IMigrationFileAttachment; if (null == sourceItem) { throw new MigrationException(MigrationToolkitResources.InvalidSourceItemForAttachmentOperation); } if (!attachmentList.Contains(action)) { attachmentList.Add(action); } } else if (action.Action == WellKnownChangeActionId.DelAttachment) { // do nothing for now continue; } } } }while (changeGroups.Count() > 0); }