2002-01-06 Ravi Pratap <ravi@ximian.com>
[mono.git] / mcs / class / System / System.Configuration / ConfigurationSettings.cs
1 //
2 // System.Configuration.ConfigurationSettings.cs
3 //
4 // Author:
5 //   Christopher Podurgiel (cpodurgiel@msn.com)
6 //
7 // C) Christopher Podurgiel
8 //
9
10 using System;
11 using System.Collections.Specialized;
12 using System.Reflection;
13 using System.Xml;
14 using System.Xml.XPath;
15
16 namespace System.Configuration
17 {
18         /// <summary>
19         ///             Component class.
20         /// </summary>
21         /// <remarks>
22         ///             Longer description
23         /// </remarks>
24
25         public sealed class ConfigurationSettings
26         {
27
28                 private static string applicationConfigFileName;
29                 
30                 /// <summary>
31                 ///             ConfigurationSettings Constructor.
32                 /// </summary>
33                 public ConfigurationSettings ()
34                 {
35                         
36                 }
37
38                 /// <summary>
39                 ///             Returns configuration settings for a user-defined configuration section.
40                 /// </summary>
41                 /// <param name="sectionName">The name of the configuration section that configuration settings are read from.</param>
42                 /// <returns></returns>
43                 public static object GetConfig(string sectionName)
44                 {
45                         //Create an instance of an XML Document.
46                         XmlDocument ConfigurationDocument = new XmlDocument();
47
48                         /*
49                          * LAMESPEC: The .config file that needs to be parsed is the name of the application, plus ".config"
50                          * ie. "Myapplication.exe.config"
51                          * The only way I could find to get the name of the application is through System.Forms.Application.ExecutablePath, this
52                          * may be an incorrect way to get this information.  It works properly on a windows machine when building an executable,
53                          * however, I'm not sure how this would work under other platforms.
54                         */
55                         //Get the full path to the Applicaton Configuration File.
56                         applicationConfigFileName =  "FIXME:ConfigurationSettings" + ".config";
57
58                         //Try to load the XML Document.
59                         try
60                         { 
61                                 ConfigurationDocument.Load(applicationConfigFileName);
62                         }
63                         catch(XmlException e)
64                         {
65                                 //Error loading the XML Document.  Throw a ConfigurationException.
66                                 throw(new ConfigurationException(e.Message, applicationConfigFileName, e.LineNumber));
67                         }
68
69                                 string sectionHandlerName = GetSectionHanderType(ConfigurationDocument, sectionName);
70                              
71                                 XmlNode sectionNode = ConfigurationDocument.SelectSingleNode("/configuration/" + sectionName);
72                         
73                         
74                         
75                         //If the specified sectionName is not found, then sectionNode will be null.  When calling objNVSHandler.Create(),
76                         //sectionNode cannot be null.
77                          if(sectionNode == null)
78                         {
79                                 return null;
80                         }
81                         
82
83                         //Create a new SectionHandler\r
84 \r
85                         //According to the Docs provided by Microsoft, the user can create their own configuration sections, and create a custom\r
86                         //handler class for it. The user would specify the class and its assebly in the <configSections> section.  These would be\r
87                         //seperated by a comma.\r
88 \r
89                         string sectionHandlerClassName = sectionHandlerName;
90                         string sectionHandlerAssemblyName = "System";\r
91 \r
92                         //Split the SectionHandler Class Name from the Assembly Name (if provided).\r
93                         string[] sectionHandlerArray = sectionHandlerName.Split(new char[]{','}, 2);
94                         if(sectionHandlerArray.Length == 2)
95                         {
96                                 sectionHandlerClassName = sectionHandlerArray[0];
97                                 sectionHandlerAssemblyName = sectionHandlerArray[1];
98                         }
99                         
100                         // Load the assembly to use.
101                         Assembly assem = Assembly.Load(sectionHandlerAssemblyName);
102                         //Get the class type.
103                         Type handlerObjectType = assem.GetType(sectionHandlerClassName);
104                         //Get a reference to the method "Create"
105                         MethodInfo createMethod = handlerObjectType.GetMethod("Create");
106                         //Create an Instance of this SectionHandler.
107                         Object objSectionHandler = Activator.CreateInstance(handlerObjectType);
108
109                         //define the arguments to be passed to the "Create" Method.
110                         Object[] args = new Object[3];
111                         args[0] = null;
112                         args[1] = null;
113                         args[2] = sectionNode;
114
115                         object sectionHandlerCollection = createMethod.Invoke(objSectionHandler, args);
116
117                         //Return the collection
118                         return sectionHandlerCollection;
119
120                 }
121
122
123                 /// <summary>\r
124                 ///             Gets the name of the SectionHander Class that will handle this section.\r
125                 /// </summary>\r
126                 /// <param name="xmlDoc">An xml Configuration Document.</param>\r
127                 /// <param name="sectionName">The name of the configuration section that configuration settings are read from.</param>\r
128                 /// <returns>The name of the Handler Object for this configuration section, including the name if its Assembly.</returns>
129                 [MonoTODO]
130                 private static string GetSectionHanderType(XmlDocument xmlDoc, string sectionName)
131                 {
132                         //TODO: This method does not account for sectionGroups yet.
133                         string handlerName = null;
134
135                         //<appSettings> is a predefined configuration section. It does not have a definition
136                         // in the <configSections> section, and will always be handled by the NameValueSectionHandler.
137                         if(sectionName == "appSettings")
138                         {
139                                 handlerName = "System.Configuration.NameValueSectionHandler";
140                         }
141                         else
142                         {
143                                 
144                                 string[] sectionPathArray = sectionName.Split(new char[]{'/'});
145
146                                 //Build an XPath statement.
147                                 string xpathStatement = "/configuration/configSections";
148                                 for (int i=0; i < sectionPathArray.Length; i++)
149                                 {
150                                         if(i < sectionPathArray.Length - 1)
151                                         {
152                                                 xpathStatement = xpathStatement + "/sectionGroup[@name='" + sectionPathArray[i] + "']";
153                                         }
154                                         else
155                                         {
156                                                 xpathStatement = xpathStatement + "/section[@name='" + sectionPathArray[i] + "']";
157                                         }
158                                 }
159                                 
160                                 //Get all of the <section> node using the xpath statement.
161                                 XmlNode sectionNode = xmlDoc.SelectSingleNode(xpathStatement);
162
163                                 // if this section isn't found, then there was something wrong with the config document,
164                                 // or the sectionName didn't have a proper definition.
165                                 if(sectionNode == null)
166                                 {
167                                         
168                                         throw (new ConfigurationException("Unrecognized element."));
169                                 }
170
171                                 handlerName =  sectionNode.Attributes["type"].Value;
172
173                         }\r
174
175                         //Return the name of the handler.
176                         return handlerName;
177                 }
178
179
180
181                 /// <summary>
182                 ///             Get the Application Configuration Settings.
183                 /// </summary>
184                 public static NameValueCollection AppSettings
185                 {
186                         get
187                         {       
188                                 //Get the Configuration Settings for the "appSettings" section.
189                                 NameValueCollection appSettings = (NameValueCollection)GetConfig("appSettings");;
190
191                                 return appSettings;
192                         }
193                 }
194
195         }
196 }
197
198