private void SetAttachments(WorkItem source, WorkItemMap map, WorkItem target) { if (map.Attachments == WorkItemMap.AttachmentMode.DoNotSync) { return; } var srcColl = new AttachmentEnumerable(source.Attachments); var dstColl = new AttachmentEnumerable(target.Attachments); var comparer = new AttachmentComparer(); if ((map.Attachments & WorkItemMap.AttachmentMode.ClearTarget) == WorkItemMap.AttachmentMode.ClearTarget) { target.Attachments.Clear(); } else if ((map.Attachments & WorkItemMap.AttachmentMode.RemoveIfAbsent) == WorkItemMap.AttachmentMode.RemoveIfAbsent) { var onlyInTarget = dstColl.Except(srcColl, comparer).ToList(); // remove foreach (var a in onlyInTarget) { try { target.Attachments.Remove(a); } catch (Exception ex) { this.EventSink.ExceptionWhileRemovingAttachment(ex, a, target); } //try } //for } //if if ((map.Attachments & WorkItemMap.AttachmentMode.AddAndUpdate) == WorkItemMap.AttachmentMode.AddAndUpdate) { var onlyInSource = srcColl.Except(dstColl, comparer).ToList(); //add foreach (var sourceAttachment in onlyInSource) { try { // see http://stackoverflow.com/questions/3507939/how-can-i-add-an-attachment-via-the-sdk-to-a-work-item-without-using-a-physical string tempFile = DownloadAttachment(sourceAttachment); Attachment newAttachment = new Attachment(tempFile, sourceAttachment.Comment); // TODO check SourceStore.MaxBulkUpdateBatchSize vs DestinationStore.MaxBulkUpdateBatchSize target.Attachments.Add(newAttachment); } catch (Exception ex) { this.EventSink.ExceptionWhileAddingAttachment(ex, sourceAttachment, source); } //try } //for } //if }
private FieldCopier GetCopier(WorkItemType sourceType, WorkItemMap map, WorkItemType targetType) { if (copiers.ContainsKey(map)) { return(copiers[map]); } var copier = new FieldCopier(this.Mapping, this.functions, this.UseEditableProperty, sourceType, map, targetType, this.EventSink); //cache copiers[map] = copier; return(copier); }
internal object MapState(FieldMap rule, WorkItemMap map, WorkItemsStageConfiguration mapping, object sourceValue) { var x = map.FindMappedState(sourceValue.ToString()); if (x != null) { return(x.Destination); } else { eventSink.NoTargetState(map, sourceValue); return(string.Empty); } }
protected virtual void SetWorkItemFields(WorkItem source, WorkItemMap map, WorkItem target) { var copier = GetCopier(source.Type, map, target.Type); if (this.OpenTargetWorkItem) { // force load and edit mode target.Open(); } else if (this.PartialOpenTargetWorkItem) { // force load and edit mode target.PartialOpen(); } copier.Copy(source, target, this.EventSink); }
internal object MapIterationPath(FieldMap rule, WorkItemMap map, WorkItemsStageConfiguration mapping, object sourceValue) { var path = sourceValue.ToString(); // search suitable mapping var x = mapping.FindExactMappedIterationPath(path); if (x == null) { x = mapping.GetDefaultIterationPathMapping(); if (x == null) { eventSink.NoWildcardIterationRule(mapping, sourceValue); } else { eventSink.IterationPathNotFoundUsingWildcardRule(mapping, sourceValue); } } if (x != null) { if (x.DestinationPath == "*") { // replace project name path = this.destProjectName + path.Substring(this.sourceProjectName.Length); } else if (!string.IsNullOrWhiteSpace(x.DestinationPath)) { path = x.DestinationPath; } else { path = this.destProjectName; } } return(path); }
public FieldCopier(WorkItemsStageConfiguration mapping, MapperFunctions functions, bool useEditableProperty, WorkItemType sourceType, WorkItemMap map, WorkItemType targetType, IEngineEvents engineEvents) { engineEvents.TraceRule("Interpreting rules for mapping '{0}' workitems to '{1}'", sourceType.Name, targetType.Name); foreach (FieldDefinition fromField in sourceType.FieldDefinitions) { var rule = map.FindFieldRule(fromField.ReferenceName); if (rule == null) { // if no rule -> skip field engineEvents.NoRuleFor(sourceType, fromField.ReferenceName); continue; } string targetFieldName = rule.IsWildcard ? fromField.ReferenceName : rule.Destination; if (string.IsNullOrWhiteSpace(rule.Destination)) { engineEvents.TraceRule("Skip {0}", fromField.ReferenceName); continue; } if (!targetType.FieldDefinitions.Contains(targetFieldName)) { engineEvents.TraceRule("Skip {0} (Target field {1} does not exist)", fromField.ReferenceName, targetFieldName); continue; } var toField = targetType.FieldDefinitions[targetFieldName]; if (!IsAssignable(useEditableProperty, fromField, toField)) { engineEvents.TraceRule("Skip {0} (Not assignable to {1})", fromField.ReferenceName, targetFieldName); continue; }//if // make the proper copier function Action <Field, Field> copyAction; if (rule.IsWildcard) { engineEvents.TraceRule("Copy {0} to {1} (Wildcard)", fromField.ReferenceName, targetFieldName); copyAction = (src, dst) => { dst.Value = src.Value; }; } else if (!string.IsNullOrWhiteSpace(rule.Set)) { engineEvents.TraceRule("Set {0} to value '{1}'", targetFieldName, rule.Set); copyAction = (src, dst) => { engineEvents.Trace(" *** converting '{0}' to {1}", rule.Set, dst.FieldDefinition.FieldType); SetFieldWithConstant(dst, rule.Set); }; } else if (!string.IsNullOrWhiteSpace(rule.SetIfNull)) { engineEvents.TraceRule("Set {0} to value '{1}' when source is null or empty", targetFieldName, rule.SetIfNull); copyAction = (src, dst) => { if (src.Value == null || string.IsNullOrEmpty(src.Value.ToString())) { SetFieldWithConstant(dst, rule.SetIfNull); } else { dst.Value = src.Value; } }; } else if (!string.IsNullOrWhiteSpace(rule.Translate)) { var flags = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic; // TODO optimize var translatorMethod = functions.GetType().GetMethod(rule.Translate, flags); if (translatorMethod == null) { engineEvents.TranslatorFunctionNotFoundUsingDefault(rule); // default: no translation engineEvents.TraceRule("Copy {0} to {1} (fallback)", fromField.ReferenceName, targetFieldName); copyAction = (src, dst) => { dst.Value = src.Value; }; } else { engineEvents.TraceRule("Translate {0} via {1}", targetFieldName, rule.Translate); copyAction = (src, dst) => { dst.Value = translatorMethod.Invoke(functions, new object[] { rule, map, mapping, src.Value }); }; } } else { //engineEvents.InvalidRule(rule); engineEvents.TraceRule("Copy {0} to {1} (Explicit)", fromField.ReferenceName, targetFieldName); // crossing fingers copyAction = (src, dst) => { dst.Value = src.Value; }; }//if tasks.Add(fromField, new CopyTask() { SourceFieldName = fromField.ReferenceName, CopyAction = copyAction, TargetFieldName = targetFieldName }); }//for fields // now the Set rules! foreach (var rule in map.Fields) { if (string.IsNullOrWhiteSpace(rule.Source)) { if (!string.IsNullOrWhiteSpace(rule.Set)) { engineEvents.TraceRule("Set {0} to value '{1}'", rule.Destination, rule.Set); unboundTasks.Add(new CopyTask() { SourceFieldName = string.Empty, CopyAction = (src, dst) => { SetFieldWithConstant(dst, rule.Set); }, TargetFieldName = rule.Destination }); } else if (!string.IsNullOrWhiteSpace(rule.SetIfNull)) { engineEvents.TraceRule("Set {0} to value '{1}' when destination is null or empty", rule.Destination, rule.SetIfNull); unboundTasks.Add(new CopyTask() { SourceFieldName = string.Empty, CopyAction = (src, dst) => { if (dst.Value == null || string.IsNullOrEmpty(dst.Value.ToString())) { SetFieldWithConstant(dst, rule.SetIfNull); } }, TargetFieldName = rule.Destination }); } } //if } //for }
public FieldMap FindIdFieldForTargetWorkItemType(string destWorkItemType) { WorkItemMap wiMap = WorkItemMappings.Where(m => m.DestinationType == destWorkItemType).FirstOrDefault(); return(wiMap.IDField); }
public void NoTargetState(WorkItemMap map, object state) { this.UniqueWarning(" State '{0}'\'{1}' not found in '{2}'.", map.SourceType, state, map.DestinationType); }