protected SourceControllerAbstract(XmlNode node, int chainDepth, List <string> triggersInUse, int serverOffset, NgExecutionController executionController)
        {
            this.node                = node;
            this.triggersInUse       = triggersInUse;
            this.clientHub           = executionController?.clientHub;
            eventDistributor         = executionController?.eventDistributor;
            this.executionController = executionController;
            this.serverOffset        = serverOffset;
            name = node.Attributes["name"]?.Value;
            id   = node.Attributes["ID"]?.Value;

            dataSourceType   = node.Attributes["dataSource"]?.Value;
            flightSourceType = node.Attributes["flttype"]?.Value;

            executionNodeID = node.Attributes["executionNodeUuid"]?.Value;
            uuid            = node.Attributes["uuid"]?.Value;

            if ((flightSourceType != null && flightSourceType != "none") || node.Name == "amsdatadriven")
            {
                if (flightSourceType == "arr")
                {
                    flttype = FlightType.Arrival;
                }
                else if (flightSourceType == "dep")
                {
                    flttype = FlightType.Departure;
                }
                else
                {
                    flttype = FlightType.Both;
                }

                try {
                    if (node.Attributes["flightSetFrom"] != null)
                    {
                        flightSetFrom = int.Parse(node.Attributes["flightSetFrom"]?.Value);
                    }
                    else
                    {
                        flightSetFrom = -180;
                    }
                } catch (Exception) {
                    flightSetFrom = -180;
                }
                try {
                    if (node.Attributes["flightSetTo"] != null)
                    {
                        flightSetTo = int.Parse(node.Attributes["flightSetTo"]?.Value);
                    }
                    else
                    {
                        flightSetTo = 180;
                    }
                } catch (Exception) {
                    flightSetTo = 180;
                }
                try {
                    if (node.Attributes["refreshFlight"] != null)
                    {
                        refreshFlight = bool.Parse(node.Attributes["refreshFlight"]?.Value);
                    }
                    else
                    {
                        refreshFlight = false;
                    }
                } catch (Exception) {
                    refreshFlight = false;
                }
            }
            else
            {
                flttype = FlightType.None;
            }

            switch (dataSourceType)
            {
            case "CSV":
                dataFile            = node.Attributes["dataFile"]?.Value;
                dataSourceFileOrURL = node.Attributes["sourceType"]?.Value;
                dataRestURL         = node.Attributes["dataRestURL"]?.Value;
                break;

            case "Excel":
                dataFile      = node.Attributes["dataFile"]?.Value;
                excelSheet    = node.Attributes["excelSheet"]?.Value;
                excelRowStart = node.Attributes["excelRowStart"]?.Value;
                excelRowEnd   = node.Attributes["excelRowEnd"]?.Value;
                break;

            case "XML":
                dataFile            = node.Attributes["dataFile"]?.Value;
                dataRestURL         = node.Attributes["dataRestURL"]?.Value;
                repeatingElement    = node.Attributes["repeatingElement"]?.Value;
                dataSourceFileOrURL = node.Attributes["sourceType"]?.Value;
                try {
                    xmlToString = bool.Parse(node.Attributes["xmlToString"]?.Value);
                } catch (Exception) {
                    xmlToString = false;
                }
                break;

            case "JSON":
                dataFile            = node.Attributes["dataFile"]?.Value;
                dataRestURL         = node.Attributes["dataRestURL"]?.Value;
                dataSourceFileOrURL = node.Attributes["sourceType"]?.Value;
                repeatingElement    = node.Attributes["repeatingElement"]?.Value;
                break;

            case "DATABASE":
            case "MSSQL":
            case "MySQL":
            case "ORACLE":
                connStr = node.Attributes["connStr"]?.Value;
                sql     = node.Attributes["sql"]?.Value;
                dbType  = node.Attributes["sourceType"]?.Value;
                break;
            }

            dataSourceFileOrURL = dataSourceFileOrURL ?? "file";

            XmlNode filtersDefn = node.SelectSingleNode("./filter");

            if (filtersDefn != null)
            {
                /*
                 * At the top level, there is only one Expresssion, which it self can be a compound
                 * expression or a single data filter
                 *
                 * When the Expression itself is constucted, it recurssive creates all the Expression o
                 * filters configured under it
                 */

                // Cycle through the expressions types (and, or, not, xor) to see if any exist
                foreach (string eType in Expression.expressionTypes)
                {
                    XmlNode exprDefn = filtersDefn.SelectSingleNode($"./{eType}");
                    if (exprDefn != null)
                    {
                        expression = new Expression(exprDefn);
                    }
                }

                FilterFactory fact = new FilterFactory();
                // Cycle through the data filter types (and, or, not, xor) to see if any exist
                foreach (string fType in Expression.filterTypes)
                {
                    XmlNode filtDefn = filtersDefn.SelectSingleNode($"./{fType}");
                    if (filtDefn != null)
                    {
                        topLevelFilter = fact.GetFilter(filtDefn);
                    }
                }

                try {
                    filterTime = filtersDefn.Attributes["filterTime"]?.Value;
                } catch (Exception) {
                    filterTime = "post";
                }

                if (filterTime == null)
                {
                    filterTime = "post";
                }
            }

            // Add the chained controllers
            foreach (XmlNode chained in node.SelectNodes("./chained"))
            {
                chainedController.Add(new RateDrivenSourceController(chained, chainDepth++, triggersInUse, serverOffset, executionController));
            }
        }
 public TriggerEventDistributor(NgExecutionController executionController)
 {
     this.executionController = executionController;
     instance = this;
 }