< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Configuration.ServiceModelExtensionCollectionElement<T>
Assembly: CoreWCF.ConfigurationManager
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.ConfigurationManager/src/CoreWCF/Configuration/ServiceModelExtensionCollectionElement.cs
Line coverage
33%
Covered lines: 73
Uncovered lines: 146
Coverable lines: 219
Total lines: 524
Line coverage: 33.3%
Branch coverage
35%
Covered branches: 45
Total branches: 126
Branch coverage: 35.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)100%11100%
Add(...)50%8861.11%
AddItem(...)0%220%
CanAdd(...)0%440%
Clear()0%880%
Contains(...)50%2266.66%
ContainsKey(...)50%2266.66%
ContainsKey(...)50%8840%
CopyTo(...)0%14140%
CreateNewSection(...)50%101040%
GetExtensionType(...)50%4460%
MergeWith(...)0%220%
Merge(...)0%440%
DeserializeElement(...)100%11100%
DeserializeElementCore(...)94.44%181893.75%
GetEnumerator()100%22100%
IsModified()0%660%
OnDeserializeUnrecognizedElement(...)100%110%
Remove(...)0%440%
Reset(...)0%220%
ResetModified()100%22100%
SetIsModified()100%110%
SetReadOnly()0%220%
System.Collections.IEnumerable.GetEnumerator()100%110%
Unmerge(...)0%220%
UpdateProperties(...)0%880%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.ConfigurationManager/src/CoreWCF/Configuration/ServiceModelExtensionCollectionElement.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;
 5using System.Collections;
 6using System.Collections.Generic;
 7using System.Configuration;
 8using System.Security;
 9using System.Xml;
 10
 11namespace CoreWCF.Configuration
 12{
 13    public abstract class ServiceModelExtensionCollectionElement<TServiceModelExtensionElement> : ServiceModelConfigurat
 14        where TServiceModelExtensionElement : ServiceModelExtensionElement
 15    {
 16        private readonly string _extensionCollectionName;
 17        private bool _modified;
 18        private List<TServiceModelExtensionElement> _items;
 19
 2020        internal ServiceModelExtensionCollectionElement(string extensionCollectionName)
 21        {
 2022            _extensionCollectionName = extensionCollectionName;
 2023        }
 24
 25        public TServiceModelExtensionElement this[int index]
 26        {
 027            get { return Items[index]; }
 28        }
 29
 30        public TServiceModelExtensionElement this[Type extensionType]
 31        {
 32            get
 33            {
 3434                if (extensionType == null)
 35                {
 036                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(extensionType));
 37                }
 38
 3439                if (!CollectionElementBaseType.IsAssignableFrom(extensionType))
 40                {
 041                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("extensionType",
 042                        SR.Format(SR.ConfigInvalidExtensionType,
 043                        extensionType.ToString(),
 044                        CollectionElementBaseType.FullName,
 045                        _extensionCollectionName));
 46
 47                }
 3448                TServiceModelExtensionElement retval = null;
 49
 6850                foreach (TServiceModelExtensionElement collectionElement in this)
 51                {
 052                    if (null != collectionElement)
 53                    {
 054                        if (collectionElement.GetType() == extensionType)
 55                        {
 056                            retval = collectionElement;
 57                        }
 58                    }
 59                }
 60
 3461                return retval;
 62            }
 63        }
 64
 65        public int Count
 66        {
 067            get { return Items.Count; }
 68        }
 69
 70        bool ICollection<TServiceModelExtensionElement>.IsReadOnly
 71        {
 072            get { return IsReadOnly(); }
 73        }
 74
 75        internal List<TServiceModelExtensionElement> Items
 76        {
 77            get
 78            {
 18579                if (_items == null)
 80                {
 2081                    _items = new List<TServiceModelExtensionElement>();
 82                }
 18583                return _items;
 84            }
 85        }
 86
 87        public virtual void Add(TServiceModelExtensionElement element)
 88        {
 1789            if (IsReadOnly())
 90            {
 091                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.Format(SR.
 92            }
 1793            if (element == null)
 94            {
 095                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(element));
 96            }
 97
 1798            element.ExtensionCollectionName = _extensionCollectionName;
 99
 17100            if (Contains(element))
 101            {
 0102                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("element", SR.Format(SR.ConfigDuplicateKey,
 103            }
 17104            else if (!CanAdd(element))
 105            {
 0106                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("element",
 0107                    SR.Format(SR.ConfigElementTypeNotAllowed,
 0108                    element.ConfigurationElementName,
 0109                    _extensionCollectionName));
 110            }
 111            else
 112            {
 17113                ConfigurationProperty configProperty = new ConfigurationProperty(element.ConfigurationElementName, eleme
 17114                Properties.Add(configProperty);
 17115                this[configProperty] = element;
 17116                Items.Add(element);
 17117                _modified = true;
 118            }
 17119        }
 120
 121        internal void AddItem(TServiceModelExtensionElement element)
 122        {
 0123            if (IsReadOnly())
 124            {
 0125                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.Format(SR.
 126            }
 0127            element.ExtensionCollectionName = _extensionCollectionName;
 0128            Items.Add(element);
 0129            _modified = true;
 0130        }
 131
 132        public virtual bool CanAdd(TServiceModelExtensionElement element)
 133        {
 0134            if (element == null)
 135            {
 0136                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(element));
 137            }
 138
 0139            Type elementType = element.GetType();
 140
 0141            return !IsReadOnly() && !ContainsKey(elementType);
 142        }
 143
 144        public void Clear()
 145        {
 0146            if (IsReadOnly())
 147            {
 0148                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.Format(SR.
 149            }
 0150            if (Properties.Count > 0)
 151            {
 0152                _modified = true;
 153            }
 154
 0155            List<string> propertiesToRemove = new List<string>(Items.Count);
 0156            foreach (TServiceModelExtensionElement item in Items)
 157            {
 0158                propertiesToRemove.Add(item.ConfigurationElementName);
 159            }
 160
 0161            Items.Clear();
 162
 0163            foreach (string name in propertiesToRemove)
 164            {
 0165                Properties.Remove(name);
 166            }
 0167        }
 168
 169        internal Type CollectionElementBaseType
 170        {
 51171            get { return typeof(TServiceModelExtensionElement); }
 172        }
 173
 174        public bool Contains(TServiceModelExtensionElement element)
 175        {
 17176            if (element == null)
 177            {
 0178                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(element));
 179            }
 17180            return ContainsKey(element.GetType());
 181        }
 182
 183        public bool ContainsKey(Type elementType)
 184        {
 34185            if (elementType == null)
 186            {
 0187                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(elementType));
 188            }
 34189            return (this[elementType] != null);
 190        }
 191
 192        public bool ContainsKey(string elementName)
 193        {
 17194            if (string.IsNullOrEmpty(elementName))
 195            {
 0196                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(elementName));
 197            }
 17198            bool retval = false;
 34199            foreach (TServiceModelExtensionElement element in this)
 200            {
 0201                if (null != element)
 202                {
 0203                    string configuredSectionName = element.ConfigurationElementName;
 0204                    if (configuredSectionName.Equals(elementName, StringComparison.Ordinal))
 205                    {
 0206                        retval = true;
 0207                        break;
 208                    }
 209                }
 210            }
 17211            return retval;
 212        }
 213
 214        public void CopyTo(TServiceModelExtensionElement[] elements, int start)
 215        {
 0216            if (elements == null)
 217            {
 0218                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(elements));
 219            }
 0220            if (start < 0 || start >= elements.Length)
 221            {
 0222                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("start",
 0223                    SR.Format(SR.ConfigInvalidStartValue,
 0224                    elements.Length - 1,
 0225                    start));
 226            }
 227
 0228            foreach (TServiceModelExtensionElement element in this)
 229            {
 0230                if (null != element)
 231                {
 0232                    string configuredSectionName = element.ConfigurationElementName;
 233
 0234                    TServiceModelExtensionElement copiedElement = CreateNewSection(configuredSectionName);
 0235                    if ((copiedElement != null) && (start < elements.Length))
 236                    {
 0237                        copiedElement.CopyFrom(element);
 0238                        elements[start] = copiedElement;
 0239                        ++start;
 240                    }
 241                }
 242            }
 0243        }
 244
 245        /// <summary>
 246        /// Returns the extension element, or null if the type cannot be loaded in certain situations (see the code for 
 247        /// </summary>
 248        private TServiceModelExtensionElement CreateNewSection(string name)
 249        {
 17250            if (ContainsKey(name) && !(name == ConfigurationStrings.Clear || name == ConfigurationStrings.Remove))
 251            {
 0252                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.Format(SR.
 0253                    name,
 0254                    GetType().Name),
 0255                    ElementInformation.Source,
 0256                    ElementInformation.LineNumber));
 257            }
 258
 259            TServiceModelExtensionElement retval;
 260
 261            Type elementType;
 17262            ContextInformation evaluationContext = EvaluationContext;
 263
 17264            elementType = GetExtensionType(evaluationContext, name);
 265
 266
 17267            if (null != elementType)
 268            {
 17269                if (CollectionElementBaseType.IsAssignableFrom(elementType))
 270                {
 17271                    retval = (TServiceModelExtensionElement)Activator.CreateInstance(elementType);
 17272                    retval.ExtensionCollectionName = _extensionCollectionName;
 17273                    retval.ConfigurationElementName = name;
 17274                    retval.InternalInitializeDefault();
 275                }
 276                else
 277                {
 0278                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.Format
 0279                        name,
 0280                        CollectionElementBaseType.FullName),
 0281                        ElementInformation.Source,
 0282                        ElementInformation.LineNumber));
 283                }
 284            }
 285            else
 286            {
 0287                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.Format(SR.
 0288                    name,
 0289                    _extensionCollectionName),
 0290                    ElementInformation.Source,
 0291                    ElementInformation.LineNumber));
 292            }
 293
 17294            return retval;
 295        }
 296
 297
 298        private Type GetExtensionType(ContextInformation evaluationContext, string name)
 299        {
 17300            ExtensionElementCollection collection = ExtensionsSection.LookupCollection(_extensionCollectionName, evaluat
 17301            if (collection.ContainsKey(name))
 302            {
 17303                ExtensionElement element = collection.GetElementExtension(name);
 17304                Type elementType = Type.GetType(element.Type, false);
 17305                if (null == elementType)
 306                {
 0307                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ConfigurationErrorsException(SR.Format
 0308                        ElementInformation.Source,
 0309                        ElementInformation.LineNumber));
 310                }
 17311                return elementType;
 312            }
 0313            return null;
 314        }
 315
 316        internal void MergeWith(List<TServiceModelExtensionElement> parentExtensionElements)
 317        {
 0318            Merge(parentExtensionElements, this);
 0319            Clear();
 0320            foreach (TServiceModelExtensionElement parentExtensionElement in parentExtensionElements)
 321            {
 0322                Add(parentExtensionElement);
 323            }
 0324        }
 325
 326        private static void Merge(List<TServiceModelExtensionElement> parentExtensionElements, IEnumerable<TServiceModel
 327        {
 0328            foreach (TServiceModelExtensionElement childExtensionElement in childExtensionElements)
 329            {
 0330                Type childExtensionElementType = childExtensionElement.GetType();
 0331                parentExtensionElements.RemoveAll(element =>
 0332                    element != null && element.GetType() == childExtensionElementType);
 0333                parentExtensionElements.Add(childExtensionElement);
 334            }
 0335        }
 336
 337
 338        protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey)
 339        {
 20340            DeserializeElementCore(reader);
 20341        }
 342
 343        private void DeserializeElementCore(XmlReader reader)
 344        {
 20345            if (reader.HasAttributes && 0 < reader.AttributeCount)
 346            {
 44347                while (reader.MoveToNextAttribute())
 348                {
 24349                    if (Properties.Contains(reader.Name))
 350                    {
 24351                        this[reader.Name] = Properties[reader.Name].Converter.ConvertFromString(reader.Value);
 352                    }
 353                    else
 354                    {
 0355                        OnDeserializeUnrecognizedAttribute(reader.Name, reader.Value);
 356                    }
 357                }
 358            }
 359
 20360            if (XmlNodeType.Element != reader.NodeType)
 361            {
 20362                reader.MoveToElement();
 363            }
 364
 20365            XmlReader subTree = reader.ReadSubtree();
 20366            if (subTree.Read())
 367            {
 94368                while (subTree.Read())
 369                {
 74370                    if (XmlNodeType.Element == subTree.NodeType)
 371                    {
 372                        // Create new child element and add it to the property collection to
 373                        // associate the element with an EvaluationContext.  Then deserialize
 374                        // XML further to set actual values.
 17375                        TServiceModelExtensionElement collectionElement = CreateNewSection(subTree.Name);
 17376                        if (collectionElement != null)
 377                        {
 17378                            Add(collectionElement);
 17379                            collectionElement.DeserializeInternal(subTree, false);
 380                        }
 381                    }
 382                }
 383            }
 20384        }
 385
 386        public IEnumerator<TServiceModelExtensionElement> GetEnumerator()
 387        {
 228388            for (int index = 0; index < Items.Count; ++index)
 389            {
 17390                TServiceModelExtensionElement currentValue = _items[index];
 17391                yield return currentValue;
 392            }
 97393        }
 394
 395        protected override bool IsModified()
 396        {
 0397            bool retval = _modified;
 0398            if (!retval)
 399            {
 0400                for (int i = 0; i < Items.Count; i++)
 401                {
 0402                    TServiceModelExtensionElement element = Items[i];
 0403                    if (element.IsModifiedInternal())
 404                    {
 0405                        retval = true;
 0406                        break;
 407                    }
 408                }
 409            }
 0410            return retval;
 411        }
 412
 413        protected override bool OnDeserializeUnrecognizedElement(string elementName, XmlReader reader)
 414        {
 415            // When this is used as a DefaultCollection (i.e. CommonBehaviors)
 416            // the element names are unrecognized by the parent tag, which delegates
 417            // to the collection's OnDeserializeUnrecognizedElement.  In this case,
 418            // an unrecognized element may be expected, simply try to deserialize the
 419            // element and let DeserializeElement() throw the appropriate exception if
 420            // an error is hit.
 0421            DeserializeElement(reader, false);
 0422            return true;
 423        }
 424
 425        public bool Remove(TServiceModelExtensionElement element)
 426        {
 0427            if (element == null)
 428            {
 0429                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(element));
 430            }
 0431            bool retval = false;
 0432            if (Contains(element))
 433            {
 0434                string configuredSectionName = element.ConfigurationElementName;
 435
 0436                TServiceModelExtensionElement existingElement = this[element.GetType()];
 0437                Items.Remove(existingElement);
 0438                Properties.Remove(configuredSectionName);
 0439                _modified = true;
 0440                retval = true;
 441            }
 0442            return retval;
 443        }
 444
 445        protected override void Reset(ConfigurationElement parentElement)
 446        {
 0447            ServiceModelExtensionCollectionElement<TServiceModelExtensionElement> collection =
 0448                (ServiceModelExtensionCollectionElement<TServiceModelExtensionElement>)parentElement;
 0449            foreach (TServiceModelExtensionElement collectionElement in collection.Items)
 450            {
 0451                Items.Add(collectionElement);
 452            }
 453            // Update my properties
 0454            UpdateProperties(collection);
 455
 0456            base.Reset(parentElement);
 0457        }
 458
 459        protected override void ResetModified()
 460        {
 74461            for (int i = 0; i < Items.Count; i++)
 462            {
 17463                TServiceModelExtensionElement collectionElement = Items[i];
 17464                collectionElement.ResetModifiedInternal();
 465            }
 20466            _modified = false;
 20467        }
 468
 469        protected void SetIsModified()
 470        {
 0471            _modified = true;
 0472        }
 473
 474        protected override void SetReadOnly()
 475        {
 0476            base.SetReadOnly();
 477
 0478            for (int i = 0; i < Items.Count; i++)
 479            {
 0480                TServiceModelExtensionElement element = Items[i];
 0481                element.SetReadOnlyInternal();
 482            }
 0483        }
 484
 485        IEnumerator IEnumerable.GetEnumerator()
 486        {
 0487            return GetEnumerator();
 488        }
 489
 490        protected override void Unmerge(ConfigurationElement sourceElement, ConfigurationElement parentElement, Configur
 491        {
 0492            if (sourceElement == null)
 493            {
 0494                return;
 495            }
 496
 0497            ServiceModelExtensionCollectionElement<TServiceModelExtensionElement> sourceCollectionElement = (ServiceMode
 498
 0499            UpdateProperties(sourceCollectionElement);
 0500            base.Unmerge(sourceElement, parentElement, saveMode);
 0501        }
 502
 503        private void UpdateProperties(ServiceModelExtensionCollectionElement<TServiceModelExtensionElement> sourceElemen
 504        {
 0505            foreach (ConfigurationProperty property in sourceElement.Properties)
 506            {
 0507                if (!Properties.Contains(property.Name))
 508                {
 0509                    Properties.Add(property);
 510                }
 511            }
 512
 0513            foreach (TServiceModelExtensionElement extension in Items)
 514            {
 0515                string configuredSectionName = extension.ConfigurationElementName;
 0516                if (!Properties.Contains(configuredSectionName))
 517                {
 0518                    ConfigurationProperty configProperty = new ConfigurationProperty(configuredSectionName, extension.Ge
 0519                    Properties.Add(configProperty);
 520                }
 521            }
 0522        }
 523    }
 524}