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

📄 executionengineimpl.cs

📁 工作流的基本资料(文档资料
💻 CS
📖 第 1 页 / 共 2 页
字号:
using System;
using System.Collections;
using Iesi.Collections;
using log4net;
using NetBpm.Util.DB;
using NetBpm.Workflow.Definition;
using NetBpm.Workflow.Definition.Impl;
using NetBpm.Workflow.Delegation.Impl;
using NetBpm.Workflow.Log.Impl;
using NetBpm.Workflow.Organisation;
using NHibernate.Type;

namespace NetBpm.Workflow.Execution.Impl
{
	public class ExecutionEngineImpl
	{
		private static readonly DelegationHelper delegationHelper = DelegationHelper.Instance;
		private static readonly ExecutionEngineImpl instance = new ExecutionEngineImpl();
		private static readonly ActorExpressionResolver actorExpressionResolver = ActorExpressionResolver.Instance;
		private static readonly ILog log = LogManager.GetLogger(typeof (ExecutionEngineImpl));

		/// <summary> gets the singleton instance.</summary>
		public static ExecutionEngineImpl Instance
		{
			get { return instance; }
		}

		private ExecutionEngineImpl()
		{
		}

		private const String queryFindActionsByEventType = "select a from a in class NetBpm.Workflow.Definition.Impl.ActionImpl " +
			"where a.EventType = ? " +
			"  and a.DefinitionObjectId = ? ";

		public void RunActionsForEvent(EventType eventType, Int64 definitionObjectId, ExecutionContextImpl executionContext)
		{
			log.Debug("processing '" + eventType + "' events for executionContext " + executionContext);

			DbSession dbSession = executionContext.DbSession;

			// find all actions for definitionObject on the given eventType
			Object[] values = new Object[] {eventType, definitionObjectId};
			IType[] types = new IType[] {DbType.INTEGER, DbType.LONG};

			IList actions = dbSession.Find(queryFindActionsByEventType, values, types);
			IEnumerator iter = actions.GetEnumerator();
			log.Debug("list" + actions);
			while (iter.MoveNext())
			{
				ActionImpl action = (ActionImpl) iter.Current;
				log.Debug("action: " + action);
				delegationHelper.DelegateAction(action.ActionDelegation, executionContext);
			}
			log.Debug("ende runActionsForEvent!");
		}

		public void ProcessTransition(TransitionImpl transition, ExecutionContextImpl executionContext)
		{
			log.Debug("processing transition '" + transition + "' for flow '" + executionContext.GetFlow() + "'");

			// trigger all the actions scheduled for this transition
			RunActionsForEvent(EventType.TRANSITION, transition.Id, executionContext);

			// first set the state of the execution context and the flow
			// to the node that is going to be processed 
			FlowImpl flow = (FlowImpl) executionContext.GetFlow();
			NodeImpl destination = (NodeImpl) transition.To;
			flow.Node = destination;
			executionContext.SetNode(destination);

			// note : I want to keep the engine methods grouped in this class, that is why I
			// didn't use inheritance but used an instanceof-switch instead.
			if (destination is ActivityStateImpl)
			{
				ProcessActivityState((ActivityStateImpl) destination, executionContext);
			}
			else if (destination is ProcessStateImpl)
			{
				ProcessProcessState((ProcessStateImpl) destination, executionContext);
			}
			else if (destination is DecisionImpl)
			{
				ProcessDecision((DecisionImpl) destination, executionContext);
			}
			else if (destination is ForkImpl)
			{
				ProcessFork((ForkImpl) destination, executionContext);
			}
			else if (destination is JoinImpl)
			{
				ProcessJoin((JoinImpl) destination, executionContext);
			}
			else if (destination is EndStateImpl)
			{
				ProcessEndState((EndStateImpl) destination, executionContext);
			}
			else
			{
				throw new SystemException("");
			}
		}

		public void ProcessActivityState(ActivityStateImpl activityState, ExecutionContextImpl executionContext)
		{
			// first set the flow-state to the activity-state  
			FlowImpl flow = (FlowImpl) executionContext.GetFlow();

			log.Debug("processing activity-state '" + activityState + "' for flow '" + executionContext.GetFlow() + "'");

			// execute the actions scheduled for this assignment
			RunActionsForEvent(EventType.BEFORE_ACTIVITYSTATE_ASSIGNMENT, activityState.Id, executionContext);

			String actorId = null;
			String role = activityState.ActorRoleName;
			DelegationImpl assignmentDelegation = activityState.AssignmentDelegation;

			if (assignmentDelegation != null)
			{
				// delegate the assignment of the activity-state
				actorId = delegationHelper.DelegateAssignment(activityState.AssignmentDelegation, executionContext);
				if ((Object) actorId == null)
				{
					throw new SystemException("invalid process definition : assigner of activity-state '" + activityState.Name + "' returned null instead of a valid actorId");
				}
				log.Debug("setting actor of flow " + flow + " to " + actorId);
			}
			else
			{
				// get the assigned actor from the specified attribute instance
				if ((Object) role != null)
				{
					IActor actor = (IActor) executionContext.GetAttribute(role);
					if (actor == null)
					{
						throw new SystemException("invalid process definition : activity-state must be assigned to role '" + role + "' but that attribute instance is null");
					}
					actorId = actor.Id;
				}
				else
				{
					throw new SystemException("invalid process definition : activity-state '" + activityState.Name + "' does not have an assigner or a role");
				}
			}

			flow.ActorId = actorId;

			// If necessary, store the actor in the role
			if (((Object) role != null) && (assignmentDelegation != null))
			{
				executionContext.StoreRole(actorId, activityState);
			}

			// the client of performActivity wants to be Informed of the people in charge of the process
			executionContext.AssignedFlows.Add(flow);

			// log the assignment
			executionContext.CreateLog(actorId, EventType.AFTER_ACTIVITYSTATE_ASSIGNMENT);
			executionContext.AddLogDetail(new ObjectReferenceImpl(activityState));

			// execute the actions scheduled for this assignment
			RunActionsForEvent(EventType.AFTER_ACTIVITYSTATE_ASSIGNMENT, activityState.Id, executionContext);
		}

		public void ProcessProcessState(ProcessStateImpl processState, ExecutionContextImpl executionContext)
		{
			// TODO : try to group similarities between this method and ExecutionComponentImpl.startProcessInstance and 
			//        group them in a common method 

			// provide a convenient local var for the database session
			DbSession dbSession = executionContext.DbSession;

			// get the sub-process-definition and its start-state    
			ProcessDefinitionImpl subProcessDefinition = (ProcessDefinitionImpl) processState.SubProcess;
			StartStateImpl startState = (StartStateImpl) subProcessDefinition.StartState;

			log.Info("processState '" + processState.Name + "' starts an instance of process '" + subProcessDefinition.Name + "'...");

			// get the actor that is supposed to start this process instance
			IActor subProcessStarter = actorExpressionResolver.ResolveArgument(processState.ActorExpression, executionContext);
			String subProcessStarterId = subProcessStarter.Id;

			// create the process-instance
			ProcessInstanceImpl subProcessInstance = new ProcessInstanceImpl(subProcessStarterId, subProcessDefinition);
			FlowImpl rootFlow = (FlowImpl) subProcessInstance.RootFlow;

			// attach the subProcesInstance to the parentFlow
			FlowImpl superProcessFlow = (FlowImpl) executionContext.GetFlow();
			superProcessFlow.SetSubProcessInstance(subProcessInstance);
			subProcessInstance.SuperProcessFlow = superProcessFlow;

			// create the execution context for the sub-process 
			ExecutionContextImpl subExecutionContext = new ExecutionContextImpl(subProcessStarterId, rootFlow, dbSession, executionContext.GetOrganisationComponent());

			// save the process instance to allow hibernate queries    
			dbSession.Save(subProcessInstance);

			// add the log
			executionContext.CreateLog(EventType.SUB_PROCESS_INSTANCE_START);
			executionContext.AddLogDetail(new ObjectReferenceImpl(subProcessInstance));

			// delegate the attributeValues
			Object[] processInvocationData = delegationHelper.DelegateProcessInvocation(processState.ProcessInvokerDelegation, subExecutionContext);

⌨️ 快捷键说明

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