📄 executionengineimpl.cs
字号:
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 + -