最近在做一个项目,涉及到工作流,在网上找了一下,发现JBPM还是不错的。于是打算用它来做工作流引擎。不过我以前是做.NET的,从来没有写过Java的程序,一切都得从头开始,不过也算是对自己的一个锻炼吧。
因为是新手,所以开始很难,前两天下载了个MyEclipse,费了九牛二虎之力,总算把JBPM的开发环境搭起来了。对照着JBPM的用户手册,目前已经实现了数据库存储,以及一个基本流程的流转(纯流程,静态表单数据)。数据库设计也大概做完了,也搭起了Hibernate环境,并根据数据库生成了数据层代码。从今天开始,就要着手实现动态加载工作流表单了。
首先,我的工作流表单是定义在数据库里,大概的结构是这样:
[img]/upload/attachment/50161/9bcfcaa3-2d2e-354c-b92a-36c272f5a0b0.jpg[/img]
每个流程定义了一个Form,FormItem里存放这个Form里各有什么控件,以及控件的类型及值类型等。据我了解,Java(或者Jsp)里,没有像.NET里那样的动态加载控件机制,所以,我写了一个Bean,根据传进来的流程名称,来加载相应的表单及里面的控件。
在处理流程的页面里,调用这个Bean,就可以得到需要加载的表单了。
提交的时候,在根据数据库里的配置,分别得到这些控件的值,然后存储就行了。
我目前是存储到了流程的变量里,当然也可以存储到数据库里。
现在的问题是,一个流程里,有好多人参与(好多Task),每个人看到的,和可以编辑的控件不可能一样。如果根据当前的不同的环节,或者不同的人,在我定义的Bean里返回不同的控件内容呢?我现在是在fwo_FormItem表里定义了两个字段:VisibleNode和EditableNode,里面存的是相应的Task的Id。这样的话,只需要在调用Bean之前,先把当前Task的Id传进来就可以了。
[color=red]如果是流程中的环节,我可以使用jbpmContext.getTaskList来得到当前的任务,从而得到Task的Id。但是,当一个用户新建流程的时候,如果获得Task的Id呢?因为我想是当这个用户提交了表单的时候,我才应该创建流程实例什么的。但是此时还没有流程实例,也无法得到相应的Task。请大家帮帮忙,看如何实现?[/color]
附一张我的流程设计图,画红圈的就是如何加载表单的地方:
[img]/upload/attachment/50167/21fd71eb-9eea-3065-a232-d5249bbd42f5.jpg[/img]
因为是新手,所以开始很难,前两天下载了个MyEclipse,费了九牛二虎之力,总算把JBPM的开发环境搭起来了。对照着JBPM的用户手册,目前已经实现了数据库存储,以及一个基本流程的流转(纯流程,静态表单数据)。数据库设计也大概做完了,也搭起了Hibernate环境,并根据数据库生成了数据层代码。从今天开始,就要着手实现动态加载工作流表单了。
首先,我的工作流表单是定义在数据库里,大概的结构是这样:
[img]/upload/attachment/50161/9bcfcaa3-2d2e-354c-b92a-36c272f5a0b0.jpg[/img]
每个流程定义了一个Form,FormItem里存放这个Form里各有什么控件,以及控件的类型及值类型等。据我了解,Java(或者Jsp)里,没有像.NET里那样的动态加载控件机制,所以,我写了一个Bean,根据传进来的流程名称,来加载相应的表单及里面的控件。
public class WrokflowFormBean {
private String processDefinitionName = "";
private String outputControl = "";
public void setProcessDefinitionName(String processDefinitionName) {
this.processDefinitionName = processDefinitionName;
}
public String getOutputControl() {
if(processDefinitionName.equals(""))
return "";
FormDAO formDao = new FormDAO();
List<Form> forms = formDao.findByProcessDefinitionName(this.processDefinitionName);
if(forms.size() > 0){
Form form = forms.get(0);
Set<FormItem> formItems = form.getFormItems();
for(FormItem item : formItems){
String controlContent = "";
ControlType controlType = item.getControlType();
if(controlType.getControlType().equals("text")){
String controlValue = "";
Set<FormItemValue> formItemValues = item.getFormItemValues();
for(FormItemValue v : formItemValues){
if(v.getIsDefault() == 1){
controlValue = v.getItemValue();
}
}
controlContent = String.format("<input type=\"text\" name=\"%s\" style=\"%s\" value=\"%s\" />",item.getName(),item.getCssStyle(),controlValue);
}
else if(controlType.getControlType().equals("select")){
//...
}
outputControl += controlContent;
}
}
return outputControl;
}
}
在处理流程的页面里,调用这个Bean,就可以得到需要加载的表单了。
提交的时候,在根据数据库里的配置,分别得到这些控件的值,然后存储就行了。
//找到这一步需要提交的表单数据
FormDAO formDAO = new FormDAO();
List<Form> forms = formDAO.findByProcessDefinitionName(workflowName);
if(forms.size() > 0){
Form myform = forms.get(0);
Set<FormItem> formItems = myform.getFormItems();
for(FormItem item : formItems){
if(item.getEditableNode().indexOf(String.format("%d,", taskInstance.getTask().getId())) != -1){
contextInstance.createVariable(item.getName(), ParseValue(item,request.getParameter(item.getName())));
}
}
}
我目前是存储到了流程的变量里,当然也可以存储到数据库里。
现在的问题是,一个流程里,有好多人参与(好多Task),每个人看到的,和可以编辑的控件不可能一样。如果根据当前的不同的环节,或者不同的人,在我定义的Bean里返回不同的控件内容呢?我现在是在fwo_FormItem表里定义了两个字段:VisibleNode和EditableNode,里面存的是相应的Task的Id。这样的话,只需要在调用Bean之前,先把当前Task的Id传进来就可以了。
[color=red]如果是流程中的环节,我可以使用jbpmContext.getTaskList来得到当前的任务,从而得到Task的Id。但是,当一个用户新建流程的时候,如果获得Task的Id呢?因为我想是当这个用户提交了表单的时候,我才应该创建流程实例什么的。但是此时还没有流程实例,也无法得到相应的Task。请大家帮帮忙,看如何实现?[/color]
附一张我的流程设计图,画红圈的就是如何加载表单的地方:
[img]/upload/attachment/50167/21fd71eb-9eea-3065-a232-d5249bbd42f5.jpg[/img]