File: System\ServiceModel\Dispatcher\StrictAndMessageFilter.cs
Project: ndp\cdf\src\NetFx40\System.ServiceModel.Routing\System.ServiceModel.Routing.csproj (System.ServiceModel.Routing)
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//----------------------------------------------------------------
 
namespace System.ServiceModel.Dispatcher
{
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Dispatcher;
    using System.Collections;
    using System.ServiceModel.Routing;
 
    [SuppressMessage(FxCop.Category.Xaml, FxCop.Rule.TypesMustHaveXamlCallableConstructors)]
    [SuppressMessage(FxCop.Category.Xaml, FxCop.Rule.TypesShouldHavePublicParameterlessConstructors)]
    public class StrictAndMessageFilter : MessageFilter
    {
        MessageFilter filter1;
        MessageFilter filter2;
 
        public StrictAndMessageFilter(MessageFilter filter1, MessageFilter filter2)
        {
            if (filter1 == null || filter2 == null)
            {
                throw FxTrace.Exception.ArgumentNull(filter1 == null ? "filter1" : "filter2");
            }
 
            this.filter1 = filter1;
            this.filter2 = filter2;
        }
 
        public override bool Match(Message message)
        {
            throw FxTrace.Exception.AsError(new NotSupportedException());
        }
 
        public override bool Match(MessageBuffer buffer)
        {
            throw FxTrace.Exception.AsError(new NotSupportedException());
        }
 
        protected internal override IMessageFilterTable<TFilterData> CreateFilterTable<TFilterData>()
        {
            StrictAndMessageFilterTable<TFilterData> table = new StrictAndMessageFilterTable<TFilterData>();
            return table;
        }
 
        class StrictAndMessageFilterTable<TFilterData> : IMessageFilterTable<TFilterData>
        {
            Dictionary<MessageFilter, TFilterData> andFilters;
            MessageFilterTable<StrictAndMessageFilter> filterTable;
 
            public StrictAndMessageFilterTable()
            {
                this.andFilters = new Dictionary<MessageFilter, TFilterData>();
                this.filterTable = new MessageFilterTable<StrictAndMessageFilter>();
            }
 
            public int Count
            {
                get { return this.andFilters.Count; }
            }
 
            public bool IsReadOnly
            {
                get { return true; }
            }
 
            public ICollection<MessageFilter> Keys
            {
                get { return this.andFilters.Keys; }
            }
 
            public ICollection<TFilterData> Values
            {
                get { return this.andFilters.Values; }
            }
 
            public TFilterData this[MessageFilter key]
            {
                get
                {
                    return this.andFilters[key];
                }
                set
                {
                    this.andFilters[key] = value;
                }
            }
 
            public bool GetMatchingFilter(MessageBuffer messageBuffer, out MessageFilter filter)
            {
                throw FxTrace.Exception.AsError(new NotImplementedException());
            }
 
            public bool GetMatchingFilter(Message message, out MessageFilter filter)
            {
                throw FxTrace.Exception.AsError(new NotImplementedException());
            }
 
            public bool GetMatchingFilters(MessageBuffer messageBuffer, ICollection<MessageFilter> results)
            {
                if (messageBuffer == null)
                {
                    throw FxTrace.Exception.ArgumentNull("messageBuffer");
                }
 
                List<MessageFilter> firstPassResults = new List<MessageFilter>();
                if (this.filterTable.GetMatchingFilters(messageBuffer, firstPassResults))
                {
                    IList<StrictAndMessageFilter> matchingFilters = FindMatchingAndFilters(firstPassResults);
                    foreach (StrictAndMessageFilter andFilter in matchingFilters)
                    {
                        results.Add(andFilter);
                    }
                    return (matchingFilters.Count > 0);
                }
                return false;
            }
 
            public bool GetMatchingFilters(Message message, ICollection<MessageFilter> results)
            {
                if (message == null)
                {
                    throw FxTrace.Exception.ArgumentNull("message");
                }
 
                List<MessageFilter> firstPassResults = new List<MessageFilter>();
                if (this.filterTable.GetMatchingFilters(message, firstPassResults))
                {
                    IList<StrictAndMessageFilter> matchingFilters = FindMatchingAndFilters(firstPassResults);
                    foreach (StrictAndMessageFilter andFilter in matchingFilters)
                    {
                        results.Add(andFilter);
                    }
                    return (matchingFilters.Count > 0);
                }
                return false;
            }
 
            public bool GetMatchingValue(MessageBuffer messageBuffer, out TFilterData value)
            {
                value = default(TFilterData);
                List<TFilterData> results = new List<TFilterData>();
                bool result = this.GetMatchingValues(messageBuffer, results);
                if (results.Count == 1)
                {
                    value = results[0];
                }
                if (results.Count > 1)
                {
                    throw FxTrace.Exception.AsError(new MultipleFilterMatchesException());
                }
                return result;
            }
 
            public bool GetMatchingValue(Message message, out TFilterData value)
            {
                value = default(TFilterData);
                List<TFilterData> results = new List<TFilterData>();
                bool result = this.GetMatchingValues(message, results);
                if (results.Count == 1)
                {
                    value = results[0];
                }
                else if (results.Count > 1)
                {
                    throw FxTrace.Exception.AsError(new MultipleFilterMatchesException());
                }
                return result;
            }
 
            public bool GetMatchingValues(MessageBuffer messageBuffer, ICollection<TFilterData> results)
            {
                if (messageBuffer == null)
                {
                    throw FxTrace.Exception.ArgumentNull("messageBuffer");
                }
 
                List<MessageFilter> firstPassResults = new List<MessageFilter>();
                if (this.filterTable.GetMatchingFilters(messageBuffer, firstPassResults))
                {
                    IList<StrictAndMessageFilter> matchingFilters = FindMatchingAndFilters(firstPassResults);
                    foreach (StrictAndMessageFilter andFilter in matchingFilters)
                    {
                        results.Add(this.andFilters[andFilter]);
                    }
                    return (matchingFilters.Count > 0);
                }
                return false;
            }
 
            public bool GetMatchingValues(Message message, ICollection<TFilterData> results)
            {
                if (message == null)
                {
                    throw FxTrace.Exception.ArgumentNull("message");
                }
 
                List<MessageFilter> firstPassResults = new List<MessageFilter>();
                if (this.filterTable.GetMatchingFilters(message, firstPassResults))
                {
                    IList<StrictAndMessageFilter> matchingFilters = FindMatchingAndFilters(firstPassResults);
                    foreach (StrictAndMessageFilter andFilter in matchingFilters)
                    {
                        results.Add(this.andFilters[andFilter]);
                    }
                    return (matchingFilters.Count > 0);
                }
                return false;
            }
 
            IList<StrictAndMessageFilter> FindMatchingAndFilters(List<MessageFilter> firstPassResults)
            {
                IList<StrictAndMessageFilter> matchingFilters = new List<StrictAndMessageFilter>();
                foreach (MessageFilter filter in firstPassResults)
                {
                    StrictAndMessageFilter andFilter = this.filterTable[filter];
                    // Check if this StrictAndMessageFilter is already in our result set
                    if (!matchingFilters.Contains(andFilter))
                    {
                        if (firstPassResults.Contains(andFilter.filter1) && firstPassResults.Contains(andFilter.filter2))
                        {
                            matchingFilters.Add(andFilter);
                        }
                    }
                }
                return matchingFilters;
            }
 
            public void Add(MessageFilter key, TFilterData value)
            {
                StrictAndMessageFilter andFilter = (StrictAndMessageFilter)key;
                this.andFilters.Add(andFilter, value);
                this.filterTable.Add(andFilter.filter1, andFilter);
                this.filterTable.Add(andFilter.filter2, andFilter);
            }
 
            public bool ContainsKey(MessageFilter key)
            {
                return this.andFilters.ContainsKey(key);
            }
 
            public bool Remove(MessageFilter key)
            {
                StrictAndMessageFilter andFilter = (StrictAndMessageFilter)key;
                if (this.andFilters.Remove(andFilter))
                {
                    this.filterTable.Remove(andFilter.filter1);
                    this.filterTable.Remove(andFilter.filter2);
                    return true;
                }
                return false;
            }
 
            public bool TryGetValue(MessageFilter key, out TFilterData value)
            {
                return this.andFilters.TryGetValue(key, out value);
            }
 
            public void Add(KeyValuePair<MessageFilter, TFilterData> item)
            {
                this.Add(item.Key, item.Value);
            }
 
            public void Clear()
            {
                this.andFilters.Clear();
                this.filterTable.Clear();
            }
 
            public bool Contains(KeyValuePair<MessageFilter, TFilterData> item)
            {
                return this.andFilters.Contains(item);
            }
 
            public void CopyTo(KeyValuePair<MessageFilter, TFilterData>[] array, int arrayIndex)
            {
                throw FxTrace.Exception.AsError(new NotImplementedException());
            }
 
            public bool Remove(KeyValuePair<MessageFilter, TFilterData> item)
            {
                return this.andFilters.Remove(item.Key);
            }
 
            public IEnumerator<KeyValuePair<MessageFilter, TFilterData>> GetEnumerator()
            {
                throw FxTrace.Exception.AsError(new NotImplementedException());
            }
 
            IEnumerator IEnumerable.GetEnumerator()
            {
                throw FxTrace.Exception.AsError(new NotImplementedException());
            }
        }
    }
}