/** * Copyright 2007-2010 非也 * All rights reserved. * * This library is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License v3 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 Lesser General Public License along * with this library; if not, see http://www.gnu.org/licenses/lgpl.html. * */ package org.fireflow.pdl.fpdl.enginemodules.workitem; import java.util.Iterator; import java.util.Map; import javax.script.ScriptException; import org.apache.commons.lang.StringUtils; 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.ProcessInstance; import org.fireflow.engine.entity.runtime.WorkItem; import org.fireflow.engine.entity.runtime.WorkItemProperty; import org.fireflow.engine.entity.runtime.WorkItemState; import org.fireflow.engine.entity.runtime.impl.LocalWorkItemImpl; import org.fireflow.engine.exception.EngineException; import org.fireflow.engine.invocation.impl.AbsServiceInvoker; import org.fireflow.engine.modules.calendar.CalendarService; import org.fireflow.engine.modules.ousystem.User; import org.fireflow.engine.modules.persistence.PersistenceService; import org.fireflow.engine.modules.persistence.WorkItemPersister; import org.fireflow.engine.modules.processlanguage.ProcessLanguageManager; import org.fireflow.engine.modules.script.ScriptEngineHelper; import org.fireflow.engine.modules.workitem.event.WorkItemEventTrigger; import org.fireflow.engine.modules.workitem.impl.AbsWorkItemManager; import org.fireflow.model.binding.ResourceBinding; import org.fireflow.model.binding.ServiceBinding; import org.fireflow.model.data.Expression; import org.fireflow.model.resourcedef.WorkItemAssignmentStrategy; import org.fireflow.pdl.fpdl.misc.LoopStrategy; import org.fireflow.pdl.fpdl.process.Activity; import org.fireflow.service.human.HumanService; /** * * @author 非也 nychen2000@163.com Fire Workflow 官方网站:www.firesoa.com 或者 * www.fireflow.org * */ public class WorkItemManagerFpdl20Impl extends AbsWorkItemManager { /* * (non-Javadoc) * * @see * org.fireflow.engine.service.form.WorkItemManager#createWorkItem(org.fireflow * .engine.WorkflowSession, * org.fireflow.engine.entity.runtime.ProcessInstance, * org.fireflow.engine.entity.runtime.ActivityInstance, java.lang.String) */ public WorkItem createWorkItem(WorkflowSession currentSession, ProcessInstance processInstance, ActivityInstance activityInstance, User user, Object theActivity, Map<WorkItemProperty, Object> workitemPropertyValues) throws EngineException { RuntimeContext ctx = ((WorkflowSessionLocalImpl) currentSession) .getRuntimeContext(); Activity activity = (Activity) theActivity; ServiceBinding serviceBinding = activity.getServiceBinding(); HumanService humanService = null; if (serviceBinding != null) { ProcessLanguageManager processUtil = ctx.getEngineModule(ProcessLanguageManager.class, activityInstance.getProcessType()); humanService = (HumanService) processUtil.getServiceDef(activityInstance, activity, serviceBinding.getServiceId()); } ResourceBinding resourceBinding = activity.getResourceBinding(); CalendarService calendarService = ctx.getEngineModule( CalendarService.class, activityInstance.getProcessType()); PersistenceService persistenceService = ctx.getEngineModule( PersistenceService.class, activityInstance.getProcessType()); WorkItemPersister workItemPersister = persistenceService .getWorkItemPersister(); LocalWorkItemImpl wi = new LocalWorkItemImpl(); wi.setWorkItemName(activityInstance.getDisplayName()); // 计算工作项摘要表达式 if (humanService != null) { wi.setSubject(parseDescription(humanService.getWorkItemSubject(), currentSession, ctx, processInstance, activityInstance)); } wi.setCreatedTime(calendarService.getSysDate()); wi.setExpiredTime(activityInstance.getExpiredTime()); //工作项所有者信息 wi.setOwnerId(user.getId()); wi.setOwnerName(user.getName()); wi.setOwnerDeptId(user.getDeptId()); wi.setOwnerDeptName(user.getDeptName()); //构建表单Url String formUrl = humanService.getFormUrl();//将参数追加在formUrl后面 if(formUrl!=null){ Map<String, Object> theInputValues = null; try { theInputValues = AbsServiceInvoker.resolveInputAssignments(ctx,currentSession, processInstance,activityInstance,activity.getServiceBinding(),humanService); } catch (ScriptException e) { throw new EngineException(activityInstance,""); } StringBuffer queryStr = new StringBuffer(""); int flag = 0; if (theInputValues!=null && theInputValues.size()>0){ Iterator<Map.Entry<String, Object>> iterator = theInputValues.entrySet().iterator(); while (iterator.hasNext()){ flag = flag+1; Map.Entry<String, Object> entry = iterator.next(); queryStr.append(entry.getKey()) .append("=") .append(entry.getValue()); if (flag>0 && flag<theInputValues.size()){ queryStr.append("&"); } } } if (queryStr.length()>0){ int idx = formUrl.indexOf("?"); if (idx>=0){ formUrl = formUrl + "&" +queryStr.toString(); }else{ formUrl = formUrl + "?"+queryStr.toString(); } } //TODO 是否要将WorkItemId固定追加在url末尾? //注:此处无法将workItemId追加在url末尾,因为此时workItem还未保存,id属性还为空 } wi.setActionUrl(formUrl); wi.setBizId(activityInstance.getBizId()); if (resourceBinding != null && resourceBinding.getAssignmentStrategy() != null) { wi.setAssignmentStrategy(resourceBinding.getAssignmentStrategy()); } wi.setResponsiblePersonId(user.getId()); wi.setResponsiblePersonName(user.getName()); wi.setResponsiblePersonDeptId(user.getDeptId()); wi.setResponsiblePersonDeptName(user.getDeptName()); if (workitemPropertyValues != null) { if (workitemPropertyValues.get(WorkItemProperty.STATE) != null) { wi.setState((WorkItemState) workitemPropertyValues .get(WorkItemProperty.STATE)); } if (workitemPropertyValues .get(WorkItemProperty.ASSIGNMENT_STRATEGY) != null) { wi.setAssignmentStrategy((WorkItemAssignmentStrategy) workitemPropertyValues .get(WorkItemProperty.ASSIGNMENT_STRATEGY)); } wi.setReassignType((String) workitemPropertyValues .get(WorkItemProperty.REASSIGN_TYPE)); wi.setParentWorkItemId((String) workitemPropertyValues .get(WorkItemProperty.PARENT_WORKITEM_ID)); } wi.setProcInstCreatorId(processInstance.getCreatorId()); wi.setProcInstCreatorName(processInstance.getCreatorName()); wi.setProcInstCreatedTime(processInstance.getCreatedTime()); wi.setProcessId(processInstance.getProcessId()); wi.setSubProcessId(processInstance.getSubProcessId()); wi.setProcessType(processInstance.getProcessType()); wi.setVersion(processInstance.getVersion()); wi.setActivityId(activityInstance.getNodeId()); wi.setProcessInstanceId(processInstance.getId()); wi.setStepNumber(activityInstance.getStepNumber()); wi.setActivityInstanceId(activityInstance.getId()); // 发布事件 this.fireWorkItemEvent(currentSession, wi, theActivity, WorkItemEventTrigger.BEFORE_WORKITEM_CREATED); workItemPersister.saveOrUpdate(wi); // 发布事件 this.fireWorkItemEvent(currentSession, wi, theActivity, WorkItemEventTrigger.AFTER_WORKITEM_CREATED); return wi; } private String parseDescription(Expression descExpression, WorkflowSession session, RuntimeContext runtimeContext, ProcessInstance processInstance, ActivityInstance activityInstance) { if (descExpression == null || StringUtils.isEmpty(descExpression.getLanguage())) { return ""; } Map<String, Object> contextVars = ScriptEngineHelper .fulfillScriptContext(session, runtimeContext, processInstance, activityInstance); Object obj = null; obj = ScriptEngineHelper.evaluateExpression(runtimeContext, descExpression, contextVars); return obj == null ? null : obj.toString(); } protected boolean isSkip(WorkflowSession session, ActivityInstance activityInstance, ServiceBinding serviceBinding, ResourceBinding resourceBinding, Object theActivityObj){ Activity theActivity = (Activity)theActivityObj; LoopStrategy loopStrategy = theActivity.getLoopStrategy(); if (loopStrategy!=null && loopStrategy.equals(LoopStrategy.SKIP)){ return true; } return false; } protected boolean isRedo(WorkflowSession session, ActivityInstance activityInstance, ServiceBinding serviceBinding, ResourceBinding resourceBinding, Object theActivityObj){ Activity theActivity = (Activity)theActivityObj; LoopStrategy loopStrategy = theActivity.getLoopStrategy(); if (loopStrategy!=null && loopStrategy.equals(LoopStrategy.REDO)){ return true; } return false; } }