public IProcessInstance StartProcessInstance(String authenticatedActorId, Int64 processDefinitionId, IDictionary attributeValues, String transitionName, Relations relations, DbSession dbSession, IOrganisationSessionLocal organisationComponent) { ProcessInstanceImpl processInstance = null; // First check if the actor is allowed to start this instance authorizationHelper.CheckStartProcessInstance(authenticatedActorId, processDefinitionId, attributeValues, transitionName, dbSession); // get the process-definition and its start-state ProcessDefinitionImpl processDefinition = (ProcessDefinitionImpl) dbSession.Load(typeof (ProcessDefinitionImpl), processDefinitionId); StartStateImpl startState = (StartStateImpl) processDefinition.StartState; log.Info("actor '" + authenticatedActorId + "' starts an instance of process '" + processDefinition.Name + "'..."); // create the process-instance processInstance = new ProcessInstanceImpl(authenticatedActorId, processDefinition); FlowImpl rootFlow = (FlowImpl) processInstance.RootFlow; // create the execution-context ExecutionContextImpl executionContext = new ExecutionContextImpl(authenticatedActorId, rootFlow, dbSession, organisationComponent); // save the process instance to allow hibernate queries dbSession.Save(processInstance); //dbSession.Lock(processInstance,LockMode.Upgrade); // run the actions engine.RunActionsForEvent(EventType.BEFORE_PERFORM_OF_ACTIVITY, startState.Id, executionContext); // store the attributes executionContext.CreateLog(authenticatedActorId, EventType.PROCESS_INSTANCE_START); executionContext.CheckAccess(attributeValues, startState); executionContext.StoreAttributeValues(attributeValues); // if this activity has a role-name, save the actor in the corresponding attribute executionContext.StoreRole(authenticatedActorId, startState); // run the actions engine.RunActionsForEvent(EventType.PROCESS_INSTANCE_START, processDefinitionId, executionContext); // from here on, we consider the actor as being the previous actor executionContext.SetActorAsPrevious(); // process the start-transition TransitionImpl startTransition = executionContext.GetTransition(transitionName, startState, dbSession); engine.ProcessTransition(startTransition, executionContext); // run the actions engine.RunActionsForEvent(EventType.AFTER_PERFORM_OF_ACTIVITY, startState.Id, executionContext); // flush the updates to the db dbSession.Update(processInstance); dbSession.Flush(); //@portme /* if (relations != null) { relations.resolve(processInstance); } */ return processInstance; }
public void ProcessEndState(EndStateImpl endState, ExecutionContextImpl executionContext) { RunActionsForEvent(EventType.PROCESS_INSTANCE_END, endState.ProcessDefinition.Id, executionContext); executionContext.CreateLog(EventType.PROCESS_INSTANCE_END); FlowImpl rootFlow = (FlowImpl) executionContext.GetFlow(); rootFlow.ActorId = null; rootFlow.End = DateTime.Now; rootFlow.Node = endState; // setting the node is not necessary if this method is called // from processTransition, but it is necessary if this method is // called from cancelProcessInstance in the component-impl. ProcessInstanceImpl processInstance = (ProcessInstanceImpl) executionContext.GetProcessInstance(); FlowImpl superProcessFlow = (FlowImpl) processInstance.SuperProcessFlow; if (superProcessFlow != null) { log.Debug("reactivating the super process..."); // create the execution context for the parent-process ExecutionContextImpl superExecutionContext = new ExecutionContextImpl(executionContext.PreviousActorId, superProcessFlow, executionContext.DbSession, executionContext.GetOrganisationComponent()); superExecutionContext.SetInvokedProcessContext(executionContext); // delegate the attributeValues ProcessStateImpl processState = (ProcessStateImpl) superProcessFlow.Node; Object[] completionData = delegationHelper.DelegateProcessTermination(processState.ProcessInvokerDelegation, superExecutionContext); IDictionary attributeValues = (IDictionary) completionData[0]; String transitionName = (String) completionData[1]; TransitionImpl transition = superExecutionContext.GetTransition(transitionName, processState, executionContext.DbSession); // process the super process transition ProcessTransition(transition, superExecutionContext); } }
public IList PerformActivity(String authenticatedActorId, Int64 flowId, IDictionary attributeValues, String transitionName, Relations relations, DbSession dbSession, IOrganisationSessionLocal organisationComponent) { IList assignedFlows = null; // get the flow FlowImpl flow = (FlowImpl) dbSession.Load(typeof (FlowImpl), flowId); dbSession.Lock(flow.ProcessInstance, LockMode.Upgrade); ActivityStateImpl activityState = (ActivityStateImpl) flow.Node; // TODO : check which part can move to the DefaultAuthorizationHandler if ((Object) flow.ActorId == null) { throw new SystemException("the flow on which you try to perform an activity is not assigned to an actor"); } else { if ((Object) authenticatedActorId == null) { throw new AuthorizationException("you can't perform an activity because you are not authenticated"); } // else if ( ! authenticatedActorId.equals( flow.getActorId() ) ) { // throw new AuthorizationException( "activity '" + activityState.getName() + "' in flow " + flow.getId() + " is not assigned to the authenticated actor (" + authenticatedActorId + ") but to " + flow.getActorId() ); // } } // first check if the actor is allowed to perform this activity authorizationHelper.CheckPerformActivity(authenticatedActorId, flowId, attributeValues, transitionName, dbSession); log.Info("actor '" + authenticatedActorId + "' performs activity '" + activityState.Name + "'..."); // create the execution-context ExecutionContextImpl executionContext = new ExecutionContextImpl(authenticatedActorId, flow, dbSession, organisationComponent); // if this activity has a role-name, save the actor in the corresponding attribute // attributeValues = state.addRoleAttributeValue( attributeValues, authenticatedActorId, organisationComponent ); // log event & trigger actions engine.RunActionsForEvent(EventType.BEFORE_PERFORM_OF_ACTIVITY, activityState.Id, executionContext); // store the supplied attribute values executionContext.CreateLog(authenticatedActorId, EventType.PERFORM_OF_ACTIVITY); executionContext.AddLogDetail(new ObjectReferenceImpl(activityState)); executionContext.CheckAccess(attributeValues, activityState); executionContext.StoreAttributeValues(attributeValues); // log event & trigger actions engine.RunActionsForEvent(EventType.PERFORM_OF_ACTIVITY, activityState.Id, executionContext); // from here on, we consider the actor as being the previous actor executionContext.SetActorAsPrevious(); // select and process the transition TransitionImpl startTransition = executionContext.GetTransition(transitionName, activityState, dbSession); engine.ProcessTransition(startTransition, executionContext); // log event & trigger actions engine.RunActionsForEvent(EventType.AFTER_PERFORM_OF_ACTIVITY, activityState.Id, executionContext); assignedFlows = executionContext.AssignedFlows; // flush the updates to the db dbSession.Update(flow.ProcessInstance); dbSession.Flush(); if (relations != null) { relations.Resolve(assignedFlows); } dbSession.Update(flow.ProcessInstance); return assignedFlows; }
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); String transitionName = (String) processInvocationData[0]; IDictionary attributeValues = (IDictionary) processInvocationData[1]; // store the attributes subExecutionContext.CreateLog(subProcessStarterId, EventType.PROCESS_INSTANCE_START); subExecutionContext.StoreAttributeValues(attributeValues); subExecutionContext.StoreRole(subProcessStarterId, startState); // log event & trigger actions RunActionsForEvent(EventType.SUB_PROCESS_INSTANCE_START, processState.Id, subExecutionContext); RunActionsForEvent(EventType.PROCESS_INSTANCE_START, subProcessDefinition.Id, subExecutionContext); // from here on, we consider the actor as being the previous actor subExecutionContext.SetActorAsPrevious(); // process the start-transition TransitionImpl startTransition = subExecutionContext.GetTransition(transitionName, startState, dbSession); ProcessTransition(startTransition, subExecutionContext); // add the assigned flows of the subContext to the parentContext executionContext.AssignedFlows.AddRange(subExecutionContext.AssignedFlows); // flush the updates to the db dbSession.Update(subProcessInstance); dbSession.Flush(); }