package com.norteksoft.wf.engine.core; import java.lang.reflect.InvocationTargetException; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.lang.StringUtils; import org.jbpm.api.ExecutionService; import org.jbpm.api.ProcessEngine; import org.jbpm.api.activity.ActivityExecution; import org.jbpm.api.listener.EventListener; import org.jbpm.api.listener.EventListenerExecution; import org.jbpm.internal.log.Log; import org.springframework.dao.DataAccessException; import org.springframework.util.Assert; import com.norteksoft.mms.form.dao.GeneralDao; import com.norteksoft.mms.form.entity.FormView; import com.norteksoft.mms.form.jdbc.JdbcSupport; import com.norteksoft.mms.form.service.FormViewManager; import com.norteksoft.product.util.ContextUtils; import com.norteksoft.product.util.PropUtils; import com.norteksoft.task.base.enumeration.TaskProcessingMode; import com.norteksoft.task.base.enumeration.TaskState; import com.norteksoft.task.entity.WorkflowTask; import com.norteksoft.wf.base.enumeration.CommonStrings; import com.norteksoft.wf.base.enumeration.ProcessState; import com.norteksoft.wf.base.utils.WebUtil; import com.norteksoft.wf.engine.client.EndInstanceInterface; import com.norteksoft.wf.engine.core.impl.UserParseCalculator; import com.norteksoft.wf.engine.entity.WorkflowDefinition; import com.norteksoft.wf.engine.entity.WorkflowInstance; import com.norteksoft.wf.engine.service.TaskService; import com.norteksoft.wf.engine.service.WorkflowDefinitionManager; import com.norteksoft.wf.engine.service.WorkflowInstanceManager; import edu.emory.mathcs.backport.java.util.Arrays; public class ProcessEndListener implements EventListener { private static final long serialVersionUID = 1L; private static final Log log = Log.getLog(ProcessEndListener.class.getName()); public static final SimpleDateFormat SIMPLEDATEFORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private String creator; private String processAdmin; private TaskService taskService; private String processId; private String parentDefinitionId; private String subDefinitionId; private WorkflowInstance parentWorkflow; private FormView parentForm; private FormView subForm; private WorkflowInstance workflow; private String parentActivityName; public void notify(EventListenerExecution execution) { Assert.notNull(execution,"流程结束监听中,execution不能为null"); WorkflowDefinitionManager workflowDefinitionManager = (WorkflowDefinitionManager)ContextUtils.getBean("workflowDefinitionManager"); WorkflowInstanceManager workflowInstanceManager = (WorkflowInstanceManager)ContextUtils.getBean("workflowInstanceManager"); FormViewManager formManager = (FormViewManager)ContextUtils.getBean("formViewManager"); ProcessEngine processEngine = (ProcessEngine)ContextUtils.getBean("processEngine"); JdbcSupport jdbcDao=(JdbcSupport)ContextUtils.getBean("jdbcDao"); //数据库方言 boolean isOracle = PropUtils.DATABASE_ORACLE.equals(PropUtils.getDataBase()); taskService = (TaskService) ContextUtils.getBean("taskService"); processId = execution.getProcessInstance().getId(); creator = execution.getVariable("creator").toString(); WorkflowDefinition workflowDefinition = workflowDefinitionManager.getWorkflowDefinitionByProcessId(execution.getProcessDefinitionId()); if(workflowDefinition==null){throw new RuntimeException("流程结束监听中,流程定义实体不能为null");} processAdmin = workflowDefinition.getAdminLoginName(); workflow = workflowInstanceManager.getWorkflowInstance(processId); subForm = formManager.getFormView(workflow.getFormId());//子流程表单 Object obj=execution.getVariable(CommonStrings.CANCEL_FLAG); execution.removeVariable(CommonStrings.CANCEL_FLAG); Object comobj=execution.getVariable(CommonStrings.COMPEL_END_FLAG); execution.removeVariable(CommonStrings.COMPEL_END_FLAG); if(StringUtils.isNotEmpty(workflow.getParentProcessId())&&StringUtils.isNotEmpty(workflow.getParentExcutionId())){ ExecutionService executionService = processEngine.getExecutionService(); subDefinitionId = execution.getProcessDefinitionId(); parentWorkflow = workflowInstanceManager.getWorkflowInstance(workflow.getParentProcessId()); parentDefinitionId = parentWorkflow.getProcessDefinitionId(); parentForm = formManager.getFormView(parentWorkflow.getFormId()); ActivityExecution exe=((ActivityExecution)executionService.findExecutionById(workflow.getParentExcutionId())); if(exe!=null){ parentActivityName = exe.getActivityName(); if(!(obj!=null||comobj!=null)){//正常结束时才进行主子表单赋值操作 subProcessEnd((ActivityExecution)execution); } if(workflowInstanceManager.getActivityWorkflowInstance(parentWorkflow.getProcessInstanceId(), parentActivityName).size()==1 &&workflowInstanceManager.getActivityWorkflowInstance(parentWorkflow.getProcessInstanceId(), parentActivityName).get(0).equals(workflow)){ String transitionName = DefinitionXmlParse.getSubProcessTransition(parentDefinitionId,parentActivityName); executionService.signalExecutionById(workflow.getParentExcutionId(),transitionName); } } } ActivityExecution ae = (ActivityExecution)execution; Timestamp submitTime = new Timestamp(System.currentTimeMillis()); Timestamp endTime = new Timestamp(System.currentTimeMillis()); if(obj!=null||comobj!=null){//取消流程或强制结束时 if((obj !=null&& "true".equals(obj.toString()))||(comobj!=null&&"true".equals(comobj.toString()))){ if(subForm.isStandardForm()){ try{ StringBuilder sql = new StringBuilder("UPDATE ").append(subForm.getDataTable().getName()).append(" SET "); if(workflow.getProcessState()==ProcessState.UNSUBMIT){ if(isOracle){ sql.append("submit_time=to_timestamp('"+SIMPLEDATEFORMAT.format(submitTime)+"','yyyy-MM-dd hh24:mi:ss')").append(","); }else{ sql.append("submit_time='"+SIMPLEDATEFORMAT.format(submitTime)+"'").append(","); } } sql.append("current_activity_name='"+ae.getActivityName()+"'"); sql.append(",process_state=2"); if(isOracle){ sql.append(",end_time=to_timestamp('"+SIMPLEDATEFORMAT.format(endTime)+"','yyyy-MM-dd hh24:mi:ss')"); }else{ sql.append(",end_time='"+SIMPLEDATEFORMAT.format(endTime)+"'"); } sql.append(" where id="+workflow.getDataId()); jdbcDao.updateTable(sql.toString()); } catch (NumberFormatException e) { throw new RuntimeException("numberFormatException",e); } catch (DataAccessException e) { throw new RuntimeException("update Exception",e); } }else{ StringBuilder sql = new StringBuilder("UPDATE ").append(subForm.getDataTable().getName()).append(" SET "); sql.append("current_activity_name='"+ae.getActivityName()+"'"); sql.append(",process_state=2"); sql.append(" where id="+workflow.getDataId()); jdbcDao.updateTable(sql.toString()); } } }else{//流程正常结束 if(subForm.isStandardForm()){ try { GeneralDao generalDao = (GeneralDao)ContextUtils.getBean("generalDao"); Object entity = generalDao.getObject(subForm.getDataTable().getEntityName(), workflow.getDataId()); if(workflow.getProcessState()==ProcessState.UNSUBMIT){ BeanUtils.setProperty(entity, "workflowInfo.submitTime", submitTime); } BeanUtils.setProperty(entity, "workflowInfo.currentActivityName", ae.getActivityName()); BeanUtils.setProperty(entity, "workflowInfo.processState",ProcessState.END); BeanUtils.setProperty(entity, "workflowInfo.endTime",endTime); generalDao.save(entity); } catch (IllegalAccessException e) { log.error(e.getMessage()); throw new RuntimeException(e); } catch (InvocationTargetException e) { log.error(e.getMessage()); throw new RuntimeException(e); } }else{ StringBuilder sql = new StringBuilder("UPDATE ").append(subForm.getDataTable().getName()).append(" SET "); sql.append("current_activity_name='"+ae.getActivityName()+"'"); sql.append(",process_state=2"); sql.append(" where id="+workflow.getDataId()); jdbcDao.updateTable(sql.toString()); } } if(workflow.getProcessState()==ProcessState.UNSUBMIT){ workflow.setSubmitTime(submitTime); } workflow.setEndTime(endTime); if(workflow.getProcessState()!=ProcessState.MANUAL_END){ workflow.setProcessState(ProcessState.END); } workflow.setCurrentActivity("流程结束"); if(workflow.getProcessState()!=ProcessState.MANUAL_END){ workflowInstanceManager.setWorkflowInstanceEnd(workflow); } workflowInstanceManager.saveWorkflowInstance(workflow); List<WorkflowTask> tasks=taskService.getActivityTasks(processId, workflow.getCompanyId()); if(tasks.size()>0){ WorkflowTask task=tasks.get(0); if(task.getProcessingMode()!=TaskProcessingMode.TYPE_READ){//当前任务不是抄送环节、分发环节时,设置当前任务的状态为已完成 task.setActive(TaskState.COMPLETED.getIndex()); } } //流程正常结束时业务补偿 if(workflow.getProcessState()==ProcessState.END){ if(!(comobj!=null && "true".equals(comobj.toString()))){//不是强制结束流程时 endInstanceSet(workflow); } } inform(execution.getProcessDefinitionId()); } /** * 当是流程正常结束时业务补偿 * @param instance * @param form */ private void endInstanceSet(WorkflowInstance instance){ String endInstanceBeanName = DefinitionXmlParse.getEndInstanceBean(instance.getProcessDefinitionId()); if(StringUtils.isNotEmpty(endInstanceBeanName)){ EndInstanceInterface endInstanceBean=(EndInstanceInterface)ContextUtils.getBean(endInstanceBeanName); if(endInstanceBean==null){throw new RuntimeException("流程结束监听中,流程结束时业务补偿bean不能为null");} endInstanceBean.endInstanceExecute(instance.getDataId()); } } /* * 判断是否共用表单 * 如果共用表单,不做处理 * 如果不公用表单,判断父子表单类型,然后赋值 */ private void subProcessEnd(ActivityExecution execution){ if(!DefinitionXmlParse.isSharedForm(parentDefinitionId,subDefinitionId)){ if(parentForm==null){throw new RuntimeException("流程结束监听中,父流程对应的表单不能为null");} if(parentForm.isStandardForm()){ fillParentEntity(); }else if(!parentForm.isStandardForm()){ fillSubDefaultForm(); } } } @SuppressWarnings("unchecked") private void fillParentEntity(){ FormViewManager formManager = (FormViewManager)ContextUtils.getBean("formViewManager"); GeneralDao generalDao = (GeneralDao)ContextUtils.getBean("generalDao"); try { Object parentFormEntity = generalDao.getObject(parentForm.getDataTable().getEntityName(), parentWorkflow.getDataId()); Map<String,String> subToMainMap = DefinitionXmlParse.getSubToMain(parentDefinitionId, parentActivityName); Map<String,Object> valueMap = new HashMap<String,Object>(); if(subForm==null){throw new RuntimeException("流程结束监听中,子流程对应的表单不能为null");} if(subForm.isStandardForm()){ if(subForm.getDataTable()==null){throw new RuntimeException("流程结束监听中,子流程表单对应的数据表不能为null");} if(subForm.getDataTable().getEntityName()==null){throw new RuntimeException("流程结束监听中,表单对应的数据表实体类名不能为null");} Object subEntity = generalDao.getObject(subForm.getDataTable().getEntityName(), workflow.getDataId()); for(String subFieldName:subToMainMap.keySet()){ Object subFieldValue = BeanUtils.getProperty(subEntity, subFieldName); if(subFieldValue!=null){ valueMap.put(subToMainMap.get(subFieldName),subFieldValue); } } }else if(!subForm.isStandardForm()){ Map dataMap = formManager.getDataMap(subForm.getDataTable().getName(), workflow.getDataId()); for(String subFieldName:subToMainMap.keySet()){ Object subFieldValue = dataMap.get(JdbcSupport.FORM_FIELD_PREFIX_STRING+subFieldName); if(subFieldValue!=null){ valueMap.put(subToMainMap.get(subFieldName),subFieldValue); } } } BeanUtils.populate(parentFormEntity, valueMap); generalDao.save(parentFormEntity); } catch (IllegalAccessException e) { log.error(e.getMessage()); throw new RuntimeException(e); } catch (InvocationTargetException e) { log.error(e.getMessage()); throw new RuntimeException(e); } catch (NoSuchMethodException e) { log.error(e.getMessage()); throw new RuntimeException(e); } } @SuppressWarnings("unchecked") private void fillSubDefaultForm(){ FormViewManager formManager = (FormViewManager)ContextUtils.getBean("formViewManager"); GeneralDao generalDao = (GeneralDao)ContextUtils.getBean("generalDao"); Map<String,String> subToMainMap = DefinitionXmlParse.getSubToMain(parentDefinitionId, parentActivityName); Map<String,String[]> valueMap = new HashMap<String,String[]>(); try { if(subForm.isStandardForm()){ if(subForm.getDataTable()==null){throw new RuntimeException("流程结束监听中,子流程表单对应的数据表不能为null");} if(subForm.getDataTable().getEntityName()==null){throw new RuntimeException("流程结束监听中,表单对应的数据表实体类名不能为null");} Object subEntity = generalDao.getObject(subForm.getDataTable().getEntityName(), workflow.getDataId()); for(String subFieldName:subToMainMap.keySet()){ Object subFieldValue = BeanUtils.getProperty(subEntity, subFieldName); if(subFieldValue!=null){ valueMap.put(subToMainMap.get(subFieldName), new String[]{subFieldValue.toString()}); } } }else if(!subForm.isStandardForm()){ Map dataMap = formManager.getDataMap(subForm.getDataTable().getName(), workflow.getDataId()); for(String subFieldName:subToMainMap.keySet()){ Object subFieldValue = dataMap.get(JdbcSupport.FORM_FIELD_PREFIX_STRING+subFieldName); if(subFieldValue!=null){ valueMap.put(subToMainMap.get(subFieldName),new String[]{subFieldValue.toString()}); } } } } catch (IllegalAccessException e) { log.error(e.getMessage()); throw new RuntimeException(e); } catch (InvocationTargetException e) { log.error(e.getMessage()); throw new RuntimeException(e); } catch (NoSuchMethodException e) { log.error(e.getMessage()); throw new RuntimeException(e); } if(!valueMap.isEmpty()){ formManager.saveFormContentToTable(valueMap,parentForm.getId(),parentWorkflow.getDataId()); } } /* * 通知 */ @SuppressWarnings("unchecked") private void inform( String myProcessId){ if(DefinitionXmlParse.processInform(myProcessId)){ log.info("流程结束时有需要通知的用户"); String informType=DefinitionXmlParse.getProcessInformType(myProcessId); String[] types=informType.split(","); List<String> list = Arrays.asList(types); if(list.contains(CommonStrings.EMAIL_STYLE)){ Set<String> emails = getEmailsInformCondition(myProcessId);//根据users得到所有结束通知的email地址 log.info("需要通知的用户email地址有:" + emails.toString()); DefinitionXmlParse.processInformMail(myProcessId,emails); } if(list.contains(CommonStrings.RTX_STYLE)){ String loginNames = getLoginNameInformCondition(myProcessId);//根据users得到得到登录名 log.info("需要通知的用户登录名有:" + loginNames); DefinitionXmlParse.processInformRTX(myProcessId,loginNames); } if(list.contains(CommonStrings.SWING_STYLE)){ String loginNames = getLoginNameInformCondition(myProcessId);//根据users得到得到登录名 log.info("需要通知的用户登录名有:" + loginNames); DefinitionXmlParse.processInformSwing(myProcessId,loginNames,workflow); } } } /* * 解析通知条件获得需要通知用户的邮件地址 */ private Set<String> getEmailsInformCondition(String myProcessId){ WorkflowInstanceManager workflowInstanceManager = (WorkflowInstanceManager)ContextUtils.getBean("workflowInstanceManager"); WorkflowInstance wi = workflowInstanceManager.getWorkflowInstance(processId); String condition = DefinitionXmlParse.getProcessInformUserCondition(myProcessId); log.info("根据流程定义文件得到流程结束时需要通知的用户条件为:" + condition); UserParseCalculator upc = WebUtil.getUserParseInfor(processId,creator,processAdmin); return WebUtil.getEmailsInformCondition(condition, wi.getSystemId(), wi.getCompanyId(),upc); } /* * 解析通知条件获得需要通知用户的登录名 */ private String getLoginNameInformCondition(String myProcessId){ WorkflowInstanceManager workflowInstanceManager = (WorkflowInstanceManager)ContextUtils.getBean("workflowInstanceManager"); WorkflowInstance wi = workflowInstanceManager.getWorkflowInstance(processId); String condition = DefinitionXmlParse.getProcessInformUserCondition(myProcessId); log.info("根据流程定义文件得到流程结束时需要通知的用户条件为:" + condition); UserParseCalculator upc = WebUtil.getUserParseInfor(processId,creator,processAdmin); return WebUtil.getLoginNameInformCondition(condition, wi.getSystemId(), wi.getCompanyId(),upc); } }