< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Description.WsdlContractConversionContext
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Description/WsdlContractConversionContext.cs
Line coverage
31%
Covered lines: 28
Uncovered lines: 61
Coverable lines: 89
Total lines: 255
Line coverage: 31.4%
Branch coverage
7%
Covered branches: 4
Total branches: 54
Branch coverage: 7.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)100%11100%
GetOperation(...)100%11100%
GetOperationMessage(...)100%11100%
GetOperationFault(...)100%110%
GetOperationDescription(...)100%110%
GetMessageDescription(...)100%110%
GetFaultDescription(...)100%110%
AddOperation(...)100%11100%
AddMessage(...)100%11100%
AddFault(...)100%110%
GetOperationBindings(...)0%14140%
Match(...)0%12120%
MatchOperationParameterName(...)0%10100%
GetOperationMessageName(...)0%14140%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Description/WsdlContractConversionContext.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Xml;
 5using System.Xml.Schema;
 6using System.Collections.Generic;
 7using System.Collections.ObjectModel;
 8using WsdlNS = System.Web.Services.Description;
 9using System.Linq;
 10using System;
 11using CoreWCF.Runtime;
 12
 13namespace CoreWCF.Description
 14{
 15    // This class is created as part of the export process and passed to
 16    // Wsdlmporter and WsdlExporter implementations as a utility for
 17    // Correlating between the WSDL OM and the WCF OM
 18    // in the conversion process.
 19    public class WsdlContractConversionContext
 20    {
 21        private readonly Dictionary<OperationDescription, WsdlNS.Operation> _wsdlOperations;
 22        private readonly Dictionary<WsdlNS.Operation, OperationDescription> _operationDescriptions;
 23        private readonly Dictionary<MessageDescription, WsdlNS.OperationMessage> _wsdlOperationMessages;
 24        private readonly Dictionary<FaultDescription, WsdlNS.OperationFault> _wsdlOperationFaults;
 25        private readonly Dictionary<WsdlNS.OperationMessage, MessageDescription> _messageDescriptions;
 26        private readonly Dictionary<WsdlNS.OperationFault, FaultDescription> _faultDescriptions;
 27        private readonly Dictionary<WsdlNS.Operation, Collection<WsdlNS.OperationBinding>> _operationBindings;
 28
 2429        internal WsdlContractConversionContext(ContractDescription contract, WsdlNS.PortType wsdlPortType)
 30        {
 2431            Contract = contract;
 2432            WsdlPortType = wsdlPortType;
 33
 2434            _wsdlOperations = new Dictionary<OperationDescription, WsdlNS.Operation>();
 2435            _operationDescriptions = new Dictionary<WsdlNS.Operation, OperationDescription>();
 2436            _wsdlOperationMessages = new Dictionary<MessageDescription, WsdlNS.OperationMessage>();
 2437            _messageDescriptions = new Dictionary<WsdlNS.OperationMessage, MessageDescription>();
 2438            _wsdlOperationFaults = new Dictionary<FaultDescription, WsdlNS.OperationFault>();
 2439            _faultDescriptions = new Dictionary<WsdlNS.OperationFault, FaultDescription>();
 2440            _operationBindings = new Dictionary<WsdlNS.Operation, Collection<WsdlNS.OperationBinding>>();
 2441        }
 42
 43        internal IEnumerable<IWsdlExportExtension> ExportExtensions
 44        {
 45            get
 46            {
 4847                IEnumerable<IWsdlExportExtension> result = Contract.ContractBehaviors.Where(cb => cb is IWsdlExportExten
 28648                foreach (OperationDescription operation in Contract.Operations)
 49                {
 11950                    if (!WsdlExporter.OperationIsExportable(operation))
 51                    {
 52                        continue;
 53                    }
 54
 55                    // In 3.0SP1, the DCSOB and XSOB were moved from before to after the custom behaviors.  For
 56                    // IWsdlExportExtension compat, run them in the pre-SP1 order.
 107157                    var operationExtensions = operation.OperationBehaviors.Where(ob => ob is IWsdlExportExtension).Selec
 23858                    result = result.Concat(operationExtensions.Where(oe => WsdlExporter.IsBuiltInOperationBehavior(oe)))
 23859                    result = result.Concat(operationExtensions.Where(oe => !WsdlExporter.IsBuiltInOperationBehavior(oe))
 60                }
 61
 2462                return result;
 63            }
 64        }
 65
 74766        public ContractDescription Contract { get; }
 107267        public WsdlNS.PortType WsdlPortType { get; }
 24668        public WsdlNS.Operation GetOperation(OperationDescription operation) => _wsdlOperations[operation];
 23869        public WsdlNS.OperationMessage GetOperationMessage(MessageDescription message) => _wsdlOperationMessages[message
 070        public WsdlNS.OperationFault GetOperationFault(FaultDescription fault) => _wsdlOperationFaults[fault];
 071        public OperationDescription GetOperationDescription(WsdlNS.Operation operation) => _operationDescriptions[operat
 072        public MessageDescription GetMessageDescription(WsdlNS.OperationMessage operationMessage) => _messageDescription
 073        public FaultDescription GetFaultDescription(WsdlNS.OperationFault operationFault) => _faultDescriptions[operatio
 74
 75        // --------------------------------------------------------------------------------------------------
 76
 77        internal void AddOperation(OperationDescription operationDescription, WsdlNS.Operation wsdlOperation)
 78        {
 11979            _wsdlOperations.Add(operationDescription, wsdlOperation);
 11980            _operationDescriptions.Add(wsdlOperation, operationDescription);
 11981        }
 82
 83        internal void AddMessage(MessageDescription messageDescription, WsdlNS.OperationMessage wsdlOperationMessage)
 84        {
 23885            _wsdlOperationMessages.Add(messageDescription, wsdlOperationMessage);
 23886            _messageDescriptions.Add(wsdlOperationMessage, messageDescription);
 23887        }
 88
 89        internal void AddFault(FaultDescription faultDescription, WsdlNS.OperationFault wsdlOperationFault)
 90        {
 091            _wsdlOperationFaults.Add(faultDescription, wsdlOperationFault);
 092            _faultDescriptions.Add(wsdlOperationFault, faultDescription);
 093        }
 94
 95        internal Collection<WsdlNS.OperationBinding> GetOperationBindings(WsdlNS.Operation operation)
 96        {
 97            Collection<WsdlNS.OperationBinding> bindings;
 098            if (!_operationBindings.TryGetValue(operation, out bindings))
 99            {
 0100                bindings = new Collection<WsdlNS.OperationBinding>();
 0101                WsdlNS.ServiceDescriptionCollection wsdlDocuments = WsdlPortType.ServiceDescription.ServiceDescriptions;
 0102                foreach (WsdlNS.ServiceDescription wsdl in wsdlDocuments)
 103                {
 0104                    foreach (WsdlNS.Binding wsdlBinding in wsdl.Bindings)
 105                    {
 0106                        if (wsdlBinding.Type.Name == WsdlPortType.Name && wsdlBinding.Type.Namespace == WsdlPortType.Ser
 107                        {
 0108                            foreach (WsdlNS.OperationBinding operationBinding in wsdlBinding.Operations)
 109                            {
 0110                                if (Binding2DescriptionHelper.Match(operationBinding, operation) != Binding2DescriptionH
 111                                {
 0112                                    bindings.Add(operationBinding);
 0113                                    break;
 114                                }
 115                            }
 116                        }
 117                    }
 118                }
 119
 0120                _operationBindings.Add(operation, bindings);
 121            }
 122
 0123            return bindings;
 124        }
 125
 126        internal static class Binding2DescriptionHelper
 127        {
 128            internal enum MatchResult
 129            {
 130                None,
 131                Partial,
 132                Exact
 133            }
 134
 135            internal static MatchResult Match(WsdlNS.OperationBinding wsdlOperationBinding, WsdlNS.Operation wsdlOperati
 136            {
 137                // This method checks if there is a match based on Names, between the specified OperationBinding and Ope
 138                // When searching for the Operation associated with an OperationBinding, we need to return an exact matc
 139                // or a partial match otherwise (when some of the Names are null).
 140                // Bug 16833 @ CSDMain requires that partial matches are allowed, while the TFS bug 477838 requires that
 0141                if (wsdlOperationBinding.Name != wsdlOperation.Name)
 142                {
 0143                    return MatchResult.None;
 144                }
 145
 0146                MatchResult result = MatchResult.Exact;
 147
 0148                foreach (WsdlNS.OperationMessage wsdlOperationMessage in wsdlOperation.Messages)
 149                {
 150                    WsdlNS.MessageBinding wsdlMessageBinding;
 0151                    if (wsdlOperationMessage is WsdlNS.OperationInput)
 152                    {
 0153                        wsdlMessageBinding = wsdlOperationBinding.Input;
 154                    }
 155                    else
 156                    {
 0157                        wsdlMessageBinding = wsdlOperationBinding.Output;
 158                    }
 159
 0160                    if (wsdlMessageBinding == null)
 161                    {
 0162                        return MatchResult.None;
 163                    }
 164
 0165                    switch (MatchOperationParameterName(wsdlMessageBinding, wsdlOperationMessage))
 166                    {
 167                        case MatchResult.None:
 0168                            return MatchResult.None;
 169                        case MatchResult.Partial:
 0170                            result = MatchResult.Partial;
 171                            break;
 172                    }
 173                }
 174
 0175                return result;
 0176            }
 177
 178            private static MatchResult MatchOperationParameterName(WsdlNS.MessageBinding wsdlMessageBinding, WsdlNS.Oper
 179            {
 0180                string wsdlOperationMessageName = wsdlOperationMessage.Name;
 0181                string wsdlMessageBindingName = wsdlMessageBinding.Name;
 182
 0183                if (wsdlOperationMessageName == wsdlMessageBindingName)
 184                {
 0185                    return MatchResult.Exact;
 186                }
 187
 0188                string wsdlOperationMessageDecodedName = WsdlNamingHelper.GetOperationMessageName(wsdlOperationMessage);
 0189                if ((wsdlOperationMessageName == null) && (wsdlMessageBindingName == wsdlOperationMessageDecodedName))
 190                {
 0191                    return MatchResult.Partial;
 192                }
 0193                else if ((wsdlMessageBindingName == null) && (wsdlOperationMessageName == wsdlOperationMessageDecodedNam
 194                {
 0195                    return MatchResult.Partial;
 196                }
 197                else
 198                {
 0199                    return MatchResult.None;
 200                }
 201            }
 202        }
 203
 204        private static class WsdlNamingHelper
 205        {
 206            internal static string GetOperationMessageName(WsdlNS.OperationMessage wsdlOperationMessage)
 207            {
 0208                string messageName = null;
 0209                if (!string.IsNullOrEmpty(wsdlOperationMessage.Name))
 210                {
 0211                    messageName = wsdlOperationMessage.Name;
 212                }
 0213                else if (wsdlOperationMessage.Operation.Messages.Count == 1)
 214                {
 0215                    messageName = wsdlOperationMessage.Operation.Name;
 216                }
 0217                else if (wsdlOperationMessage.Operation.Messages.IndexOf(wsdlOperationMessage) == 0)
 218                {
 0219                    if (wsdlOperationMessage is WsdlNS.OperationInput)
 220                    {
 0221                        messageName = wsdlOperationMessage.Operation.Name + "Request";
 222                    }
 0223                    else if (wsdlOperationMessage is WsdlNS.OperationOutput)
 224                    {
 0225                        messageName = wsdlOperationMessage.Operation.Name + "Solicit";
 226                    }
 227                }
 0228                else if (wsdlOperationMessage.Operation.Messages.IndexOf(wsdlOperationMessage) == 1)
 229                {
 0230                    messageName = wsdlOperationMessage.Operation.Name + "Response";
 231                }
 232                else
 233                {
 234                    Fx.Assert("Unsupported WSDL OM (More than 2 OperationMessages encountered in an Operation or WsdlOM 
 235                }
 236
 237                // This is the same validation that ServiceDescriptor.XmlName performs
 238                try
 239                {
 0240                    if (messageName != null)
 241                    {
 0242                        XmlConvert.VerifyNCName(messageName);
 243                    }
 0244                }
 0245                catch (XmlException e)
 246                {
 0247                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(e.Message, nameof(Ws
 248                }
 249
 250                // The original code returned XmlName and the called used DecodedName, this does the equivalent
 0251                return XmlConvert.DecodeName(messageName);
 252            }
 253        }
 254    }
 255}