1 // 2 // System.Web.Services.Description.ExtensionManager.cs 3 // 4 // Author: 5 // Lluis Sanchez Gual (lluis@ximian.com) 6 // 7 // Copyright (C) 2003 Ximian, Inc. 8 // 9 10 // 11 // Permission is hereby granted, free of charge, to any person obtaining 12 // a copy of this software and associated documentation files (the 13 // "Software"), to deal in the Software without restriction, including 14 // without limitation the rights to use, copy, modify, merge, publish, 15 // distribute, sublicense, and/or sell copies of the Software, and to 16 // permit persons to whom the Software is furnished to do so, subject to 17 // the following conditions: 18 // 19 // The above copyright notice and this permission notice shall be 20 // included in all copies or substantial portions of the Software. 21 // 22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 // 30 31 using System.Reflection; 32 using System.Collections; 33 using System.Web.Services.Configuration; 34 using System.Xml.Serialization; 35 using System.Xml; 36 37 namespace System.Web.Services.Description 38 { 39 internal abstract class ExtensionManager 40 { 41 static Hashtable extensionsByName; 42 static Hashtable extensionsByType; 43 static ArrayList maps = new ArrayList (); 44 static ArrayList extensions = new ArrayList (); 45 ExtensionManager()46 static ExtensionManager () 47 { 48 extensionsByName = new Hashtable (); 49 extensionsByType = new Hashtable (); 50 51 RegisterExtensionType (typeof (HttpAddressBinding)); 52 RegisterExtensionType (typeof (HttpBinding)); 53 RegisterExtensionType (typeof (HttpOperationBinding)); 54 RegisterExtensionType (typeof (HttpUrlEncodedBinding)); 55 RegisterExtensionType (typeof (HttpUrlReplacementBinding)); 56 RegisterExtensionType (typeof (MimeContentBinding)); 57 RegisterExtensionType (typeof (MimeMultipartRelatedBinding)); 58 RegisterExtensionType (typeof (MimeTextBinding)); 59 RegisterExtensionType (typeof (MimeXmlBinding)); 60 RegisterExtensionType (typeof (SoapAddressBinding)); 61 RegisterExtensionType (typeof (SoapBinding)); 62 RegisterExtensionType (typeof (SoapBodyBinding)); 63 RegisterExtensionType (typeof (SoapFaultBinding)); 64 RegisterExtensionType (typeof (SoapHeaderBinding)); 65 // RegisterExtensionType (typeof (SoapHeaderFaultBinding)); 66 RegisterExtensionType (typeof (SoapOperationBinding)); 67 RegisterExtensionType (typeof (Soap12AddressBinding)); 68 RegisterExtensionType (typeof (Soap12Binding)); 69 RegisterExtensionType (typeof (Soap12BodyBinding)); 70 RegisterExtensionType (typeof (Soap12FaultBinding)); 71 RegisterExtensionType (typeof (Soap12HeaderBinding)); 72 RegisterExtensionType (typeof (Soap12OperationBinding)); 73 74 #if !MOBILE && !XAMMAC_4_5 75 /* 76 * Currently, the mobile profile has not support for 77 * System.Configuration, so there are no external modules 78 * defined 79 */ 80 foreach (TypeElement el in WebServicesSection.Current.ServiceDescriptionFormatExtensionTypes) 81 RegisterExtensionType (el.Type); 82 #endif 83 CreateExtensionSerializers (); 84 } 85 RegisterExtensionType(Type type)86 static void RegisterExtensionType (Type type) 87 { 88 ExtensionInfo ext = new ExtensionInfo(); 89 ext.Type = type; 90 91 object[] ats = type.GetCustomAttributes (typeof(XmlFormatExtensionPrefixAttribute), true); 92 93 foreach (XmlFormatExtensionPrefixAttribute at in ats) 94 ext.NamespaceDeclarations.Add (new XmlQualifiedName (at.Prefix, at.Namespace)); 95 96 ats = type.GetCustomAttributes (typeof(XmlFormatExtensionAttribute), true); 97 if (ats.Length > 0) 98 { 99 XmlFormatExtensionAttribute at = (XmlFormatExtensionAttribute)ats[0]; 100 ext.ElementName = at.ElementName; 101 if (at.Namespace != null) ext.Namespace = at.Namespace; 102 } 103 104 XmlRootAttribute root = new XmlRootAttribute (); 105 root.ElementName = ext.ElementName; 106 if (ext.Namespace != null) root.Namespace = ext.Namespace; 107 108 XmlReflectionImporter ri = new XmlReflectionImporter (); 109 XmlTypeMapping map = ri.ImportTypeMapping (type, root); 110 111 if (ext.ElementName == null) throw new InvalidOperationException ("XmlFormatExtensionAttribute must be applied to type " + type); 112 extensionsByName.Add (ext.Namespace + " " + ext.ElementName, ext); 113 extensionsByType.Add (type, ext); 114 115 maps.Add (map); 116 extensions.Add (ext); 117 } 118 CreateExtensionSerializers()119 static void CreateExtensionSerializers () 120 { 121 XmlSerializer[] sers = XmlSerializer.FromMappings ((XmlMapping[]) maps.ToArray (typeof(XmlMapping))); 122 for (int n=0; n<sers.Length; n++) 123 ((ExtensionInfo)extensions[n]).Serializer = sers[n]; 124 125 maps = null; 126 extensions = null; 127 } 128 GetFormatExtensionInfo(string elementName, string namesp)129 public static ExtensionInfo GetFormatExtensionInfo (string elementName, string namesp) 130 { 131 return (ExtensionInfo) extensionsByName [namesp + " " + elementName]; 132 } 133 GetFormatExtensionInfo(Type extType)134 public static ExtensionInfo GetFormatExtensionInfo (Type extType) 135 { 136 return (ExtensionInfo) extensionsByType [extType]; 137 } 138 GetFormatExtensions()139 public static ICollection GetFormatExtensions () 140 { 141 return extensionsByName.Values; 142 } 143 GetExtensionPoint(object ob)144 public static ServiceDescriptionFormatExtensionCollection GetExtensionPoint (object ob) 145 { 146 Type type = ob.GetType (); 147 object[] ats = type.GetCustomAttributes (typeof(XmlFormatExtensionPointAttribute), true); 148 if (ats.Length == 0) return null; 149 150 XmlFormatExtensionPointAttribute at = (XmlFormatExtensionPointAttribute)ats[0]; 151 152 PropertyInfo prop = type.GetProperty (at.MemberName); 153 if (prop != null) 154 return prop.GetValue (ob, null) as ServiceDescriptionFormatExtensionCollection; 155 else { 156 FieldInfo field = type.GetField (at.MemberName); 157 if (field != null) 158 return field.GetValue (ob) as ServiceDescriptionFormatExtensionCollection; 159 else 160 throw new InvalidOperationException ("XmlFormatExtensionPointAttribute: Member " + at.MemberName + " not found"); 161 } 162 } 163 164 /* 165 * The mobile profile lacks support for configuration 166 */ 167 #if MOBILE || XAMMAC_4_5 BuildExtensionImporters()168 public static ArrayList BuildExtensionImporters () 169 { 170 return new ArrayList (0); 171 } 172 BuildExtensionReflectors()173 public static ArrayList BuildExtensionReflectors () 174 { 175 return new ArrayList (0); 176 } 177 178 #else BuildExtensionImporters()179 public static ArrayList BuildExtensionImporters () 180 { 181 return BuildExtensionList (WebServicesSection.Current.SoapExtensionImporterTypes); 182 } 183 BuildExtensionReflectors()184 public static ArrayList BuildExtensionReflectors () 185 { 186 return BuildExtensionList (WebServicesSection.Current.SoapExtensionReflectorTypes); 187 } 188 BuildExtensionList(TypeElementCollection exts)189 public static ArrayList BuildExtensionList (TypeElementCollection exts) 190 { 191 ArrayList extensionTypes = new ArrayList (); 192 193 if (exts != null) 194 { 195 foreach (TypeElement econf in exts) 196 { 197 extensionTypes.Add (econf); 198 } 199 } 200 201 ArrayList extensions = new ArrayList (extensionTypes.Count); 202 foreach (TypeElement econf in extensionTypes) 203 extensions.Add (Activator.CreateInstance (econf.Type)); 204 205 return extensions; 206 } 207 #endif 208 } 209 210 internal class ExtensionInfo 211 { 212 ArrayList _namespaceDeclarations; 213 string _namespace; 214 string _elementName; 215 Type _type; 216 XmlSerializer _serializer; 217 218 public ArrayList NamespaceDeclarations 219 { 220 get { 221 if (_namespaceDeclarations == null) _namespaceDeclarations = new ArrayList (); 222 return _namespaceDeclarations; 223 } 224 } 225 226 public string Namespace 227 { 228 get { return _namespace; } 229 set { _namespace = value; } 230 } 231 232 public string ElementName 233 { 234 get { return _elementName; } 235 set { _elementName = value; } 236 } 237 238 public Type Type 239 { 240 get { return _type; } 241 set { _type = value; } 242 } 243 244 public XmlSerializer Serializer 245 { 246 get { return _serializer; } 247 set { _serializer = value; } 248 } 249 } 250 } 251