PolicyReader.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Description / PolicyReader.cs / 2 / PolicyReader.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Description
{ 
    using System.Collections;
    using System.Collections.Generic; 
    using System.Collections.ObjectModel; 
    using System.Xml;
    using WsdlNS = System.Web.Services.Description; 
    using System.Globalization;

    //
    // PolicyReader is a complex nested class in the MetadataImporter 
    //
    public abstract partial class MetadataImporter 
    { 
        internal MetadataImporterQuotas Quotas;
 
        PolicyReader policyNormalizer = null;

        internal delegate void PolicyWarningHandler(XmlElement contextAssertion, string warningMessage);
 
        // Consider, [....], make this public?
        internal event PolicyWarningHandler PolicyWarningOccured; 
 
        internal IEnumerable> NormalizePolicy(IEnumerable policyAssertions)
        { 
            if (this.policyNormalizer == null)
            {
                this.policyNormalizer = new PolicyReader(this);
            } 

            return this.policyNormalizer.NormalizePolicy(policyAssertions); 
        } 

        //DevNote: The error handling goal for this class is to NEVER throw an exception. 
        //  * Any Ignored Policy should generate a warning
        //  * All policy parsing errors should be logged as warnings in the WSDLImporter.Errors collection.
        sealed class PolicyReader
        { 
            int nodesRead = 0;
 
            readonly MetadataImporter metadataImporter; 

            internal PolicyReader(MetadataImporter metadataImporter) 
            {
                this.metadataImporter = metadataImporter;
            }
 
            static IEnumerable Empty = new PolicyHelper.EmptyEnumerable();
            static IEnumerable> EmptyEmpty = new PolicyHelper.SingleEnumerable>(new PolicyHelper.EmptyEnumerable()); 
 
            //
            // the core policy reading logic 
            // each step returns a list of lists -- an "and of ors":
            // each inner list is a policy alternative: it contains the set of assertions that comprise the alternative
            // the outer list represents the choice between alternatives
            // 

            IEnumerable> ReadNode(XmlNode node, XmlElement contextAssertion, YieldLimiter yieldLimiter) 
            { 
                if (nodesRead >= this.metadataImporter.Quotas.MaxPolicyNodes)
                { 
                    if (nodesRead == this.metadataImporter.Quotas.MaxPolicyNodes)
                    {
                        // add wirning once
                        string warningMsg = SR.GetString(SR.ExceededMaxPolicyComplexity, node.Name, PolicyHelper.GetFragmentIdentifier((XmlElement)node)); 
                        metadataImporter.PolicyWarningOccured.Invoke(contextAssertion, warningMsg);
                        nodesRead++; 
                    } 
                    return EmptyEmpty;
                } 
                nodesRead++;
                IEnumerable> nodes = EmptyEmpty;
                switch (PolicyHelper.GetNodeType(node))
                { 
                    case PolicyHelper.NodeType.Policy:
                    case PolicyHelper.NodeType.All: 
                        nodes = ReadNode_PolicyOrAll((XmlElement)node, contextAssertion, yieldLimiter); 
                        break;
                    case PolicyHelper.NodeType.ExactlyOne: 
                        nodes = ReadNode_ExactlyOne((XmlElement)node, contextAssertion, yieldLimiter);
                        break;
                    case PolicyHelper.NodeType.Assertion:
                        nodes = ReadNode_Assertion((XmlElement)node, yieldLimiter); 
                        break;
                    case PolicyHelper.NodeType.PolicyReference: 
                        nodes = ReadNode_PolicyReference((XmlElement)node, contextAssertion, yieldLimiter); 
                        break;
                    case PolicyHelper.NodeType.UnrecognizedWSPolicy: 
                        string warningMsg = SR.GetString(SR.UnrecognizedPolicyElementInNamespace, node.Name, node.NamespaceURI);
                        metadataImporter.PolicyWarningOccured.Invoke(contextAssertion, warningMsg);
                        break;
                    //consider [....], add more error handling here. default? 
                }
                return nodes; 
            } 

            IEnumerable> ReadNode_PolicyReference(XmlElement element, XmlElement contextAssertion, YieldLimiter yieldLimiter) 
            {
                string idRef = element.GetAttribute(MetadataStrings.WSPolicy.Attributes.URI);
                if (idRef == null)
                { 
                    string warningMsg = SR.GetString(SR.PolicyReferenceMissingURI, MetadataStrings.WSPolicy.Attributes.URI);
                    metadataImporter.PolicyWarningOccured.Invoke(contextAssertion, warningMsg); 
                    return EmptyEmpty; 
                }
                else if (idRef == string.Empty) 
                {
                    string warningMsg = SR.GetString(SR.PolicyReferenceInvalidId);
                    metadataImporter.PolicyWarningOccured.Invoke(contextAssertion, warningMsg);
                    return EmptyEmpty; 
                }
 
                XmlElement policy = metadataImporter.ResolvePolicyReference(idRef, contextAssertion); 
                if (policy == null)
                { 
                    string warningMsg = SR.GetString(SR.UnableToFindPolicyWithId, idRef);
                    metadataImporter.PolicyWarningOccured.Invoke(contextAssertion, warningMsg);
                    return EmptyEmpty;
                } 

                // 
                // Since we looked up a reference, the context assertion changes. 
                //
                return ReadNode_PolicyOrAll(policy, policy, yieldLimiter); 

            }

            IEnumerable> ReadNode_Assertion(XmlElement element, YieldLimiter yieldLimiter) 
            {
                if (yieldLimiter.IncrementAndLogIfExceededLimit()) 
                    yield return Empty; 
                else
                    yield return new PolicyHelper.SingleEnumerable(element); 
            }

            IEnumerable> ReadNode_ExactlyOne(XmlElement element, XmlElement contextAssertion, YieldLimiter yieldLimiter)
            { 
                foreach (XmlNode child in element.ChildNodes)
                { 
                    if (child.NodeType == XmlNodeType.Element) 
                    {
                        foreach (IEnumerable alternative in ReadNode(child, contextAssertion, yieldLimiter)) 
                        {
                            if (yieldLimiter.IncrementAndLogIfExceededLimit())
                            {
                                yield break; 
                            }
                            else 
                            { 
                                yield return alternative;
                            } 
                        }
                    }
                }
            } 

            IEnumerable> ReadNode_PolicyOrAll(XmlElement element, XmlElement contextAssertion, YieldLimiter yieldLimiter) 
            { 
                IEnumerable> target = EmptyEmpty;
 
                foreach (XmlNode child in element.ChildNodes)
                {
                    if (child.NodeType == XmlNodeType.Element)
                    { 
                        IEnumerable> childPolicy = ReadNode(child, contextAssertion, yieldLimiter);
                        target = PolicyHelper.CrossProduct(target, childPolicy, yieldLimiter); 
                    } 
                }
                return target; 
            }

            internal IEnumerable> NormalizePolicy(IEnumerable policyAssertions)
            { 
                IEnumerable> target = EmptyEmpty;
                YieldLimiter yieldLimiter = new YieldLimiter(this.metadataImporter.Quotas.MaxYields, this.metadataImporter); 
                foreach (XmlElement child in policyAssertions) 
                {
                    IEnumerable> childPolicy = ReadNode(child, child, yieldLimiter); 
                    target = PolicyHelper.CrossProduct(target, childPolicy, yieldLimiter);
                }

                return target; 
            }
        } 
 
        internal class YieldLimiter
        { 
            int maxYields;
            int yieldsHit;
            readonly MetadataImporter metadataImporter;
 
            internal YieldLimiter(int maxYields, MetadataImporter metadataImporter)
            { 
                this.metadataImporter = metadataImporter; 
                this.yieldsHit = 0;
                this.maxYields = maxYields; 
            }

            internal bool IncrementAndLogIfExceededLimit()
            { 
                if (++yieldsHit > maxYields)
                { 
                    string warningMsg = SR.GetString(SR.ExceededMaxPolicySize); 
                    metadataImporter.PolicyWarningOccured.Invoke(null, warningMsg);
                    return true; 
                }
                else
                {
                    return false; 
                }
            } 
        } 

        internal static class PolicyHelper 
        {


            internal static string GetFragmentIdentifier(XmlElement element) 
            {
                string id = element.GetAttribute(MetadataStrings.Wsu.Attributes.Id, MetadataStrings.Wsu.NamespaceUri); 
 
                if (id == null)
                { 
                    id = element.GetAttribute(MetadataStrings.Xml.Attributes.Id, MetadataStrings.Xml.NamespaceUri);
                }

                if (string.IsNullOrEmpty(id)) 
                    return string.Empty;
                else 
                    return string.Format(CultureInfo.InvariantCulture, "#{0}", id); 
            }
 
            internal static bool IsPolicyURIs(XmlAttribute attribute)
            {
                return ((attribute.NamespaceURI == MetadataStrings.WSPolicy.NamespaceUri
                    || attribute.NamespaceURI == MetadataStrings.WSPolicy.NamespaceUri15) 
                            && attribute.LocalName == MetadataStrings.WSPolicy.Attributes.PolicyURIs);
            } 
 
            internal static NodeType GetNodeType(XmlNode node)
            { 
                XmlElement currentElement = node as XmlElement;

                if (currentElement == null)
                    return PolicyHelper.NodeType.NonElement; 

                if (currentElement.NamespaceURI != MetadataStrings.WSPolicy.NamespaceUri 
                    && currentElement.NamespaceURI != MetadataStrings.WSPolicy.NamespaceUri15) 
                    return NodeType.Assertion;
                else if (currentElement.LocalName == MetadataStrings.WSPolicy.Elements.Policy) 
                    return NodeType.Policy;
                else if (currentElement.LocalName == MetadataStrings.WSPolicy.Elements.All)
                    return NodeType.All;
                else if (currentElement.LocalName == MetadataStrings.WSPolicy.Elements.ExactlyOne) 
                    return NodeType.ExactlyOne;
                else if (currentElement.LocalName == MetadataStrings.WSPolicy.Elements.PolicyReference) 
                    return NodeType.PolicyReference; 
                else
                    return PolicyHelper.NodeType.UnrecognizedWSPolicy; 
            }

            //
            // some helpers for dealing with ands of ors 
            //
 
            internal static IEnumerable> CrossProduct(IEnumerable> xs, IEnumerable> ys, YieldLimiter yieldLimiter) 
            {
                foreach (IEnumerable x in AtLeastOne(xs, yieldLimiter)) 
                {
                    foreach (IEnumerable y in AtLeastOne(ys, yieldLimiter))
                    {
                        if (yieldLimiter.IncrementAndLogIfExceededLimit()) 
                        {
                            yield break; 
                        } 
                        else
                        { 
                            yield return Merge(x, y, yieldLimiter);
                        }
                    }
                } 
            }
 
            static IEnumerable> AtLeastOne(IEnumerable> xs, YieldLimiter yieldLimiter) 
            {
                bool gotOne = false; 
                foreach (IEnumerable x in xs)
                {
                    gotOne = true;
 
                    if (yieldLimiter.IncrementAndLogIfExceededLimit())
                    { 
                        yield break; 
                    }
                    else 
                    {
                        yield return x;
                    }
                } 
                if (!gotOne)
                { 
                    if (yieldLimiter.IncrementAndLogIfExceededLimit()) 
                    {
                        yield break; 
                    }
                    else
                    {
                        yield return new EmptyEnumerable(); 
                    }
                } 
            } 

            static IEnumerable Merge(IEnumerable e1, IEnumerable e2, YieldLimiter yieldLimiter) 
            {
                foreach (T t1 in e1)
                {
                    if (yieldLimiter.IncrementAndLogIfExceededLimit()) 
                    {
                        yield break; 
                    } 
                    else
                    { 
                        yield return t1;
                    }

                } 
                foreach (T t2 in e2)
                { 
                    if (yieldLimiter.IncrementAndLogIfExceededLimit()) 
                    {
                        yield break; 
                    }
                    else
                    {
                        yield return t2; 
                    }
                } 
            } 

            // 
            // some helper enumerators
            //

            internal class EmptyEnumerable : IEnumerable, IEnumerator 
            {
                IEnumerator IEnumerable.GetEnumerator() 
                { 
                    return this.GetEnumerator();
                } 

                public IEnumerator GetEnumerator()
                {
                    return this; 
                }
 
                object IEnumerator.Current 
                {
                    get { return this.Current; } 
                }

                public T Current
                { 
                    get
                    { 
#pragma warning suppress 56503 // [....], IEnumerator guidelines, Current throws exception before calling MoveNext 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.NoValue0)));
                    } 
                }

                public bool MoveNext()
                { 
                    return false;
                } 
 
                public void Dispose()
                { 
                }

                void IEnumerator.Reset()
                { 
                }
            } 
 
            internal class SingleEnumerable : IEnumerable
            { 
                T value;

                internal SingleEnumerable(T value)
                { 
                    this.value = value;
                } 
 
                IEnumerator IEnumerable.GetEnumerator()
                { 
                    return this.GetEnumerator();
                }

                public IEnumerator GetEnumerator() 
                {
                    yield return this.value; 
                } 
            }
 
            //
            // the NodeType enum
            //
            internal enum NodeType 
            {
                NonElement, 
                Policy, 
                All,
                ExactlyOne, 
                Assertion,
                PolicyReference,
                UnrecognizedWSPolicy,
            } 

 
        } 

    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK