using System;
using System.Collections;
using System.Collections.Generic;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Framework.Config;
using NHibernate.Expression;

namespace SettingsManager
{
    public partial class SettingsManagerException : Exception
    {
        public SettingsManagerException(string message) : base(message)
        {
        }
    }

    public partial class SettingsManager
    {
        private const char BACKSLASH = '\x005c';

        public SettingsManager(string ConnectionString)
        {
            Hashtable properties = new Hashtable();
            properties.Add("hibernate.connection.driver_class", "NHibernate.Driver.SqlClientDriver");
            properties.Add("hibernate.dialect", "NHibernate.Dialect.MsSql2000Dialect");
            properties.Add("hibernate.connection.provider", "NHibernate.Connection.DriverConnectionProvider");
            properties.Add("hibernate.connection.connection_string", ConnectionString);
            InPlaceConfigurationSource source = new InPlaceConfigurationSource();
            source.Add(typeof (ActiveRecordBase), properties);
            ActiveRecordStarter.Initialize(source, typeof (Setting), typeof (Section));
            //ActiveRecordStarter.CreateSchema();
        }

        private static List<T> MakeList<T>(IList<T> sourceList)
        {
            List<T> resultList = sourceList as List<T>;
            if (resultList == null)
                resultList = new List<T>(sourceList);
            return resultList;
        }

        public void SetSetting<T>(string ApplicationName, string SectionPath, string SettingName, T SettingValue)
        {
            SetSetting<T>(ApplicationName, SectionPath, SettingName, SettingValue, DateTime.UtcNow.AddYears(1));
        }

        public void SetSetting<T>(string ApplicationName, string SectionPath, string SettingName, T SettingValue, DateTime ExpiresOnUTC)
        {
            SetSetting(ApplicationName,
                       SectionPath.Split(new char[] {BACKSLASH}, StringSplitOptions.RemoveEmptyEntries),
                       SettingName,
                       SettingValue,
                       ExpiresOnUTC);
        }

        private static Section GetSectionForApplication(string ApplicationName)
        {
            ICriterion[] criteria =
                new ICriterion[] {Expression.IsNull("ParentSection"), Expression.Eq("SectionName", ApplicationName)};
            return Section.FindOne(criteria);
        }

        public void SetSetting<T>(string ApplicationName,
                                  string[] SectionPath,
                                  string SettingName,
                                  T SettingValue,
                                  DateTime ExpiresOnUTC)
        {
            Section foundSection = GetSectionForApplication(ApplicationName);
            if (foundSection == null)
            {
                foundSection = new Section(ApplicationName, null);
                foundSection.Save();
                foundSection = GetSectionForApplication(ApplicationName);
            }
            Section prevSection = foundSection;
            foreach (string sectionPath in SectionPath)
            {
                foundSection =
                    MakeList(foundSection.Sections).Find(
                        delegate(Section sec) { return sec.SectionName.Equals(sectionPath); });
                if (foundSection == null)
                {
                    foundSection = new Section(sectionPath, prevSection);
                    foundSection.Save();
                }
                prevSection = foundSection;
            }
            Setting setting =
                MakeList(foundSection.Settings).Find(
                    delegate(Setting set) { return set.SettingName.Equals(SettingName); });
            if (setting == null)
            {
                setting = new Setting(SettingName, SettingValue.ToString(), ExpiresOnUTC);
                setting.Save();
                foundSection.Settings.Add(setting);
                foundSection.Save();
            }
            else
            {
                setting.SettingValue = SettingValue.ToString();
                setting.ExpiresOnUTC = ExpiresOnUTC;
                setting.Save();
            }
        }

        public T GetSetting<T>(string ApplicationName, string SectionPath, string SettingName)
        {
            return
                GetSetting<T>(ApplicationName,
                              SectionPath.Split(new char[] {BACKSLASH}, StringSplitOptions.RemoveEmptyEntries),
                              SettingName);
        }

        public T GetSetting<T>(string ApplicationName, string[] SectionPath, string SettingName)
        {
            Section foundSection = GetSectionForApplication(ApplicationName);
            foreach (string sectionPath in SectionPath)
            {
                foundSection =
                    MakeList(foundSection.Sections).Find(
                        delegate(Section sec) { return sec.SectionName.Equals(sectionPath); });
                if (foundSection == null)
                    throw new SettingsManagerException("Section not found.");
            }
            Setting setting =
                MakeList(foundSection.Settings).Find(
                    delegate(Setting set) { return set.SettingName.Equals(SettingName); });
            if (setting == null)
                throw new SettingsManagerException("Setting not found.");
            if (setting.ExpiresOnUTC < DateTime.UtcNow)
                throw new SettingsManagerException("Setting has expired.");
            return (T) (object) setting.SettingValue;
        }

        public void DeleteSetting(string ApplicationName, string SectionPath, string SettingName)
        {
            DeleteSetting(ApplicationName,
                          SectionPath.Split(new char[] {BACKSLASH}, StringSplitOptions.RemoveEmptyEntries),
                          SettingName);
        }

