📄 configurationrecord.cs
字号:
//==========================================================================================
//
// OpenNETCF.Configuration.ConfigurationRecord
// Copyright (c) 2003, OpenNETCF.org
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the OpenNETCF.org Shared Source License.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the OpenNETCF.org Shared Source License
// for more details.
//
// You should have received a copy of the OpenNETCF.org Shared Source License
// along with this library; if not, email licensing@opennetcf.org to request a copy.
//
// If you wish to contact the OpenNETCF Advisory Board to discuss licensing, please
// email licensing@opennetcf.org.
//
// For general enquiries, email enquiries@opennetcf.org or visit our website at:
// http://www.opennetcf.org
//
//==========================================================================================
using System;
using System.Collections;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Net;
using System.Reflection;
using System.Security;
using System.Security.Permissions;
using System.Security.Policy;
using System.Threading;
using System.Xml;
namespace OpenNETCF.Configuration
{
class ConfigurationRecord
{
private enum HaveFactoryEnum
{
NotFound = 0,
Group = 1,
Section = 2,
}
private Hashtable results;
private Hashtable factories;
private Hashtable unevaluatedSections;
private bool factoriesNoInherit;
private string filename = null;
private Exception error;
private readonly ConfigurationRecord parent = null;
private static object RemovedFactorySingleton = new Object();
private static object GroupSingleton = new Object();
private Hashtable EnsureFactories
{
get
{
// Check if factories has already been initialized
if (factories == null)
{
factories = new Hashtable();
}
return factories;
}
}
public ConfigurationRecord() : this(null)
{
}
public ConfigurationRecord(ConfigurationRecord Parent)
{
results = new Hashtable();
parent = Parent;
}
public bool Load(string Filename)
{
Uri uri = new Uri(Filename);
// Is the file we're trying to load a local file?
if (uri.Scheme == "file")
{
// If so, use the URI's local path
filename = uri.LocalPath;
}
else
{
// Else just use the filename as provided
filename = Filename;
}
XmlTextReader xmlTextReader = null;
try
{
// Load the config file into a XmlReader
xmlTextReader = OpenXmlTextReader(filename);
if (xmlTextReader != null)
{
// Generate section factories from the raw XML
ScanFactoriesRecursive(xmlTextReader);
//
if (xmlTextReader.Depth == 1)
{
ScanSectionsRecursive(xmlTextReader, null);
}
bool flag = true;
return flag;
}
}
catch (ConfigurationException)
{
throw;
}
catch (Exception e)
{
error = TranslateXmlParseOrEvaluateErrors(e);
throw error;
}
finally
{
if (xmlTextReader != null)
{
xmlTextReader.Close();
}
}
return false;
}
public object GetConfig(string configKey)
{
if (error != null)
{
throw error;
}
if (!results.Contains(configKey))
{
object config = ResolveConfig(configKey);
lock(results.SyncRoot)
{
results[configKey] = config;
}
return config;
}
// else
return results[configKey];
}
public object ResolveConfig(string configKey)
{
if (unevaluatedSections != null && unevaluatedSections.Contains(configKey))
{
return Evaluate(configKey);
}
if (parent != null)
{
return parent.GetConfig(configKey);
}
return null;
}
private object Evaluate(string configKey)
{
// Get config factory
IConfigurationSectionHandler factory = GetFactory(configKey);
// Get the parent result which will be passed to the section handler
object parentResult = (parent == null) ? null : parent.GetConfig(configKey);
// Evaluate the config section
string[] strs = configKey.Split(new char[]{'/'});
XmlTextReader xmlTextReader = null;
object result = null;
try
{
xmlTextReader = OpenXmlTextReader(filename);
result = EvaluateRecursive(factory, parentResult, strs, 0, xmlTextReader);
}
catch (ConfigurationException)
{
throw;
}
catch (Exception e)
{
throw TranslateXmlParseOrEvaluateErrors(e);
}
finally
{
if (xmlTextReader != null)
{
xmlTextReader.Close();
}
}
// Remove the configKey from _unevaluatedSections
// When all sections are removed throw it away
if (unevaluatedSections.Count == 0)
{
unevaluatedSections = null;
}
return result;
}
private HaveFactoryEnum HaveFactory(string configKey)
{
if (factories != null)
{
if(factories.Contains(configKey))
{
object o = factories[configKey];
if (o == RemovedFactorySingleton)
{
return HaveFactoryEnum.NotFound;
}
if (o == GroupSingleton)
{
return HaveFactoryEnum.Group;
}
return HaveFactoryEnum.Section;
}
}
if (!factoriesNoInherit && parent != null)
{
return parent.HaveFactory(configKey);
}
return HaveFactoryEnum.NotFound;
}
private IConfigurationSectionHandler GetFactory(string configKey)
{
if (factories != null)
{
if(factories.Contains(configKey))
{
object o = factories[configKey];
if (o == RemovedFactorySingleton)
{
return null;
}
IConfigurationSectionHandler factory = o as IConfigurationSectionHandler;
if (factory != null)
{
return factory;
}
// If we still have a string, get the type and create the IConfigurationSectionHandler
string factoryType = (string)o;
o = null;
try
{
Type t = Type.GetType(factoryType);
if (t != null)
{
if (!typeof(IConfigurationSectionHandler).IsAssignableFrom(t))
{
throw new ConfigurationException("Type does not implement IConfigSectionHandler");
}
// throws MissingMethodException if there is no valid ctor
o = Activator.CreateInstance(t);
}
}
catch (Exception e)
{
throw new ConfigurationException(e.Message, e);
}
if (o == null)
{
throw new ConfigurationException("Could not create type instance");
}
factory = o as IConfigurationSectionHandler;
if (factory == null)
{
throw new ConfigurationException("Type doesn't implement IConfigSectionHandler");
}
lock(factories.SyncRoot)
{
factories[configKey] = factory;
}
return factory;
}
}
if (!factoriesNoInherit && parent != null)
{
return parent.GetFactory(configKey);
}
else
{
return null;
}
}
private object EvaluateRecursive(IConfigurationSectionHandler factory, object config, string[] keys, int iKey, XmlTextReader reader)
{
string name = keys[iKey];
int depth = reader.Depth;
while(reader.Read() && reader.NodeType != XmlNodeType.Element);
while (reader.Depth == depth + 1)
{
if (reader.Name == name)
{
if (iKey < keys.Length - 1)
{
config = EvaluateRecursive(factory, config, keys, iKey + 1, reader);
}
else
{
// Call configuration section handler
int line = reader.LineNumber;
// Try-catch is necessary to protect from exceptions in user config handlers
try
{
ConfigXmlDocument doc = new ConfigXmlDocument();
doc.LoadSingleElement(filename, reader);
config = factory.Create(config, null, doc.DocumentElement);
}
catch(ConfigurationException)
{
// Bubble ConfigurationExceptions
throw;
}
catch (XmlException)
{
// Bubble XmlExceptions
throw;
}
catch(Exception ex)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -