using System;
using System.Collections.Generic;
using Core.Common.Base.Properties;
using log4net;
namespace Core.Common.Base.Service
{
///
/// Abstract class that can be used for performing activies (like calculations, data imports, data exports, etc.).
/// The regular workflow for completely performing an is: -> .
/// can be called for cancelling a running .
///
public abstract class Activity
{
public event EventHandler ProgressChanged;
private readonly ILog log = LogManager.GetLogger(typeof(Activity));
private string progressText;
///
/// Constructs a new .
///
protected Activity()
{
LogMessages = new List();
}
///
/// Gets or sets the name of the .
///
public virtual string Name { get; set; }
///
/// Gets or sets the of the .
///
public ActivityStatus Status { get; protected set; }
///
/// Gets or sets the progress text of the .
/// listeners are notified when the progress text is set.
///
public string ProgressText
{
get
{
return progressText;
}
protected set
{
progressText = value;
OnProgressChanged();
}
}
///
/// Gets or sets the collection of log messages of the (which is appended while performing the ).
///
public IList LogMessages { get; private set; }
///
/// This method runs the .
///
public void Run()
{
try
{
OnExecute();
if (Status == ActivityStatus.Failed ||
Status == ActivityStatus.Cancelled)
{
// keep this status
return;
}
}
catch (Exception e)
{
Status = ActivityStatus.Failed;
log.Error(e.Message);
return;
}
if (Status == ActivityStatus.Failed)
{
log.ErrorFormat(Resources.Activity_Run_Execution_of_0_has_failed, Name);
return;
}
Status = ActivityStatus.Executed;
}
///
/// This method cancels a running .
///
public void Cancel()
{
ChangeState(OnCancel, ActivityStatus.Cancelled);
}
///
/// This method finishes an that successfully ran.
/// Successfully ran activities can be identified by a not equal to or .
///
public void Finish()
{
if (Status != ActivityStatus.Failed && Status != ActivityStatus.Cancelled)
{
ChangeState(OnFinish, ActivityStatus.Finished);
}
}
///
/// Executes one step. This method will be called multiple times to allow for multiple
/// execution steps. After calling this method, will be set to
/// if no error has occurred.
///
///
/// Set to
/// when an error has occurred while executing.
///
protected abstract void OnExecute();
///
/// Activity has finished successfully. After calling this method,
/// will be set to if no error has occurred.
///
protected abstract void OnFinish();
///
/// Cancels current run. will change to
/// after this method has been called.
///
protected abstract void OnCancel();
private void OnProgressChanged()
{
if (ProgressChanged != null)
{
ProgressChanged(this, EventArgs.Empty);
}
}
private void ChangeState(Action transitionAction, ActivityStatus statusAfter)
{
try
{
transitionAction();
if (Status == ActivityStatus.Failed)
{
return;
}
}
catch (Exception e)
{
Status = ActivityStatus.Failed;
log.Error(e.Message);
return;
}
Status = statusAfter;
}
}
}