2 // System.Web.Services.Description.ExtensionManager.cs
5 // Lluis Sanchez Gual (lluis@ximian.com)
7 // Copyright (C) 2003 Ximian, Inc.
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:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
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.
31 using System
.Reflection
;
32 using System
.Collections
;
33 using System
.Web
.Services
.Configuration
;
34 using System
.Xml
.Serialization
;
37 namespace System
.Web
.Services
.Description
39 internal abstract class ExtensionManager
41 static Hashtable extensionsByName
;
42 static Hashtable extensionsByType
;
43 static ArrayList maps
= new ArrayList ();
44 static ArrayList extensions
= new ArrayList ();
46 static ExtensionManager ()
48 extensionsByName
= new Hashtable ();
49 extensionsByType
= new Hashtable ();
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
));
68 foreach (Type type
in WSConfig
.Instance
.FormatExtensionTypes
)
69 RegisterExtensionType (type
);
71 CreateExtensionSerializers ();
74 static void RegisterExtensionType (Type type
)
76 ExtensionInfo ext
= new ExtensionInfo();
79 object[] ats
= type
.GetCustomAttributes (typeof(XmlFormatExtensionPrefixAttribute
), true);
81 foreach (XmlFormatExtensionPrefixAttribute at
in ats
)
82 ext
.NamespaceDeclarations
.Add (new XmlQualifiedName (at
.Prefix
, at
.Namespace
));
84 ats
= type
.GetCustomAttributes (typeof(XmlFormatExtensionAttribute
), true);
87 XmlFormatExtensionAttribute at
= (XmlFormatExtensionAttribute
)ats
[0];
88 ext
.ElementName
= at
.ElementName
;
89 if (at
.Namespace
!= null) ext
.Namespace
= at
.Namespace
;
92 XmlRootAttribute root
= new XmlRootAttribute ();
93 root
.ElementName
= ext
.ElementName
;
94 if (ext
.Namespace
!= null) root
.Namespace
= ext
.Namespace
;
96 XmlReflectionImporter ri
= new XmlReflectionImporter ();
97 XmlTypeMapping map
= ri
.ImportTypeMapping (type
, root
);
99 if (ext
.ElementName
== null) throw new InvalidOperationException ("XmlFormatExtensionAttribute must be applied to type " + type
);
100 extensionsByName
.Add (ext
.Namespace
+ " " + ext
.ElementName
, ext
);
101 extensionsByType
.Add (type
, ext
);
104 extensions
.Add (ext
);
107 static void CreateExtensionSerializers ()
109 XmlSerializer
[] sers
= XmlSerializer
.FromMappings ((XmlMapping
[]) maps
.ToArray (typeof(XmlMapping
)));
110 for (int n
=0; n
<sers
.Length
; n
++)
111 ((ExtensionInfo
)extensions
[n
]).Serializer
= sers
[n
];
117 public static ExtensionInfo
GetFormatExtensionInfo (string elementName
, string namesp
)
119 return (ExtensionInfo
) extensionsByName
[namesp
+ " " + elementName
];
122 public static ExtensionInfo
GetFormatExtensionInfo (Type extType
)
124 return (ExtensionInfo
) extensionsByType
[extType
];
127 public static ICollection
GetFormatExtensions ()
129 return extensionsByName
.Values
;
132 public static ServiceDescriptionFormatExtensionCollection
GetExtensionPoint (object ob
)
134 Type type
= ob
.GetType ();
135 object[] ats
= type
.GetCustomAttributes (typeof(XmlFormatExtensionPointAttribute
), true);
136 if (ats
.Length
== 0) return null;
138 XmlFormatExtensionPointAttribute at
= (XmlFormatExtensionPointAttribute
)ats
[0];
140 PropertyInfo prop
= type
.GetProperty (at
.MemberName
);
142 return prop
.GetValue (ob
, null) as ServiceDescriptionFormatExtensionCollection
;
144 FieldInfo field
= type
.GetField (at
.MemberName
);
146 return field
.GetValue (ob
) as ServiceDescriptionFormatExtensionCollection
;
148 throw new InvalidOperationException ("XmlFormatExtensionPointAttribute: Member " + at
.MemberName
+ " not found");
152 public static ArrayList
BuildExtensionImporters ()
154 return BuildExtensionList (WSConfig
.Instance
.ExtensionImporterTypes
);
157 public static ArrayList
BuildExtensionReflectors ()
159 return BuildExtensionList (WSConfig
.Instance
.ExtensionReflectorTypes
);
162 public static ArrayList
BuildExtensionList (ArrayList exts
)
164 ArrayList extensionTypes
= new ArrayList ();
168 foreach (WSExtensionConfig econf
in exts
)
171 for (int n
=0; n
<extensionTypes
.Count
&& !added
; n
++)
173 WSExtensionConfig cureconf
= (WSExtensionConfig
) extensionTypes
[n
];
175 if ((econf
.Group
< cureconf
.Group
) || ((econf
.Group
== cureconf
.Group
) && (econf
.Priority
< cureconf
.Priority
))) {
176 extensionTypes
.Insert (n
, econf
);
180 if (!added
) extensionTypes
.Add (econf
);
184 ArrayList extensions
= new ArrayList (extensionTypes
.Count
);
185 foreach (WSExtensionConfig econf
in extensionTypes
)
186 extensions
.Add (Activator
.CreateInstance (econf
.Type
));
192 internal class ExtensionInfo
194 ArrayList _namespaceDeclarations
;
198 XmlSerializer _serializer
;
200 public ArrayList NamespaceDeclarations
203 if (_namespaceDeclarations
== null) _namespaceDeclarations
= new ArrayList ();
204 return _namespaceDeclarations
;
208 public string Namespace
210 get { return _namespace; }
211 set { _namespace = value; }
214 public string ElementName
216 get { return _elementName; }
217 set { _elementName = value; }
222 get { return _type; }
223 set { _type = value; }
226 public XmlSerializer Serializer
228 get { return _serializer; }
229 set { _serializer = value; }