minor CLS conformance tweaks (visibility, virtual, abstract, sealed, etc...)
[mono.git] / mcs / class / System / System.Configuration / ConfigurationSettings.cs
index 86fcb9a764fb142a45cef78d192d7721d40d8c2b..ba5ccf02ad0e331ca1c1005066944b4990857800 100644 (file)
@@ -4,11 +4,14 @@
 // Author:
 //   Christopher Podurgiel (cpodurgiel@msn.com)
 //
-// (C) Ximian, Inc.  http://www.ximian.com
+// C) Christopher Podurgiel
 //
 
 using System;
 using System.Collections.Specialized;
+using System.Reflection;
+using System.Xml;
+using System.Xml.XPath;
 
 namespace System.Configuration
 {
@@ -22,38 +25,173 @@ namespace System.Configuration
        public sealed class ConfigurationSettings
        {
 
-               private NameValueCollection appsettings;
-
-
+               private static string applicationConfigFileName;
+               
                /// <summary>
                ///             ConfigurationSettings Constructor.
                /// </summary>
-               public ConfigurationSettings ()
+               private ConfigurationSettings ()
                {
-                       appsettings = new NameValueCollection();
+                       
                }
 
                /// <summary>
                ///             Returns configuration settings for a user-defined configuration section.
                /// </summary>
-               /// <param name="sectionName"></param>
+               /// <param name="sectionName">The name of the configuration section that configuration settings are read from.</param>
                /// <returns></returns>
-               public static object GetConfig( string sectionName)
+               public static object GetConfig(string sectionName)
                {
-                       //FIXME: Not sure how to determine the correct .config file to parse.
-                       return null;
+                       //Create an instance of an XML Document.
+                       XmlDocument ConfigurationDocument = new XmlDocument();
+
+                       /*
+                        * LAMESPEC: The .config file that needs to be parsed is the name of the application, plus ".config"
+                        * ie. "Myapplication.exe.config"
+                        * The only way I could find to get the name of the application is through System.Forms.Application.ExecutablePath, this
+                        * may be an incorrect way to get this information.  It works properly on a windows machine when building an executable,
+                        * however, I'm not sure how this would work under other platforms.
+                       */
+                       //Get the full path to the Applicaton Configuration File.
+                       applicationConfigFileName =  "FIXME:ConfigurationSettings" + ".config";
+
+                       //Try to load the XML Document.
+                       try
+                       { 
+                               ConfigurationDocument.Load(applicationConfigFileName);
+                       }
+                       catch(XmlException e)
+                       {
+                               //Error loading the XML Document.  Throw a ConfigurationException.
+                               throw(new ConfigurationException(e.Message, applicationConfigFileName, e.LineNumber));
+                       }
+
+                               string sectionHandlerName = GetSectionHanderType(ConfigurationDocument, sectionName);
+                            
+                               XmlNode sectionNode = ConfigurationDocument.SelectSingleNode("/configuration/" + sectionName);
+                       
+                       
+                       
+                       //If the specified sectionName is not found, then sectionNode will be null.  When calling objNVSHandler.Create(),
+                       //sectionNode cannot be null.
+                        if(sectionNode == null)
+                       {
+                               return null;
+                       }
+                       
+
+                       //Create a new SectionHandler\r
+\r
+                       //According to the Docs provided by Microsoft, the user can create their own configuration sections, and create a custom\r
+                       //handler class for it. The user would specify the class and its assebly in the <configSections> section.  These would be\r
+                       //seperated by a comma.\r
+\r
+                       string sectionHandlerClassName = sectionHandlerName;
+                       string sectionHandlerAssemblyName = "System";\r
+\r
+                       //Split the SectionHandler Class Name from the Assembly Name (if provided).\r
+                       string[] sectionHandlerArray = sectionHandlerName.Split(new char[]{','}, 2);
+                       if(sectionHandlerArray.Length == 2)
+                       {
+                               sectionHandlerClassName = sectionHandlerArray[0];
+                               sectionHandlerAssemblyName = sectionHandlerArray[1];
+                       }
+                       
+                       // Load the assembly to use.
+                       Assembly assem = Assembly.Load(sectionHandlerAssemblyName);
+                       //Get the class type.
+                       Type handlerObjectType = assem.GetType(sectionHandlerClassName);
+                       //Get a reference to the method "Create"
+                       MethodInfo createMethod = handlerObjectType.GetMethod("Create");
+                       //Create an Instance of this SectionHandler.
+                       Object objSectionHandler = Activator.CreateInstance(handlerObjectType);
+
+                       //define the arguments to be passed to the "Create" Method.
+                       Object[] args = new Object[3];
+                       args[0] = null;
+                       args[1] = null;
+                       args[2] = sectionNode;
+
+                       object sectionHandlerCollection = createMethod.Invoke(objSectionHandler, args);
+
+                       //Return the collection
+                       return sectionHandlerCollection;
+
                }
 
+
+               /// <summary>\r
+               ///             Gets the name of the SectionHander Class that will handle this section.\r
+               /// </summary>\r
+               /// <param name="xmlDoc">An xml Configuration Document.</param>\r
+               /// <param name="sectionName">The name of the configuration section that configuration settings are read from.</param>\r
+               /// <returns>The name of the Handler Object for this configuration section, including the name if its Assembly.</returns>
+               [MonoTODO]
+               private static string GetSectionHanderType(XmlDocument xmlDoc, string sectionName)
+               {
+                       //TODO: This method does not account for sectionGroups yet.
+                       string handlerName = null;
+
+                       //<appSettings> is a predefined configuration section. It does not have a definition
+                       // in the <configSections> section, and will always be handled by the NameValueSectionHandler.
+                       if(sectionName == "appSettings")
+                       {
+                               handlerName = "System.Configuration.NameValueSectionHandler";
+                       }
+                       else
+                       {
+                               
+                               string[] sectionPathArray = sectionName.Split(new char[]{'/'});
+
+                               //Build an XPath statement.
+                               string xpathStatement = "/configuration/configSections";
+                               for (int i=0; i < sectionPathArray.Length; i++)
+                               {
+                                       if(i < sectionPathArray.Length - 1)
+                                       {
+                                               xpathStatement = xpathStatement + "/sectionGroup[@name='" + sectionPathArray[i] + "']";
+                                       }
+                                       else
+                                       {
+                                               xpathStatement = xpathStatement + "/section[@name='" + sectionPathArray[i] + "']";
+                                       }
+                               }
+                               
+                               //Get all of the <section> node using the xpath statement.
+                               XmlNode sectionNode = xmlDoc.SelectSingleNode(xpathStatement);
+
+                               // if this section isn't found, then there was something wrong with the config document,
+                               // or the sectionName didn't have a proper definition.
+                               if(sectionNode == null)
+                               {
+                                       
+                                       throw (new ConfigurationException("Unrecognized element."));
+                               }
+
+                               handlerName =  sectionNode.Attributes["type"].Value;
+
+                       }\r
+
+                       //Return the name of the handler.
+                       return handlerName;
+               }
+
+
+
                /// <summary>
                ///             Get the Application Configuration Settings.
                /// </summary>
-               public NameValueCollection AppSettings
+               public static NameValueCollection AppSettings
                {
                        get
-                       {
-                               return appsettings;
+                       {       
+                               //Get the Configuration Settings for the "appSettings" section.
+                               NameValueCollection appSettings = (NameValueCollection)GetConfig("appSettings");;
+
+                               return appSettings;
                        }
                }
+
        }
 }