static IEnumerable <T> Merge <T>(IEnumerable <T> e1, IEnumerable <T> 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); } } }
internal IEnumerable <IEnumerable <XmlElement> > NormalizePolicy(IEnumerable <XmlElement> policyAssertions) { IEnumerable <IEnumerable <XmlElement> > target = s_emptyEmpty; YieldLimiter yieldLimiter = new YieldLimiter(_metadataImporter.Quotas.MaxYields, _metadataImporter); foreach (XmlElement child in policyAssertions) { IEnumerable <IEnumerable <XmlElement> > childPolicy = ReadNode(child, child, yieldLimiter); target = PolicyHelper.CrossProduct <XmlElement>(target, childPolicy, yieldLimiter); } return(target); }
// // 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 // private IEnumerable <IEnumerable <XmlElement> > ReadNode(XmlNode node, XmlElement contextAssertion, YieldLimiter yieldLimiter) { if (_nodesRead >= _metadataImporter.Quotas.MaxPolicyNodes) { if (_nodesRead == _metadataImporter.Quotas.MaxPolicyNodes) { // add wirning once string warningMsg = string.Format(SRServiceModel.ExceededMaxPolicyComplexity, node.Name, PolicyHelper.GetFragmentIdentifier((XmlElement)node)); _metadataImporter.PolicyWarningOccured.Invoke(contextAssertion, warningMsg); _nodesRead++; } return(s_emptyEmpty); } _nodesRead++; IEnumerable <IEnumerable <XmlElement> > nodes = s_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 = string.Format(SRServiceModel.UnrecognizedPolicyElementInNamespace, node.Name, node.NamespaceURI); _metadataImporter.PolicyWarningOccured.Invoke(contextAssertion, warningMsg); break; //consider hsomu, add more error handling here. default? } return(nodes); }
private static IEnumerable <IEnumerable <T> > AtLeastOne <T>(IEnumerable <IEnumerable <T> > xs, YieldLimiter yieldLimiter) { bool gotOne = false; foreach (IEnumerable <T> 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 <T>()); } } }
// // some helpers for dealing with ands of ors // internal static IEnumerable <IEnumerable <T> > CrossProduct <T>(IEnumerable <IEnumerable <T> > xs, IEnumerable <IEnumerable <T> > ys, YieldLimiter yieldLimiter) { foreach (IEnumerable <T> x in AtLeastOne <T>(xs, yieldLimiter)) { foreach (IEnumerable <T> y in AtLeastOne <T>(ys, yieldLimiter)) { if (yieldLimiter.IncrementAndLogIfExceededLimit()) { yield break; } else { yield return(Merge <T>(x, y, yieldLimiter)); } } } }
private IEnumerable <IEnumerable <XmlElement> > ReadNode_PolicyOrAll(XmlElement element, XmlElement contextAssertion, YieldLimiter yieldLimiter) { IEnumerable <IEnumerable <XmlElement> > target = s_emptyEmpty; foreach (XmlNode child in element.ChildNodes) { if (child.NodeType == XmlNodeType.Element) { IEnumerable <IEnumerable <XmlElement> > childPolicy = ReadNode(child, contextAssertion, yieldLimiter); target = PolicyHelper.CrossProduct <XmlElement>(target, childPolicy, yieldLimiter); } } return(target); }
private IEnumerable <IEnumerable <XmlElement> > ReadNode_ExactlyOne(XmlElement element, XmlElement contextAssertion, YieldLimiter yieldLimiter) { foreach (XmlNode child in element.ChildNodes) { if (child.NodeType == XmlNodeType.Element) { foreach (IEnumerable <XmlElement> alternative in ReadNode(child, contextAssertion, yieldLimiter)) { if (yieldLimiter.IncrementAndLogIfExceededLimit()) { yield break; } else { yield return(alternative); } } } } }
private IEnumerable <IEnumerable <XmlElement> > ReadNode_Assertion(XmlElement element, YieldLimiter yieldLimiter) { if (yieldLimiter.IncrementAndLogIfExceededLimit()) { yield return(s_empty); } else { yield return(new PolicyHelper.SingleEnumerable <XmlElement>(element)); } }
private IEnumerable <IEnumerable <XmlElement> > ReadNode_PolicyReference(XmlElement element, XmlElement contextAssertion, YieldLimiter yieldLimiter) { string idRef = element.GetAttribute(MetadataStrings.WSPolicy.Attributes.URI); if (idRef == null) { string warningMsg = string.Format(SRServiceModel.PolicyReferenceMissingURI, MetadataStrings.WSPolicy.Attributes.URI); _metadataImporter.PolicyWarningOccured.Invoke(contextAssertion, warningMsg); return(s_emptyEmpty); } else if (idRef == string.Empty) { string warningMsg = SRServiceModel.PolicyReferenceInvalidId; _metadataImporter.PolicyWarningOccured.Invoke(contextAssertion, warningMsg); return(s_emptyEmpty); } XmlElement policy = _metadataImporter.ResolvePolicyReference(idRef, contextAssertion); if (policy == null) { string warningMsg = string.Format(SRServiceModel.UnableToFindPolicyWithId, idRef); _metadataImporter.PolicyWarningOccured.Invoke(contextAssertion, warningMsg); return(s_emptyEmpty); } // // Since we looked up a reference, the context assertion changes. // return(ReadNode_PolicyOrAll(policy, policy, yieldLimiter)); }