/// <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);
        }
예제 #2
0
        /// <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();
            }
        }
예제 #4
0
 /// <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();
 }
예제 #5
0
 /// <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());
        }
예제 #7
0
        /// <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();
        }
예제 #12
0
        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);
            }
        }
예제 #13
0
        /// <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;
        }
예제 #14
0
        /// <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));
        }
예제 #18
0
        /// <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;
        }
예제 #19
0
        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));
        }
예제 #20
0
        /// <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);
        }