        public void DeleteSetting(string ApplicationName, string[] SectionPath, string SettingName)
        {
            Section foundSection = GetSectionForApplication(ApplicationName);
            foreach (string sectionPath in SectionPath)
            {
                foundSection =
                    MakeList(foundSection.Sections).Find(
                        delegate(Section sec) { return sec.SectionName.Equals(sectionPath); });
                if (foundSection == null)
                    throw new SettingsManagerException("Section not found.");
            }
            Setting setting =
                MakeList(foundSection.Settings).Find(
                    delegate(Setting set) { return set.SettingName.Equals(SettingName); });
            if (setting != null)
                setting.Delete();
        }

        public Dictionary<string, string> GetAllSettings(string ApplicationName, string SectionPath)
        {
            return
                GetAllSettings(ApplicationName,
                               SectionPath.Split(new char[] {BACKSLASH}, StringSplitOptions.RemoveEmptyEntries));
        }

        public Dictionary<string, string> GetAllSettings(string ApplicationName, string[] SectionPath)
        {
            Dictionary<string, string> returnDic = new Dictionary<string, string>();
            Section foundSection = GetSectionForApplication(ApplicationName);
            foreach (string sectionPath in SectionPath)
            {
                foundSection =
                    MakeList(foundSection.Sections).Find(
                        delegate(Section sec) { return sec.SectionName.Equals(sectionPath); });
                if (foundSection == null)
                    throw new SettingsManagerException("Section not found.");
            }

            foreach (Setting setting in foundSection.Settings)
                returnDic.Add(string.Concat(foundSection.SectionName, BACKSLASH, setting.SettingName), setting.SettingValue);
            foreach (Section section in foundSection.Sections)
                TraverseSection(section, returnDic);

            return returnDic;
        }

        private static void TraverseSection(Section section, Dictionary<string, string> dic)
        {
            if (section.Sections.Count >= 1)
                foreach (Section sec in section.Sections)
                    TraverseSection(sec, dic);
            else
                foreach (Setting setting in section.Settings)
                    dic.Add(string.Concat(section.SectionName, BACKSLASH, setting.SettingName), setting.SettingValue);
        }
    }

    [ActiveRecord("Section", Schema = "dbo")]
    internal partial class Section : ActiveRecordBase<Section>
    {
        private Section _parentsection;
        private int _sectionId;
        private string _sectionName;
        private IList<Section> _sections = new List<Section>();
        private IList<Setting> _settings = new List<Setting>();

        public Section()
        {
        }

        public Section(string SectionName, Section ParentSection)
        {
            _sectionName = SectionName;
            _parentsection = ParentSection;
        }

        [Property("SectionName", ColumnType = "String", NotNull = true)]
        public virtual string SectionName { get { return _sectionName; } set { _sectionName = value; } }

        [PrimaryKey(PrimaryKeyType.Identity, "SectionId", ColumnType = "Int32")]
        public virtual int SectionId { get { return _sectionId; } set { _sectionId = value; } }

        [HasMany(typeof (Section), ColumnKey = "ParentSectionId", Table = "Section")]
        public virtual IList<Section> Sections { get { return _sections; } set { _sections = value; } }

        [BelongsTo("ParentSectionId", NotNull = false)]
        public virtual Section ParentSection { get { return _parentsection; } set { _parentsection = value; } }

        [HasAndBelongsToMany(typeof (Setting), ColumnRef = "SettingId", ColumnKey = "SectionId", Schema = "dbo",
            Table = "SectionSetting")]
        public virtual IList<Setting> Settings { get { return _settings; } set { _settings = value; } }
    }

    [ActiveRecord("Setting", Schema = "dbo")]
    internal partial class Setting : ActiveRecordBase<Setting>
    {
        private DateTime _expiresOnUTC;
        private IList<Section> _sections = new List<Section>();
        private int _settingId;
        private string _settingName;
        private string _settingValue;

        public Setting()
        {
        }

        public Setting(string SettingName, string SettingValue, DateTime ExpiresOnUTC)
        {
            _settingName = SettingName;
            _settingValue = SettingValue;
            _expiresOnUTC = ExpiresOnUTC;
        }

        [Property("SettingName", ColumnType = "String", NotNull = true)]
        public virtual string SettingName { get { return _settingName; } set { _settingName = value; } }

        [Property("SettingValue", ColumnType = "String", NotNull = true)]
        public virtual string SettingValue { get { return _settingValue; } set { _settingValue = value; } }

        [Property("ExpiresOnUTC", ColumnType = "Timestamp", NotNull = true)]
        public virtual DateTime ExpiresOnUTC { get { return _expiresOnUTC; } set { _expiresOnUTC = value; } }

        [PrimaryKey(PrimaryKeyType.Identity, "SettingId", ColumnType = "Int32")]
        public virtual int SettingId { get { return _settingId; } set { _settingId = value; } }

        [HasAndBelongsToMany(typeof (Section), ColumnRef = "SectionId", ColumnKey = "SettingId", Schema = "dbo",
            Table = "SectionSetting")]
        public virtual IList<Section> Sections { get { return _sections; } set { _sections = value; } }
    }
}

Comments


Comments are closed