File: FrameworkFork\System.ServiceModel\System\ServiceModel\Security\ScopedMessagePartSpecification.cs
Web Access
Project: src\src\dotnet-svcutil\lib\src\dotnet-svcutil-lib.csproj (dotnet-svcutil-lib)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System.Collections.Generic;
using System.ServiceModel.Channels;
using Microsoft.Xml;
 
namespace System.ServiceModel.Security
{
    public class ScopedMessagePartSpecification
    {
        private MessagePartSpecification _channelParts;
        private Dictionary<string, MessagePartSpecification> _actionParts;
        private Dictionary<string, MessagePartSpecification> _readOnlyNormalizedActionParts;
        private bool _isReadOnly;
 
        public ScopedMessagePartSpecification()
        {
            _channelParts = new MessagePartSpecification();
            _actionParts = new Dictionary<string, MessagePartSpecification>();
        }
 
        public ICollection<string> Actions
        {
            get
            {
                return _actionParts.Keys;
            }
        }
 
        public MessagePartSpecification ChannelParts
        {
            get
            {
                return _channelParts;
            }
        }
 
        public bool IsReadOnly
        {
            get
            {
                return _isReadOnly;
            }
        }
 
        public ScopedMessagePartSpecification(ScopedMessagePartSpecification other)
            : this()
        {
            if (other == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("other"));
 
            _channelParts.Union(other._channelParts);
            if (other._actionParts != null)
            {
                foreach (string action in other._actionParts.Keys)
                {
                    MessagePartSpecification p = new MessagePartSpecification();
                    p.Union(other._actionParts[action]);
                    _actionParts[action] = p;
                }
            }
        }
 
        internal ScopedMessagePartSpecification(ScopedMessagePartSpecification other, bool newIncludeBody)
            : this(other)
        {
            _channelParts.IsBodyIncluded = newIncludeBody;
            foreach (string action in _actionParts.Keys)
                _actionParts[action].IsBodyIncluded = newIncludeBody;
        }
 
        public void AddParts(MessagePartSpecification parts)
        {
            if (parts == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("parts"));
 
            ThrowIfReadOnly();
 
            _channelParts.Union(parts);
        }
 
        public void AddParts(MessagePartSpecification parts, string action)
        {
            if (action == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("action"));
            if (parts == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("parts"));
 
            ThrowIfReadOnly();
 
            if (!_actionParts.ContainsKey(action))
                _actionParts[action] = new MessagePartSpecification();
            _actionParts[action].Union(parts);
        }
 
        internal void AddParts(MessagePartSpecification parts, XmlDictionaryString action)
        {
            if (action == null)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("action"));
            AddParts(parts, action.Value);
        }
 
        internal bool IsEmpty()
        {
            bool result;
            if (!_channelParts.IsEmpty())
            {
                result = false;
            }
            else
            {
                result = true;
                foreach (string action in this.Actions)
                {
                    MessagePartSpecification parts;
                    if (TryGetParts(action, true, out parts))
                    {
                        if (!parts.IsEmpty())
                        {
                            result = false;
                            break;
                        }
                    }
                }
            }
 
            return result;
        }
 
        public bool TryGetParts(string action, bool excludeChannelScope, out MessagePartSpecification parts)
        {
            if (action == null)
                action = MessageHeaders.WildcardAction;
            parts = null;
 
            if (_isReadOnly)
            {
                if (_readOnlyNormalizedActionParts.ContainsKey(action))
                    if (excludeChannelScope)
                        parts = _actionParts[action];
                    else
                        parts = _readOnlyNormalizedActionParts[action];
            }
            else if (_actionParts.ContainsKey(action))
            {
                MessagePartSpecification p = new MessagePartSpecification();
                p.Union(_actionParts[action]);
                if (!excludeChannelScope)
                    p.Union(_channelParts);
                parts = p;
            }
 
            return parts != null;
        }
 
        internal void CopyTo(ScopedMessagePartSpecification target)
        {
            if (target == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("target");
            }
            target.ChannelParts.IsBodyIncluded = this.ChannelParts.IsBodyIncluded;
            foreach (XmlQualifiedName headerType in ChannelParts.HeaderTypes)
            {
                if (!target._channelParts.IsHeaderIncluded(headerType.Name, headerType.Namespace))
                {
                    target.ChannelParts.HeaderTypes.Add(headerType);
                }
            }
            foreach (string action in _actionParts.Keys)
            {
                target.AddParts(_actionParts[action], action);
            }
        }
 
        public bool TryGetParts(string action, out MessagePartSpecification parts)
        {
            return this.TryGetParts(action, false, out parts);
        }
 
        public void MakeReadOnly()
        {
            if (!_isReadOnly)
            {
                _readOnlyNormalizedActionParts = new Dictionary<string, MessagePartSpecification>();
                foreach (string action in _actionParts.Keys)
                {
                    MessagePartSpecification p = new MessagePartSpecification();
                    p.Union(_actionParts[action]);
                    p.Union(_channelParts);
                    p.MakeReadOnly();
                    _readOnlyNormalizedActionParts[action] = p;
                }
                _isReadOnly = true;
            }
        }
 
        private void ThrowIfReadOnly()
        {
            if (_isReadOnly)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SRServiceModel.ObjectIsReadOnly));
        }
    }
}