//******************************************************************************************************
// Adapter.cs - Gbtc
//
// Copyright © 2012, 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 MIT License (MIT), 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/MIT
//
// 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/23/2010 - Pinal C. Patel
// Generated original version of source code.
// 11/19/2010 - Pinal C. Patel
// Removed the persistence of Enabled property to the config file.
// 11/24/2010 - Pinal C. Patel
// Modified Name property to use SettingsCategory instead of Type name.
// 12/07/2010 - Pinal C. Patel
// Updated PersistSettings property to default to false instead of true.
// 03/08/2011 - Pinal C. Patel
// Added StatusUpdate and Disposed events.
// Added Type and File properties to support serialized adapter instances.
// Added attributes to fields and properties to enable serialization of derived type instances.
// 04/05/2011 - Pinal C. Patel
// Changed properties Type to TypeName and File to HostFile to avoid naming conflict.
// Modified Name property to use the file name (no extension) from HostFile property if available.
// 04/08/2011 - Pinal C. Patel
// Added ExecutionException event.
// Renamed StatusUpdate event to StatusMessage.
// 05/11/2011 - Pinal C. Patel
// Modified OnStatusUpdate() method to allow for parameterized arguments.
// 09/21/2011 - J. Ritchie Carroll
// Added Mono implementation exception regions.
// 01/18/2012 - Pinal C. Patel
// Added DataContract attribute to prevent serialization of events when serializing using
// DataContractSerializer
// 12/13/2012 - Starlynn Danyelle Gilliam
// Modified Header.
//
//******************************************************************************************************
using System;
using System.ComponentModel;
using System.Configuration;
using System.Runtime.Serialization;
using System.Text;
using System.Xml.Serialization;
using GSF.IO;
namespace GSF.Adapters
{
///
/// Represents an adapter that could execute in isolation in a separate .
///
///
///
[Serializable, DataContract(Namespace = "")]
public class Adapter : MarshalByRefObject, IAdapter
{
#region [ Members ]
// Fields
[NonSerialized]
private DateTime m_created;
[NonSerialized]
private string m_hostFile;
[NonSerialized]
private bool m_persistSettings;
[NonSerialized]
private string m_settingsCategory;
[NonSerialized]
private bool m_enabled;
[NonSerialized]
private bool m_disposed;
[NonSerialized]
private bool m_initialized;
// Events
///
/// Occurs when the wants to provide a status update.
///
///
/// is the .
/// is the update message.
///
public event EventHandler> StatusUpdate;
///
/// Occurs when the encounters an during execution.
///
///
/// is the text that describes the activity that was being performed by the .
/// is the encountered .
///
public event EventHandler> ExecutionException;
///
/// Occurs when is disposed.
///
public event EventHandler Disposed;
#endregion
#region [ Constructors ]
///
/// Initializes a new instance of the .
///
public Adapter()
{
m_created = DateTime.UtcNow;
m_settingsCategory = this.GetType().Name;
}
///
/// Releases the unmanaged resources before the is reclaimed by .
///
~Adapter()
{
Dispose(false);
}
#endregion
#region [ Properties ]
///
/// Gets or sets the text representation of the 's .
///
///
/// This can be used for looking up the of the when deserializing it using .
///
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual string TypeName
{
get
{
Type type = this.GetType();
return string.Format("{0}, {1}", type.FullName, type.Assembly.GetName().Name);
}
set
{
// Ignore
}
}
///
/// Gets or sets the path to the file where the is housed.
///
///
/// This can be used to update the when changes are made to the file where it is housed.
///
[XmlIgnore, Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public virtual string HostFile
{
get
{
return m_hostFile;
}
set
{
m_hostFile = value;
}
}
///
/// Gets or sets a boolean value that indicates whether the is currently enabled.
///
[XmlIgnore]
public virtual bool Enabled
{
get
{
return m_enabled;
}
set
{
m_enabled = value;
}
}
///
/// Gets a flag that indicates whether the object has been disposed.
///
[XmlIgnore]
public bool IsDisposed
{
get
{
return m_disposed;
}
}
///
/// Gets or sets a boolean value that indicates whether settings are to be saved to the config file.
///
[XmlIgnore]
public virtual bool PersistSettings
{
get
{
return m_persistSettings;
}
set
{
m_persistSettings = value;
}
}
///
/// Gets or sets the category under which settings are to be saved to the config file if the property is set to true.
///
/// The value being assigned is a null or empty string.
[XmlIgnore]
public virtual string SettingsCategory
{
get
{
return m_settingsCategory;
}
set
{
if (string.IsNullOrEmpty(value))
throw new ArgumentNullException(nameof(value));
m_settingsCategory = value;
}
}
///
/// Gets the memory utilization of the in bytes if executing in a separate , otherwise .
///
///
///
/// gets updated only after a full blocking collection by (e.g. ).
///
///
/// This method always returns under Mono deployments.
///
///
public double MemoryUsage
{
get
{
#if !MONO
if (!Domain.IsDefaultAppDomain() && AppDomain.MonitoringIsEnabled)
// Both app domain isolation and app domain resource monitoring is enabled.
return Domain.MonitoringSurvivedMemorySize;
#endif
return double.NaN;
}
}
///
/// Gets the % processor utilization of the if executing in a separate otherwise .
///
///
/// This method always returns under Mono deployments.
///
public double ProcessorUsage
{
get
{
#if !MONO
if (!Domain.IsDefaultAppDomain() && AppDomain.MonitoringIsEnabled)
// Both app domain isolation and app domain resource monitoring is enabled.
return Domain.MonitoringTotalProcessorTime.TotalSeconds / Ticks.ToSeconds(DateTime.UtcNow.Ticks - m_created.Ticks) / Environment.ProcessorCount * 100;
#endif
return double.NaN;
}
}
///
/// Gets the unique identifier of the .
///
public virtual string Name
{
get
{
if (string.IsNullOrEmpty(m_hostFile))
return m_settingsCategory;
return FilePath.GetFileNameWithoutExtension(m_hostFile);
}
}
///
/// Gets the descriptive status of the .
///
public virtual string Status
{
get
{
StringBuilder status = new StringBuilder();
status.Append(" Adapter domain: ");
status.Append(Domain.FriendlyName);
status.AppendLine();
status.Append(" Adapter state: ");
status.Append(Enabled ? "Enabled" : "Disabled");
status.AppendLine();
status.Append(" Memory usage: ");
status.Append(double.IsNaN(MemoryUsage) ? "Not tracked" : MemoryUsage.ToString("0 bytes"));
status.AppendLine();
status.Append(" Processor usage: ");
status.Append(double.IsNaN(ProcessorUsage) ? "Not tracked" : ProcessorUsage.ToString("0'%'"));
status.AppendLine();
return status.ToString();
}
}
///
/// Gets the in which the is executing.
///
public virtual AppDomain Domain
{
get
{
return AppDomain.CurrentDomain;
}
}
#endregion
#region [ Methods ]
///
/// Releases all the resources used by the .
///
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
///
/// Initializes the .
///
public virtual void Initialize()
{
if (!m_initialized)
{
LoadSettings(); // Load settings from the config file.
m_initialized = true; // Initialize only once.
}
}
///
/// Saves settings to the config file if the property is set to true.
///
/// has a value of null or empty string.
public virtual void SaveSettings()
{
if (m_persistSettings)
{
// Ensure that settings category is specified.
if (string.IsNullOrEmpty(m_settingsCategory))
throw new ConfigurationErrorsException("SettingsCategory property has not been set.");
}
}
///
/// Loads saved settings from the config file if the property is set to true.
///
/// has a value of null or empty string.
public virtual void LoadSettings()
{
if (m_persistSettings)
{
// Ensure that settings category is specified.
if (string.IsNullOrEmpty(m_settingsCategory))
throw new ConfigurationErrorsException("SettingsCategory property has not been set.");
}
}
///
/// Releases the unmanaged resources used by the and optionally releases the managed resources.
///
/// true to release both managed and unmanaged resources; false to release only unmanaged resources.
protected virtual void Dispose(bool disposing)
{
if (!m_disposed)
{
try
{
// This will be done regardless of whether the object is finalized or disposed.
if (disposing)
{
// This will be done only when the object is disposed by calling Dispose().
SaveSettings();
}
}
finally
{
m_disposed = true; // Prevent duplicate dispose.
OnDisposed(); // Raise dispose event.
}
}
}
///
/// Raises the event.
///
/// to send to event.
/// Update message to send to event.
/// Arguments to be used when formatting the .
protected virtual void OnStatusUpdate(UpdateType updateType, string updateMessage, params object[] args)
{
if ((object)StatusUpdate != null)
StatusUpdate(this, new EventArgs(updateType, string.Format(updateMessage, args)));
}
///
/// Raises the event.
///
/// Activity description to send to event.
/// Encountered to send to event.
protected virtual void OnExecutionException(string activityDescription, Exception encounteredException)
{
if ((object)ExecutionException != null)
ExecutionException(this, new EventArgs(activityDescription, encounteredException));
}
///
/// Raises the event.
///
protected virtual void OnDisposed()
{
if ((object)Disposed != null)
Disposed(this, EventArgs.Empty);
}
#endregion
}
}