a7903610e99c212f3a2a70e1d2c336c971ffa6b8
[mono.git] / mcs / class / System / System.Net.Configuration / ConnectionManagementHandler.cs
1 //
2 // System.Net.Configuration.ConnectionManagementHandler
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.Collections;
11 using System.Configuration;
12 using System.Xml;
13
14 namespace System.Net.Configuration
15 {
16         class ConnectionManagementData
17         {
18                 Hashtable data; // key -> address, value -> maxconnections
19                 
20                 public ConnectionManagementData (object parent)
21                 {
22                         data = new Hashtable ();
23                         if (parent != null && parent is ConnectionManagementData) {
24                                 ConnectionManagementData p = (ConnectionManagementData) parent;
25                                 foreach (string k in p.data.Keys)
26                                         data [k] = p.data [k];  
27                         }
28                 }
29
30                 public void Add (string address, string nconns)
31                 {
32                         if (nconns == null || nconns == "")
33                                 nconns = "2";
34                         // Adding duplicates works fine under MS, so...
35                         data [address] = UInt32.Parse (nconns);
36                 }
37
38                 public void Remove (string address)
39                 {
40                         // Removing non-existent address is fine.
41                         data.Remove (address);
42                 }
43
44                 public void Clear ()
45                 {
46                         data.Clear ();
47                 }
48
49                 public Hashtable Data {
50                         get { return data; }
51                 }
52         }
53
54         class ConnectionManagementHandler : IConfigurationSectionHandler
55         {
56                 public virtual object Create (object parent, object configContext, XmlNode section)
57                 {
58                         ConnectionManagementData cmd = new ConnectionManagementData (parent);
59                         
60                         if (section.Attributes != null && section.Attributes.Count != 0)
61                                 HandlersUtil.ThrowException ("Unrecognized attribute", section);
62
63                         XmlNodeList httpHandlers = section.ChildNodes;
64                         foreach (XmlNode child in httpHandlers) {
65                                 XmlNodeType ntype = child.NodeType;
66                                 if (ntype == XmlNodeType.Whitespace || ntype == XmlNodeType.Comment)
67                                         continue;
68
69                                 if (ntype != XmlNodeType.Element)
70                                         HandlersUtil.ThrowException ("Only elements allowed", child);
71                                 
72                                 string name = child.Name;
73                                 if (name == "clear") {
74                                         if (child.Attributes != null && child.Attributes.Count != 0)
75                                                 HandlersUtil.ThrowException ("Unrecognized attribute", child);
76
77                                         cmd.Clear ();
78                                         continue;
79                                 }
80
81                                 //LAMESPEC: the MS doc says that <remove name="..."/> but they throw an exception
82                                 // if you use that. "address" is correct.
83
84                                 string address = HandlersUtil.ExtractAttributeValue ("address", child);
85                                 if (name == "add") {
86                                         string maxcnc = HandlersUtil.ExtractAttributeValue ("maxconnection", child, true);
87                                         if (child.Attributes != null && child.Attributes.Count != 0)
88                                                 HandlersUtil.ThrowException ("Unrecognized attribute", child);
89
90                                         cmd.Add (address, maxcnc);
91                                         continue;
92                                 }
93
94                                 if (name == "remove") {
95                                         if (child.Attributes != null && child.Attributes.Count != 0)
96                                                 HandlersUtil.ThrowException ("Unrecognized attribute", child);
97
98                                         cmd.Remove (address);
99                                         continue;
100                                 }
101
102                                 HandlersUtil.ThrowException ("Unexpected element", child);
103                         }
104
105                         return cmd;
106                 }
107         }
108
109         internal class HandlersUtil
110         {
111                 private HandlersUtil ()
112                 {
113                 }
114
115                 static internal string ExtractAttributeValue (string attKey, XmlNode node)
116                 {
117                         return ExtractAttributeValue (attKey, node, false);
118                 }
119                         
120                 static internal string ExtractAttributeValue (string attKey, XmlNode node, bool optional)
121                 {
122                         if (node.Attributes == null) {
123                                 if (optional)
124                                         return null;
125
126                                 ThrowException ("Required attribute not found: " + attKey, node);
127                         }
128
129                         XmlNode att = node.Attributes.RemoveNamedItem (attKey);
130                         if (att == null) {
131                                 if (optional)
132                                         return null;
133                                 ThrowException ("Required attribute not found: " + attKey, node);
134                         }
135
136                         string value = att.Value;
137                         if (value == String.Empty) {
138                                 string opt = optional ? "Optional" : "Required";
139                                 ThrowException (opt + " attribute is empty: " + attKey, node);
140                         }
141
142                         return value;
143                 }
144
145                 static internal void ThrowException (string msg, XmlNode node)
146                 {
147                         if (node != null && node.Name != String.Empty)
148                                 msg = msg + " (node name: " + node.Name + ") ";
149                         throw new ConfigurationException (msg, node);
150                 }
151         }
152 }
153