a8a606a0ea98314cec8c986f93ff79d615b0a8af
[mono.git] / mcs / class / referencesource / System / compmod / system / diagnostics / SourceElementsCollection.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="SourceElementsCollection .cs" company="Microsoft Corporation">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
6 using System.Configuration;
7 using System.Collections;
8 using System.Collections.Specialized;
9 using System.Xml;
10
11 namespace System.Diagnostics {
12     [ConfigurationCollection(typeof(SourceElement), AddItemName = "source",
13      CollectionType = ConfigurationElementCollectionType.BasicMap)]
14     internal class SourceElementsCollection  : ConfigurationElementCollection {
15
16         new public SourceElement this[string name] {
17             get {
18                 return (SourceElement) BaseGet(name);
19             }
20         }
21         
22         protected override string ElementName {
23             get {
24                 return "source";
25             }
26         }
27
28         public override ConfigurationElementCollectionType CollectionType {
29             get {
30                 return ConfigurationElementCollectionType.BasicMap;
31             }
32         }
33
34         protected override ConfigurationElement CreateNewElement() {
35             SourceElement se = new SourceElement();
36             se.Listeners.InitializeDefaultInternal();
37             return se;
38         }
39
40         protected override Object GetElementKey(ConfigurationElement element) {
41             return ((SourceElement) element).Name;
42         }
43     }
44
45
46     internal class SourceElement : ConfigurationElement {
47         private static readonly ConfigurationPropertyCollection _properties;
48         private static readonly ConfigurationProperty _propName = new ConfigurationProperty("name", typeof(string), "", ConfigurationPropertyOptions.IsRequired);
49         private static readonly ConfigurationProperty _propSwitchName = new ConfigurationProperty("switchName", typeof(string), null, ConfigurationPropertyOptions.None);
50         private static readonly ConfigurationProperty _propSwitchValue = new ConfigurationProperty("switchValue", typeof(string), null, ConfigurationPropertyOptions.None);
51         private static readonly ConfigurationProperty _propSwitchType = new ConfigurationProperty("switchType", typeof(string), null, ConfigurationPropertyOptions.None);
52         private static readonly ConfigurationProperty _propListeners = new ConfigurationProperty("listeners", typeof(ListenerElementsCollection), new ListenerElementsCollection(), ConfigurationPropertyOptions.None);
53
54         private Hashtable _attributes;
55
56         static SourceElement() {
57             _properties = new ConfigurationPropertyCollection();
58             _properties.Add(_propName);
59             _properties.Add(_propSwitchName);
60             _properties.Add(_propSwitchValue);
61             _properties.Add(_propSwitchType);
62             _properties.Add(_propListeners);
63         }
64
65         public Hashtable Attributes {
66             get {
67                 if (_attributes == null)
68                     _attributes = new Hashtable(StringComparer.OrdinalIgnoreCase);
69                 return _attributes;
70             }
71         }
72
73         [ConfigurationProperty("listeners")]
74         public ListenerElementsCollection Listeners {
75             get {
76                 return (ListenerElementsCollection) this[_propListeners];
77             }
78         }
79
80         [ConfigurationProperty("name", IsRequired=true, DefaultValue="")]
81         public string Name {
82             get { 
83                 return (string) this[_propName]; 
84             }
85         }
86         
87         protected override ConfigurationPropertyCollection Properties {
88             get {
89                 return _properties;
90             }
91         }
92
93         [ConfigurationProperty("switchName")]
94         public string SwitchName {
95             get { 
96                 return (string) this[_propSwitchName]; 
97             }
98         }
99
100         [ConfigurationProperty("switchValue")]
101         public string SwitchValue {
102             get { 
103                 return (string) this[_propSwitchValue]; 
104             }
105         }
106
107         [ConfigurationProperty("switchType")]
108         public string SwitchType {
109             get { 
110                 return (string) this[_propSwitchType];
111             }
112         }
113                 
114         protected override void DeserializeElement(XmlReader reader, bool serializeCollectionKey)
115         {
116             base.DeserializeElement(reader, serializeCollectionKey);
117
118             if (!String.IsNullOrEmpty(SwitchName) && !String.IsNullOrEmpty(SwitchValue))
119                 throw new ConfigurationErrorsException(SR.GetString(SR.Only_specify_one, Name));
120         }
121
122         // Our optional attributes implementation is little convoluted as there is 
123         // no such firsclass mechanism from the config system. We basically cache 
124         // any "unrecognized" attribute here and serialize it out later. 
125         protected override bool OnDeserializeUnrecognizedAttribute(String name, String value) {
126             Attributes.Add(name, value);
127             return true;         
128         }
129
130         // We need to serialize optional attributes here, a better place would have   
131         // been inside SerializeElement but the base class implementation from
132         // ConfigurationElement doesn't take into account for derived class doing
133         // extended serialization, it basically writes out child element that 
134         // forces the element closing syntax, so any attribute serialization needs
135         // to happen before normal element serialization from ConfigurationElement.
136         // This means we would write out custom attributes ahead of normal ones. 
137         // The other alternative would be to re-implement the entire routine here 
138         // which is an overkill and a maintenance issue. 
139         protected override void PreSerialize(XmlWriter writer) {
140             if (_attributes != null) {
141                 IDictionaryEnumerator e = _attributes.GetEnumerator();
142                 while (e.MoveNext()) {
143                     string xmlValue = (string)e.Value;
144                     string xmlName = (string)e.Key;
145
146                     if ((xmlValue != null) && (writer != null)) {
147                         writer.WriteAttributeString(xmlName, xmlValue);
148                     }
149                 }
150             }
151         }
152
153         // Account for optional attributes from custom listeners. 
154         protected override bool SerializeElement(XmlWriter writer, bool serializeCollectionKey) {
155             bool DataToWrite = base.SerializeElement(writer, serializeCollectionKey);
156             DataToWrite = DataToWrite || ((_attributes != null) && (_attributes.Count > 0));
157             return DataToWrite;
158         }
159
160         protected override void Unmerge(ConfigurationElement sourceElement,
161                                                 ConfigurationElement parentElement,
162                                                 ConfigurationSaveMode saveMode) {
163             base.Unmerge(sourceElement, parentElement, saveMode);
164             
165             // Unmerge the optional attributes cache as well
166             SourceElement le = sourceElement as SourceElement; 
167             if ((le != null) && (le._attributes != null)) 
168                 this._attributes = le._attributes;  
169         }
170
171         internal void ResetProperties() 
172         {
173             // blow away any UnrecognizedAttributes that we have deserialized earlier 
174             if (_attributes != null) {
175                 _attributes.Clear();
176                 _properties.Clear();
177                 _properties.Add(_propName);
178                 _properties.Add(_propSwitchName);
179                 _properties.Add(_propSwitchValue);
180                 _properties.Add(_propSwitchType);
181                 _properties.Add(_propListeners);
182             }
183         }
184     }
185         
186 }
187