下载
MoonDataset(自定义Dataset实践) v1.0.doc
MoonDataset工程文件.rar
目录
前言
名词
目标
扩展
初始化
两个功能
数据查询
字段集
查询动作
数据提交
字段集
提交动作
工具类
com.bstek.dorado.common.fileloader.FileLoader
com.bstek.dorado.utils.xml.XmlFactory
效果图
在Studio中添加MoonDataset
配置MoonDataset
自动生成字段
页面效果
前言
目前自定义Dataset的权威文档是Benny编写的《自定义Dataset的步骤-Benny-v10-20070903》,总结其中的步骤如下:
1. 为了在项目运行期间可以使用自定义的Dataset1. 将自定义Dataset打jar包放到项目的WEB-INF/lib下。
2. 编写view-datasets.xml放到项目的%doradohome%下。
2. 为了让studio为我们提供可视化的配置自定义Dataset功能。
1. 将自定义Dataset打jar包放到studio/lib下。
2. 编写user-view-rules.xml放到studio/config下。
名词
名称 |
含义 |
MoonDataset |
本文谈论的自定义数据集。 |
OrigDataset |
原始数据集,即被MoonDataset引用的数据集。 |
View配置文件 |
指View的XML定义文件,名字以.view.xml为后缀。 |
dataset节点 |
指View配置文件中表示dataset的XML节点。 |
目标
允许一个View引用在其他View中定义的Dataset,使用时与直接定义在自身View中的Dataset具有相同的效果。即:
- MoonDataset可以不定义字段而使用/合并OrigDataset的字段。
- MoonDataset可以不定义Parameters而使用OrigDataset的Parameters。
- MoonDataset可以不定义Properties而使用OrigDataset的Properties。
- MoonDataset可以不定义Event而使用OrigDataset的Event。
扩展
MoonDataset继承了com.bstek.dorado.view.data.CustomDataset。根据自身的功能目标需要定义3个属性:
名称 |
类型 |
含义 |
origViewModelConfig |
String |
OrigDataset所在的View配置文件。 |
origDatasetId |
String |
原始数据集ID,即被引用的Dataset的ID。 |
appendFields |
boolean |
合并字段? |
初始化
任何类型的Dataset都有init()方法,通过继承com.bstek.dorado.view.data.DatasetSupport的该方法完成初始化的工作,API说明如下:
public void init(DoradoContext context,
XmlNode node)
throws java.lang.Exception
根据一个XML节点对象自动配置本Dataset。
Parameters:
context - DoradoContext
node - XmlNode
Throws:
java.lang.Exception |
参数说明如下:
- XmlNode node – View配置文件中的dataset节点。
- DoradoContext context – 通常来说实例化dataset只需要node参数就足够了,那么context参数的作用可能是为了解决I18N问题。
|
功能说明如下:
1. 将node的所有attribute的值通过setXxx方法设置到dataset的属性中。
2. 如果配置了listener,则初始化监听器。
3. 根据dataset/masterlink节点初始化主从关系。
4. 根据dataset/fields/field节点初始化字段集。
5. 根据dataset/parameters/parameter节点初始化参数集。
6. 根据dataset/properties/property节点初始化属性集。
- 根据dataset/events/event节点初始化EventHandlers。
|
那么MoonDataset除了完成上面的工作外,还要初始化OrigDataset。相关方法如下:
public void init(DoradoContext context, XmlNode xmlNode) throws Exception {
super.init(context, xmlNode);
initOrigDataset();//初始化源Dataset
initSelfEventHandlers();
//将源Dataset的EventHandler合并到MoonDataset中
}
/**
* 初始化源Dataset
*
* @throws Exception
*/
protected void initOrigDataset() throws Exception {
XmlNode xmlNode = new XmlTool().getDatasetXmlNode(config
.getOrigViewModelConfig(), config.getOrigDatasetId());
ViewModel viewModel = this.getViewModel();
origDataset = (new DefaultDatasetFactory()).createDataset(viewModel,
xmlNode.getAttribute("type"), DEFAULT_MOON_PREFIX
+ this.getId());
origDataset.init(DoradoContext.getContext(), xmlNode);
Class c = this.getObjectClazz();
if (c != null) {
origDataset.setObjectClazz(c);
} else {
this.setObjectClazz(origDataset.getObjectClazz());
}
}
/**
* 将源Dataset的EventHandler合并到MoonDataset中
*/
private void initSelfEventHandlers() {
if (state == ViewModel.STATE_VIEW) {
Iterator i = origDataset.eventHandlers().entrySet().iterator();
EventHandler eventHandler = null;
String eventName = null;
Map.Entry entry = null;
while (i.hasNext()) {
entry = (Map.Entry) i.next();
eventHandler = (EventHandler) entry.getValue();
eventName = (String) entry.getKey();
if (this.getEventHandler(eventName) == null) {
this.addEventHandler(eventHandler);
}
}
}
} |
说明:
1. super.init(context, xmlNode);此时MoonDataset初始化了自身的属性,并且origViewModelConfig与origDatasetId已经得到了View配置的值,但origDataset还没有初始化。
2. initOrigDataset();
初始化origDataset,依据为origViewModelConfig与origDatasetId的值。此时也调用了origDataset的init()方法。
- initSelfEventHandlers();初始化MoonDataset的EventHandler,合并MoonDataset与origDataset的EventHandler。
|
两个功能
Dataset的两大功能是:数据查询与数据提交,所以自定义Dataset的终极目标就是实现这两个功能。
数据查询
需要继承com.bstek.dorado.data.DatasetSupport类的doLoad方法,API如下:
protected abstract void doLoad(boolean createFields,
boolean loadData)
throws java.lang.Exception
根据已设定的条件读取外部数据.
Parameters:
createFields - 是否要执行自动创建字段的操作
loadData - 是否要装载数据
Throws:
java.lang.Exception |
根据API的说明我们知道在这个方法体中我们要注意两点:
- 根据createField的布尔值控制生成dataset字段集的方式。
- 根据loadData的布尔值控制是否加载数据。
所以会出现下面的代码:
if(createFields){
... ...//自动生成字段
}
if(loadDada){
... ...//加载数据
} |
字段集
在MoonDataset中是通过void syncFieldSet (boolean createFields)方法完成字段的同步功能的,规则如下:
- 如果appendFields为true,则合并MoonDataset和OrigDataset的字段集合。
- 否则OrigDataset以MoonDataset定义的字段集合为准。
代码如下:
其中createFieldsFromObjectClazz()的API说明如下,来自com.bstek.dorado.data.DatasetSupport类:
public void createFieldsFromObjectClazz()
自动利用反射将objectClazz中包含的属性映射成Dataset的字段.
此方法将自动为Dataset添加字段对象.
Specified by:
createFieldsFromObjectClazz in interface Dataset |
合并fieldset的两大步骤:
- 将OrigDataset的FieldSet合并到MoonDataset的FieldSet中。
- 把MoonDataset的FieldSet给OrigDataset。
|
注:在syncFieldSet4OrigDataset()方法中,
- 当state为ViewModel.STATE_DESIGN时表明在处理Studio发送自动生成字段的请求,由于目前Studio不支持生成DummyField,所以此处将这种字段过滤掉了,否则会将DummyField按照Field的方式传递给Studio,这样OrigDataset的DummyField到了MoonDataset中就变成一般的字段了。
- 当state为ViewModel.STATE_VIEW或ViewModel.STATE_SERVICE或ViewModel.STATE_REPORT时只需要合并MoonDataset与OrigDatset的字段集。
- 这里没有对state为ViewModel.STATE_UPDATING情景做处理,原因是在服务器端处理UpdateCommand请求时,被提交的Dataset的字段以客户端的为准,并一同提交的服务器端。
|
查询动作
由于MoonDataset是利用origDataset完成查询功能,所以与此相关的依据都要传递给origDataset,包括: pageSize、pageIndex、parameters、properties。MoonDataset的查询动作的代码如下:
/**
* 加载数据的动作
*
* @param createFields
* 是否创建字段
* @param loadData
* 是否加载数据
*/
protected void doLoad(boolean createFields, boolean loadData)
throws Exception {
syncFieldSet(createFields);
if (loadData) {
int pageSize;
if ((pageSize = this.getPageSize()) >= 0) {// $$ Not caution.
origDataset.setPageSize(pageSize);
}
origDataset.setPageIndex(this.getPageIndex());
origDataset.parameters().assign(this.parameters());
origDataset.properties().assign(this.properties());
origDataset.load(loadData);
RecordSet rs = origDataset.recordSet();
this.setRecordSet(rs);
this.setPageSize(origDataset.getPageSize());
this.setPageIndex(origDataset.getPageIndex());
this.setPossibleRecordCount(origDataset.getPossibleRecordCount());
this.setPageCount(origDataset.getPageCount());
this.parameters().assign(origDataset.parameters());
this.properties().assign(origDataset.properties());
}
} |
其中用到了com.bstek.dorado.utils.variant.VariantSet的assing()方法,API说明如下:
public void assign(VariantSet variants)
将本集合中的所有数据全部指派到给定的另一个集合中.
Parameters:
variants - VariantSet |
数据提交
需要继承com.bstek.dorado.data.DatasetSupport的doUpdate方法,API说明如下:
protected abstract void doUpdate()
throws java.lang.Exception
把用户对Dataset中数据的操作更新到外部数据中.
Throws:
java.lang.Exception |
字段集
数据提交时也会涉及到字段集的问题,所以此时syncFieldSet ()方法也会被调用,描述同数据查询。
提交动作
通常提交动作会涉及与数据库的交互,而MoonDataset则需要调用origDataset的update()方法,另外也同样涉及parameters与properties问题,MoonDataset的doUpdate方法代码如下:
protected void doUpdate() throws Exception {
/*
* @1.before update.
*/
// parameters && properties
origDataset.parameters().assign(this.parameters());
origDataset.properties().assign(this.properties());
/*
* @2.update
*/
origDataset.setRecordSet(this.recordSet());
origDataset.update();
this.setRecordSet(origDataset.recordSet());
/*
* @3.after update
*/
// parameters && properties
this.parameters().assign(origDataset.parameters());
this.properties().assign(origDataset.properties());
} |
工具类
com.bstek.dorado.common.fileloader.FileLoader
文件加载器。目前Dorado中两种常见的FileLoader是:
1. com.bstek.dorado.common.fileloader.ResourceFileLoader – 针对存放在classpath中的资源加载器。
2. com.bstek.dorado.common.fileloader.PathFileLoader – 针对绝对路径资源的加载器。
注:决定Dorado使用哪种FileLoader加载资源的是决策者是com.bstek.dorado.common.fileloader.FileLoaderFactory,依据为%webroot%\WEB-INF\dorado.properties。
com.bstek.dorado.utils.xml.XmlFactory
XML解析对象的工厂类。屏蔽了解析XML使用的底层解析器,目前支持JDOM9、JDOM10、DOM4J,详情见Dorado安装目录下的support/jaxen/readme.txt。摘录如下:
dorado中自带的JDOM版本为JDOM 9(也被称为JDOM 0.9)。
如果您的部署环境中必须使用JDOM 10(也被称为JDOM 1.0), 那么请将dorado自带的jdom.jar替换为您所使用的版本,此时dorado可自动适配JDOM 9或JDOM 10。但是dorado使用的第三方工具包jaxen.jar却无法自动进行此类适配,因此您还需要手工用此处的JDOM10/jaxen.jar覆盖原先自带的同名文件。
注: dorado中默认使用的jaxen.jar(即安装目录中的/lib/thirdparty/jaxen.jar)是适用与JDOM 9的版本。
另外,dorado除可自适应JDOM 9和JDOM 10之外也可以自动适配DOM4j。如果您的希望dorado使用DOM4j作为XML解析器,那么请删除部署环境中的jdom.jar。此时dorado将自动尝试适配DOM4j。
注:某些应用服务器的运行是依赖于JDOM 的,如WebLogic、JBOSS等。在这种情况下您可能无法从部署环境中移除JDOM。 |
效果图
在Studio中添加MoonDataset
配置MoonDataset
自动生成字段
页面效果