NetReflectorConfigurationReader.cs :  » Build-Systems » CruiseControl.NET » ThoughtWorks » CruiseControl » Core » Config » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Build Systems » CruiseControl.NET 
CruiseControl.NET » ThoughtWorks » CruiseControl » Core » Config » NetReflectorConfigurationReader.cs

using System;
using System.IO;
using System.Xml;
using Exortech.NetReflector;
using ThoughtWorks.CruiseControl.Core.Security;
using System.Collections.Generic;
using System.Configuration;
using ThoughtWorks.CruiseControl.Core.Util;
using System.Reflection;

namespace ThoughtWorks.CruiseControl.Core.Config{
    /// <summary>
    /// Load a configuration file using NetReflector.
    /// </summary>
  public class NetReflectorConfigurationReader
        : INetReflectorConfigurationReader
  {
    private const string ROOT_ELEMENT = "cruisecontrol";
    private const string CONFIG_ASSEMBLY_PATTERN = "ccnet.*.plugin.dll";
    private readonly NetReflectorTypeTable typeTable;
    private NetReflectorReader reader;

    public NetReflectorConfigurationReader()
    {
      typeTable = new NetReflectorTypeTable();
      typeTable.Add(AppDomain.CurrentDomain);
            string pluginLocation = ConfigurationManager.AppSettings["PluginLocation"];
            if (!string.IsNullOrEmpty(pluginLocation))
            {
                if (Directory.Exists(pluginLocation))
                {
                    typeTable.Add(pluginLocation, CONFIG_ASSEMBLY_PATTERN);
                }
                else
                {
                    throw new CruiseControlException("Unable to find plugin directory: " + pluginLocation);
                }
            }
      typeTable.Add(Directory.GetCurrentDirectory(), CONFIG_ASSEMBLY_PATTERN);
      reader = new NetReflectorReader(typeTable);
    }

        /// <summary>
        /// Reads an XML config document.
        /// </summary>
        /// <param name="document">The document to read.</param>
        /// <param name="errorProcesser">The error processer to use (can be null).</param>
        /// <returns>The loaded configuration.</returns>
        public IConfiguration Read(XmlDocument document, 
            IConfigurationErrorProcesser errorProcesser)
    {
            Configuration configuration = new Configuration();
            string ConflictingXMLNode = string.Empty;
            List<string> projectNames = new List<string>();

            // Validate the document element
            var actualErrorProcesser = errorProcesser ?? new DefaultErrorProcesser();
            VerifyDocumentHasValidRootElement(document, actualErrorProcesser);

            InvalidNodeEventHandler invalidNodeHandler = (args) =>
            {
                if (!actualErrorProcesser.ProcessUnhandledNode(args.Node))
                {
                    actualErrorProcesser.ProcessError(args.Message);
                }
            };
            typeTable.InvalidNode += invalidNodeHandler;
            try
            {
                foreach (XmlNode node in document.DocumentElement)
                {
                    ConflictingXMLNode = string.Empty;

                    if (!(node is XmlComment))
                    {
                        ConflictingXMLNode = "Conflicting project data : " + node.OuterXml;

                        object loadedItem = reader.Read(node);
                        if (loadedItem is IProject)
                        {
                            LoadAndValidateProject(actualErrorProcesser, projectNames, configuration, loadedItem);
                        }
                        else if (loadedItem is IQueueConfiguration)
                        {
                            LoadAndValidateQueue(configuration, loadedItem);
                        }
                        else if (loadedItem is ISecurityManager)
                        {
                            LoadAndValidateSecurityManager(configuration, loadedItem);
                        }
                        else
                        {
                            actualErrorProcesser.ProcessError(
                                new ConfigurationException(
                                    "\nUnknown configuration item found\n" + node.OuterXml));
                        }
                    }
                }

                // Do a validation check to ensure internal configuration consistency
                ValidateConfiguration(configuration, actualErrorProcesser);
            }
            catch (NetReflectorException ex)
            {
                actualErrorProcesser.ProcessError(new ConfigurationException("\nUnable to instantiate CruiseControl projects from configuration document." +
                    "\nConfiguration document is likely missing Xml nodes required for properly populating CruiseControl configuration.\n"
                    + ex.Message +
                    "\n " + ConflictingXMLNode, ex));
            }
            finally
            {
                typeTable.InvalidNode -= invalidNodeHandler;
            }

            return configuration;
        }

        private void LoadAndValidateSecurityManager(Configuration configuration, object loadedItem)
        {
            ISecurityManager securityManager = loadedItem as ISecurityManager;
            configuration.SecurityManager = securityManager as ISecurityManager;
        }

        private void LoadAndValidateQueue(Configuration configuration, object loadedItem)
        {
            IQueueConfiguration queueConfig = loadedItem as IQueueConfiguration;
            configuration.QueueConfigurations.Add(queueConfig);
        }

        private void LoadAndValidateProject(IConfigurationErrorProcesser errorProcesser, 
            List<string> projectNames, Configuration configuration, object loadedItem)
        {
            IProject project = loadedItem as IProject;

            // Validate that the project name is unique
            string projectName = project.Name.ToLowerInvariant();
            if (projectNames.Contains(projectName))
            {
                errorProcesser.ProcessError(
                    new CruiseControlException(
                        string.Format(
                            "A duplicate project name ({0})has been found - projects must be unique per server",
                            projectName)));
            }
            else
            {
                projectNames.Add(projectName);
            }

            configuration.AddProject(project);
        }

        private void VerifyDocumentHasValidRootElement(XmlDocument configXml, IConfigurationErrorProcesser errorProcesser)
    {
            var version = Assembly.GetExecutingAssembly().GetName().Version;
            if (configXml.DocumentElement == null || configXml.DocumentElement.Name != ROOT_ELEMENT)
      {
        throw new ConfigurationException("The configuration document has an invalid root element.  Expected <cruisecontrol>.");
            }
            else if (string.IsNullOrEmpty(configXml.DocumentElement.NamespaceURI))
            {
                // Tell the user there is no version information
                errorProcesser.ProcessWarning("Configuration does not have any version information - assuming the configuration is for version " + version.ToString(2));
            }
            else
            {
                // The last two items are the version number
                var parts = configXml.DocumentElement.NamespaceURI.Split('/');
                var versionNumber = parts[parts.Length - 2] + "." + parts[parts.Length - 1];
                if (version.ToString(2) != versionNumber)
                {
                    // Tell the user the version does not match
                    errorProcesser.ProcessWarning(
                        "Version mismatch - CruiseControl.NET is version " + version.ToString(2) +
                        ", the configuration is for version " + versionNumber);
                }
            }
    }

        /// <summary>
        /// Validate the internal consistency of the configuration.
        /// </summary>
        /// <param name="value">The configuration to check.</param>
        /// <param name="errorProcesser">The error processer to use.</param>
        /// <remarks>
        /// <para>
        /// This will add the following internal consistency checks:
        /// </para>
        /// <list type="bullet">
        /// <item>
        /// <description>Each queue definitition is used by at least one project.</description>
        /// </item>
        /// </list>
        /// </remarks>
        private void ValidateConfiguration(Configuration value, IConfigurationErrorProcesser errorProcesser)
        {
            var rootTrace = ConfigurationTrace.Start(value);

            // Validate the security manager - need to do this first
            if (value.SecurityManager is IConfigurationValidation)
            {
                (value.SecurityManager as IConfigurationValidation).Validate(value, rootTrace, errorProcesser);
            }

            // Validate all the projects
            foreach (IProject project in value.Projects)
            {
                if (project is IConfigurationValidation)
                {
                    (project as IConfigurationValidation).Validate(value, rootTrace, errorProcesser);
                }
            }

            // Validate all the queues
            foreach (IQueueConfiguration queue in value.QueueConfigurations)
            {
                if (queue is IConfigurationValidation)
                {
                    (queue as IConfigurationValidation).Validate(value, rootTrace, errorProcesser);
                }
            }
        }

        private class DefaultErrorProcesser
            : IConfigurationErrorProcesser
        {
            public void ProcessError(string message)
            {
                throw new ConfigurationException(message);
            }

            public void ProcessError(Exception error)
            {
                throw error;
            }

            public void ProcessWarning(string message)
            {
                Log.Warning(message);
            }

            public bool ProcessUnhandledNode(XmlNode node)
            {
                return false;
            }

            public void ProcessError(string message, params object[] args)
            {
                throw new ConfigurationException(string.Format(message,args)) ;
            }

            public void ProcessWarning(string message, params object[] args)
            {
                Log.Warning(message, args) ;
            }
        }
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.