added WebServicesConfigurationSectionHandler.cs
[mono.git] / mcs / class / System.Web.Services / System.Web.Services.Configuration / WebServicesConfigurationSectionHandler.cs
1 //
2 // System.Web.Services.Configuration.WebServicesConfigurationSectionHandler
3 //
4 // Authors:
5 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //
7 // (C) 2003 Ximian, Inc (http://www.ximian.com)
8 //
9
10 using System;
11 using System.Configuration;
12 using System.Xml;
13
14 namespace System.Web.Services.Configuration
15 {
16         [Flags]
17         enum WSProtocol
18         {
19                 HttpSoap = 1,
20                 HttpPost = 1 << 1,
21                 HttpGet =  1 << 2,
22                 Documentation = 1 << 3,
23                 All = 0x0F
24         }
25         
26         class WSConfig
27         {
28                 WSProtocol protocols;
29                 string wsdlHelpPage;
30                 
31                 public WSConfig (WSConfig parent)
32                 {
33                         if (parent == null)
34                                 return;
35                         
36                         protocols = parent.protocols;
37                         wsdlHelpPage = parent.wsdlHelpPage;
38                 }
39                 
40                 static WSProtocol ParseProtocol (string protoName, out string error)
41                 {
42                         WSProtocol proto;
43                         error = null;
44                         try {
45                                 proto = (WSProtocol) Enum.Parse (typeof (WSProtocol), protoName);
46                         } catch {
47                                 error = "Invalid protocol name";
48                                 return 0;
49                         }
50
51                         return proto;
52                 }
53
54                 // Methods to modify configuration values
55                 public bool AddProtocol (string protoName, out string error)
56                 {
57                         if (protoName == "All") {
58                                 error = "Invalid protocol name";
59                                 return false;
60                         }
61
62                         WSProtocol proto = ParseProtocol (protoName, out error);
63                         if (error != null)
64                                 return false;
65
66                         if ((protocols & proto) != 0) {
67                                 error = "Protocol already added";
68                                 return false;
69                         }
70
71                         protocols |= proto;
72                         return true;
73                 }
74
75                 // Methods to query/get configuration
76                 public bool IsSupported (WSProtocol proto)
77                 {
78                         return (proto & WSProtocol.All) == proto;
79                 }
80
81                 // Properties
82                 public string WsdlHelpPage {
83                         get { return wsdlHelpPage; }
84                         set { wsdlHelpPage = value; }
85                 }
86
87         }
88         
89         class WebServicesConfigurationSectionHandler : IConfigurationSectionHandler
90         {
91                 [MonoTODO("Some nodes not supported, see below")]
92                 public object Create (object parent, object context, XmlNode section)
93                 {
94                         WSConfig config = new WSConfig (parent as WSConfig);    
95
96                         if (section.Attributes != null && section.Attributes.Count != 0)
97                                 ThrowException ("Unrecognized attribute", section);
98
99                         XmlNodeList nodes = section.ChildNodes;
100                         foreach (XmlNode child in nodes) {
101                                 XmlNodeType ntype = child.NodeType;
102                                 if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
103                                         continue;
104
105                                 if (ntype != XmlNodeType.Element)
106                                         ThrowException ("Only elements allowed", child);
107                                 
108                                 string name = child.Name;
109                                 if (name == "protocols") {
110                                         ConfigProtocols (child, config);
111                                         continue;
112                                 }
113
114                                 if (name == "soapExtensionTypes") {
115                                         //TODO: Not supported by now
116                                         continue;
117                                 }
118
119                                 if (name == "soapExtensionReflectorTypes") {
120                                         //TODO: Not supported by now
121                                         continue;
122                                 }
123
124                                 if (name == "soapExtensionImporterTypes") {
125                                         //TODO: Not supported by now
126                                         continue;
127                                 }
128
129                                 if (name == "serviceDescriptionFormatExtensionTypes") {
130                                         //TODO: Not supported by now
131                                         continue;
132                                 }
133
134                                 if (name == "wsdlHelpGenerator") {
135                                         string href = AttValue ("href", child, false);
136                                         if (child.Attributes != null && child.Attributes.Count != 0)
137                                                 HandlersUtil.ThrowException ("Unrecognized attribute", child);
138
139                                         config.WsdlHelpPage = href;
140                                         continue;
141                                 }
142
143                                 ThrowException ("Unexpected element", child);
144                         }
145
146                         return null;
147                 }
148
149                 static void ConfigProtocols (XmlNode section, WSConfig config)
150                 {
151                         if (section.Attributes != null && section.Attributes.Count != 0)
152                                 ThrowException ("Unrecognized attribute", section);
153
154                         XmlNodeList nodes = section.ChildNodes;
155                         foreach (XmlNode child in nodes) {
156                                 XmlNodeType ntype = child.NodeType;
157                                 if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
158                                         continue;
159
160                                 if (ntype != XmlNodeType.Element)
161                                         ThrowException ("Only elements allowed", child);
162                                 
163                                 string name = child.Name;
164                                 string error;
165                                 if (name == "add") {
166                                         string protoName = AttValue ("name", child, false);
167                                         if (child.Attributes != null && child.Attributes.Count != 0)
168                                                 HandlersUtil.ThrowException ("Unrecognized attribute", child);
169
170                                         if (!config.AddProtocol (protoName, out error))
171                                                 ThrowException (error, child);
172                                         
173                                         continue;
174                                 }
175
176                                 ThrowException ("Unexpected element", child);
177                         }
178                 }
179                 
180                 // To save some typing...
181                 static string AttValue (string name, XmlNode node, bool optional)
182                 {
183                         return HandlersUtil.ExtractAttributeValue (name, node, optional);
184                 }
185
186                 static string AttValue (string name, XmlNode node)
187                 {
188                         return HandlersUtil.ExtractAttributeValue (name, node, true);
189                 }
190
191                 static void ThrowException (string message, XmlNode node)
192                 {
193                         HandlersUtil.ThrowException (message, node);
194                 }
195                 //
196         }
197         
198         class HandlersUtil
199         {
200                 private HandlersUtil ()
201                 {
202                 }
203
204                 static internal string ExtractAttributeValue (string attKey, XmlNode node)
205                 {
206                         return ExtractAttributeValue (attKey, node, false);
207                 }
208                         
209                 static internal string ExtractAttributeValue (string attKey, XmlNode node, bool optional)
210                 {
211                         if (node.Attributes == null) {
212                                 if (optional)
213                                         return null;
214
215                                 ThrowException ("Required attribute not found: " + attKey, node);
216                         }
217
218                         XmlNode att = node.Attributes.RemoveNamedItem (attKey);
219                         if (att == null) {
220                                 if (optional)
221                                         return null;
222                                 ThrowException ("Required attribute not found: " + attKey, node);
223                         }
224
225                         string value = att.Value;
226                         if (value == String.Empty) {
227                                 string opt = optional ? "Optional" : "Required";
228                                 ThrowException (opt + " attribute is empty: " + attKey, node);
229                         }
230
231                         return value;
232                 }
233
234                 static internal void ThrowException (string msg, XmlNode node)
235                 {
236                         if (node != null && node.Name != String.Empty)
237                                 msg = msg + " (node name: " + node.Name + ") ";
238                         throw new ConfigurationException (msg, node);
239                 }
240         }
241
242 }
243