/** * Copyright 2007-2010 非也 * All rights reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation。 * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses. * */ package org.fireflow.pdl.fpdl.behavior; import java.util.List; import org.fireflow.client.WorkflowQuery; import org.fireflow.client.WorkflowSession; import org.fireflow.client.impl.WorkflowSessionLocalImpl; import org.fireflow.engine.context.RuntimeContext; import org.fireflow.engine.entity.runtime.ActivityInstance; import org.fireflow.engine.entity.runtime.ActivityInstanceState; import org.fireflow.engine.entity.runtime.ProcessInstance; import org.fireflow.engine.entity.runtime.ScheduleJob; import org.fireflow.engine.entity.runtime.ScheduleJobState; import org.fireflow.engine.entity.runtime.impl.ActivityInstanceImpl; import org.fireflow.engine.entity.runtime.impl.ScheduleJobImpl; import org.fireflow.engine.modules.calendar.CalendarService; import org.fireflow.engine.modules.instancemanager.ActivityInstanceManager; import org.fireflow.engine.modules.persistence.ActivityInstancePersister; import org.fireflow.engine.modules.persistence.PersistenceService; import org.fireflow.engine.modules.persistence.ProcessInstancePersister; import org.fireflow.engine.modules.persistence.ScheduleJobPersister; import org.fireflow.engine.modules.persistence.TokenPersister; import org.fireflow.engine.modules.schedule.Scheduler; import org.fireflow.pdl.fpdl.misc.FpdlConstants; import org.fireflow.pdl.fpdl.process.Synchronizer; import org.fireflow.pvm.kernel.PObjectKey; import org.fireflow.pvm.kernel.Token; import org.fireflow.pvm.kernel.TokenState; import org.fireflow.pvm.pdllogic.BusinessStatus; import org.fireflow.pvm.pdllogic.ContinueDirection; import org.fireflow.pvm.pdllogic.ExecuteResult; /** * @author 非也 * @version 2.0 */ public abstract class AbsSynchronizerBehavior extends AbsNodeBehavior{ //(2012-02-05,Cancel动作容易和handleTermination混淆,意义也不是特别大,暂且注销) // protected CancellationHandler cancellationHandler = new SynchronizerCancellationHandler(); /* (non-Javadoc) * @see org.fireflow.pvm.pdllogic.WorkflowBehavior#execute(org.fireflow.engine.WorkflowSession, org.fireflow.pvm.kernel.Token, java.lang.Object) */ public ExecuteResult execute(WorkflowSession session, Token token, Object workflowElement) { ExecuteResult result = new ExecuteResult(); result.setStatus(BusinessStatus.COMPLETED); return result; } /** * 如果返回一个正整数,表示可以继续执行,且该正整数为stepnumber;-1表示尚未准备好 * @param session * @param token * @param siblings * @param synchronizer * @return */ public abstract int canBeFired(WorkflowSession session, Token token,List<Token> siblings, Synchronizer synchronizer); /* (non-Javadoc) * @see org.fireflow.pvm.pdllogic.WorkflowBehavior#prepare(org.fireflow.engine.WorkflowSession, org.fireflow.pvm.kernel.Token, java.lang.Object) */ public Boolean prepare(WorkflowSession session, Token token, Object workflowElement) { WorkflowSessionLocalImpl sessionLocalImpl = (WorkflowSessionLocalImpl)session; Synchronizer node = (Synchronizer)workflowElement; RuntimeContext ctx = ((WorkflowSessionLocalImpl) session) .getRuntimeContext(); PersistenceService persistenceStrategy = ctx.getEngineModule( PersistenceService.class, FpdlConstants.PROCESS_TYPE_FPDL20); TokenPersister tokenPersister = persistenceStrategy.getTokenPersister(); //0、校验processInstance与token的一致性 ProcessInstance processInstance = sessionLocalImpl.getCurrentProcessInstance(); if (processInstance==null || !processInstance.getId().equals(token.getProcessInstanceId())){ WorkflowQuery<ProcessInstance> q4ProcInst = sessionLocalImpl.createWorkflowQuery(ProcessInstance.class); processInstance = q4ProcInst.get(token.getProcessInstanceId()); sessionLocalImpl.setCurrentProcessInstance(processInstance); } boolean multiEnteringTransitions = false;// 表示是否有多条输入边 if (node.getEnteringTransitions() != null && node.getEnteringTransitions().size() > 1) { multiEnteringTransitions = true; } List<Token> siblings = null; if (multiEnteringTransitions ) { siblings = tokenPersister.findSiblings(token); } //1、缺省采用AndJoinEvaluator判断 int canBeFired = this.canBeFired(session, token,siblings, node); // 2、如果汇聚完成,则创建对应的ActivityInstance if (canBeFired>0) { int stepNumber = canBeFired; ActivityInstanceManager activityInstanceMgr = ctx.getEngineModule( ActivityInstanceManager.class, FpdlConstants.PROCESS_TYPE_FPDL20); ActivityInstancePersister actInstPersistSvc = persistenceStrategy .getActivityInstancePersister(); // 1、创建并保存活动实例 ActivityInstanceImpl activityInstance = (ActivityInstanceImpl) activityInstanceMgr .createActivityInstance(session, processInstance, node); activityInstance.setStepNumber(stepNumber); activityInstance.setTokenId(token.getId()); actInstPersistSvc.saveOrUpdate(activityInstance); // 2、设置session和token ((WorkflowSessionLocalImpl) session) .setCurrentActivityInstance(activityInstance); // 3.更新所有token的elementInstanceId if (siblings==null){ token.setElementInstanceId(activityInstance.getId()); tokenPersister.saveOrUpdate(token); }else{ for(Token sibling : siblings){ sibling.setElementInstanceId(activityInstance.getId()); tokenPersister.saveOrUpdate(sibling); } } return true; }else{ return false; } } /* (non-Javadoc) * @see org.fireflow.pvm.pdllogic.WorkflowBehavior#continueOn(org.fireflow.engine.WorkflowSession, org.fireflow.pvm.kernel.Token, java.lang.Object) */ public ContinueDirection continueOn(WorkflowSession session, Token token, Object workflowElement) { WorkflowSessionLocalImpl sessionLocalImpl = (WorkflowSessionLocalImpl)session; //检验currentActivityInstance和currentProcessInstance的一致性 ProcessInstance oldProcInst = sessionLocalImpl.getCurrentProcessInstance(); ActivityInstance oldActInst = sessionLocalImpl.getCurrentActivityInstance(); RuntimeContext ctx = ((WorkflowSessionLocalImpl)session).getRuntimeContext(); PersistenceService persistenceStrategy = ctx.getEngineModule(PersistenceService.class, FpdlConstants.PROCESS_TYPE_FPDL20); ActivityInstancePersister actInstPersistenceService = persistenceStrategy.getActivityInstancePersister(); ProcessInstancePersister processInstancePersister = persistenceStrategy.getProcessInstancePersister(); if (oldProcInst==null || !oldProcInst.getId().equals(token.getProcessInstanceId())){ ProcessInstance procInst = processInstancePersister.fetch(ProcessInstance.class, token.getProcessInstanceId()); ((WorkflowSessionLocalImpl)session).setCurrentProcessInstance(procInst); } if (oldActInst==null || !oldActInst.getId().equals(token.getElementInstanceId())){ ActivityInstance actInst = actInstPersistenceService.fetch(ActivityInstance.class, token.getElementInstanceId()); ((WorkflowSessionLocalImpl)session).setCurrentActivityInstance(actInst); } if (token.getState().getValue()<TokenState.DELIMITER.getValue() && token.getState().getValue()!=TokenState.RUNNING.getValue()){ return ContinueDirection.closeMe(); } List<PObjectKey> nextPObjectKeys = determineNextPObjectKeys(session,token,workflowElement); ContinueDirection direction = ContinueDirection.closeMe(); if (nextPObjectKeys.size()>0){ direction.setNextProcessObjectKeys(nextPObjectKeys); } ((WorkflowSessionLocalImpl)session).setCurrentProcessInstance(oldProcInst); ((WorkflowSessionLocalImpl)session).setCurrentActivityInstance(oldActInst); return direction; } //(2012-02-05,Cancel动作容易和handleTermination混淆,意义也不是特别大,暂且注销) // public CancellationHandler getCancellationHandler(){ // return this.cancellationHandler; // } /* (non-Javadoc) * @see org.fireflow.pvm.pdllogic.WorkflowBehavior#onTokenStateChanged(org.fireflow.engine.WorkflowSession, org.fireflow.pvm.kernel.Token, java.lang.Object) */ public void onTokenStateChanged(WorkflowSession session, Token token, Object workflowElement) { WorkflowSessionLocalImpl sessionLocalImpl = (WorkflowSessionLocalImpl)session; RuntimeContext ctx = ((WorkflowSessionLocalImpl)session).getRuntimeContext(); PersistenceService persistenceStrategy = ctx.getEngineModule(PersistenceService.class, FpdlConstants.PROCESS_TYPE_FPDL20); ActivityInstancePersister actInstPersistenceService = persistenceStrategy.getActivityInstancePersister(); CalendarService calendarService = ctx.getEngineModule(CalendarService.class, FpdlConstants.PROCESS_TYPE_FPDL20); ActivityInstance oldActInst = sessionLocalImpl.getCurrentActivityInstance(); ActivityInstance activityInstance = oldActInst; if (oldActInst==null || !oldActInst.getId().equals(token.getElementInstanceId())){ activityInstance = actInstPersistenceService.fetch(ActivityInstance.class, token.getElementInstanceId()); ((WorkflowSessionLocalImpl)session).setCurrentActivityInstance(activityInstance); } try{ if (activityInstance!=null){//synchronizer有可能没有产生相应的activity instance ActivityInstanceManager activityInstanceMgr = ctx.getEngineModule(ActivityInstanceManager.class, token.getProcessType()); ActivityInstanceState state = ActivityInstanceState.valueOf(token.getState().name()); if (state.getValue()>ActivityInstanceState.DELIMITER.getValue()){ //将调度器中的timmer删除 ,同时将ScheduleJob的状态修改为非活动状态。 ScheduleJobPersister scheduleJobPersister = persistenceStrategy.getScheduleJobPersister(); List<ScheduleJob> scheduleJobs = scheduleJobPersister.findScheduleJob4ActivityInstance(activityInstance.getId()); if (scheduleJobs!=null && scheduleJobs.size()>0){ for (ScheduleJob job : scheduleJobs){ if (job.getState().getValue()<ScheduleJobState.DELIMITER.getValue()){ Scheduler scheduler = ctx.getEngineModule(Scheduler.class, activityInstance.getProcessType()); scheduler.unSchedule(job, ctx); ScheduleJobState scheduleJobState = ScheduleJobState.COMPLETED; try{ scheduleJobState = ScheduleJobState.valueOf(state.getValue()); }catch(Exception e){ scheduleJobState = ScheduleJobState.ABORTED; } ((ScheduleJobImpl)job).setState(scheduleJobState); scheduleJobPersister.saveOrUpdate(job); } } } } //修改ActivityInstance的状态,在此处调用ActivityInstanceManager.changeActivityInstanceState(...)完成 activityInstanceMgr.changeActivityInstanceState(session, activityInstance, state, workflowElement); } }finally{ sessionLocalImpl.setCurrentActivityInstance(oldActInst); } } /* //2012-02-05 abort方法没有意义 public void abort(WorkflowSession session,Token token,Object workflowElement){ //1、检验currentActivityInstance和currentProcessInstance的一致性 ProcessInstance oldProcInst = session.getCurrentProcessInstance(); ActivityInstance oldActInst = session.getCurrentActivityInstance(); RuntimeContext ctx = ((WorkflowSessionLocalImpl)session).getRuntimeContext(); PersistenceService persistenceService = ctx.getEngineModule(PersistenceService.class, FpdlConstants.PROCESS_TYPE_FPDL20); ActivityInstancePersister actInstPersistenceService = persistenceService.getActivityInstancePersister(); ProcessInstancePersister processInstancePersister = persistenceService.getProcessInstancePersister(); if (oldProcInst==null || !oldProcInst.getId().equals(token.getProcessInstanceId())){ ProcessInstance procInst = processInstancePersister.find(ProcessInstance.class, token.getProcessInstanceId()); ((WorkflowSessionLocalImpl)session).setCurrentProcessInstance(procInst); } if (oldActInst==null || !oldActInst.getId().equals(token.getElementInstanceId())){ ActivityInstance actInst = actInstPersistenceService.find(ActivityInstance.class, token.getElementInstanceId()); ((WorkflowSessionLocalImpl)session).setCurrentActivityInstance(actInst); } try{ ActivityInstance thisActInst = session.getCurrentActivityInstance(); //将调度器中的timmer删除 ScheduleJobPersister scheduleJobPersister = persistenceService.getScheduleJobPersister(); List<ScheduleJob> scheduleJobs = scheduleJobPersister.findScheduleJob4ActivityInstance(thisActInst.getId()); if (scheduleJobs!=null && scheduleJobs.size()>0){ for (ScheduleJob job : scheduleJobs){ if (job.getState().getValue()<ScheduleJobState.DELIMITER.getValue()){ Scheduler scheduler = ctx.getEngineModule(Scheduler.class, thisActInst.getProcessType()); scheduler.unSchedule(job, ctx); ((ScheduleJobImpl)job).setState(ScheduleJobState.ABORTED); scheduleJobPersister.saveOrUpdate(job); } } } }finally{ ((WorkflowSessionLocalImpl)session).setCurrentProcessInstance(oldProcInst); ((WorkflowSessionLocalImpl)session).setCurrentActivityInstance(oldActInst); } }*/ }