创建基于gwtext的数据绑定应用(1)

参考Delphi的数据绑定设计,此设计的一大特点就是以数据源控件为中心外围大量的扩展各种数据控件,并且能够支持和响应数据源的事件,这里我也要做这样一件事情,数据源称为Dataset

创建Dataset
毫无疑问,Dataset是整个数据绑定应用的核心,这个Dataset应该包括如下这些内容的支持:
1、数据存储(使用Store)
2、数据交互(与服务器端的交互);
3、事件触发;
3、动作处理;


public class Dataset implements DatasetInterceptor, JSONable {
private final DatasetView view;
private final List<Record> removedRecords = new ArrayList<Record>();
private final List<Record> insertedRecords = new ArrayList<Record>();
private final Set<Record> selectedRecords = new HashSet<Record>();
private final List<DatasetInterceptor> interceptors = new ArrayList<DatasetInterceptor>(); //包含所有客户端的拦截器以及所有的slave数据集
private final Map<String, DatasetAction> actions = new HashMap<String, DatasetAction>(); //数据处理动作

protected int cursor = -1; // 当前游标位置 (用户正在操作的位置)
protected int start; // 本次取数据的开始位置
protected int pageSize; // 分页大小
protected int rowCount; // 本次提取数据的行数
protected int totalRowCount; // 记录集的总行数
protected Store store;
protected Dataset masterDataset;
protected boolean append;

protected final ConditionSet staticConditions = new ConditionSet(Constants.CONDITION_AND); //静态条件,服务器定义的条件,或者主从表定义的条件
protected final ConditionSet dynamicConditions = new ConditionSet(Constants.CONDITION_AND); //动态条件,客户端的查询等,每次会被清空,与staticConditions是and关系的

public JSONValue toJSON() {
JSONProxy json = new JSONProxy();
json.put("cursor", this.cursor);
json.put("start", this.start);
json.put("pageSize", this.pageSize);
json.put("rowCount", this.rowCount);
json.put("totalRowCount", this.totalRowCount);
json.put("view", this.view);
json.put("entity", this.view.getEntity());
json.put("viewCode", this.view.getCode());
//
if(this.staticConditions != null) {
json.put("staticConditions", this.staticConditions);
}
if(this.dynamicConditions != null) {
json.put("dynamicConditions", this.dynamicConditions);
}
//
List<JSONValue> removedRecords = new ArrayList<JSONValue>();
for(Record rec: this.removedRecords) {
removedRecords.add(this.view.toJSON(rec));
}
json.putArray("removedRecords", removedRecords);
//
List<JSONValue> modifiedRecords = new ArrayList<JSONValue>();
Record[] records = this.getStore().getModifiedRecords();
for(Record rec: records) {
modifiedRecords.add(this.view.toJSON(rec));
}
json.putArray("modifiedRecords", modifiedRecords);
//子数据集
for(DatasetInterceptor in: this.interceptors) {
if(in instanceof Dataset) {
Dataset child = (Dataset)in;
json.putNew2Array("child", new String[]{child.view.getCode()});
json.put(child.view.getCode(), child.toJSON());
}
}
return json.toJSON();
}

public Dataset(DatasetView view) {
this.view = view;
this.pageSize = view.getPageSize();
this.getStore();
if(this.view.isAutoLoad()) {
this.query();
}
if(view.getActions() != null) {
for(DatasetActionDescriptor desc: this.view.getActions().getActions()) {
DatasetAction da = DatasetActionFactory.createDatasetAction(desc.getAction(), desc.getDesicion());
if(da != null)
this.actions.put(desc.getAction(), da);
}
for(DatasetActionDescriptors group: this.view.getActions().getGroups()) {
for(DatasetActionDescriptor desc: group.getActions()) {
DatasetAction da = DatasetActionFactory.createDatasetAction(desc.getAction(), desc.getDesicion());
if(da != null)
this.actions.put(desc.getAction(), da);
}
}
}
}

public Dataset(Dataset masterDataset, DatasetView view) {
this(view);
this.masterDataset = masterDataset;
this.masterDataset.addInterceptor(this);
}

// properties

public ConditionSet getStaticConditions() {
return staticConditions;
}

public ConditionSet getDynamicConditions() {
return dynamicConditions;
}

public List<Record> getRemovedRecords() {
return removedRecords;
}

public List<Record> getInsertedRecords() {
return insertedRecords;
}

public int getStart() {
return start;
}

public int getPageSize() {
return this.pageSize;
}

public void setPageSize(int pageSize) {
if(pageSize > 0) {
this.pageSize = pageSize;
}
}

public int getPageCount() {
return this.totalRowCount / this.pageSize + (this.totalRowCount % this.pageSize == 0?0:1);
}

public int getRowCount() {
return rowCount;
}

public int getTotalRowCount() {
return totalRowCount;
}

public int getCursor() {
return this.cursor;
}

public Record getRecordAtCursor() {
return this.getRecordAt(this.cursor);
}

public Record getRecordAt(int rowIndex) {
Store store = this.getStore();
if(rowIndex >= 0 && rowIndex < store.getCount())
return store.getAt(rowIndex);
else
return null;
}

public void set(String field, Object value) {
Record rec = this.getRecordAtCursor();
if(rec == null) return;
Object oldValue = null;
if(value instanceof String) {
oldValue = rec.getAsString(field);
} else if(value instanceof Integer) {
oldValue = rec.getAsInteger(field);
} else if(value instanceof Double) {
oldValue = rec.getAsDouble(field);
} else if(value instanceof Float) {
oldValue = rec.getAsFloat(field);
} else if(value instanceof Boolean) {
oldValue = rec.getAsBoolean(field);
} else if(value instanceof Date) {
oldValue = rec.getAsDate(field);
} else {
oldValue = rec.getAsObject(field);
}
if(!this.fireBeforeIntercept(Constants.ACTION_DATACHANGED, new Object[]{field, oldValue, value})) {
return;
}
this.fireOnIntercept(Constants.ACTION_DATACHANGED, new Object[]{field, oldValue, value});
rec.set(field, value);
this.fireAfterIntercept(Constants.ACTION_DATACHANGED, new Object[]{field, oldValue, value},
Constants.DATASET_ACTION_RESULT_OK);
}

public Store getStore() {
if(this.store == null) {
JsonReader reader = new JsonReader(this.view.asRecordDef());
reader.setRoot("rows");
reader.setTotalProperty("totalRowCount");
if(StringUtils.isEmpty(this.view.getGroupBy())) {
this.store = new Store(reader);
} else {
this.store = new GroupingStore(reader);
((GroupingStore)store).setGroupField(this.view.getGroupBy());
}
store.setSortInfo(new SortState(this.view.getFields()[0].getName(), SortDir.ASC));
}
return this.store;
}

public DatasetView getView() {
return this.view;
}

public Dataset getMasterDataset() {
return this.masterDataset;
}

public boolean isAppend() {
return append;
}

public void setAppend(boolean append) {
this.append = append;
}

public void loadJsonData(String jsonString) {
Store store = this.getStore();
store.loadJsonData(jsonString, append);
this.totalRowCount = store.getTotalCount();
this.rowCount = store.getCount();
this.cursor = -1;
}

// selected rows
public void selectRows(Record[] rows) {
Set<Record> set = new HashSet<Record>();
for(Record row: rows) {
set.add(row);
}
this.resetSelectionRows(set, null);
}

public void deselectRows(Record[] rows) {
Set<Record> set = new HashSet<Record>();
for(Record row: rows) {
set.add(row);
}
this.resetSelectionRows(null, set);
}

public void resetSelectionRows(Record[] rows) {
if(rows == null) return;
Set<Record> newRows = new HashSet<Record>(rows.length);
for(Record row: rows) {
newRows.add(row);
}
Set<Record> selectionRows = new HashSet<Record>();
Set<Record> deselectionRows = new HashSet<Record>();
for(Record row: this.selectedRecords) {
if(!newRows.contains(row)) {
deselectionRows.add(row);
}
}
for(Record row: newRows) {
if(!this.selectedRecords.contains(row)) {
selectionRows.add(row);
}
}
this.resetSelectionRows(selectionRows, deselectionRows);
}

public void resetSelectionRows(Set<Record> selectionRows, Set<Record> deselectionRows) {
if(!this.fireBeforeIntercept(Constants.ACTION_SELECTIONCHANGED, new Object[]{this.selectedRecords, selectionRows, deselectionRows})) {
return;
}
this.fireOnIntercept(Constants.ACTION_SELECTIONCHANGED, new Object[]{this.selectedRecords, selectionRows, deselectionRows});
if(selectionRows != null)
this.selectedRecords.addAll(selectionRows);
if(deselectionRows != null)
this.selectedRecords.removeAll(deselectionRows);
this.fireAfterIntercept(Constants.ACTION_SELECTIONCHANGED, new Object[]{this.selectedRecords, selectionRows, deselectionRows},
Constants.DATASET_ACTION_RESULT_OK);
}

public final Set<Record> getSelectedRecords() {
return selectedRecords;
}

/**
* 数据集复位,恢复初始状态
*/
public void reset() {
this.totalRowCount = 0;
this.cursor = -1;
this.insertedRecords.clear();
this.removedRecords.clear();
}

public void resetTotalRowCount() {
this.totalRowCount = 0;
}

// events
public void addInterceptor(DatasetInterceptor event) {
if(this.containsInterceptor(event)) return;
this.interceptors.add(event);
}

public void removeInterceptor(DatasetInterceptor event) {
if(event == null) return;
this.interceptors.remove(event);
}

public boolean containsInterceptor(DatasetInterceptor event) {
return this.interceptors.contains(event);
}

public boolean fireBeforeIntercept(String operation, Object[] params) {
boolean res = true;
for(DatasetInterceptor e: this.interceptors) {
res = e.doBeforeIntercept(this, operation, params) && res;
}
return res;
}

public void fireOnIntercept(String operation, Object[] params) {
for(DatasetInterceptor e: this.interceptors) {
e.onIntercept(this, operation, params);
}
}

public void fireAfterIntercept(String operation, Object[] params, int resultCode) {
for(DatasetInterceptor e: this.interceptors) {
e.doAfterIntercept(this, operation, params, resultCode);
}
}

// actions
public void setAction(String actionName, DatasetAction action) {
this.actions.put(actionName, action);
}

public void removeAction(String actionName) {
this.actions.remove(actionName);
}

@Override
public void doAfterIntercept(Dataset dataset, String operation, Object[] params, int resultCode) {

}

@Override
public boolean doBeforeIntercept(Dataset dataset, String operation, Object[] params) {
return true;
}

@Override
public void onIntercept(Dataset dataset, String operation, Object[] params) {

}

// operations
public boolean isDirty() {
return this.store.getModifiedRecords().length >= 0 || !this.removedRecords.isEmpty();
}

public void move(int p) {
if(this.rowCount == 0) return;
int c = this.cursor + p;
if(c == this.cursor) return;
if(c < 0) c = 0;
if(c >= this.rowCount) c = this.rowCount - 1;
this.moveTo(c);
}

public void moveTo(int p) {
if(this.cursor == p) return;
if(!this.fireBeforeIntercept(Constants.ACTION_MOVE, new Object[]{this.cursor, p})) {
return;
}
this.fireOnIntercept(Constants.ACTION_MOVE, new Object[]{this.cursor, p});
if(this.rowCount > 0)
this.cursor = p;
this.fireAfterIntercept(Constants.ACTION_MOVE, new Object[]{this.cursor, p},
this.rowCount >0?0:this.rowCount);
}

public boolean first() {
if(this.rowCount == 0) return false;
this.moveTo(0);
return true;
}

public boolean previous() {
if(this.rowCount == 0 || this.cursor == 0) return false;
this.move(-1);
return true;
}

public boolean next() {
if(this.rowCount == 0 || this.cursor >= this.rowCount - 1) return false;
this.move(1);
return true;
}

public boolean last() {
if(this.rowCount == 0 || this.cursor >= this.rowCount - 1) return false;
this.moveTo(this.rowCount - 1);
return true;
}

public boolean firstPage() {
if(this.start == 0) return false;
this.start = 0;
this.query();
return true;
}

public boolean previousPage() {
if(this.start == 0 || this.totalRowCount < this.pageSize) return false;
this.start -= this.pageSize;
this.query();
return true;
}

public boolean nextPage() {
if(this.totalRowCount == 0 || this.start >= this.totalRowCount - this.pageSize - 1) return false;
this.start += this.pageSize;
this.query();
return true;
}

public boolean lastPage() {
if(this.totalRowCount == 0 || this.start >= this.totalRowCount - this.pageSize - 1) return false;
int lastPageSize = this.totalRowCount % this.pageSize;
if(lastPageSize == 0) lastPageSize = this.pageSize;
this.start = this.totalRowCount - lastPageSize;
this.query();
return true;
}

public void query() {
this.submit(Constants.ACTION_QUERY, null, DatasetActionInterceptorFactory.getActionInterceptor(Constants.ACTION_QUERY));
}

public void insert(int row) {
final String action = Constants.ACTION_INSERT;
final DatasetInterceptor actionInterceptor = DatasetActionInterceptorFactory.getActionInterceptor(action);
if(!fireBeforeIntercept(action, new Object[]{this})) {
return;
}
if(actionInterceptor != null && !actionInterceptor.doBeforeIntercept(this, action, new Object[]{this})) {
return;
}
//
Record rec = this.view.asRecordDef().createRecord(new Object[]{});
fireOnIntercept(action, new Object[]{rec});
if(actionInterceptor != null) {
actionInterceptor.onIntercept(this, action, new Object[]{rec, row});
}
//
if(row == -1) {
row = this.cursor;
}
this.getStore().insert(row, rec);
this.insertedRecords.add(rec);
fireAfterIntercept(action, new Object[]{rec, row}, Constants.DATASET_ACTION_RESULT_OK);
if(actionInterceptor != null) {
actionInterceptor.doAfterIntercept(Dataset.this, action, new Object[]{rec, row}, Constants.DATASET_ACTION_RESULT_OK);
}
}

public void remove(int row) {
final String action = Constants.ACTION_REMOVE;
final DatasetInterceptor actionInterceptor = DatasetActionInterceptorFactory.getActionInterceptor(action);
if(!fireBeforeIntercept(action, new Object[]{this})) {
return;
}
if(actionInterceptor != null && !actionInterceptor.doBeforeIntercept(this, action, new Object[]{this})) {
return;
}
//
if(row == -1) {
row = this.cursor;
}
Record removedRecord = null;
if(row >= 0 && row < this.store.getCount()) {
removedRecord = this.store.getAt(row);
this.getStore().remove(removedRecord);
fireAfterIntercept(action, new Object[]{removedRecord, row}, Constants.DATASET_ACTION_RESULT_OK);
if(actionInterceptor != null) {
actionInterceptor.doAfterIntercept(Dataset.this, action, new Object[]{removedRecord, row}, Constants.DATASET_ACTION_RESULT_OK);
}
if(this.selectedRecords.contains(removedRecord)) {
this.deselectRows(new Record[]{removedRecord});
}
} else {
fireAfterIntercept(action, new Object[]{null, row}, Constants.DATASET_ACTION_RESULT_NOK);
if(actionInterceptor != null) {
actionInterceptor.doAfterIntercept(Dataset.this, action, new Object[]{removedRecord, row}, Constants.DATASET_ACTION_RESULT_NOK);
}
}
}

public void submit(final String action, final Map<String, String> params, final DatasetInterceptor actionInterceptor) {
//
if(actionInterceptor != null && !actionInterceptor.doBeforeIntercept(this, action, new Object[]{this})) {
return;
}
if(!fireBeforeIntercept(action, new Object[]{this})) {
return;
}
//
JSONProxy json = new JSONProxy(this);
json.put("serviceID", this.view.getServiceID());
json.put("action", action);
//
if(actionInterceptor != null) {
actionInterceptor.onIntercept(this, action, new Object[]{json, this.view.getServiceID(), action});
}
fireOnIntercept(action, new Object[]{json, this.view.getServiceID(), action});

JsonRemoteService.Util.getInstance().invoke(this.view.getServiceID(), action, json.toJSON().toString(), new AsyncCallback<String[]>(){
@Override
public void onFailure(Throwable caught) {
Logger.error(caught);
//
if(actionInterceptor != null) {
actionInterceptor.doAfterIntercept(Dataset.this, action, new Object[]{caught}, -1);
}
fireAfterIntercept(action, new Object[]{caught}, -1);
}

@Override
public void onSuccess(String[] result) {
String jsonString = result[0];
String serviceID = result[1];
String action = result[2];
int resultCode = Integer.parseInt(result[3]);
Logger.debug("SERVICEID:" + serviceID + "; ACTION:" + action + "RESULTCODE:"+resultCode+"; RESULT: " +jsonString);
//
if(actionInterceptor != null) {
actionInterceptor.doAfterIntercept(Dataset.this, action, new Object[]{result}, resultCode);
}
fireAfterIntercept(action, new Object[]{result}, resultCode);
}

});
}

public void rejectChanges() {
this.removedRecords.clear();
this.insertedRecords.clear();
this.getStore().rejectChanges();
}

public void commitChanges() {
this.removedRecords.clear();
this.insertedRecords.clear();
this.getStore().commitChanges();
}

public void handle(String actionName) {
DatasetAction action = this.actions.get(actionName);
if(action != null) {
action.handle(this);
} else {
Logger.error("Action " + actionName + " not found!");
}
}

public boolean canHandle(String actionName) {
DatasetAction action = this.actions.get(actionName);
if(action != null) {
return action.canHandle(this);
} else {
Logger.error("Action " + actionName + " not found!");
}
return false;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值