http://www.blogdriver.com/macrochen/1185209.html
1 Ofbiz概况
OFBiz是一个非常著名的开源项目,提供了创建基于最新J2EE/XML规范和技术标准,构建大中型企业级、跨平台、跨数据库、跨应用服务器的多层、分布式电子商务类WEB应用系统的框架。
OFBiz最主要的特点是OFBiz提供了一整套的开发基于Java的web应用程序的组件和工具。包括实体引擎, 服务引擎, 消息引擎, 工作流引擎, 规则引擎等。
2 系统组成与层次结构
1)几大引擎
实体引擎, 服务引擎, 消息引擎, 工作流引擎, 规则引擎等;
其中所有最底层的是实体引擎和服务引擎,工作流引擎是基于这两个引擎之上的。
2)几大应用
下面按应用名称和目录进行排列:
内容管理 content
用户管理 PartyMgr
市场管理 Marketing
编目管理 catalog
设备管理 facility
订单管理 ordermgr(使用了工作流引擎)
帐户管理 accounting
人力资源管理 workeffort
系统管理 webtools
3. 工作流模块特点分析
1)根据ofbiz开发者在网上的反馈,ofbiz的工作流引擎能满足大多数的用户提出的功能需求;性能也不错。但它的用户群主要来自其他模块。
2)根据研究和代码分析,ofbiz的代码比较复杂。因为对于想用ofbiz来开发工作流的开发者来说,它不仅仅是一个纯工作流引擎,它还是一个开发平台和工具集,它的各个模块交叉较多(比如启动流程不是调用工作流引擎的接口,而是调用entity engine和service engine的接口),代码量大。
复杂性的另一个表现是ofbiz的呈现层使用了大量自己定义的TagLib,业务逻辑层的采用自己独立的页面流转控制逻辑,持久层用实体引擎来实现,都不是采用通用的方法。
3)完整版数据库有500多张表,limit版(自己搭建的用于工作流的版本)数据库有170多张表。
4) ofbiz的工作流引擎已经有用户使用,而且其他模块已经在很多行业投入应用;但它的工作流引擎还是处于阿尔法版本。
ofbiz2.11提供的缺省的web server是jetty,我们打算把他转移到tomcat上来。ofbiz2.11提供的缺省的数据库是hsql的,用webtools,转移他的数据库是非常方便的,这里我们介绍如何安装到mysql中。
我认为不要问为什么要这么装,在你用本文的方法安装两遍后,一切你都明白了。
1下载ofbiz2.11
可以通过www.ofbiz.org下载,也可以直接到http://sf.net上面查找ofbiz项目下载。
2下载并安装tomcat
建议使用tomcat4.1.18以后的版本,曾经在网上看到过有人介绍tomcat.4.1.7之前的版本运行ofbiz时,taglib的处理非常慢,之后的版本就没有这个问题了。tomcat可以到www.apache.org处下载。
3 安装Mysql
主要是建立表空间和建立用户。
4安装ofbiz
4.1设置环境变量
JAVA_HOME
ANT_HOME
CATALINA_HOME
OFBIZ_HOME
4.2复制classes和jar文件
复制OFBIZ_HOME\commonapp\etc\目录下面的所有文件到CATALINA_HOME\share\classes中。
复制OFBIZ_HOME\commonapp\lib\目录下*.jar到CATALINA_HOME\share\lib中。
复制OFBIZ_HOME\core\lib\目录下*.jar到CATALINA_HOME\share\lib中。
复制OFBIZ_HOME\lib\目录下*.jar到CATALINA_HOME\share\lib中。
注意OFBIZ_HOME\lib\中的jar文件是按目录分门别类存放的,复制到CATALINA_HOME\share\lib需要去掉所有目录,把所有jar都放到lib目录下。
4.3编辑CATALINA_HOME\share\classes\entityengine.xml文件
找到如下文字:
<datasource name=localmysql
helper-class=org.ofbiz.core.entity.GenericHelperDAO
field-type-name=mysql
check-on-start=true
add-missing-on-start=true
use-foreign-keys=false
join-style=theta-oracle>
<sql-load-path path=commonapp/db prepend-env=ofbiz.home/>
<sql-load-path path=ecommerce/etc prepend-env=ofbiz.home/>
<inline-jdbc
jdbc-driver=org.gjt.mm.mysql.Driver
jdbc-uri=jdbc:mysql://127.0.0.1/ofbiz
jdbc-username=root
jdbc-password=gg
isolation-level=Serializable/>
</datasource>
编辑相应的配置。
查找
<delegator name=default entity-model-reader=main......>
<group-map group-name=org.ofbiz.commonapp datasource-name=localhsql/>
</delegator>
改成
<delegator name=default entity-model-reader=main......>
<group-map group-name=org.ofbiz.commonapp datasource-name=localmysql/>
</delegator>
4.4 复制可执行程序
复制OFBIZ_HOME\setup\catalina41\bin中的ofbiz.bat到CATALINA_HOME\bin
复制OFBIZ_HOME\setup\catalina41\conf中的server.xml到CATALINA_HOME\conf中
注意,这里的server.xml也可以不复制,这里面就是配置ofbiz的Context,手工更新到server.xml中即可
另外注意,ofbiz默认ofbiz和tomcat在一个目录下,因此在server.xml中,他的context路径都是用的相对路径
例如
<Context path=/content docBase=../../ofbiz/content/webapp debug=0 reloadable=true>
4.5 启动
在OFBIZ_HOME\setup\catalina41\bin\runofbiz.bat
内容如下:
ofbiz.bat run
用该命令启动
它首先调用ofbiz.bat设置环境变量,然后启动tomcat.
启动tomcat的时候,ofbiz的DatabaseUtils会检查数据库中是否已经存在系统的表,没有就会自动创建的,一般的创建过程不会出错误的。
如果有错误产生,请察看CATALINA_HOME\logs中的日志文件,一般都是少某个jar,看到少哪个到OFBIZ_HOME中找到后复制到CATALINA_HOME\share\lib中
OFBIZ流程操作使用过程
1 流程定义
一般用JaWe进行流程定义。根据查找的资料,使用JaWe生成的xpdl文件和workflow engine有少许不兼容的情况,摘抄总结如下:
1)JAWE生成DataFields会和ofbiz Implementation Tool里的ActualParameter冲突, 导致runtime data不能正常的获取, 如果你的Tool需要ActualParameter的话,直接输入即可,不需要把它定义成为workflow relevant data.
2)在Activity的TransitionRef部分, 由于FK的缘故,不能import到db
修改方法1: 注释掉 XpdlReader readTransitionRestriction 最后读取readTransitionRefs的代码(由于ofbiz workflow engine没有用到TransitionRefs, 故可以直接注释掉)
修改方法2:修改entity定义文件: WorkflowTransitionRef with WorkflowTransitions relationship type to one-nofk
3)在Activity的TransitionRestriction部分,如果Join/Split transition只有唯一情况,JAWE是不会生成定义Join/Split Type的
修改方法1:手工加上:<Join Type=XOR/> <Split Type=XOR/>
修改方法2:修改 XpdlReader 代码,使其默认为XOR
2流程装载
ofbiz提供页面来实现流程装载,如下:
图 流程装载
3 流程使用
ofbiz没有提供自己的工具来说明流程的使用方法,要求开发人员找到相应的api来调用;另外,ofbiz的orderMgr模块,使用了工作流引擎,但不是纯工作流引擎的应用,它包含了自己的独立的复杂的业务逻辑。
大致的流程使用步骤如下:
1)启动流程
首先,获取实体引擎和服务引擎,一般从页面的request中获取;然后,调用实体引擎新建工作流记录;最后,调用服务引擎启动流程。
2)获取工作列表
首先,用EntityExpr类构造约束List;然后,将约束List作为参数传递给实体引擎查找符合条件的记录;对于查找本部门的或本角色的或指定到本人的工作列表都采用同样的方法。
3)执行活动
首先,调用工作流引擎判断任务是否由该用户操作或是否已经被其他用户accept;其次,调用WorkflowClient类来获取流程实例号,定位流程;然后,调用实体引擎获取该流程实例号的数据;最后,按流程定义调用工作流引擎
获取活动信息并执行相应的活动。
http://www.51one.net/study/otherstu/47190.html
补充几点:
1、 对于Ofbiz构造动态查询语句
(1) 构造查询条件
(2) 给每个条件之间加上逻辑关系,用mainCond = new EntityConditionList(andExprs, EntityOperator.AND);
(3) 设置要显示的字段列表
(4) 设置排序字段列表
(5) 设置Distinct列表
EntityFindOptions findOpts = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true);
(6) 获取实体列表
EntityListIterator pli = delegator.findListIteratorByCondition(entityName, mainCond, null, fieldsToSelect, orderBy, findOpts);
(7) 一个动态查询语句的具体实例
<%
String entityName="study";
List andExprs = new ArrayList();
String number="";
String name="";
String sex="";
String tel="";
//GenericDelegator delegator = GenericDelegator.getGenericDelegator("default");
EntityConditionList mainCond=null;
if (request.getParameter("number")!=null)
number=request.getParameter("number").toString();
if (request.getParameter("name")!=null)
name=request.getParameter("name").toString();
if (request.getParameter("sex")!=null)
sex=request.getParameter("sex").toString();
if (request.getParameter("tel")!=null)
tel=request.getParameter("tel").toString();
//构造查询条件
if (number.compareTo("")!=0)
andExprs.add(new EntityExpr("number",EntityOperator.EQUALS,number));
if (name.compareTo("")!=0)
andExprs.add(new EntityExpr("name1",true,EntityOperator.LIKE,"%"+name+"%",true));
if (sex.compareTo("")!=0)
andExprs.add(new EntityExpr("sex1",true,EntityOperator.LIKE,"%"+sex+"%",true));
if (tel.compareTo("")!=0)
andExprs.add(new EntityExpr("tel",true,EntityOperator.LIKE,"%"+tel+"%",true));
//每个条件间的逻辑关系
if (andExprs.size() > 0)
mainCond = new EntityConditionList(andExprs, EntityOperator.AND);
//要显示的字段列表
List fieldsToSelect = new ArrayList();
fieldsToSelect.add("number");
fieldsToSelect.add("name1");
fieldsToSelect.add("sex1");
fieldsToSelect.add("tel");
//排序字段列表
List orderBy = UtilMisc.toList("number", "name1");
//Distinct列表
EntityFindOptions findOpts = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true);
//获取实体列表
EntityListIterator pli = delegator.findListIteratorByCondition(entityName, mainCond, null, fieldsToSelect, orderBy, findOpts);
while(pli.hasNext())
{
GenericValue cust = (GenericValue)pli.next();%>
<tr>
<td><%=cust.getString("number")%></td>
<td><%=cust.getString("name1")%></td>
<td><%=cust.getString("sex1")%></td>
<td><%=cust.getString("tel")%></td>
</tr>
<%}%>
</table>
2、 对于所有的图片文件,都放在images目录下
3、 设置图片的标签<ofbiz:contenturl>图片路径</ofbiz:contenturl>
4、 链接Tag <ofbiz:url>control.xml里面设置的请求</ofbiz.url>
5、 <region:render section='header'/>引入header定义的文件
header这个标识在regions.xml里面定义
<define id='MAIN_REG' template='/templates/main_template1.jsp'>
<put section='title'>Application Page</put> <!-- this is a default and is meant to overridden -->
<put section='header' content='/includes/bottom.jsp'/>
<put section='leftbar' content='/includes/left.jsp'/>
<put section='middle' content='/includes/middle.jsp'/>
<put section='content' content='/includes/middle.jsp'/> <!-- this is a default and is meant to overridden -->
<put section='top' content='/includes/top.jsp'/>
<put section='error' type="jpublish" content='/includes/errormsg.ftl'/>
<!--<put section='footer' type="jpublish" content='/includes/footer.ftl'/>-->
</define>
然后其它页面只要如下定义即可
<define id='BasePubEmp' region='MAIN_REG'>
<put section='title'>View BasePubEmp</put>
<put section='content' content='/BasePubEmp.jsp'/>
</define>
注意,这边的content所指定的区块就是我们上面定义的content
6、 这些标签都挺简单的,Ofbiz里面都有例子,参照一下就可以了
后续将对Ofbiz中的shark工作流进行描述。
