bdf2-jbpm4模塊不再維護更新
2013年10月01日起,BDF2中集成的jBPM4模塊將不再做任何更新,今后將主推銳道自己的流程引擎UFLO,項目地址為bsdn.org/projects/uflo ,UFLO文檔教程地址為UFLO Home。
無論是通過哪種方式設(shè)計好流程模版并部署到BDF2系統(tǒng)當中,一旦部署成功之后,接下來就可以對流程模版進行配置了,這里需要注意的是,一般情況下,我們在設(shè)計流程模版時(也就是在畫流程圖的時候)不需要對任務(wù)節(jié)點做太多配置(唯一要做的就是為其賦一個正確的名稱),所以關(guān)于任務(wù)節(jié)點的配置都是在BDF2當中提供的配置與監(jiān)控當中實現(xiàn)。
在BDF2當中提供的配置與監(jiān)控當中,選中要配置的流程模版,點擊工具欄上的“節(jié)點配置”按鈕,系統(tǒng)會彈出一個dialog,并在所有的任務(wù)節(jié)點上添加鏈接,點擊這個鏈接會彈出與這個任務(wù)節(jié)點相關(guān)的配置信息,如下圖所示:
從彈出的窗口當中可以看出,對于任務(wù)節(jié)點,我們可以在線配置的內(nèi)容有四塊:第一個就是當前任務(wù)節(jié)點對應(yīng)處理表單頁面,它可以是一個標準的
doradoview(比如aa.bb.cc.Demo.d),也可是一個標準的JSP;第二個是配置任務(wù)的處理人,也就是任務(wù)分配,就是決定在這個節(jié)點上產(chǎn)生的任務(wù)由誰來處理;第三個是定義任務(wù)在產(chǎn)生以后如何提醒任務(wù)處理人(發(fā)站內(nèi)消息、郵件或其它);第四個任務(wù)過期就是可以給任務(wù)一個處理時間,一旦超過個時間還沒有人處理,那么就通知任務(wù)處理人或做些其它動作。
我們首先來看看“任務(wù)分配”頁中的配置內(nèi)容,如下圖所示:
點擊“添加”在彈出的窗口當中選擇我們采用的任務(wù)分配器,但可以看到彈出窗口是空的,這是因為在選擇任務(wù)分配器前,我們還需要將要采用的任務(wù)分配器加載到系統(tǒng)當中,具體做法就是點擊菜單導(dǎo)航中的“任務(wù)分配管理”,在其中添加我們要采用的任務(wù)分配器,如下圖所示:
從上圖當中可以看出,任務(wù)分配方式列表中,默認系統(tǒng)只提供了兩種,對于用戶來說,一般情況下,我都都需要定義自己的任務(wù)分配方式,如果需要定義,那么我們可以實現(xiàn)一個IAssignmentProvider接口的實現(xiàn)類,這個接口源碼如下:
IAssignmentProvider接口源碼
package com.bstek.bdf2.jbpm4.view.assignment.provider;
import java.util.Collection;
import org.jbpm.api.model.OpenExecution;
import com.bstek.bdf2.jbpm4.model.AssignmentInfo;
import com.bstek.bdf2.jbpm4.model.PrincipalDef;
/**
* @author Jacky.gao
* @since 2013-3-23
*/
public interface IAssignmentProvider {
/**
* @return 返回配置頁面所在的URL
*/
String getUrl();
/**
* @return 返回配置類型的ID
*/
String getTypeId();
/**
* @return 返回與配置類型ID對象的Name描述
*/
String getTypeName();
/**
* @param assignmentDefId 任務(wù)分配定義的ID
* @return 根據(jù)任務(wù)分配定義的ID返回與之對應(yīng)的任務(wù)分配信息
*/
Collection<AssignmentInfo> getAssignmentInfos(String assignmentDefId);
/**
* 刪除指定分配定義下的分配定義信息
* @param assignmentDefId 分配定義信息的ID
*/
void deleteAssignmentInfos(String assignmentDefId);
/**
* @param assignmentDefId 任務(wù)分配定義的ID
* @param execution 當前流程實例執(zhí)行上下文對象
* @return 根據(jù)任務(wù)分配定義的ID返回所有與之對應(yīng)的任務(wù)處理人的PrincipalDef集合
*/
Collection<PrincipalDef> getTaskPrincipals(String assignmentDefId,OpenExecution execution);
/**
* @return 是否禁用
*/
boolean isDisabled();
}
實際上,我們看到的系統(tǒng)當中默認提供的兩種任務(wù)分配方式:流程實例發(fā)起人與指定一個用戶,它們都是通過實現(xiàn)IAssignmentProvider接口,然后配置到Spring當中才出現(xiàn)在上圖中的下接列表當中的。所以如果我們要定義自己的,同樣要實現(xiàn)IAssignmentProvider接口。
如果不想系統(tǒng)默認提供的流程實例發(fā)起人出現(xiàn)在列表中,那么可以將bdf2.jbpm4.disablePromoterAssignment屬性設(shè)置成true,同樣對于指定一個用戶的任務(wù)分配方式,如果不需要那么就將bdf2.jbpm4.disableSpecifyUserAssignment屬性設(shè)置成true即可。
實際上,BDF2默認提供的兩種任務(wù)分配方式:流程實例發(fā)起人與指定一個用戶,就是給我們對如何編寫IAssignmentProvider接口實現(xiàn)類提供了兩種不同類型的示例。對于流程實例發(fā)起人這種任務(wù)分配方式,在使用不需要界面配置,所以它的實現(xiàn)類相對簡單,其源碼如下:
PromoterAssignmentProvider類源碼
package com.bstek.bdf2.jbpm4.view.assignment.provider.impl.promoter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.jbpm.api.model.OpenExecution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.bstek.bdf2.jbpm4.model.AssignmentInfo;
import com.bstek.bdf2.jbpm4.model.PrincipalDef;
import com.bstek.bdf2.jbpm4.service.IBpmService;
import com.bstek.bdf2.jbpm4.view.assignment.provider.IAssignmentProvider;
/**
* 流程發(fā)起人任務(wù)分配方式
* @author Jacky.gao
* @since 2013-3-23
*/
@Component
public class PromoterAssignmentProvider implements IAssignmentProvider {
@Value("${bdf2.jbpm4.disablePromoterAssignment}")
private boolean disabled;
@Autowired
@Qualifier(IBpmService.BEAN_ID)
private IBpmService bmpService;
public String getUrl() {
return null;
}
public String getTypeId() {
return "promoter";
}
public String getTypeName() {
return "流程實例發(fā)起人";
}
public Collection<AssignmentInfo> getAssignmentInfos(String assignmentDefId) {
List<AssignmentInfo> info=new ArrayList<AssignmentInfo>();
AssignmentInfo a=new AssignmentInfo();
a.setName("流程實例發(fā)起人");
a.setValue("從流程實例中取名為["+IBpmService.PROCESS_INSTANCE_PROMOTER+"]的變量值,這個變量值表
示流程實例發(fā)起人用戶名");
info.add(a);
return info;
}
public Collection<PrincipalDef> getTaskPrincipals(String assignmentDefId,OpenExecution execution) {
List<PrincipalDef> usernames=new ArrayList<PrincipalDef>();
String username=(String)execution.getVariable(IBpmService.PROCESS_INSTANCE_PROMOTER);
if(StringUtils.isEmpty(username)){
throw new RuntimeException("Variable not found ["+IBpmService.PROCESS_INSTANCE_PROMOTER+"]
in current process instance");
}
PrincipalDef p=new PrincipalDef();
p.setId(username);
usernames.add(p);
return usernames;
}
public void deleteAssignmentInfos(String assignmentDefId){
//do nothing
}
public boolean isDisabled(){
return disabled;
}
}
但對于指定一個用戶這種任務(wù)分配方式,因為涉及到頁面,相比之下就復(fù)雜一些,我們來看看它的源碼:
SpecifyUserAssignmentProvider類源碼
package com.bstek.bdf2.jbpm4.view.assignment.provider.impl.specifyuser;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hibernate.Session;
import org.jbpm.api.model.OpenExecution;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.bstek.bdf2.jbpm4.Jbpm4HibernateDao;
import com.bstek.bdf2.jbpm4.model.AssignmentInfo;
import com.bstek.bdf2.jbpm4.model.InternalAssignment;
import com.bstek.bdf2.jbpm4.model.PrincipalDef;
import com.bstek.bdf2.jbpm4.view.assignment.provider.IAssignmentProvider;
/**
* 指定一個用戶作為任務(wù)處理人
* @author Jacky.gao
* @since 2013-3-23
*/
@Component
public class SpecifyUserAssignmentProvider extends Jbpm4HibernateDao implements
IAssignmentProvider {
@Value("${bdf2.jbpm4.disableSpecifyUserAssignment}")
private boolean disabled;
public String getUrl() {
return "bdf2.jbpm4.view.assignment.provider.impl.specifyuser.SpecifyUserProvider";
}
public String getTypeId() {
return "specify_user";
}
public String getTypeName() {
return "指定一個用戶";
}
public Collection<AssignmentInfo> getAssignmentInfos(String assignmentDefId) {
String hql="from "+InternalAssignment.class.getName()+" where assignmentDefId=:assignmentDefId";
Map<String,Object> map=new HashMap<String,Object>();
map.put("assignmentDefId", assignmentDefId);
List<InternalAssignment> internals=this.query(hql, map);
List<AssignmentInfo> infos=new ArrayList<AssignmentInfo>();
for(InternalAssignment internal:internals){
AssignmentInfo info=new AssignmentInfo();
info.setName("一個用戶");
info.setValue(internal.getName());
infos.add(info);
}
return infos;
}
public Collection<PrincipalDef> getTaskPrincipals(String assignmentDefId,OpenExecution execution) {
String hql="from "+InternalAssignment.class.getName()+" where assignmentDefId=:assignmentDefId";
Map<String,Object> map=new HashMap<String,Object>();
map.put("assignmentDefId", assignmentDefId);
List<InternalAssignment> internals=this.query(hql, map);
List<PrincipalDef> result=new ArrayList<PrincipalDef>();
for(InternalAssignment internal:internals){
PrincipalDef def=new PrincipalDef();
def.setId(internal.getValue());
result.add(def);
}
return result;
}
public void deleteAssignmentInfos(String assignmentDefId){
String hql="delete "+InternalAssignment.class.getName()+" where assignmentDefId=:assignmentDefId";
Map<String,Object> map=new HashMap<String,Object>();
map.put("assignmentDefId", assignmentDefId);
Session session=this.getSessionFactory().openSession();
try{
session.createQuery(hql).setString("assignmentDefId", assignmentDefId).executeUpdate();
}finally{
session.flush();
session.close();
}
}
public boolean isDisabled() {
return disabled;
}
}
可以看到,指定一個用戶這種任務(wù)分配方式當中用到的頁面是通過實現(xiàn)類當中的getUrl方法返回的,這個返回的頁面是bdf2.jbpm4.view.assignment.provider.impl.specifyuser.SpecifyUserProvider,實際上這是一個標準的dorado7view文件,我們可以在BDF2-JBPM4源碼包中找到bdf2.jbpm4.view.assignment.provider.impl.specifyuser包下的名為SpecifyUserProvider.view.xml文件,具體頁面中的實現(xiàn)大家可以參考這個view文件,值得注意的是,這里的getUrl方法返回的頁面只能是一個標準的dorado7view,而不能是JSP或其它,因為返回的URL會被系統(tǒng)采用dorado7中的subviewholder引入到父頁面當中,而subviewholder中的頁面只能是標準的dorado7 view。
定義一個任務(wù)分配方式,確認后,再次打開任務(wù)節(jié)點配置界面,就可以看到定義的任務(wù)分配方式,如下圖所示:
任務(wù)處理人配置好之后,就可以利用這個配置與監(jiān)控對流程模版進行測試了,通過點擊工具欄上的“創(chuàng)建實例”按鈕就可以創(chuàng)建一個新的流程實例,以這個流程模版為例,新的流程實例產(chǎn)生后,流程將會流轉(zhuǎn)到初審節(jié)點,右上邊的任務(wù)列表中也會出現(xiàn)這個初審節(jié)點上產(chǎn)生的任務(wù),點擊其上的“查看流程圖按鈕”,可以看到當前流程實例所處位置,如下圖所示:
更多建議: