2 // PolicyImportHelper.cs
5 // Martin Baulig <martin.baulig@xamarin.com>
7 // Copyright (c) 2012 Xamarin Inc. (http://www.xamarin.com)
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 using System.Collections.Generic;
29 using System.ServiceModel.Description;
31 using QName = System.Xml.XmlQualifiedName;
33 namespace System.ServiceModel.Channels {
35 internal static class PolicyImportHelper {
37 internal const string SecurityPolicyNS = "http://schemas.xmlsoap.org/ws/2005/07/securitypolicy";
38 internal const string PolicyNS = "http://schemas.xmlsoap.org/ws/2004/09/policy";
39 internal const string MimeSerializationNS = "http://schemas.xmlsoap.org/ws/2004/09/policy/optimizedmimeserialization";
40 internal const string HttpAuthNS = "http://schemas.microsoft.com/ws/06/2004/policy/http";
42 internal const string FramingPolicyNS = "http://schemas.microsoft.com/ws/2006/05/framing/policy";
43 internal const string NetBinaryEncodingNS = "http://schemas.microsoft.com/ws/06/2004/mspolicy/netbinary1";
45 internal const string WSSecurityNS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
47 internal static XmlElement GetTransportBindingPolicy (PolicyAssertionCollection collection)
49 return FindAndRemove (collection, "TransportBinding", SecurityPolicyNS);
52 internal static XmlElement GetStreamedMessageFramingPolicy (PolicyAssertionCollection collection)
54 return FindAndRemove (collection, "Streamed", FramingPolicyNS);
57 internal static XmlElement GetBinaryMessageEncodingPolicy (PolicyAssertionCollection collection)
59 return FindAndRemove (collection, "BinaryEncoding", NetBinaryEncodingNS);
62 internal static XmlElement GetMtomMessageEncodingPolicy (PolicyAssertionCollection collection)
64 return FindAndRemove (collection, "OptimizedMimeSerialization", MimeSerializationNS);
67 static XmlElement FindAndRemove (PolicyAssertionCollection collection, string name, string ns)
69 var element = collection.Find (name, ns);
71 collection.Remove (element);
75 internal static List<XmlElement> FindAssertionByNS (
76 PolicyAssertionCollection collection, string ns)
78 var list = new List<XmlElement> ();
79 foreach (var assertion in collection) {
80 if (assertion.NamespaceURI.Equals (ns))
86 internal static List<XmlElement> GetPolicyElements (XmlElement root, out bool error)
88 XmlElement policy = null;
89 var list = new List<XmlElement> ();
91 foreach (var node in root.ChildNodes) {
92 var e = node as XmlElement;
95 if (!PolicyNS.Equals (e.NamespaceURI) || !e.LocalName.Equals ("Policy")) {
106 if (policy == null) {
111 foreach (var node in policy.ChildNodes) {
112 var e = node as XmlElement;
121 internal static bool FindPolicyElement (MetadataImporter importer, XmlElement root,
122 QName name, bool required, bool removeWhenFound,
123 out XmlElement element)
125 if (!FindPolicyElement (root, name, removeWhenFound, out element)) {
126 importer.AddWarning ("Invalid policy element: {0}", root.OuterXml);
129 if (required && (element == null)) {
130 importer.AddWarning ("Did not find policy element `{0}'.", name);
136 internal static bool FindPolicyElement (XmlElement root, QName name,
137 bool removeWhenFound, out XmlElement element)
139 XmlElement policy = null;
140 foreach (var node in root.ChildNodes) {
141 var e = node as XmlElement;
144 if (!PolicyNS.Equals (e.NamespaceURI) || !e.LocalName.Equals ("Policy")) {
148 if (policy != null) {
155 if (policy == null) {
161 foreach (var node in policy.ChildNodes) {
162 var e = node as XmlElement;
165 if (!name.Namespace.Equals (e.NamespaceURI) || !name.Name.Equals (e.LocalName))
172 if (!removeWhenFound || (element == null))
175 policy.RemoveChild (element);
177 bool foundAnother = false;
178 foreach (var node in policy.ChildNodes) {
179 var e = node as XmlElement;
187 root.RemoveChild (policy);
191 internal static XmlElement GetElement (MetadataImporter importer,
192 XmlElement root, string name, string ns)
194 return GetElement (importer, root, name, ns, false);
197 internal static XmlElement GetElement (MetadataImporter importer,
198 XmlElement root, string name, string ns,
201 return GetElement (importer, root, new QName (name, ns), required);
204 internal static XmlElement GetElement (MetadataImporter importer,
205 XmlElement root, QName name, bool required)
207 var list = root.GetElementsByTagName (name.Name, name.Namespace);
208 if (list.Count < 1) {
210 importer.AddWarning ("Did not find required policy element `{0}'", name);
214 if (list.Count > 1) {
215 importer.AddWarning ("Found duplicate policy element `{0}'", name);
219 var element = list [0] as XmlElement;
220 if (required && (element == null))
221 importer.AddWarning ("Did not find required policy element `{0}'", name);
225 internal static XmlElement WrapPolicy (XmlElement element)
227 var policy = element.OwnerDocument.CreateElement ("wsp", "Policy", PolicyNS);
228 policy.AppendChild (element);
233 // Add a single element, wrapping it inside <wsp:Policy>
235 internal static void AddWrappedPolicyElement (XmlElement root, XmlElement element)
237 if (root.OwnerDocument != element.OwnerDocument)
238 element = (XmlElement)root.OwnerDocument.ImportNode (element, true);
239 if (!element.NamespaceURI.Equals (PolicyNS) || !element.LocalName.Equals ("Policy"))
240 element = WrapPolicy (element);
241 root.AppendChild (element);
245 // Add multiple elements, wrapping them inside a single <wsp:Policy>
247 internal static void AddWrappedPolicyElements (XmlElement root, params XmlElement[] elements)
249 var policy = root.OwnerDocument.CreateElement ("wsp", "Policy", PolicyNS);
250 root.AppendChild (policy);
252 foreach (var element in elements) {
254 if (root.OwnerDocument != element.OwnerDocument)
255 imported = (XmlElement)root.OwnerDocument.ImportNode (element, true);
258 policy.AppendChild (element);