(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / System / System.Diagnostics / DiagnosticsConfigurationHandler.cs
blob8821e14e1de9247f818930d11b72597d7adfd050
1 //
2 // System.Diagnostics.DiagnosticsConfigurationHandler.cs
3 //
4 // Comments from John R. Hicks <angryjohn69@nc.rr.com> original implementation
5 // can be found at: /mcs/docs/apidocs/xml/en/System.Diagnostics
6 //
7 // Authors:
8 // John R. Hicks <angryjohn69@nc.rr.com>
9 // Jonathan Pryor <jonpryor@vt.edu>
11 // (C) 2002
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 //
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 //
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System;
35 using System.Collections;
36 using System.Configuration;
37 #if (XML_DEP)
38 using System.Xml;
39 #endif
40 namespace System.Diagnostics
42 internal sealed class DiagnosticsConfiguration
44 private static IDictionary settings = null;
46 public static IDictionary Settings {
47 get {
48 // TODO: Does anybody know if this is actually thread-safe under .NET?
49 // I've heard that this construct isn't safe under Java, but it's used
50 // reasonably often under C++, so I'm not sure about .NET.
51 if (settings == null) {
52 lock (typeof(DiagnosticsConfiguration)) {
53 if (settings == null)
54 settings = (IDictionary) ConfigurationSettings.GetConfig ("system.diagnostics");
57 return settings;
61 #if (XML_DEP)
62 public class DiagnosticsConfigurationHandler : IConfigurationSectionHandler
64 delegate void ElementHandler (IDictionary d, XmlNode node);
66 IDictionary elementHandlers = new Hashtable ();
68 public DiagnosticsConfigurationHandler ()
70 elementHandlers ["assert"] = new ElementHandler (AddAssertNode);
71 elementHandlers ["switches"] = new ElementHandler (AddSwitchesNode);
72 elementHandlers ["trace"] = new ElementHandler (AddTraceNode);
75 public virtual object Create (object parent, object configContext, XmlNode section)
77 IDictionary d;
78 if (parent == null)
79 d = new Hashtable (CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default);
80 else
81 d = (IDictionary) ((ICloneable)parent).Clone();
83 foreach (XmlNode child in section.ChildNodes) {
84 XmlNodeType type = child.NodeType;
86 switch (type) {
87 /* ignore */
88 case XmlNodeType.Whitespace:
89 case XmlNodeType.Comment:
90 continue;
91 case XmlNodeType.Element:
92 ElementHandler eh = (ElementHandler) elementHandlers [child.Name];
93 if (eh != null)
94 eh (d, child);
95 else
96 ThrowUnrecognizedElement (child);
97 break;
98 default:
99 ThrowUnrecognizedElement (child);
100 break;
104 return d;
107 // Remarks: Both attribute are optional
108 private void AddAssertNode (IDictionary d, XmlNode node)
110 XmlAttributeCollection c = node.Attributes;
111 string assertuienabled = GetAttribute (c, "assertuienabled", false, node);
112 string logfilename = GetAttribute (c, "logfilename", false, node);
113 ValidateInvalidAttributes (c, node);
114 if (assertuienabled != null) {
115 try {
116 d ["assertuienabled"] = bool.Parse (assertuienabled);
118 catch (Exception e) {
119 throw new ConfigurationException ("The `assertuienabled' attribute must be `true' or `false'",
120 e, node);
124 if (logfilename != null)
125 d ["logfilename"] = logfilename;
127 DefaultTraceListener dtl = (DefaultTraceListener) TraceImpl.Listeners["Default"];
128 if (dtl != null) {
129 if (assertuienabled != null)
130 dtl.AssertUiEnabled = (bool) d ["assertuienabled"];
131 if (logfilename != null)
132 dtl.LogFileName = logfilename;
135 if (node.ChildNodes.Count > 0)
136 ThrowUnrecognizedElement (node.ChildNodes[0]);
139 // name attribute is required, value is optional
140 // Docs do not define "remove" or "clear" elements, but .NET recognizes
141 // them
142 private void AddSwitchesNode (IDictionary d, XmlNode node)
144 // There are no attributes on <switch/>
145 ValidateInvalidAttributes (node.Attributes, node);
147 IDictionary newNodes = new Hashtable ();
149 foreach (XmlNode child in node.ChildNodes) {
150 XmlNodeType t = child.NodeType;
151 if (t == XmlNodeType.Whitespace || t == XmlNodeType.Comment)
152 continue;
153 if (t == XmlNodeType.Element) {
154 XmlAttributeCollection attributes = child.Attributes;
155 string name = null;
156 string value = null;
157 switch (child.Name) {
158 case "add":
159 name = GetAttribute (attributes, "name", true, child);
160 value = GetAttribute (attributes, "value", false, child);
161 newNodes[name] = AsString (value);
162 break;
163 case "remove":
164 name = GetAttribute (attributes, "name", true, child);
165 newNodes.Remove (name);
166 break;
167 case "clear":
168 newNodes.Clear ();
169 break;
170 default:
171 ThrowUnrecognizedElement (child);
172 break;
174 ValidateInvalidAttributes (attributes, child);
176 else
177 ThrowUnrecognizedNode (child);
180 d [node.Name] = newNodes;
183 private void AddTraceNode (IDictionary d, XmlNode node)
185 AddTraceAttributes (d, node);
187 foreach (XmlNode child in node.ChildNodes) {
188 XmlNodeType t = child.NodeType;
189 if (t == XmlNodeType.Whitespace || t == XmlNodeType.Comment)
190 continue;
191 if (t == XmlNodeType.Element) {
192 if (child.Name == "listeners")
193 AddTraceListeners (child);
194 else
195 ThrowUnrecognizedElement (child);
196 ValidateInvalidAttributes (child.Attributes, child);
198 else
199 ThrowUnrecognizedNode (child);
203 // all attributes are optional
204 private void AddTraceAttributes (IDictionary d, XmlNode node)
206 XmlAttributeCollection c = node.Attributes;
207 string autoflush = GetAttribute (c, "autoflush", false, node);
208 string indentsize = GetAttribute (c, "indentsize", false, node);
209 ValidateInvalidAttributes (c, node);
210 if (autoflush != null) {
211 try {
212 bool b = bool.Parse (autoflush);
213 d ["autoflush"] = b;
214 TraceImpl.AutoFlush = b;
216 catch (Exception e) {
217 throw new ConfigurationException ("The `autoflush' attribute must be `true' or `false'",
218 e, node);
221 if (indentsize != null) {
222 try {
223 int n = int.Parse (indentsize);
224 d ["indentsize"] = n;
225 TraceImpl.IndentSize = n;
227 catch (Exception e) {
228 throw new ConfigurationException ("The `indentsize' attribute must be an integral value.",
229 e, node);
234 // only defines "add" and "remove", but "clear" also works
235 // for add, "name" and "type" are required; initializeData is optional
236 private void AddTraceListeners (XmlNode listenersNode)
238 // There are no attributes on <listeners/>
239 ValidateInvalidAttributes (listenersNode.Attributes, listenersNode);
241 foreach (XmlNode child in listenersNode.ChildNodes) {
242 XmlNodeType t = child.NodeType;
243 if (t == XmlNodeType.Whitespace || t == XmlNodeType.Comment)
244 continue;
245 if (t == XmlNodeType.Element) {
246 XmlAttributeCollection attributes = child.Attributes;
247 string name = null;
248 string type = null;
249 string id = null;
250 switch (child.Name) {
251 case "add":
252 name = GetAttribute (attributes, "name", true, child);
253 type = GetAttribute (attributes, "type", true, child);
254 id = GetAttribute (attributes, "initializeData", false, child);
255 AddTraceListener (name, type, id);
256 break;
257 case "remove":
258 name = GetAttribute (attributes, "name", true, child);
259 RemoveTraceListener (name);
260 break;
261 case "clear":
262 TraceImpl.Listeners.Clear ();
263 break;
264 default:
265 ThrowUnrecognizedElement (child);
266 break;
268 ValidateInvalidAttributes (attributes, child);
270 else
271 ThrowUnrecognizedNode (child);
275 private void AddTraceListener (string name, string type, string initializeData)
277 Type t = Type.GetType (type);
278 if (t == null)
279 throw new ConfigurationException (string.Format ("Invalid Type Specified: {0}", type));
281 object[] args;
282 Type[] types;
284 if (initializeData != null) {
285 args = new object[] { initializeData };
286 types = new Type[] { typeof(string) };
288 else {
289 args = null;
290 types = new Type[0];
293 System.Reflection.ConstructorInfo ctor = t.GetConstructor (types);
294 if (ctor == null)
295 throw new ConfigurationException ("Couldn't find constructor for class " + type);
297 TraceListener l = (TraceListener) ctor.Invoke (args);
298 l.Name = name;
299 TraceImpl.Listeners.Add (l);
302 private void RemoveTraceListener (string name)
304 try {
305 TraceImpl.Listeners.Remove (name);
307 catch (ArgumentException) {
308 // The specified listener wasn't in the collection
309 // Ignore this; .NET does.
311 catch (Exception e) {
312 throw new ConfigurationException (
313 string.Format ("Unknown error removing listener: {0}", name),
318 private string GetAttribute (XmlAttributeCollection attrs, string attr, bool required, XmlNode node)
320 XmlAttribute a = attrs[attr];
322 string r = null;
324 if (a != null) {
325 r = a.Value;
326 if (required)
327 ValidateAttribute (attr, r, node);
328 attrs.Remove (a);
330 else if (required)
331 ThrowMissingAttribute (attr, node);
333 return r;
336 private string AsString (string s)
338 return s == null ? string.Empty : s;
341 private void ValidateAttribute (string attribute, string value, XmlNode node)
343 if (value == null || value.Length == 0)
344 throw new ConfigurationException (string.Format ("Required attribute `{0}' cannot be empty.", attribute), node);
347 private void ValidateInvalidAttributes (XmlAttributeCollection c, XmlNode node)
349 if (c.Count != 0)
350 ThrowUnrecognizedAttribute (c[0].Name, node);
353 private void ThrowMissingAttribute (string attribute, XmlNode node)
355 throw new ConfigurationException (string.Format ("Missing required attribute `{0}'.", attribute), node);
358 private void ThrowUnrecognizedNode (XmlNode node)
360 throw new ConfigurationException (
361 string.Format ("Unrecognized node `{0}'; nodeType={1}", node.Name, node.NodeType),
362 node);
365 private void ThrowUnrecognizedElement (XmlNode node)
367 throw new ConfigurationException (
368 string.Format ("Unrecognized element <{0}/>", node.Name),
369 node);
372 private void ThrowUnrecognizedAttribute (string attribute, XmlNode node)
374 throw new ConfigurationException (
375 string.Format ("Unrecognized attribute `{0}' on element <{1}/>.", attribute, node.Name),
376 node);
379 #endif