⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 executioncontextimpl.cs

📁 工作流的基本资料(文档资料
💻 CS
字号:
using System;
using System.Collections;
using Iesi.Collections;
using log4net;
using NetBpm.Util.Client;
using NetBpm.Util.DB;
using NetBpm.Workflow.Definition;
using NetBpm.Workflow.Definition.Impl;
using NetBpm.Workflow.Delegation;
using NetBpm.Workflow.Log.Impl;
using NetBpm.Workflow.Organisation;
using NetBpm.Workflow.Organisation.EComp;
using NetBpm.Workflow.Scheduler;
using NetBpm.Workflow.Scheduler.EComp;
using NHibernate.Type;

namespace NetBpm.Workflow.Execution.Impl
{
	public class ExecutionContextImpl : IAssignmentContext, IDecisionContext, IForkContext, IActionContext, IJoinContext, IProcessInvocationContext, ITaskContext
	{
		private DbSession _dbSession = null;
		private IOrganisationSessionLocal _organisationComponent = null;
		private String _actorId = null;
		private String _previousActorId = null;
		private ProcessDefinitionImpl _processDefinition = null;
		private ProcessInstanceImpl _processInstance = null;
		private FlowImpl _flow = null;
		private NodeImpl _node = null;
		private LogImpl _logField = null;
		private IDictionary _configuration = null;
		private IActionContext _invokedProcessContext = null;
		private ArrayList _assignedFlows = null;
		private IList _forkedFlows = null;
		private static readonly ServiceLocator serviceLocator;
		private static readonly ILog log = LogManager.GetLogger(typeof (ExecutionContextImpl));

		static ExecutionContextImpl()
		{
			serviceLocator = ServiceLocator.Instance;
		}

		public DbSession DbSession
		{
			get { return _dbSession; }
		}

		public String ActorId
		{
			get { return this._actorId; }
		}

		public IActor Actor
		{
			get { return _organisationComponent.FindActorById(_actorId); }
		}

		public String PreviousActorId
		{
			get { return this._previousActorId; }
		}

		public LogImpl Log
		{
			get { return this._logField; }
			set { this._logField = value; }
		}

		public ArrayList AssignedFlows
		{
			get { return this._assignedFlows; }
			set { this._assignedFlows = value; }
		}

		public IList ForkedFlows
		{
			get { return this._forkedFlows; }
			set { this._forkedFlows = value; }
		}

		/// <summary> the default constructor is necessary for the ActorExpressionTest.</summary>
		public ExecutionContextImpl()
		{
		}

		public ExecutionContextImpl(String actorId, DbSession dbSession, IOrganisationSessionLocal organisationComponent)
		{
			this._actorId = actorId;
			this._dbSession = dbSession;
			this._organisationComponent = organisationComponent;
		}

		public ExecutionContextImpl(String actorId, FlowImpl flow, DbSession dbSession, IOrganisationSessionLocal organisationComponent)
		{
			this._actorId = actorId;
			this._flow = flow;
			this._processInstance = (ProcessInstanceImpl) flow.ProcessInstance;
			this._processDefinition = (ProcessDefinitionImpl) _processInstance.ProcessDefinition;
			this._dbSession = dbSession;
			this._organisationComponent = organisationComponent;
			this._assignedFlows = new ArrayList();
		}

		public ExecutionContextImpl(String actorId, ProcessInstanceImpl processInstance, DbSession dbSession, IOrganisationSessionLocal organisationComponent)
		{
			this._actorId = actorId;
			this._processInstance = processInstance;
			this._processDefinition = (ProcessDefinitionImpl) processInstance.ProcessDefinition;
			this._dbSession = dbSession;
			this._organisationComponent = organisationComponent;
			this._assignedFlows = new ArrayList();
		}

		public virtual IOrganisationSessionLocal GetOrganisationComponent()
		{
			return _organisationComponent;
		}

		public void SetActorAsPrevious()
		{
			this._previousActorId = this._actorId;
			this._actorId = null;
			this._flow.ActorId = null;
		}

		public virtual IActor GetPreviousActor()
		{
			return _organisationComponent.FindActorById(_previousActorId);
		}

		public IProcessDefinition GetProcessDefinition()
		{
			return this._processDefinition;
		}

		public void SetProcessDefinition(IProcessDefinition processDefinition)
		{
			this._processDefinition = (ProcessDefinitionImpl) processDefinition;
		}

		public virtual IProcessInstance GetProcessInstance()
		{
			return this._processInstance;
		}

		public void SetProcessInstance(IProcessInstance processInstance)
		{
			this._processInstance = (ProcessInstanceImpl) processInstance;
		}

		public IFlow GetFlow()
		{
			return this._flow;
		}

		public void SetFlow(IFlow flow)
		{
			this._flow = (FlowImpl) flow;
		}

		public INode GetNode()
		{
			return this._node;
		}

		public void SetNode(INode node)
		{
			this._node = (NodeImpl) node;
		}

		public virtual IDictionary GetConfiguration()
		{
			return this._configuration;
		}

		public void SetConfiguration(IDictionary configuration)
		{
			this._configuration = configuration;
		}

		public IActionContext GetInvokedProcessContext()
		{
			return this._invokedProcessContext;
		}

		public void SetInvokedProcessContext(IActionContext invokedProcessContext)
		{
			this._invokedProcessContext = invokedProcessContext;
		}

		public virtual Object GetAttribute(String name)
		{
			AttributeInstanceImpl attributeInstance = FindAttributeInstanceInScope(name);
			if (attributeInstance != null)
			{
				// attribute might not be available (a warning should have been logged previosly)
				return attributeInstance.GetValue();
			}
			return null;
		}

		public void SetAttribute(String name, Object valueObject)
		{
			AttributeInstanceImpl attributeInstance = FindAttributeInstanceInScope(name);
			if (attributeInstance != null)
			{
				// ignore if cannot find attribute instance (warning should have been logged prviously)
				attributeInstance.SetValue(valueObject);
				this.AddLogDetail(new AttributeUpdateImpl(attributeInstance));
			}
		}

		private const String queryFindAttributeInstanceByName = "select ai " +
			"from ai in class NetBpm.Workflow.Execution.Impl.AttributeInstanceImpl, " +
			"     f in class NetBpm.Workflow.Execution.Impl.FlowImpl " +
			"where ai.Scope = f.id " + "  and ai.Attribute.Name = ? " +
			"  and f.id = ? ";

		private AttributeInstanceImpl FindAttributeInstanceInScope(String attributeName)
		{
			AttributeInstanceImpl attributeInstance = null;
			FlowImpl scope = this._flow;
			while (attributeInstance == null)
			{
				Object[] values = new Object[] {attributeName, scope.Id};
				IType[] types = new IType[] {DbType.STRING, DbType.LONG};
				IEnumerator iter = _dbSession.Iterate(queryFindAttributeInstanceByName, values, types).GetEnumerator();
				if (iter.MoveNext())
				{
					attributeInstance = (AttributeInstanceImpl) iter.Current;
					if (iter.MoveNext())
					{
						throw new NetBpm.Util.DB.DbException("duplicate value");
					}
				}
				else
				{
					if (!scope.IsRootFlow())
					{
						scope = (FlowImpl) scope.Parent;
					}
					else
					{
						//throw new RuntimeException( "couldn't find attribute-instance '" + attributeName + "' in scope of flow '" + this.flow + "'" ); 
						// log a warning message (indicate that attribute supplied is not defined in attribute-instance in db)
						log.Warn("couldn't find attribute-instance '" + attributeName + "' in scope of flow '" + this._flow + "'");
						break;
					}
				}
			}
			return attributeInstance;
		}

		public void AddLog(String msg)
		{
			this.AddLogDetail(new MessageImpl(msg));
		}

		public void CreateLog(EventType eventType)
		{
			this._logField = _flow.CreateLog(eventType);
		}

		public void CreateLog(String actorId, EventType eventType)
		{
			this._logField = _flow.CreateLog(actorId, eventType);
		}

		public void AddLogDetail(LogDetailImpl logDetail)
		{
			if (_logField != null)
			{
				this._logField.Details.Add(logDetail);
				logDetail.Log = this._logField;
			}
		}

		public void Schedule(Job job)
		{
			Schedule(job, null);
		}

		public void Schedule(Job job, String reference)
		{
			ISchedulerSessionLocal schedulerComponent = null;
			try
			{
				schedulerComponent = (ISchedulerSessionLocal) serviceLocator.GetService(typeof (ISchedulerSessionLocal));
				job.Context = _processInstance.RootFlow;
				schedulerComponent.ScheduleJob(job, reference);
				serviceLocator.Release(schedulerComponent);
			}
			finally
			{
				serviceLocator.Release(schedulerComponent);
			}
		}

		public void ForkFlow(String transitionName)
		{
			ForkFlow(transitionName, null);
		}

		private const String queryFindLeavingTransitionByName = "select t " +
			"from t in class NetBpm.Workflow.Definition.Impl.TransitionImpl, " +
			"     n in class NetBpm.Workflow.Definition.Impl.NodeImpl " +
			"where n.id = ? " +
			"  and t.From.id = n.id " +
			"  and t.Name = ? ";

		public void ForkFlow(String transitionName, IDictionary attributeValues)
		{
			// find the transition
			TransitionImpl transition = null;
			Object[] values = new Object[] {_node.Id, transitionName};
			IType[] types = new IType[] {DbType.LONG, DbType.STRING};
			try
			{
				transition = (TransitionImpl) _dbSession.FindOne(queryFindLeavingTransitionByName, values, types);
			}
			catch (NotUniqueException e)
			{
				throw new SystemException("transition with name '" + transitionName + "' was not found for creating sub-flow on fork '" + _node.Name + "' : " + e.Message);
			}
			ForkFlow(transition, attributeValues);
		}

		public void ForkFlow(TransitionImpl transition, IDictionary attributeValues)
		{
			// create the subflow 
			FlowImpl subFlow = new FlowImpl(transition.Name, _flow, (ProcessBlockImpl) _node.ProcessBlock);
			_flow.Children.Add(subFlow);

			// save it 
			_dbSession.Save(subFlow);

			// store the attributeValues
			this._flow = subFlow;
			StoreAttributeValues(attributeValues);
			this._flow = (FlowImpl) this._flow.Parent;

			// add the transition and the flow to the set of created sub-flows
			this._forkedFlows.Add(new ForkedFlow(transition, subFlow));
		}

		public void StoreRole(String authenticatedActorId, ActivityStateImpl activityState)
		{
			String role = activityState.ActorRoleName;
			if ((Object) role != null)
			{
				IActor authenticatedActor = OrganisationUtil.Instance.GetActor(authenticatedActorId);
				log.Debug("assigning " + authenticatedActor + " to role " + role);
				SetAttribute(role, authenticatedActor);
			}
		}

		public void StoreAttributeValues(IDictionary attributeValues)
		{
			if (attributeValues != null)
			{
				// loop over all provided attributeValues
				IEnumerator iter = attributeValues.GetEnumerator();
				while (iter.MoveNext())
				{
					DictionaryEntry entry = (DictionaryEntry) iter.Current;
					String attributeName = (String) entry.Key;
					// and store it
					SetAttribute(attributeName, entry.Value);
				}
			}
		}

		public void CheckAccess(IDictionary attributeValues, StateImpl state)
		{
			IDictionary fields = new Hashtable();

			// first we check if a value is supplied for all required fields
			IEnumerator iter = state.Fields.GetEnumerator();
			log.Debug(iter);
			while (iter.MoveNext())
			{
				FieldImpl field = (FieldImpl) iter.Current;
				String attributeName = field.Attribute.Name;
				fields[attributeName] = field;

				// if a field is found required and no attribute value is supplied throw 
				// RequiredFieldException 
				log.Debug(field);
				log.Debug(field.Access);
				if ((FieldAccessHelper.IsRequired(field.Access)) && (attributeValues == null))
				{
					throw new RequiredFieldException(field);
				}
				// OR
				// if field is found required and attribute value of it is not available
				// throw RequiredFieldException
				if ((FieldAccessHelper.IsRequired(field.Access)) && (attributeValues != null) && (!attributeValues.Contains(attributeName)))
				{
					throw new RequiredFieldException(field);
				}
			}

			// then we check if the access of all supplied values is writable
			IList attributeNamesToBeRemoved = new ArrayList(); // store attribute name of attribute to be removed
			if (attributeValues != null)
			{
				iter = attributeValues.GetEnumerator();
				while (iter.MoveNext())
				{
					DictionaryEntry entry = (DictionaryEntry) iter.Current;
					String attributeName = (String) entry.Key;

					FieldImpl field = (FieldImpl) fields[attributeName];
					if ((field != null) && (!FieldAccessHelper.IsWritable(field.Access)))
					{
						log.Warn("ignoring attributeValue for unwritable attribute '" + attributeName + "'");
						// commented out cause will result in ConcurrentModificationException
						// instead copy its attribute name and remove later OR do a deep copy of the
						// attributeValues so there is one set that gets iterated and another that 
						//gets deleted???
						//attributeValues.remove( attributeName );
						attributeNamesToBeRemoved.Add(attributeName);
					}
				}
				// now removed collected to be removed attribute
				IEnumerator itr = attributeNamesToBeRemoved.GetEnumerator();
				while (itr.MoveNext())
				{
					String an = (String) itr.Current;
					attributeValues.Remove(an);
				}
			}
		}

		private const String queryFindConcurrentFlows = "select cf " +
			"from cf in class NetBpm.Workflow.Execution.Impl.FlowImpl," +
			"     f in class NetBpm.Workflow.Execution.Impl.FlowImpl " +
			"where f.id = ? " + "  and cf.Parent = f.Parent " +
			"  and cf.EndNullable is null " + "  and cf.id <> f.id ";

		public IList GetOtherActiveConcurrentFlows()
		{
			return _dbSession.Find(queryFindConcurrentFlows, _flow.Id, DbType.LONG);
		}

		private const String queryFindTransitionByName = "select t " +
			"from t in class NetBpm.Workflow.Definition.Impl.TransitionImpl, " +
			"     s in class NetBpm.Workflow.Definition.Impl.StateImpl " +
			"where t.From = s.id " +
			"  and t.Name = ? " +
			"  and s.id = ? ";

		/* package private */

		internal virtual TransitionImpl GetTransition(String transitionName, StateImpl state, DbSession dbSession)
		{
			TransitionImpl transition = null;
			if ((Object) transitionName != null)
			{
				Object[] values = new Object[] {transitionName, state.Id};
				IType[] types = new IType[] {DbType.STRING, DbType.LONG};
				transition = (TransitionImpl) dbSession.FindOne(queryFindTransitionByName, values, types);
			}
			else
			{
				ISet leavingTransitions = state.LeavingTransitions;
				if (leavingTransitions.Count == 1)
				{
					IEnumerator transEnum = leavingTransitions.GetEnumerator();
					transEnum.MoveNext();
					transition = (TransitionImpl) transEnum.Current;
				}
				else
				{
					throw new SystemException("no transitionName was specified : this is only allowed if the state (" + state.Name + ") has exactly 1 leaving transition (" + leavingTransitions.Count + ")");
				}
			}
			return transition;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -