Beispiel #1
0
        /// <summary>
        /// Handles the recurring element filters.
        /// </summary>
        /// <param name="propertyPath">The property path.</param>
        /// <param name="isRecurringCriteria">if set to <c>true</c> is recurring criteria.</param>
        protected virtual void HandleRecurringElementFilters(string propertyPath, bool isRecurringCriteria = false)
        {
            // Pull the current filter off the stack
            var filter = Context.RecurringFilterStack.Pop();

            // Peek at the next filter in the stack, if any
            var next = Context.RecurringFilterStack.Any()
                ? Context.RecurringFilterStack.Peek()
                : null;

            if (Context.CurrentRecurringFilters.Any())
            {
                var filters = Context.CurrentRecurringFilters.ToArray();

                // Recurring criteria are joined with OR
                if (isRecurringCriteria)
                {
                    var recurringFilter = new RecurringElementFilter(propertyPath, filters);
                    filter.Filters.Add(recurringFilter);
                }
                else // Otherwise join with AND
                {
                    filter.Filters.AddRange(filters);
                }
            }

            // Reset the reference for the previous list of filters
            Context.CurrentRecurringFilters = filter.PreviousFilters;
            filter.PreviousFilters          = null;

            // Stop processing if no filters were included
            if (!filter.Filters.Any())
            {
                return;
            }

            // Check if this filter should be combined with the next filter in the stack
            if (filter.PropertyPath == next?.PropertyPath)
            {
                Context.CurrentRecurringFilters.Add(filter);
            }
            else // Otherwise add as root level filters
            {
                Context.RecurringElementFilters.Add(filter);

                // Stop processing if not handling a nested recurring element
                if (next == null)
                {
                    return;
                }

                // Add filter for parent recurring element when nested recurring elements are filtered
                Context.CurrentRecurringFilters.Add(new RecurringElementFilter(GetNestedPath(filter.PropertyPath), "Any()",
                                                                               (dataObject, instance, recurringFilter) => recurringFilter.GetPropertyValue <IList>(instance)?.Count > 0));
            }
        }
Beispiel #2
0
        /// <summary>
        /// Initializes the recurring element filters.
        /// </summary>
        /// <param name="propertyPath">The property path.</param>
        protected virtual void InitializeRecurringElementFilter(string propertyPath)
        {
            var filter = new RecurringElementFilter(propertyPath)
            {
                // Keep a reference to the previous list of filters
                PreviousFilters = Context.CurrentRecurringFilters
            };

            // Put the new filter on the stack
            Context.RecurringFilterStack.Push(filter);
            // Initialize the list of filters for the current recurring element
            Context.CurrentRecurringFilters = new List <RecurringElementFilter>();
        }
Beispiel #3
0
        /// <summary>
        /// Filters the recurring elements.
        /// </summary>
        /// <param name="dataObject">The data object.</param>
        /// <param name="instance">The instance.</param>
        /// <param name="filter">The filter.</param>
        /// <param name="propertyPath">The property path.</param>
        protected virtual bool FilterRecurringElements(object dataObject, object instance, RecurringElementFilter filter, string propertyPath)
        {
            var   propertyNames        = propertyPath.Split('.');
            IList recurringElementList = null;

            // Find recurring element list(s) in property path
            for (var i = 0; i < propertyNames.Length; i++)
            {
                // Stop processing if the object instance is null
                if (instance == null)
                {
                    return(false);
                }

                // Process nested recurring elements
                if (recurringElementList != null)
                {
                    var nestedPath = string.Join(".", propertyNames.Skip(i));

                    return(recurringElementList.Cast <object>()
                           .Aggregate(true, (current, recurringItem) => FilterRecurringElements(dataObject, recurringItem, filter, nestedPath) && current));
                }

                var propertyType = instance.GetType();
                var propertyName = propertyNames[i];
                var propertyInfo = propertyType.GetProperty(propertyName);

                // Stop processing if the property was not found
                if (propertyInfo == null)
                {
                    return(false);
                }

                // Get the current property value
                instance             = propertyInfo.GetValue(instance);
                recurringElementList = instance as IList;
            }

            // Stop processing if the list is null
            if (recurringElementList == null)
            {
                return(false);
            }

            // Process recurring elements
            var filteredItems = new ArrayList();

            foreach (var recurringItem in recurringElementList)
            {
                // Check if recurring element doesn't meet criteria
                if (!filter.Predicate(dataObject, recurringItem, filter))
                {
                    filteredItems.Add(recurringItem);
                }
            }

            // Remove filtered items from original list
            foreach (var item in filteredItems)
            {
                recurringElementList.Remove(item);
            }

            return(recurringElementList.Count <= 0);
        }