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
);
65 static ArrayList
[] globalExtensions
;
67 internal static SoapExtension
[] CreateExtensionChain (SoapExtensionRuntimeConfig
[] extensionConfigs
)
69 if (extensionConfigs
== null) return null;
70 SoapExtension
[] res
= new SoapExtension
[extensionConfigs
.Length
];
71 CreateExtensionChain (extensionConfigs
, res
, 0);
75 internal static SoapExtension
[] CreateExtensionChain (SoapExtensionRuntimeConfig
[] hiPrioExts
, SoapExtensionRuntimeConfig
[] medPrioExts
, SoapExtensionRuntimeConfig
[] lowPrioExts
)
78 if (hiPrioExts
!= null) len
+= hiPrioExts
.Length
;
79 if (medPrioExts
!= null) len
+= medPrioExts
.Length
;
80 if (lowPrioExts
!= null) len
+= lowPrioExts
.Length
;
81 if (len
== 0) return null;
83 SoapExtension
[] res
= new SoapExtension
[len
];
85 if (hiPrioExts
!= null) pos
= CreateExtensionChain (hiPrioExts
, res
, pos
);
86 if (medPrioExts
!= null) pos
= CreateExtensionChain (medPrioExts
, res
, pos
);
87 if (lowPrioExts
!= null) pos
= CreateExtensionChain (lowPrioExts
, res
, pos
);
91 static int CreateExtensionChain (SoapExtensionRuntimeConfig
[] extensionConfigs
, SoapExtension
[] destArray
, int pos
)
93 for (int n
=0; n
<extensionConfigs
.Length
; n
++)
95 SoapExtensionRuntimeConfig econf
= extensionConfigs
[n
];
96 SoapExtension ext
= (SoapExtension
) Activator
.CreateInstance (econf
.Type
);
97 ext
.Initialize (econf
.InitializationInfo
);
98 destArray
[pos
++] = ext
;
103 static void InitializeGlobalExtensions ()
105 globalExtensions
= new ArrayList
[2];
107 ArrayList exts
= WSConfig
.Instance
.ExtensionTypes
;
108 if (exts
== null) return;
110 foreach (WSExtensionConfig econf
in exts
)
112 if (globalExtensions
[(int)econf
.Group
] == null) globalExtensions
[(int)econf
.Group
] = new ArrayList ();
113 ArrayList destList
= globalExtensions
[(int) econf
.Group
];
115 for (int n
=0; n
<destList
.Count
&& !added
; n
++)
116 if (((WSExtensionConfig
)destList
[n
]).Priority
> econf
.Priority
) {
117 destList
.Insert (n
, econf
);
120 if (!added
) destList
.Add (econf
);
124 internal static SoapExtensionRuntimeConfig
[][] GetTypeExtensions (Type serviceType
)
126 if (globalExtensions
== null) InitializeGlobalExtensions();
128 SoapExtensionRuntimeConfig
[][] exts
= new SoapExtensionRuntimeConfig
[2][];
130 for (int group = 0; group < 2; group++)
132 ArrayList globList
= globalExtensions
[group];
133 if (globList
== null) continue;
134 exts
[group] = new SoapExtensionRuntimeConfig
[globList
.Count
];
135 for (int n
=0; n
<globList
.Count
; n
++)
137 WSExtensionConfig econf
= (WSExtensionConfig
) globList
[n
];
138 SoapExtensionRuntimeConfig typeconf
= new SoapExtensionRuntimeConfig ();
139 typeconf
.Type
= econf
.Type
;
140 SoapExtension ext
= (SoapExtension
) Activator
.CreateInstance (econf
.Type
);
141 typeconf
.InitializationInfo
= ext
.GetInitializer (serviceType
);
142 exts
[group][n
] = typeconf
;
148 internal static SoapExtensionRuntimeConfig
[] GetMethodExtensions (LogicalMethodInfo method
)
150 object[] ats
= method
.GetCustomAttributes (typeof (SoapExtensionAttribute
));
151 SoapExtensionRuntimeConfig
[] exts
= new SoapExtensionRuntimeConfig
[ats
.Length
];
152 int[] priorities
= new int[ats
.Length
];
154 for (int n
=0; n
<ats
.Length
; n
++)
156 SoapExtensionAttribute at
= (SoapExtensionAttribute
) ats
[n
];
157 SoapExtensionRuntimeConfig econf
= new SoapExtensionRuntimeConfig ();
158 econf
.Type
= at
.ExtensionType
;
159 priorities
[n
] = at
.Priority
;
160 SoapExtension ext
= (SoapExtension
) Activator
.CreateInstance (econf
.Type
);
161 econf
.InitializationInfo
= ext
.GetInitializer (method
, at
);
164 Array
.Sort (priorities
, exts
);
168 internal static Stream
ExecuteChainStream (SoapExtension
[] extensions
, Stream stream
)
170 if (extensions
== null) return stream
;
172 Stream newStream
= stream
;
173 foreach (SoapExtension ext
in extensions
)
174 newStream
= ext
.ChainStream (newStream
);
178 internal static void ExecuteProcessMessage(SoapExtension
[] extensions
, SoapMessage message
, bool inverseOrder
)
180 if (extensions
== null) return;
184 for (int n
= extensions
.Length
-1; n
>= 0; n
--)
185 extensions
[n
].ProcessMessage (message
);
189 for (int n
= 0; n
< extensions
.Length
; n
++)
190 extensions
[n
].ProcessMessage (message
);
194 #endregion // Methods
197 internal class SoapExtensionRuntimeConfig
201 public object InitializationInfo
;