2 // System.Web.Services.Protocols.SoapExtension.cs
5 // Tim Coleman (tim@timcoleman.com)
7 // Copyright (C) Tim Coleman, 2002
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.
32 using System
.Collections
;
33 using System
.Web
.Services
.Configuration
;
35 namespace System
.Web
.Services
.Protocols
{
36 public abstract class SoapExtension
{
46 protected SoapExtension ()
50 #endregion // Constructors
54 public virtual Stream
ChainStream (Stream stream
)
59 public abstract object GetInitializer (Type serviceType
);
60 public abstract object GetInitializer (LogicalMethodInfo methodInfo
, SoapExtensionAttribute attribute
);
61 public abstract void Initialize (object initializer
);
62 public abstract void ProcessMessage (SoapMessage message
);
66 static ArrayList
[] globalExtensions
;
68 static ArrayList
[] globalExtensions
{
70 return (ArrayList
[])AppDomain
.CurrentDomain
.GetData("SoapExtension.globalExtensions");
73 AppDomain
.CurrentDomain
.SetData("SoapExtension.globalExtensions", value);
78 internal static SoapExtension
[] CreateExtensionChain (SoapExtensionRuntimeConfig
[] extensionConfigs
)
80 if (extensionConfigs
== null) return null;
81 SoapExtension
[] res
= new SoapExtension
[extensionConfigs
.Length
];
82 CreateExtensionChain (extensionConfigs
, res
, 0);
86 internal static SoapExtension
[] CreateExtensionChain (SoapExtensionRuntimeConfig
[] hiPrioExts
, SoapExtensionRuntimeConfig
[] medPrioExts
, SoapExtensionRuntimeConfig
[] lowPrioExts
)
89 if (hiPrioExts
!= null) len
+= hiPrioExts
.Length
;
90 if (medPrioExts
!= null) len
+= medPrioExts
.Length
;
91 if (lowPrioExts
!= null) len
+= lowPrioExts
.Length
;
92 if (len
== 0) return null;
94 SoapExtension
[] res
= new SoapExtension
[len
];
96 if (hiPrioExts
!= null) pos
= CreateExtensionChain (hiPrioExts
, res
, pos
);
97 if (medPrioExts
!= null) pos
= CreateExtensionChain (medPrioExts
, res
, pos
);
98 if (lowPrioExts
!= null) pos
= CreateExtensionChain (lowPrioExts
, res
, pos
);
102 static int CreateExtensionChain (SoapExtensionRuntimeConfig
[] extensionConfigs
, SoapExtension
[] destArray
, int pos
)
104 for (int n
=0; n
<extensionConfigs
.Length
; n
++)
106 SoapExtensionRuntimeConfig econf
= extensionConfigs
[n
];
107 SoapExtension ext
= (SoapExtension
) Activator
.CreateInstance (econf
.Type
);
108 ext
.Initialize (econf
.InitializationInfo
);
109 destArray
[pos
++] = ext
;
115 static void InitializeGlobalExtensions ()
117 globalExtensions
= new ArrayList
[2];
119 if (WebServicesSection
.Current
== null) return;
121 SoapExtensionTypeElementCollection exts
= WebServicesSection
.Current
.SoapExtensionTypes
;
123 ArrayList exts
= WSConfig
.Instance
.ExtensionTypes
;
125 if (exts
== null) return;
128 foreach (SoapExtensionTypeElement econf
in exts
)
130 foreach (WSExtensionConfig econf
in exts
)
133 if (globalExtensions
[(int)econf
.Group
] == null) globalExtensions
[(int)econf
.Group
] = new ArrayList ();
134 ArrayList destList
= globalExtensions
[(int) econf
.Group
];
136 for (int n
=0; n
<destList
.Count
&& !added
; n
++)
138 if (((SoapExtensionTypeElement
)destList
[n
]).Priority
> econf
.Priority
) {
140 if (((WSExtensionConfig
)destList
[n
]).Priority
> econf
.Priority
) {
142 destList
.Insert (n
, econf
);
145 if (!added
) destList
.Add (econf
);
149 internal static SoapExtensionRuntimeConfig
[][] GetTypeExtensions (Type serviceType
)
151 if (globalExtensions
== null) InitializeGlobalExtensions();
153 SoapExtensionRuntimeConfig
[][] exts
= new SoapExtensionRuntimeConfig
[2][];
155 for (int group = 0; group < 2; group++)
157 ArrayList globList
= globalExtensions
[group];
158 if (globList
== null) continue;
159 exts
[group] = new SoapExtensionRuntimeConfig
[globList
.Count
];
160 for (int n
=0; n
<globList
.Count
; n
++)
163 SoapExtensionTypeElement econf
= (SoapExtensionTypeElement
) globList
[n
];
165 WSExtensionConfig econf
= (WSExtensionConfig
) globList
[n
];
167 SoapExtensionRuntimeConfig typeconf
= new SoapExtensionRuntimeConfig ();
168 typeconf
.Type
= econf
.Type
;
169 SoapExtension ext
= (SoapExtension
) Activator
.CreateInstance (econf
.Type
);
170 typeconf
.InitializationInfo
= ext
.GetInitializer (serviceType
);
171 exts
[group][n
] = typeconf
;
178 internal static SoapExtensionRuntimeConfig
[] GetMethodExtensions (LogicalMethodInfo method
)
180 object[] ats
= method
.GetCustomAttributes (typeof (SoapExtensionAttribute
));
181 SoapExtensionRuntimeConfig
[] exts
= new SoapExtensionRuntimeConfig
[ats
.Length
];
182 int[] priorities
= new int[ats
.Length
];
184 for (int n
=0; n
<ats
.Length
; n
++)
186 SoapExtensionAttribute at
= (SoapExtensionAttribute
) ats
[n
];
187 SoapExtensionRuntimeConfig econf
= new SoapExtensionRuntimeConfig ();
188 econf
.Type
= at
.ExtensionType
;
189 priorities
[n
] = at
.Priority
;
190 SoapExtension ext
= (SoapExtension
) Activator
.CreateInstance (econf
.Type
);
191 econf
.InitializationInfo
= ext
.GetInitializer (method
, at
);
194 Array
.Sort (priorities
, exts
);
198 internal static Stream
ExecuteChainStream (SoapExtension
[] extensions
, Stream stream
)
200 if (extensions
== null) return stream
;
202 Stream newStream
= stream
;
203 foreach (SoapExtension ext
in extensions
)
204 newStream
= ext
.ChainStream (newStream
);
208 internal static void ExecuteProcessMessage(SoapExtension
[] extensions
, SoapMessage message
, Stream stream
, bool inverseOrder
)
210 if (extensions
== null) return;
212 message
.InternalStream
= stream
;
216 for (int n
= extensions
.Length
-1; n
>= 0; n
--)
217 extensions
[n
].ProcessMessage (message
);
221 for (int n
= 0; n
< extensions
.Length
; n
++)
222 extensions
[n
].ProcessMessage (message
);
226 #endregion // Methods
229 internal class SoapExtensionRuntimeConfig
233 public object InitializationInfo
;