5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2006 Novell, 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.
30 using System
.Reflection
;
31 using System
.Web
.Services
;
32 using System
.Web
.Services
.Description
;
33 using System
.Collections
;
35 namespace System
.Web
.Services
.Protocols
46 public ServerType (Type type
)
48 this.type
= TypeStubManager
.GetLogicalTypeInfo (type
);
51 internal LogicalTypeInfo LogicalType
{
57 // This class has information about a web service. Through providess
58 // access to the TypeStubInfo instances for each protocol.
60 internal class LogicalTypeInfo
62 LogicalMethodInfo
[] logicalMethods
;
64 internal string WebServiceName
;
65 internal string WebServiceNamespace
;
66 internal string WebServiceAbstractNamespace
;
67 internal string Description
;
69 SoapBindingUse bindingUse
;
70 SoapServiceRoutingStyle routingStyle
;
72 TypeStubInfo soapProtocol
;
74 TypeStubInfo soap12Protocol
;
76 TypeStubInfo httpGetProtocol
;
77 TypeStubInfo httpPostProtocol
;
79 public LogicalTypeInfo (Type t
)
83 object [] o
= Type
.GetCustomAttributes (typeof (WebServiceAttribute
), false);
85 WebServiceAttribute a
= (WebServiceAttribute
) o
[0];
86 WebServiceName
= (a
.Name
!= string.Empty
) ? a
.Name
: Type
.Name
;
87 WebServiceNamespace
= (a
.Namespace
!= string.Empty
) ? a
.Namespace
: WebServiceAttribute
.DefaultNamespace
;
88 Description
= a
.Description
;
90 WebServiceName
= Type
.Name
;
91 WebServiceNamespace
= WebServiceAttribute
.DefaultNamespace
;
94 // Determine the namespaces for literal and encoded schema types
96 bindingUse
= SoapBindingUse
.Literal
;
98 o
= t
.GetCustomAttributes (typeof(SoapDocumentServiceAttribute
), true);
100 SoapDocumentServiceAttribute at
= (SoapDocumentServiceAttribute
) o
[0];
102 if (bindingUse
== SoapBindingUse
.Default
)
103 bindingUse
= SoapBindingUse
.Literal
;
104 routingStyle
= at
.RoutingStyle
;
106 else if (t
.GetCustomAttributes (typeof(SoapRpcServiceAttribute
), true).Length
> 0) {
107 o
= t
.GetCustomAttributes (typeof(SoapRpcServiceAttribute
), true);
108 SoapRpcServiceAttribute at
= (SoapRpcServiceAttribute
) o
[0];
112 bindingUse
= SoapBindingUse
.Encoded
;
114 routingStyle
= at
.RoutingStyle
;
115 if (bindingUse
== SoapBindingUse
.Default
)
116 bindingUse
= SoapBindingUse
.Encoded
;
119 routingStyle
= SoapServiceRoutingStyle
.SoapAction
;
120 string sep
= WebServiceNamespace
.EndsWith ("/") ? "" : "/";
122 WebServiceAbstractNamespace
= WebServiceNamespace
+ sep
+ "AbstractTypes";
124 MethodInfo
[] type_methods
;
125 if (typeof (WebClientProtocol
).IsAssignableFrom (Type
))
126 type_methods
= Type
.GetMethods (BindingFlags
.Instance
| BindingFlags
.Public
);
128 MethodInfo
[] all_type_methods
= Type
.GetMethods (BindingFlags
.Instance
| BindingFlags
.Public
| BindingFlags
.NonPublic
);
129 ArrayList list
= new ArrayList (all_type_methods
.Length
);
130 foreach (MethodInfo mi
in all_type_methods
) {
131 if (mi
.IsPublic
&& mi
.GetCustomAttributes (typeof (WebMethodAttribute
), false).Length
> 0)
134 foreach (Type ifaceType
in Type
.GetInterfaces ()) {
135 if (ifaceType
.GetCustomAttributes (typeof (WebServiceBindingAttribute
), false).Length
> 0) {
136 MethodInfo found
= FindInInterface (ifaceType
, mi
);
138 if (found
.GetCustomAttributes (typeof (WebMethodAttribute
), false).Length
> 0)
147 type_methods
= (MethodInfo
[]) list
.ToArray (typeof (MethodInfo
));
150 MethodInfo
[] type_methods
= Type
.GetMethods (BindingFlags
.Instance
| BindingFlags
.Public
);
152 logicalMethods
= LogicalMethodInfo
.Create (type_methods
, LogicalMethodTypes
.Sync
);
155 static MethodInfo
FindInInterface (Type ifaceType
, MethodInfo method
) {
156 int nameStartIndex
= 0;
157 if (method
.IsPrivate
) {
158 nameStartIndex
= method
.Name
.LastIndexOf ('.');
159 if (nameStartIndex
< 0)
162 if (String
.CompareOrdinal (
163 ifaceType
.FullName
.Replace ('+', '.'), 0, method
.Name
, 0, nameStartIndex
) != 0)
169 foreach (MethodInfo mi
in ifaceType
.GetMembers ()) {
170 if (method
.ReturnType
== mi
.ReturnType
&&
171 String
.CompareOrdinal(method
.Name
, nameStartIndex
, mi
.Name
, 0, mi
.Name
.Length
) == 0) {
172 ParameterInfo
[] rpi
= method
.GetParameters ();
173 ParameterInfo
[] lpi
= mi
.GetParameters ();
174 if (rpi
.Length
== lpi
.Length
) {
176 for (int i
= 0; i
< rpi
.Length
; i
++) {
177 if (rpi
[i
].ParameterType
!= lpi
[i
].ParameterType
) {
192 internal SoapBindingUse BindingUse
{
193 get { return bindingUse; }
196 internal SoapServiceRoutingStyle RoutingStyle
{
197 get { return routingStyle; }
200 internal LogicalMethodInfo
[] LogicalMethods
202 get { return logicalMethods; }
205 internal TypeStubInfo
GetTypeStub (string protocolName
)
209 switch (protocolName
)
212 if (soapProtocol
== null){
213 soapProtocol
= new SoapTypeStubInfo (this);
214 soapProtocol
.Initialize ();
219 if (soap12Protocol
== null){
220 soap12Protocol
= new Soap12TypeStubInfo (this);
221 soap12Protocol
.Initialize ();
223 return soap12Protocol
;
226 if (httpGetProtocol
== null){
227 httpGetProtocol
= new HttpGetTypeStubInfo (this);
228 httpGetProtocol
.Initialize ();
230 return httpGetProtocol
;
232 if (httpPostProtocol
== null){
233 httpPostProtocol
= new HttpPostTypeStubInfo (this);
234 httpPostProtocol
.Initialize ();
236 return httpPostProtocol
;
239 throw new InvalidOperationException ("Protocol " + protocolName
+ " not supported");
243 internal string GetWebServiceLiteralNamespace (string baseNamespace
)
245 if (BindingUse
== SoapBindingUse
.Encoded
) {
246 string sep
= baseNamespace
.EndsWith ("/") ? "" : "/";
247 return baseNamespace
+ sep
+ "literalTypes";
250 return baseNamespace
;
253 internal string GetWebServiceEncodedNamespace (string baseNamespace
)
255 if (BindingUse
== SoapBindingUse
.Encoded
)
256 return baseNamespace
;
258 string sep
= baseNamespace
.EndsWith ("/") ? "" : "/";
259 return baseNamespace
+ sep
+ "encodedTypes";
263 internal string GetWebServiceNamespace (string baseNamespace
, SoapBindingUse use
)
265 if (use
== SoapBindingUse
.Literal
) return GetWebServiceLiteralNamespace (baseNamespace
);
266 else return GetWebServiceEncodedNamespace (baseNamespace
);