Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

264 lines
8.1 KiB
C#

//
// PolicyImportHelper.cs
//
// Author:
// Martin Baulig <martin.baulig@xamarin.com>
//
// Copyright (c) 2012 Xamarin Inc. (http://www.xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Xml;
using System.Collections.Generic;
using System.ServiceModel.Description;
using QName = System.Xml.XmlQualifiedName;
namespace System.ServiceModel.Channels {
internal static class PolicyImportHelper {
internal const string SecurityPolicyNS = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy";
internal const string PolicyNS = "http://schemas.xmlsoap.org/ws/2004/09/policy";
internal const string MimeSerializationNS = "http://schemas.xmlsoap.org/ws/2004/09/policy/optimizedmimeserialization";
internal const string HttpAuthNS = "http://schemas.microsoft.com/ws/06/2004/policy/http";
internal const string FramingPolicyNS = "http://schemas.microsoft.com/ws/2006/05/framing/policy";
internal const string NetBinaryEncodingNS = "http://schemas.microsoft.com/ws/06/2004/mspolicy/netbinary1";
internal const string WSSecurityNS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
internal static XmlElement GetTransportBindingPolicy (PolicyAssertionCollection collection)
{
return FindAndRemove (collection, "TransportBinding", SecurityPolicyNS);
}
internal static XmlElement GetStreamedMessageFramingPolicy (PolicyAssertionCollection collection)
{
return FindAndRemove (collection, "Streamed", FramingPolicyNS);
}
internal static XmlElement GetBinaryMessageEncodingPolicy (PolicyAssertionCollection collection)
{
return FindAndRemove (collection, "BinaryEncoding", NetBinaryEncodingNS);
}
internal static XmlElement GetMtomMessageEncodingPolicy (PolicyAssertionCollection collection)
{
return FindAndRemove (collection, "OptimizedMimeSerialization", MimeSerializationNS);
}
static XmlElement FindAndRemove (PolicyAssertionCollection collection, string name, string ns)
{
var element = collection.Find (name, ns);
if (element != null)
collection.Remove (element);
return element;
}
internal static List<XmlElement> FindAssertionByNS (
PolicyAssertionCollection collection, string ns)
{
var list = new List<XmlElement> ();
foreach (var assertion in collection) {
if (assertion.NamespaceURI.Equals (ns))
list.Add (assertion);
}
return list;
}
internal static List<XmlElement> GetPolicyElements (XmlElement root, out bool error)
{
XmlElement policy = null;
var list = new List<XmlElement> ();
foreach (var node in root.ChildNodes) {
var e = node as XmlElement;
if (e == null)
continue;
if (!PolicyNS.Equals (e.NamespaceURI) || !e.LocalName.Equals ("Policy")) {
error = true;
return list;
}
if (policy != null) {
error = true;
return list;
}
policy = e;
}
if (policy == null) {
error = true;
return list;
}
foreach (var node in policy.ChildNodes) {
var e = node as XmlElement;
if (e != null)
list.Add (e);
}
error = false;
return list;
}
internal static bool FindPolicyElement (MetadataImporter importer, XmlElement root,
QName name, bool required, bool removeWhenFound,
out XmlElement element)
{
if (!FindPolicyElement (root, name, removeWhenFound, out element)) {
importer.AddWarning ("Invalid policy element: {0}", root.OuterXml);
return false;
}
if (required && (element == null)) {
importer.AddWarning ("Did not find policy element `{0}'.", name);
return false;
}
return true;
}
internal static bool FindPolicyElement (XmlElement root, QName name,
bool removeWhenFound, out XmlElement element)
{
XmlElement policy = null;
foreach (var node in root.ChildNodes) {
var e = node as XmlElement;
if (e == null)
continue;
if (!PolicyNS.Equals (e.NamespaceURI) || !e.LocalName.Equals ("Policy")) {
element = null;
return false;
}
if (policy != null) {
element = null;
return false;
}
policy = e;
}
if (policy == null) {
element = null;
return true;
}
element = null;
foreach (var node in policy.ChildNodes) {
var e = node as XmlElement;
if (e == null)
continue;
if (!name.Namespace.Equals (e.NamespaceURI) || !name.Name.Equals (e.LocalName))
continue;
element = e;
break;
}
if (!removeWhenFound || (element == null))
return true;
policy.RemoveChild (element);
bool foundAnother = false;
foreach (var node in policy.ChildNodes) {
var e = node as XmlElement;
if (e != null) {
foundAnother = true;
break;
}
}
if (!foundAnother)
root.RemoveChild (policy);
return true;
}
internal static XmlElement GetElement (MetadataImporter importer,
XmlElement root, string name, string ns)
{
return GetElement (importer, root, name, ns, false);
}
internal static XmlElement GetElement (MetadataImporter importer,
XmlElement root, string name, string ns,
bool required)
{
return GetElement (importer, root, new QName (name, ns), required);
}
internal static XmlElement GetElement (MetadataImporter importer,
XmlElement root, QName name, bool required)
{
var list = root.GetElementsByTagName (name.Name, name.Namespace);
if (list.Count < 1) {
if (required)
importer.AddWarning ("Did not find required policy element `{0}'", name);
return null;
}
if (list.Count > 1) {
importer.AddWarning ("Found duplicate policy element `{0}'", name);
return null;
}
var element = list [0] as XmlElement;
if (required && (element == null))
importer.AddWarning ("Did not find required policy element `{0}'", name);
return element;
}
internal static XmlElement WrapPolicy (XmlElement element)
{
var policy = element.OwnerDocument.CreateElement ("wsp", "Policy", PolicyNS);
policy.AppendChild (element);
return policy;
}
//
// Add a single element, wrapping it inside <wsp:Policy>
//
internal static void AddWrappedPolicyElement (XmlElement root, XmlElement element)
{
if (root.OwnerDocument != element.OwnerDocument)
element = (XmlElement)root.OwnerDocument.ImportNode (element, true);
if (!element.NamespaceURI.Equals (PolicyNS) || !element.LocalName.Equals ("Policy"))
element = WrapPolicy (element);
root.AppendChild (element);
}
//
// Add multiple elements, wrapping them inside a single <wsp:Policy>
//
internal static void AddWrappedPolicyElements (XmlElement root, params XmlElement[] elements)
{
var policy = root.OwnerDocument.CreateElement ("wsp", "Policy", PolicyNS);
root.AppendChild (policy);
foreach (var element in elements) {
XmlElement imported;
if (root.OwnerDocument != element.OwnerDocument)
imported = (XmlElement)root.OwnerDocument.ImportNode (element, true);
else
imported = element;
policy.AppendChild (element);
}
}
}
}