浅谈OFBIZ
作者:李心
今年的暑假,本着走进社会,了解生活的目的,我踏进了北京朗华世纪科技发展有限公司,开始我的暑期实习。
正在我兴奋着自己能够成功地进入了这家公司后,一个不小的挑战摆在了我的面前。公司交给我的任务是对OFBIZ的release4.0中的bug的测试。在这期间我遇到了许多大大小小的麻烦,主要是因为对OFBIZ的不熟悉造成的,幸亏同事们对我的帮助,让我克服了这一个个困难。
为了像我一样的新手们能够对OFBIZ有一个初步的了解,所以我主要从以下三个方面来对OFBIZ 4.0做一个大致的介绍。
一. OFBIZ的release4.0开发环境的搭建。
二. OFBIZ的汉化示例。
三. OFBIZ的模块开发示例。
开发环境的搭建
首先,我们先来安装JDK1.5.0。
第一步:我们要先从http://java.sun.com上下载jdk-1_5_0_04-windows-i586-p.exe。
第二步:我们要把它安装到指定的路径里。
第三步:开始配置环境变量。下面我举一个小例子:
例如我安装JDK到E:\jdk1.5.0,那么环境变量应改为如下:
Java_HOME: E:\jdk1.5.0
PATH: E:\jdk1.5.0\bin;
CLASSPATH: E:\jdk1.5.0\lib\tools.jar;
E:\jdk1.5.0\jre\lib\rt.jar;
其次,我们来安装mysql5.0.
第一步:我们要先从http://dev.mysql.com/downloads/mysql/5.0.html上下载mysql5.0的安装文件。
第二步:我们最好按照它的默认路径安装好。并记好你安装时输入的密码,在以后安装OFBIZ时还有用。
接着我们就要来安装我们的编译器eclipse了。eclipse现在主要有三个版本3.1,3.2和3.3(也就是Europe版的)。
第一步:我们要从http://www.eclipse.org上下载eclipse3.2的安装文件。
第二步:我们就按着安装步骤一步步地安装好就可以了。
然后我们打开eclipse,来安装我们要测试release4.0的subclipse, mylyn, mylyn-extras。其实它们的安装方法基本一样。
1.subclipse的安装
(1)在eclipse里点“帮助”里的软件更新中的查找并安装。
(2)点击搜索要安装的新功能部件选项后,点击下一步。
(3)在这里安装软件有两种方法:
一.选择“新建远程站点”。出来新建远程站点对话框后,输入名字和要下载的软件的地址。我们下的是subclipse,当然名字就输入subclipse了。下载subclipse的网站地址是http://subclipse.tigris.org/update_1.0.x当这些都输入好后,我们点击确定,然后再点击完成。如图1-1所示。此时就会自动地连接站点下载了,到进度快完成的时候,你会看到有提示,问是否完全安装?一般我们初学者就选择完全安装就好了,对于有自己要求的人来说,可以选择性的安装。
图1-1
二.是我们从网站上已经把软件下载到电脑里了的情况。我们选择“新建本地站点”。出来新建本地站点对话框后,输入名字和本地软件所在的地址。当这些都输入好后,我们点击确定,然后再点击完成,它就会自动安装了。
2.mylyn 的安装
和上文提到的subclipse的步骤一样,在此我就仅把mylyn的下载地址提供给大家http://download.eclipse.org/tools/mylyn/update/e3.2(这个地址是适用于3.1和3.2版的,要是要安装适用于3.3版的,把地址最后的3.2改为3.3即可)
3.mylyn-extras 的安装
也和上文提到的subclipse的步骤一样,在此我也就仅把mylyn-extras的下载地址提供给大家http://download.eclipse.org/tools/mylyn/update/extras(适用于三个版本)
下面我们就要开始用SVN检测并下载OFBIZ的release4.0了。
第一步:我们点击“文件”里的新建中的“项目”。
第二步:我们将SVN文件夹点开,选择里面的“从SVN检出项目”,然后点击下一步。
第三步:我们选择创建新的资源库位置,然后点击下一步。
第四步:会出现一个让我们输入URL的对话窗,我们在对话框里输入我们要检测出的地址http://svn.apache.org/repos/asf/ofbiz后点击下一步。
第五步:我们点开branches后,选择release4.0,然后点击下一步。如图1-2。
第六步:我们输入任意的项目名称后点击下一步。
第七步:我们可以使用省缺工作空间(也就是默认的地址),也可以自己选择路径,然后点击完成即可。
图1-2
在我们下好了OFBIZ的release4.0后,下面我们要开始安装了。
第一步:我们要更改一下数据库。我们要在“包资源管理器”或“导航器”里的你刚刚下载的OFBIZ下的branches中的release4.0下的framework下的entity里的config里面打开entityengine.xml文件。
第二步:在此文件里找有四行都是以<delegator name开头的,请将里面的datasource-name="localderby"都改为datasource-name="localmysql"。
第三步:在此文件里找到〈datasource-name="localmysql"开头的代码区域,将里面的jdbc-username= 和jdbc-password= 都改为你安装mysql时的用户名和密码。
第四步:我们要在entity下的lib下的jdbc中导入mysql5.0的驱动,mysql5.0的驱动可以上这个网页上任选其一下载http://dev.mysql.com/get/Downloads/Connector-J/ mysql-connector-java-5.0.6.zip /from/pick#mirrors
第五步:我们可以在“包资源管理器”或“导航器”里的你刚刚下载的OFBIZ下的branches中的release4.0中找到一个名为build.xml的文件,我们在此文件上点击鼠标右键,选择运行方式里的2 Ant构建。(此时不要点击1 Ant构建,这个为默认构建,第一次需要做一些调节,所以选另一个构建)
第六步:在左侧的“名称”栏目里我们要选择clean,build,run-install,然后点击运行。(接下来将是一段漫长的安装时间,大约40分钟左右)如图1-3所示。
第七步:当安装的窗口里显示complete时,就安装好了。
提示:再安装的过程中你可能会像我一样遇到了这个问题而不能安装成功,就是没有建立mysql的数据库。下面我来说一下解决方法:
第一步:打开你的MySQL Command Client,然后输入你安装mysql时的密码。
第二步:输入 show databases; 然后回车。然后你会看到一个database的表格,检查一下这个表格里有没有mysql这一项,如果有了,那说明就不是这个问题了,要是没有接着进行下一步。
第三步:输入 create database mysql; 然后回车。
第四步:重复第二步,此时应该在database的表格里有mysql这一项了。然后再按照前面说过的安装一下OFBIZ,这下应该就可以了。
图1-3
当我们安装成功了以后,要开始运行OFBIZ了。
第一步:还是找到build.xml文件,我们在此文件上点击鼠标右键,选择运行方式里的2 Ant构建。
第二步:在左侧的“名称”栏目里我们要选择clean,build,run,然后点击应用,再点击运行。
第三步:等待运行成功后,打开https://localhost:8443/accounting/control/main这一网址,输入用户名为admin,密码就是你设的密码,如果能成功进入,那就说明运行成功了。
最后我们还剩下的工作就很简单了,要加入OFBIZ的DEV_ML和Apache的JIRA。
OFBIZ的DEV_ML
第一步:打开http://docs.ofbiz.org/display/OFBADMIN/Mailing+Lists这个网址,点击User List里的Subscribe。
第二步:发送邮件,主题和内容写什么都可以。
第三步:很快你会收到一封回信,你需要再给它回一封信,确认你要加入就可以了,从此以后你就可以收到很多信息了。
Apache的JIRA
加入JIRA的方法是一样的,网址是http://www.apache.org/foundation/mailinglists.html
当这一切都做好了以后,我们就可以建立task来接受JIRA的信息了。操作步骤如下:
第一步:点开窗口,点显示视图里的“其它”选项。
第二步:选择Mylyn里的Task List,然后点确定。
第三步:用鼠标右键点击 Uncategorized里的New里的Query。
第四步:点击Add Task Repository后选择JIRA,然后点Next。
第五步:先进入https://issues.apache.org/jira/secure/Dashboard.jspa注册一个用户,然后再在server里输入https://issues.apache.org/jira,UserID和Password就是你刚刚注册的用户名和密码,Label可以随便写。输完这些以后点击一下Validate setting,检查一下是不是都可以了。都可以了以后,点击完成。
第六步:之后会出现一个大的表格有许多需要选的。我们可以根据自己的需要在里面进行选择。然后点击完成,它就会自动联网,进行同步更新。
OFBIZ的汉化示例
首先我们先来了解一个名词“汉化”,顾名思义,就是把不是中文的语言翻译成中文,方便大家的使用。
大家都知道,OFBIZ的release4.0是由各个模块组成的(会在以后有所介绍),而每个模块里又包含有许许多多的子文件夹,每个文件夹里又有许多的程序文件。几乎每个文件里都会有“键”和“值”,我们的汉化任务就是把这些“键”所对应的“值”的英文改为中文,这是一个看似简单的工作,不就是把英文翻译成中文嘛,可是实际上却实在是个累人的工作,不计其数的文件,每个文件里又有许多要翻译的,着实是个庞大的工程。所以在翻译的过程中出现错误也是在所难免的,所以这就要求我们在翻译之后要进行校对工作。
在我们核实了翻译的准确无误之后,我们再要做的就是把这些以Unicode码记录下来的中文转换为Java能够使用的ASCII码,再将修改过的文件的文件名按照国际统一标准加上后缀_zh就算是汉化完成了。
为了大家能够更好的理解,下面我就来举一个简单的小例子。
我们以release4.0下的applications/accounting/config/AccountingUiLabels.properties为例。当我们双击打开这个文件时,我们可以看到有些代码显示为蓝色,这些代码就是我们将要翻译的对象。如图2-1。
图2-1
下面翻译就是我们自己的事情了。翻译好的对应文本如图2-2。
图2-2
接下来我们的工作是进行校对,以确保准确性。我们可以通过类似于我们公司开发的这样一个工具,进行校对工作。如图2-3。
图2-3
这个工具不仅可以中英对照,更可以支持多国文字对照翻译。
最后我们只需要将这些中文对应的Unicode码,转换成Java可以识别的ASCII码就好了。我们可以通过我们公司编的一个程序实现这些。转换好的如图2-4所示。
图2-4
就是这样一个不算复杂,但是又工作量很大的过程,方便了广大的中国用户,我们公司也是中国为数不多的对OFBIZ进行汉化的公司之一,希望能够给广大的用户们带来方便。
OFBIZ的模块开发示例
一 准备工作
1. 在Eclipse下用SVN在朗华公司的网站上下载已汉化的OFBIZ项目。
2. 如图可以看到主要有4个大的主要的模块:applications、framework、hot-deploy、specialpurpose,而有些模块下又有许多小的具体的应用模块。
图3-1
二 实施阶段
下面我们将以我们公司的会议室预订服务模块为例,来具体讲解如何用OFBIZ 来做二次开发。
1.首先,建一个meetingroom模块
我们在specialpurpose模块下模仿别的小模块,建一个meetingroom模块,具体的配置等我们做的时候,再详细的介绍。
图3-2
2.加载meetingroom模块
(1)在specialpurpose模块下有一个component-load.xml的模块加载配置文件,将这行代码写入其中相应的位置
<load-component component-location="${ofbiz.home}/specialpurpose/meetingroom"/>
(2) 同时将specialpurpose模块下的build.xml里的<filelist/>修改一下,将下面的红色字加进去。
<filelistid="application-builds"dir="."files="pos/build.xml,hhfacility/build.xml,assetmaint/build.xml,rmiservice/build.xml,meetingroom/build.xml"/>
这样做只是保证了OFBIZ在运行的时候,加载meetingroom模块而已,OFBIZ并不知道我们要它做什么,让它具体做什么还要我们在meetingroom模块内进行配置。
3.meetingroom模块内的配置
(1)ofbiz-component.xml:具体配置本模块内的应用
代码如下:
<ofbiz-component name="meetingroom"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.ofbiz.org/dtds/ofbiz-component.xsd">
<resource-loader name="main"type="component"/>
<!-- place theconfig directory on the classpath to access configuration files -->
<classpath type="dir"location="config"/>
<classpath type="dir"location="script"/>
<!-- load single or multiple external libraries -->
<classpath type="jar"location="build/lib/*"/>
<!-- entityresources: model(s), eca(s), group, and data definitions -->
<entity-resource type="model"reader-name="main"loader="main"location="entitydef/entitymodel.xml"/>
<entity-resource type="group"reader-name="main"loader="main"location="entitydef/entitygroup.xml"/>
<!-- serviceresources: model(s), eca(s) and group definitions -->
<service-resource type="model"loader="main"location="servicedef/services.xml"/>
以下代码的作用如下图:在页面的模块标题中显示‘MeetingRoom’
<webapp name="meetingroom"
title="MeetingRoom"
server="default-server"
location="webapp/meetingroom"
base-permission="MEETINGROOM"
mount-point="/meetingroom"
app-bar-display="true"/>
</ofbiz-component>
图3-3
(2)build.xml的配置参考一下别的模块即可。
这样我们的模块应用环境就搭建得差不多了,剩下的就是如何实现功能了,以下图为例,为了实现登陆之后就进入下面的页面,还有一个“Main”超连接标题,当然,也是连接到本页面的,下面具体的讲解其开发过程:
图3-4
(1) Main小标题的开发过程:
在component://meetingroom/webapp/meetingroom/includes/目录下建一个meetingroomappbar.ftl文件,其代码如下:
<div class="apptitle">MeetingRoom</div>
<div class="row">
<div class="col"><ahref="<@ofbizUrl>main</@ofbizUrl>">Main</a></div>
</div>
在meetingroom/widget/meetingroom/CommonScreens.xml里,有一个名为main-decorator的screen,红色字即为‘Main’的配置代码。
<screen name="main-decorator">
<section>
<actions> <set field="layoutSettings.headerImageUrl"value="/images/ofbiz_logo.jpg"global="true"/>
<set field="activeApp"value="meetingroom" global="true"/>
<setfield="appheaderTemplate"value="component://meetingroom/webapp/meetingroom/includes/meetingroomappbar.ftl"global="true"/>
</actions>
<widgets>
<include-screen name="GlobalDecorator"location="component://common/widget/CommonScreens.xml"/>
</widgets>
</section>
</screen>
(2) 主页main跳转
controller.xml里的main配置:
<request-map uri="main">
<security https="true"auth="true"/>
<response name="success"type="view"value="main"/>
</request-map>
<view-map name="main"type="screen"page="component://meetingroom/widget/meetingroom/MeetingRoomScreens.xml#findMeetingRoom"/>
MeetingRoomScreens.xml里的findMeetingRoom配置:
<screen name="findMeetingRoom">
<section>
<actions>
<set field="titleProperty"value="PageTitleEditFacilityGroupMembers"/>
<set field="headerItem"value="facilityGroup"/>
<set field="tabButtonItem"value="EditFacilityGroupMembers"/>
<set field="productCategoryId"from-field="parameters.productCategoryId"/>
<!---java 脚本语言配置 作用是为程序准备数据即下拉框中会议室组名 -à
<script location="component://meetingroom/webapp/meetingroom/WEB-INF/actions/prodcatalog/FindCatalogs.bsh"/>
</actions>
<widgets>
<decorator-screen name="CommonMeetingRoomDecorator"location="component://meetingroom/widget/meetingroom/CommonScreens.xml">
<decorator-section name="body">
<section>
<widgets>
<platform-specific>
<!---FreeMarker配置 作用是页面的内容显示 -à
<html><html-template location="component://meetingroom/webapp/meetingroom/findcatalog/FindCatalogs.ftl"/></html>
</platform-specific>
</widgets>
</section>
</decorator-section>
</decorator-screen>
</widgets>
</section>
</screen>
(3)当你点击“select”时,即带参数的页面跳转,配置跟上一部差不多。
(4)权限设置:
OFBIZ的权限设置模式是按模块划分的,每一个模块可以是单独独立的,它有自己的安全组和权限。一个安全组可以添加或删除权限,组成一个权限更大的或更小的安全组。
默认情况下,这些安全组和权限是在OFBIZ第一次初始化的时候就加载的,过程如下:
图3-5
在specialpurpose下建一个data文件夹,在其下建一个MeetingRoomSecurityData.xml文件(如上图),在其中配置meetingroom模块的安全组和权限,主要有这些安全组和权限:
MEETINGROOMADMIN meetingroom管理员安全组
MEETINGROOM_CREATE meetingroom预订安全组
MEETINGROOM_UPDATE meetingroom编辑安全组
MEETINGROOM_DELETE meetingroom取消安全组
MEETINGROOM_VIEW meetingroom浏览安全组
MEETINGROOM_ADMIN meetingroom管理员权限
MEETINGROOM_CREATE meetingroom预订权限
MEETINGROOM_UPDATE meetingroom修改权限
MEETINGROOM_DELETE meetingroom取消预订权限
MEETINGROOM_VIEW meetingroom浏览权限
具体配置代码,参照其它模块的就可以了,很简单的。
有了安全组和权限我们就要用它来服务于我们的程序,首先,OFBIZ的通用做法是在component://meetingroom/widget/meetingroom/MeetingRoomScreens.xml里的名为CommonMeetingRoomDecorator 的screen配置浏览者必须具有MEETINGROOM_VIEW权限,如图:
图3-6
当用户具体的操作的时候,我们也要判断其是否具有对应的权限,例如,要往数据库里插入数据必须具有MEETINGROOM_CREATE权限,修改要MEETINGROOM_UPDATE权限等,例如在页面判断用户的权限,然后根据权限判断是否显示其下一步的操作,代码如下:
<#ifsecurity.hasEntityPermission("MEETINGROOM", "_CREATE",session)>
<aclass="smallSubmit" href="<@ofbizContentUrl>gotoBookMeetingRoom?sign=C&productId=${productId?if_exists}&userLoginId=${sessionAttributes.userLogin.userLoginId} &fromDate=${f}&thruDate=${t} &productCategoryId=${productCategoryId}&selectDate=${selectDate?if_exists}</@ofbizContentUrl>">新建</a>
</#if>