/// <summary> /// Updates destination item. /// </summary> /// <param name="sourceData">The source data set.</param> /// <param name="destination">The destination item.</param> private void UpdateFieldValues(DataTriggerSourceData sourceData, IEditableRoot destination) { foreach (var fieldUpdater in FieldUpdaters) fieldUpdater.CalculateNewValue(sourceData, destination); foreach (var fieldUpdater in FieldUpdaters) fieldUpdater.Update(destination); }
/// <summary> /// Calculates the new field value. /// </summary> /// <param name="sourceData"> /// The source data. /// </param> /// <param name="destination"> /// The destination. /// </param> public void CalculateNewValue(DataTriggerSourceData sourceData, IEditableRoot destination) { if (sourceData == null) throw new ArgumentNullException("sourceData"); if (destination == null) throw new ArgumentNullException("destination"); if (ValueCalculator == null) throw new InvalidOperationException("Value calculator cannot be null."); NewValue = ValueCalculator(sourceData, destination); }
/// <summary> /// Links items to destination field. /// </summary> /// <param name="source"> /// The source item. /// </param> /// <param name="destination"> /// The destination item. /// </param> private void ExecuteLink(IEditableRoot source, IEditableRoot destination) { var crList = (ICrossRefItemList)destination.GetValueByPropertyName(Property.Name); if (crList == null) { throw new InvalidOperationException("Destination field is null."); } var filterList = new FilterList(); if (crList.Count > 0) { // Exclude items that are already linked. filterList.Add(CreateLinkedItemsFilter(FilterOperator.NotIn, crList.Cast<ICrossRefItemInfo>().Select(x => x.Id))); } if (!string.IsNullOrEmpty(SourceDataFilterDefinition)) { filterList.Add(CreateSourceDataFilter(source)); } foreach (var infoItem in GetSourceItems(filterList)) { var ancestor = infoItem.GetAncestorByProcessName(ReferencedProcessName); if (ancestor == null || crList.Contains(ancestor.Id)) continue; crList.Assign(ancestor.Id); if (FieldUpdaters.Count == 0) continue; var criteria = new DetailCriteria(infoItem.Id) { AllowLazyLoading = true }; var editItem = DynamicTypeManager.GetEditableRoot<IEditableRoot>(SourceDataProcessName, criteria); if (editItem == null || editItem.Id <= 0) continue; var sourceData = new DataTriggerSourceData(); sourceData.SourceItems[DataTriggerFieldMappingExpressionNames.SourceDataProcess] = editItem; UpdateFieldValues(sourceData, editItem); ((ISavable)editItem).Save(); } }
/// <summary> /// Tries to create a filter descriptor that filters this field using the value returned by this mapping. /// </summary> /// <param name="sourceData"> /// The source data. /// </param> /// <param name="destination"> /// The destination. /// </param> /// <param name="filter"> /// The filter. /// </param> /// <returns> /// <c>true</c> if the filter was created successfully; otherwise, <c>false</c>. /// </returns> public bool TryCreateFilter(DataTriggerSourceData sourceData, IEditableRoot destination, out IFilterDescriptor filter) { throw new NotSupportedException(); }
/// <summary> /// Compares current field value with the value returned by the mapping. /// </summary> /// <param name="sourceData">The source data set.</param> /// <param name="destination">The destination item.</param> /// <returns>Returns true if field value is equal to the new value.</returns> public bool AreEqual(DataTriggerSourceData sourceData, IEditableRoot destination) { throw new NotSupportedException(); }
public void UpdateCanInsertItems() { // Arrange. const string ProcessName = "TestProcess"; const string DestinationFieldName = "TestField"; const string ReferencedProcessName = "RefProcess"; const string FieldName1 = "Field1"; const string FieldName2 = "Field2"; var dataSourceDefinition = new FieldMappingDataSourceDefinition("Test Data Source", ProcessName, "TestProperty", true, true, true); var fieldMapping1 = new DataTriggerFieldMapping(FieldName1, true, (s, d) => null); var fieldMapping2 = new DataTriggerFieldMapping(FieldName2, false, (s, d) => null); var mapping = new DataTriggerListFieldMapping(new[] { dataSourceDefinition }, DestinationFieldName, DataTriggerModificationType.Insert, new[] { fieldMapping1, fieldMapping2 }); var dtm = Mock.Create<IDynamicTypeManager>(); Mock.Arrange(() => dtm.GetEditableRootType(ProcessName)).Returns(typeof(DestinationEdit)); var item = Mock.Create<IEditableRoot>(); var sourceData1 = new DataTriggerSourceData(); var sourceData2 = new DataTriggerSourceData(); var sourceDataRetriever = Mock.Create<IFieldMappingSourceDataRetriever>(); Mock.Arrange(() => sourceDataRetriever.GetSourceData(item, null)).Returns(() => new[] { sourceData1, sourceData2 }); var savedDestinationItem1 = Mock.Create<IEditableRoot>(); Mock.Arrange(() => savedDestinationItem1.Id).Returns(111); var newDestinationItem1 = Mock.Create<IEditableRootStub>(); var savableDestinationItem1 = newDestinationItem1 as ISavable; Mock.Arrange(() => savableDestinationItem1.Save()).Returns(savedDestinationItem1); var savedDestinationItem2 = Mock.Create<IEditableRoot>(); Mock.Arrange(() => savedDestinationItem2.Id).Returns(222); var newDestinationItem2 = Mock.Create<IEditableRootStub>(); var savableDestinationItem2 = newDestinationItem2 as ISavable; Mock.Arrange(() => savableDestinationItem2.Save()).Returns(savedDestinationItem2); var newDestinationItems = new Queue<IEditableRoot>(new[] { newDestinationItem1, newDestinationItem2 }); Mock.Arrange(() => dtm.NewEditableRoot<IEditableRoot>(ReferencedProcessName)).Returns(newDestinationItems.Dequeue); var fieldUpdater1 = Mock.Create<IFieldUpdater>(); Mock.Arrange(() => fieldUpdater1.IsKey).Returns(true); var fieldUpdater2 = Mock.Create<IFieldUpdater>(); var fieldUpdaterFactory = Mock.Create<IFieldUpdaterFactory>(); Mock.Arrange(() => fieldUpdaterFactory.CreateFieldUpdater(ReferencedProcessName, fieldMapping1)).Returns(fieldUpdater1); Mock.Arrange(() => fieldUpdaterFactory.CreateFieldUpdater(ReferencedProcessName, fieldMapping2)).Returns(fieldUpdater2); var updater = new MultiCrossReferenceFieldUpdater { DynamicTypeManager = dtm, FieldUpdaterFactory = fieldUpdaterFactory, SourceDataRetrieverFactory = new ExportFactory<IFieldMappingSourceDataRetriever>( () => new Tuple<IFieldMappingSourceDataRetriever, Action>(sourceDataRetriever, () => { })) }; updater.Initialize(ProcessName, mapping); var destination = new DestinationEdit(); // Act. updater.BeforeItemUpdate(item, null); updater.AfterItemUpdate(item, null); updater.Update(item, destination); // Assert. Assert.AreEqual(2, destination.TestField.Count); Assert.IsTrue(destination.TestField.Any(x => x.Id == 111)); Assert.IsTrue(destination.TestField.Any(x => x.Id == 222)); Mock.Assert(() => fieldUpdater1.CalculateNewValue(sourceData1, newDestinationItem1), Occurs.Once()); Mock.Assert(() => fieldUpdater1.Update(newDestinationItem1), Occurs.Once()); Mock.Assert(() => fieldUpdater1.CalculateNewValue(sourceData2, newDestinationItem2), Occurs.Once()); Mock.Assert(() => fieldUpdater1.Update(newDestinationItem2), Occurs.Once()); Mock.Assert(() => fieldUpdater2.CalculateNewValue(sourceData1, newDestinationItem1), Occurs.Once()); Mock.Assert(() => fieldUpdater2.Update(newDestinationItem1), Occurs.Once()); Mock.Assert(() => fieldUpdater2.CalculateNewValue(sourceData2, newDestinationItem2), Occurs.Once()); Mock.Assert(() => fieldUpdater2.Update(newDestinationItem2), Occurs.Once()); Mock.Assert(() => savableDestinationItem1.Save(), Occurs.Once()); Mock.Assert(() => savableDestinationItem2.Save(), Occurs.Once()); }
/// <summary> /// Calculates the new field value. The new value is stored in the <see cref="NewValue"/> property. /// </summary> /// <param name="sourceData">The source data set.</param> /// <param name="destination">The destination item.</param> public void CalculateNewValue(DataTriggerSourceData sourceData, IEditableRoot destination) { if (sourceData == null) throw new ArgumentNullException("sourceData"); if (destination == null) throw new ArgumentNullException("destination"); if (AllowLocalizedData) { foreach (var localization in SupportedLocalizations) { var cultureName = localization.CultureName; SetValue(cultureName, GetValue(sourceData, destination, cultureName)); } } else { SetValue(DefaultCultureName, GetValue(sourceData, destination, DefaultCultureName)); } }
/// <summary> /// Calculates the new field value. /// </summary> /// <param name="sourceData"> /// The source data. /// </param> /// <param name="destination"> /// The destination. /// </param> public void CalculateNewValue(DataTriggerSourceData sourceData, IEditableRoot destination) { if (sourceData == null) throw new ArgumentNullException("sourceData"); if (destination == null) throw new ArgumentNullException("destination"); NewValue = GetValue(sourceData, destination); }
/// <summary> /// Compares current field value with the value returned by the mapping. /// </summary> /// <param name="sourceData">The source data set.</param> /// <param name="destination">The destination item.</param> /// <returns>Returns true if field value is equal to the new value.</returns> public bool AreEqual(DataTriggerSourceData sourceData, IEditableRoot destination) { if (sourceData == null) throw new ArgumentNullException("sourceData"); if (destination == null) throw new ArgumentNullException("destination"); var oldValue = SafeTypeConverter.Convert<int?>(destination.GetValueByPropertyName(FieldName)); var newValue = GetValue(sourceData, destination); return oldValue == newValue; }
public void CalculateNewValueWithChildMappings() { // Arrange. var dtm = Mock.Create<IDynamicTypeManager>(Behavior.Loose); var updater = new SingleCrossReferenceFieldUpdater { FieldName = ReflectionHelper.GetPropertyName<TestEdit>(x => x.Person), ReferencedProcessName = Constants.BasePersonProcessName, DynamicTypeManager = dtm }; var sourceData = new DataTriggerSourceData(); var destination = new TestEdit(); var childUpdater1 = Mock.Create<IFieldUpdater>(Behavior.Loose); Mock.Arrange(() => childUpdater1.IsKey).Returns(true); var childUpdater2 = Mock.Create<IFieldUpdater>(Behavior.Loose); Mock.Arrange(() => childUpdater2.IsKey).Returns(false); updater.ChildMappings.Add(childUpdater1); updater.ChildMappings.Add(childUpdater2); var filter = Mock.Create<IFilterDescriptor>(Behavior.Loose); Mock.Arrange(() => childUpdater1.TryCreateFilter(sourceData, destination, out filter)).Returns(true); var infoItem = Mock.Create<IInfoClass>(Behavior.Loose); Mock.Arrange(() => infoItem.Id).Returns(123); var infoList = new InfoListBase { infoItem }; Mock.Arrange( () => dtm.GetList<IInfoList>(Constants.BasePersonProcessName, string.Empty, 0, int.MaxValue, null, Arg.IsAny<FilterList>(), false)) .Returns<string, string, int, int, SortList, FilterList, bool>( (processName, filterString, pageNumber, pageSize, sortList, filterList, security) => { if (filterList != null && filterList.Count == 1 && filterList.Contains(filter)) return infoList; return null; }); // Act. updater.CalculateNewValue(sourceData, destination); // Assert. Assert.AreEqual(123, updater.NewValue); }
private void ExecuteLink(IEditableRoot source, IEditableRoot destination) { var infoItem = GetSourceItem(CreateSourceDataFilter(source)); if (infoItem == null) return; var ancestor = infoItem.GetAncestorByProcessName(ReferencedProcessName); if (ancestor == null) return; if (destination.GetValueByPropertyName(Property.Name) == ancestor.Id) return; destination.SetValueByPropertyName(Property.Name, ancestor.Id); if (FieldUpdaters.Count == 0) return; var criteria = new DetailCriteria(infoItem.Id) { AllowLazyLoading = true }; var editItem = DynamicTypeManager.GetEditableRoot<IEditableRoot>(SourceDataProcessName, criteria); if (editItem == null || editItem.Id <= 0) return; var sourceData = new DataTriggerSourceData(); sourceData.SourceItems[DataTriggerFieldMappingExpressionNames.SourceDataProcess] = editItem; UpdateFieldValues(sourceData, editItem); ((ISavable)editItem).Save(); }
private object GetValue(DataTriggerSourceData sourceData, IEditableRoot destination, string cultureName) { using (new CultureContext(cultureName)) { var value = ValueCalculator(sourceData, destination); if (FieldName == Constants.CurrentStateColumnName) return SafeTypeConverter.Convert<string>(value); return SafeTypeConverter.Convert(value, PropertyType); } }
/// <summary> /// Compares current field value with the value returned by the mapping. /// </summary> /// <param name="sourceData">The source data set.</param> /// <param name="destination">The destination item.</param> /// <returns>Returns true if field value is equal to the new value.</returns> public bool AreEqual(DataTriggerSourceData sourceData, IEditableRoot destination) { if (sourceData == null) throw new ArgumentNullException("sourceData"); if (destination == null) throw new ArgumentNullException("destination"); var oldValue = destination.GetValueByPropertyName(FieldName); var newValue = GetValue(sourceData, destination, DefaultCultureName); return oldValue != null ? oldValue.Equals(SafeTypeConverter.Convert(newValue, oldValue.GetType())) : newValue == null; }
/// <summary> /// Tries to create a filter descriptor that filters this field using the value returned by this mapping. /// </summary> /// <param name="sourceData"> /// The source data. /// </param> /// <param name="destination"> /// The destination. /// </param> /// <param name="filter"> /// The filter. /// </param> /// <returns> /// <c>true</c> if the filter was created successfully; otherwise, <c>false</c>. /// </returns> public bool TryCreateFilter(DataTriggerSourceData sourceData, IEditableRoot destination, out IFilterDescriptor filter) { if (sourceData == null) throw new ArgumentNullException("sourceData"); if (destination == null) throw new ArgumentNullException("destination"); filter = null; var value = GetValue(sourceData, destination, DefaultCultureName); if (value != null && !DateTime.MinValue.Equals(value)) { filter = new FilterDescriptor(FieldName, FilterOperator.IsEqualTo, value); return true; } return false; }
/// <summary> /// Determines whether destination item matches key values. /// </summary> /// <param name="sourceData">The source data set.</param> /// <param name="destination">The destination item.</param> /// <returns>Returns true if destination item matches key values.</returns> private bool AreEqual(DataTriggerSourceData sourceData, IEditableRoot destination) { return FieldUpdaters.Where(f => f.IsKey).All(c => c.AreEqual(sourceData, destination)); }
private int? GetValue(DataTriggerSourceData sourceData, IEditableRoot destination) { if (ValueCalculator != null) return SafeTypeConverter.Convert<int?>(ValueCalculator(sourceData, destination)); var filterList = new FilterList(); foreach (var childMapping in ChildMappings.Where(m => m.IsKey)) { IFilterDescriptor filter; if (!childMapping.TryCreateFilter(sourceData, destination, out filter)) return null; filterList.Add(filter); } if (filterList.Count != 0) { var crItems = DynamicTypeManager.GetList<IInfoList>(ReferencedProcessName, string.Empty, 0, int.MaxValue, null, filterList); return crItems != null && crItems.Count > 0 ? (int?)crItems[0].Id : null; } return null; }
public void UpdateCanRemoveItems() { // Arrange. const string ProcessName = "TestProcess"; const string DestinationFieldName = "TestField"; const string ReferencedProcessName = "RefProcess"; const string FieldName1 = "Field1"; const string FieldName2 = "Field2"; var dataSourceDefinition = new FieldMappingDataSourceDefinition("Test Data Source", ProcessName, "TestProperty", true, true, true); var fieldMapping1 = new DataTriggerFieldMapping(FieldName1, true, (s, d) => null); var fieldMapping2 = new DataTriggerFieldMapping(FieldName2, false, (s, d) => null); var mapping = new DataTriggerListFieldMapping( new[] { dataSourceDefinition }, DestinationFieldName, DataTriggerModificationType.Remove, new[] { fieldMapping1, fieldMapping2 }); var item = Mock.Create<IEditableRoot>(); var sourceData1 = new DataTriggerSourceData(); var sourceData2 = new DataTriggerSourceData(); var sourceData3 = new DataTriggerSourceData(); var sourceDataRetriever = Mock.Create<IFieldMappingSourceDataRetriever>(); Mock.Arrange(() => sourceDataRetriever.GetSourceData(item, null)).Returns(() => new[] { sourceData1, sourceData2, sourceData3 }); var oldDestinationItem1 = Mock.Create<IEditableRoot>(); Mock.Arrange(() => oldDestinationItem1.Id).Returns(111); var oldDestinationItem2 = Mock.Create<IEditableRoot>(); Mock.Arrange(() => oldDestinationItem2.Id).Returns(222); var destination = new DestinationEdit(); destination.TestField.Assign(oldDestinationItem1.Id); destination.TestField.Assign(oldDestinationItem2.Id); Mock.Arrange(() => _dtm.GetEditableRootType(ProcessName)).Returns(typeof(DestinationEdit)); SetupGetEditableRoot(ReferencedProcessName, oldDestinationItem1, oldDestinationItem2); var fieldUpdater1 = Mock.Create<IFieldUpdater>(); Mock.Arrange(() => fieldUpdater1.IsKey).Returns(true); var fieldUpdater2 = Mock.Create<IFieldUpdater>(); var fieldUpdaterFactory = Mock.Create<IFieldUpdaterFactory>(); Mock.Arrange(() => fieldUpdaterFactory.CreateFieldUpdater(ReferencedProcessName, fieldMapping1)).Returns(fieldUpdater1); Mock.Arrange(() => fieldUpdaterFactory.CreateFieldUpdater(ReferencedProcessName, fieldMapping2)).Returns(fieldUpdater2); Mock.Arrange(() => fieldUpdater1.AreEqual(sourceData1, oldDestinationItem1)).Returns(true); var updater = new MultiCrossReferenceFieldUpdater { DynamicTypeManager = _dtm, FieldUpdaterFactory = fieldUpdaterFactory, SourceDataRetrieverFactory = new ExportFactory<IFieldMappingSourceDataRetriever>( () => new Tuple<IFieldMappingSourceDataRetriever, Action>(sourceDataRetriever, () => { })) }; updater.Initialize(ProcessName, mapping); // Act. updater.BeforeItemUpdate(item, null); updater.AfterItemUpdate(item, null); updater.Update(item, destination); // Assert. Assert.AreEqual(1, destination.TestField.Count); Assert.IsTrue(destination.TestField.Any(x => x.Id == 222)); }
/// <summary> /// Calculates the new field value. The new value is stored in the <see cref="NewValue" /> property. /// </summary> /// <param name="sourceData">The source data set.</param> /// <param name="destination">The destination item.</param> /// <exception cref="System.InvalidOperationException">Source field is not a file.</exception> public void CalculateNewValue(DataTriggerSourceData sourceData, IEditableRoot destination) { var newValue = ValueCalculator(sourceData, destination); var fileValue = newValue as IFileProcess; if (newValue != fileValue) throw new InvalidOperationException("Source field is not a file."); NewValue = fileValue; }
public void AreEqualTest() { // Arrange. var comparer1 = new SimpleFieldUpdater { FieldName = TestsHelper.ExtractPropertyName(() => new TestEdit().Text), ValueCalculator = (s, d) => null, PropertyType = typeof(string) }; var comparer2 = new SimpleFieldUpdater { FieldName = TestsHelper.ExtractPropertyName(() => new TestEdit().Text), ValueCalculator = (s, d) => 123, PropertyType = typeof(string) }; var item1 = new TestEdit { Text = null }; var item2 = new TestEdit { Text = "123" }; var item3 = new TestEdit { Text = "Test" }; var sourceData = new DataTriggerSourceData(); // Act / Assert. Assert.IsTrue(comparer1.AreEqual(sourceData, item1)); Assert.IsFalse(comparer1.AreEqual(sourceData, item2)); Assert.IsFalse(comparer1.AreEqual(sourceData, item3)); Assert.IsFalse(comparer2.AreEqual(sourceData, item1)); Assert.IsTrue(comparer2.AreEqual(sourceData, item2)); Assert.IsFalse(comparer2.AreEqual(sourceData, item3)); // Exceptions. TestsHelper.VerifyThrow<ArgumentNullException>(() => comparer1.AreEqual(null, item1)); TestsHelper.VerifyThrow<ArgumentNullException>(() => comparer1.AreEqual(sourceData, null)); }
/// <summary> /// Updates destination item. /// </summary> /// <param name="source">The source item.</param> /// <param name="destination">The destination item.</param> private void UpdateFieldValues(IEditableRoot source, IEditableRoot destination) { var sourceData = new DataTriggerSourceData(); sourceData.SourceItems[DataTriggerMappingExpressionNames.SourceItem] = source; foreach (var fieldUpdater in FieldUpdaters) fieldUpdater.CalculateNewValue(sourceData, destination); foreach (var fieldUpdater in FieldUpdaters) fieldUpdater.Update(destination); }