1766 lines · 74.0 KB · C#
RawDownload
//******************************************************************************************************//  AdapterBase.cs - Gbtc////  Copyright © 2010, Grid Protection Alliance.  All Rights Reserved.////  Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See//  the NOTICE file distributed with this work for additional information regarding copyright ownership.//  The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may//  not use this file except in compliance with the License. You may obtain a copy of the License at:////      http://www.opensource.org/licenses/eclipse-1.0.php////  Unless agreed to in writing, the subject software distributed under the License is distributed on an//  "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the//  License for the specific language governing permissions and limitations.////  Code Modification History://  ----------------------------------------------------------------------------------------------------//  09/02/2010 - J. Ritchie Carroll//       Generated original version of source code.////****************************************************************************************************** using GSF.Units;using System;using System.Collections.Generic;using System.Collections.ObjectModel;using System.ComponentModel;using System.Data;using System.Globalization;using System.Linq;using System.Runtime.CompilerServices;using System.Text;using System.Text.RegularExpressions;using System.Threading; namespace GSF.TimeSeries.Adapters{    /// <summary>    /// Represents the base class for any adapter.    /// </summary>    public abstract class AdapterBase : IAdapter    {        #region [ Members ]         // Constants        private const int DefaultMeasurementReportingInterval = 100000;         /// <summary>        /// Default initialization timeout.        /// </summary>        public const int DefaultInitializationTimeout = 15000;         // Events         /// <summary>        /// Provides status messages to consumer.        /// </summary>        /// <remarks>        /// <see cref="EventArgs{T}.Argument"/> is new status message.        /// </remarks>        public event EventHandler<EventArgs<string>> StatusMessage;         /// <summary>        /// Event is raised when there is an exception encountered while processing.        /// </summary>        /// <remarks>        /// <see cref="EventArgs{T}.Argument"/> is the exception that was thrown.        /// </remarks>        public event EventHandler<EventArgs<Exception>> ProcessException;         /// <summary>        /// Event is raised when <see cref="InputMeasurementKeys"/> are updated.        /// </summary>        public event EventHandler InputMeasurementKeysUpdated;         /// <summary>        /// Event is raised when <see cref="OutputMeasurements"/> are updated.        /// </summary>        public event EventHandler OutputMeasurementsUpdated;         /// <summary>        /// Event is raised when <see cref="AdapterBase"/> is disposed.        /// </summary>        /// <remarks>        /// If an adapter references another adapter by enumerating the <see cref="Parent"/> collection, this        /// event should be monitored to release the reference.        /// </remarks>        public event EventHandler Disposed;         // Fields        private string m_name;        private uint m_id;        private string m_connectionString;        private IAdapterCollection m_parent;        private Dictionary<string, string> m_settings;        private DataSet m_dataSource;        private int m_initializationTimeout;        private bool m_autoStart;        private bool m_processMeasurementFilter;        private ManualResetEvent m_initializeWaitHandle;        private AutoResetEvent[] m_externalEventHandles;        private int m_externalEventTimeout;        private MeasurementKey[] m_inputMeasurementKeys;        private IMeasurement[] m_outputMeasurements;        private List<MeasurementKey> m_inputMeasurementKeysHash;        private long m_processedMeasurements;        private int m_measurementReportingInterval;        private bool m_enabled;        private long m_startTime;        private long m_stopTime;        private DateTime m_startTimeConstraint;        private DateTime m_stopTimeConstraint;        private int m_processingInterval;        private int m_hashCode;        private bool m_initialized;        private bool m_disposed;         #endregion         #region [ Constructors ]         /// <summary>        /// Constructs a new instance of the <see cref="AdapterBase"/>.        /// </summary>        protected AdapterBase()        {            m_name = this.GetType().Name;            m_settings = new Dictionary<string, string>();            m_startTimeConstraint = DateTime.MinValue;            m_stopTimeConstraint = DateTime.MaxValue;            m_processingInterval = -1;            GenHashCode();             // Create wait handle to use for adapter initialization            m_initializeWaitHandle = new ManualResetEvent(false);            m_initializationTimeout = DefaultInitializationTimeout;        }         /// <summary>        /// Releases the unmanaged resources before the <see cref="AdapterBase"/> object is reclaimed by <see cref="GC"/>.        /// </summary>        ~AdapterBase()        {            Dispose(false);        }         #endregion         #region [ Properties ]         /// <summary>        /// Gets or sets the name of this <see cref="AdapterBase"/>.        /// </summary>        /// <remarks>        /// Derived classes should provide a name for the adapter.        /// </remarks>        public virtual string Name        {            get            {                return m_name;            }            set            {                m_name = value;                GenHashCode();            }        }         /// <summary>        /// Gets or sets numeric ID associated with this <see cref="AdapterBase"/>.        /// </summary>        public virtual uint ID        {            get            {                return m_id;            }            set            {                m_id = value;                GenHashCode();            }        }         /// <summary>        /// Gets or sets key/value pair connection information specific to this <see cref="AdapterBase"/>.        /// </summary>        /// <remarks>        /// <para>        /// Example connection string using manually defined measurements:<br/>        /// <c>inputMeasurementKeys={P1:1245;P1:1247;P2:1335};</c><br/>        /// <c>outputMeasurements={P3:1345,60.0,1.0;P3:1346;P3:1347}</c><br/>        /// When defined manually, elements in key:<br/>        /// * inputMeasurementKeys are defined as "ArchiveSource:PointID"<br/>        /// * outputMeasurements are defined as "ArchiveSource:PointID,Adder,Multiplier", the adder and multiplier are optional        /// defaulting to 0.0 and 1.0 respectively.        /// <br/>        /// </para>        /// <para>        /// Example connection string using measurements defined in a <see cref="DataSource"/> table:<br/>        /// <c>inputMeasurementKeys={FILTER ActiveMeasurements WHERE Company='GSF' AND SignalType='FREQ' ORDER BY ID};</c><br/>        /// <c>outputMeasurements={FILTER ActiveMeasurements WHERE SignalType IN ('IPHA','VPHA') AND Phase='+'}</c><br/>        /// <br/>        /// Basic filtering syntax is as follows:<br/>        /// <br/>        ///     {FILTER &lt;TableName&gt; WHERE &lt;Expression&gt; [ORDER BY &lt;SortField&gt;]}<br/>        /// <br/>        /// Source tables are expected to have at least the following fields:<br/>        /// <list type="table">        ///     <listheader>        ///         <term>Name</term>        ///         <term>Type</term>        ///         <description>Description.</description>        ///     </listheader>        ///     <item>        ///         <term>ID</term>        ///         <term>NVARCHAR</term>        ///         <description>Measurement key formatted as: ArchiveSource:PointID.</description>        ///     </item>        ///     <item>        ///         <term>PointTag</term>        ///         <term>NVARCHAR</term>        ///         <description>Point tag of measurement.</description>        ///     </item>        ///     <item>        ///         <term>Adder</term>        ///         <term>FLOAT</term>        ///         <description>Adder to apply to value, if any (default to 0.0).</description>        ///     </item>        ///     <item>        ///         <term>Multiplier</term>        ///         <term>FLOAT</term>        ///         <description>Multipler to apply to value, if any (default to 1.0).</description>        ///     </item>        /// </list>        /// </para>        /// </remarks>        public virtual string ConnectionString        {            get            {                return m_connectionString;            }            set            {                m_connectionString = value;                 // Preparse settings upon connection string assignment                if (m_connectionString.IsNullOrWhiteSpace())                    m_settings = new Dictionary<string, string>();                else                    m_settings = m_connectionString.ParseKeyValuePairs();            }        }         /// <summary>        /// Gets a read-only reference to the collection that contains this <see cref="AdapterBase"/>.        /// </summary>        public ReadOnlyCollection<IAdapter> Parent        {            get            {                return new ReadOnlyCollection<IAdapter>(m_parent);            }        }         /// <summary>        /// Gets or sets <see cref="DataSet"/> based data source available to this <see cref="AdapterBase"/>.        /// </summary>        public virtual DataSet DataSource        {            get            {                return m_dataSource;            }            set            {                m_dataSource = value;            }        }         /// <summary>        /// Gets or sets maximum time system will wait during <see cref="Start"/> for initialization.        /// </summary>        /// <remarks>        /// Set to <see cref="Timeout.Infinite"/> to wait indefinitely.        /// </remarks>        public virtual int InitializationTimeout        {            get            {                return m_initializationTimeout;            }            set            {                m_initializationTimeout = value;            }        }         /// <summary>        /// Gets or sets flag indicating if adapter should automatically start or otherwise connect on demand.        /// </summary>        public virtual bool AutoStart        {            get            {                return m_autoStart;            }            set            {                m_autoStart = value;            }        }         /// <summary>        /// Gets or sets flag that determines if measurements being queued for processing should be tested to see if they are in the <see cref="InputMeasurementKeys"/>.        /// </summary>        public virtual bool ProcessMeasurementFilter        {            get            {                return m_processMeasurementFilter;            }            set            {                m_processMeasurementFilter = value;            }        }         /// <summary>        /// Gets or sets primary keys of input measurements the <see cref="AdapterBase"/> expects, if any.        /// </summary>        /// <remarks>        /// If your adapter needs to receive all measurements, you must explicitly set InputMeasurementKeys to null.        /// </remarks>        [ConnectionStringParameter,        DefaultValue(null),        Description("Defines primary keys of input measurements the adapter expects; can be one of a filter expression, measurement key, point tag or Guid.")]        public virtual MeasurementKey[] InputMeasurementKeys        {            get            {                return m_inputMeasurementKeys;            }            set            {                m_inputMeasurementKeys = value;                 // Update input key lookup hash table                if (value != null && value.Length > 0)                {                    m_inputMeasurementKeysHash = new List<MeasurementKey>(value);                    m_inputMeasurementKeysHash.Sort();                }                else                    m_inputMeasurementKeysHash = null;                 OnInputMeasurementKeysUpdated();            }        }         /// <summary>        /// Gets or sets output measurements that the <see cref="AdapterBase"/> will produce, if any.        /// </summary>        [ConnectionStringParameter,        DefaultValue(null),        Description("Defines primary keys of output measurements the adapter expects; can be one of a filter expression, measurement key, point tag or Guid.")]        public virtual IMeasurement[] OutputMeasurements        {            get            {                return m_outputMeasurements;            }            set            {                m_outputMeasurements = value;                OnOutputMeasurementsUpdated();            }        }         /// <summary>        /// Gets the total number of measurements handled thus far by the <see cref="AdapterBase"/>.        /// </summary>        public virtual long ProcessedMeasurements        {            get            {                return m_processedMeasurements;            }        }         /// <summary>        /// Gets or sets the measurement reporting interval.        /// </summary>        /// <remarks>        /// This is used to determined how many measurements should be processed before reporting status.        /// </remarks>        public virtual int MeasurementReportingInterval        {            get            {                return m_measurementReportingInterval;            }            set            {                m_measurementReportingInterval = value;            }        }         /// <summary>        /// Gets or sets flag indicating if the adapter has been initialized successfully.        /// </summary>        public virtual bool Initialized        {            get            {                return m_initialized;            }            set            {                m_initialized = value;                 // When initialization is complete we send notification                if ((object)m_initializeWaitHandle != null)                {                    if (value)                        m_initializeWaitHandle.Set();                    else                        m_initializeWaitHandle.Reset();                }            }        }         /// <summary>        /// Gets or sets enabled state of this <see cref="AdapterBase"/>.        /// </summary>        /// <remarks>        /// Base class simply starts or stops <see cref="AdapterBase"/> based on flag value. Derived classes should        /// extend this if needed to enable or disable operational state of the adapter based on flag value.        /// </remarks>        public bool Enabled        {            get            {                return m_enabled;            }            set            {                if (m_enabled && !value)                    Stop();                else if (!m_enabled && value)                    Start();            }        }         /// <summary>        /// Gets the UTC time this <see cref="AdapterBase"/> was started.        /// </summary>        public Ticks StartTime        {            get            {                return m_startTime;            }        }         /// <summary>        /// Gets the UTC time this <see cref="AdapterBase"/> was stopped.        /// </summary>        public Ticks StopTime        {            get            {                return m_stopTime;            }        }         /// <summary>        /// Gets the flag indicating if this adapter supports temporal processing.        /// </summary>        public abstract bool SupportsTemporalProcessing        {            get;        }         /// <summary>        /// Gets the start time temporal procesing constraint defined by call to <see cref="SetTemporalConstraint"/>.        /// </summary>        /// <remarks>        /// This value will be <see cref="DateTime.MinValue"/> when start time constraint is not set - meaning the adapter        /// is processing data in real-time.        /// </remarks>        public virtual DateTime StartTimeConstraint        {            get            {                return m_startTimeConstraint;            }

Lines 1–500 of 1766.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t