RunBase saveLast and serialization
来源:互联网 发布:秦凯何姿 知乎 编辑:程序博客网 时间:2024/06/06 06:32
继承自RunBase的所有类,都可以定义一个#CURRENTLIST宏,这个宏有两个用途:
1. 装载用户上次使用该类时所输入的数据
2. 用于实现序列化类
实现这些功能,用户必须重写pack和unpack方法。
如果#CURRENTLIST保存的数据可以实现序列化,但如果我们只想保存#CURRENTLIST中的部分值,这些值在用户下次打开该类时自动装载,又该怎么办呢?
举个例子,现在有一个类:
Class Test extends RunBase
{
CustAccount custAccount;
CustInvoiceAccount invoiceAccount;
#DEFINE.CURRENTVERSION(1)
#DEFINE.VERSION1(1)
#LOCALMACRO.CURRENTLIST
custAccount,
invoiceAccount
#ENDMACRO
}
对应的Dialog如下图:
custAccount和 invoiceAccount是序列化Test类是必须的数据,但我只想让Customer account的值被系统自己记忆。 本文首先分析系统如何实现功能1和2,然后来解决我们在上面所提到的问题。 RunBase是一个抽象类,它继承自类Object,同时实现了两个接口类SysSaveable和SysRunable, 而SysSaveable接口又继承自接口SysPackable. 这些类和接口所拥有的方法如下图所示(RunBase所拥有的方法没有列出了):
Q1:为什么宏的名字是#CURRENTLIST?
在RunBase的声明中有这样一段代码:
#if.never
#define.CurrentVersion(1)
#define.version1(1)
#localmacro.CurrentList
#endmacro
#endif
而在RunBase的pack方法中,有这样的代码:
#if.never
return [#CurrentVersion,#CurrentList];
#endif
在RunBase的unpack方法中,是这样写的:
#if.never
Version version = runbase::getVersion(packedClass);
switch (version)
{
case #CurrentVersion:
[version,#CurrentList] = packedClass;
break;
default:
return false;
}
return true;
#endif
所以,如果你要问为什么继承自RunBase的类要定义#CurrentVersion,#CurrentList这样的宏,原因就是父类是这样写的,所以大家很自然就定义了同样名字的宏来使用。
在重写子类的pack和unpack时,你完全可以定义这里个宏为其它名字,如#MYCURRENTVERSION,#MYCURRENTLIST,如:
Class Test extends RunBase
{
CustAccount custAccount;
CustInvoiceAccount invoiceAccount;
#DEFINE.MYCURRENTVERSION(1)
#DEFINE.VERSION1(1)
#LOCALMACRO.MYCURRENTLIST
custAccount,
invoiceAccount
#ENDMACRO
}
Public container pack()
{
Return [#MYCURRENTVERSION,#MYCURRENTLIST];
}
public boolean unpack(container packedClass)
{
boolean ret = true;
Version version = Runbase::getVersion(packedClass);
container packedQueryRun;
;
switch (version)
{
case #MYCurrentVersion:
[version,#MYCurrentList,packedQueryRun] = packedClass;
if (SysQuery::isPackedOk(packedQueryRun))
{
queryRun = new QueryRun(packedQueryRun);
}
break;
default:
ret = false;
break;
}
return ret;
}
Q2: RunBase的基本调用流程是什么
现在我们来回答文章一开始提的知识点1:装载用户上次使用该类时所输入的数据 在RunBase的子类完成new之后,直接调用Prompt方法,该方法会最终调用到getLast方法,getLast方法根据version,areaId,userId,type和name来查询上次的值(name是保存对象的类名,type是保存对象的类别,如report),然后试图unpack查询到的结果,如果unpack失败,则调用InitParmDefault来赋值。然后显示Dialog. 在Dialog成功关闭后(即点OK关闭),判断当前对象是否是从服务器产生过来的,如果是,就不做saveLast,因为服务器端会做这一步。如果不是,则在客户端做saveLast,通过pack来完成这一动作。 然后是文章一开始提到的知识点2:用于实现序列化类 如果RunBase的某个子类运行在服务器端,而要求其Dialog是在客户端运行,那么系统会使用如下的代码: // Move prompt to client when running on server and the class is swappable if (isRunningOnServer() && this.canSwapBetweenCS() && this.canSwapBetweenCSPrim()) { [clientPrompt,clientPacked] =RunBase::promptOnClient(classidget(this),this.promptPack()); this.promptUnpack(clientPacked,clientPrompt); if(clientPrompt) this.saveLast(); return clientPrompt; } PromptPack方法会调用pack方法,promptUnpack方法会调用unpack方法。 RunBase::promptOnClient(classidget(this),this.promptPack());使Dialog在客户端显示,在Dialog关闭后,Dialog会将数据pack起来以返回值的形式传递进来,我们使用容器: [clientPrompt,clientPacked]将数据接收,再通过promptUnpack调用unpack来重写赋值数据。 如何解决我们在文章开头提到的问题? 在SaveLast和GetLast时,我们不再使用pack和unpack, 而是定义新的专门为savelast和getLast服务的unpackSysLastValue和packSysLastValue方法。 部分代码如下: class LearnRunBase2 extends RunBase { CustAccount custAccount; CustInvoiceAccount invoiceAccount; QueryRun queryRun; int counter; DialogField dlgCustAccount; DialogField dlgInvoiceAccount; //syslastvaluelist是需要保存的用户输入数据 #DEFINE.SYSLASTVALUECURRENTVERSION(9) #LOCALMACRO.SYSLASTVALUELIST custAccount, counter #ENDMACRO #DEFINE.SYSLASTVALUESFORKEDFROMVERSION(10) //Mycurrentlist是用来实现序列化的变量,是类中所有声明了的变量 #DEFINE.MYCURRENTVERSION(11) #DEFINE.VERSION1(11) #LOCALMACRO.MYCURRENTLIST custAccount, invoiceAccount, counter #ENDMACRO //在为getLast和setLast定义专门的pack和unpack方法时, //有可能改变原来mycurrentversion的值(如原来是10,现在被改为11), //为了能够获取保存了的数据,将定义SYSLASTVALUESFORKEDFROMVERSION=10, #DEFINE.VERSION1(10) #LOCALMACRO.CURRENTLISTV1 custAccount, counter #ENDMACRO } public container packSysLastValue() { //想把queryRun的值也保存起来 return [#SYSLASTVALUECURRENTVERSION,#SYSLASTVALUELIST,queryRun.pack()]; } public boolean unpackSysLastValue(container _packedValue) { Version version = RunBase::getVersion(_packedValue); container packedQueryRun; boolean ret = true; ; switch (version) { case #SYSLASTVALUECURRENTVERSION: { [version,#SYSLASTVALUELIST,packedQueryRun] = _packedValue; if (SysQuery::isPackedOk(packedQueryRun)) { queryRun = new QueryRun(packedQueryRun); } break; } case #SYSLASTVALUESFORKEDFROMVERSION: { //在原来的pack和unpack方法中,queryRun也被pack了起来 [version,#CURRENTLISTV1,packedQueryRun] = _packedValue; if (SysQuery::isPackedOk(packedQueryRun)) { queryRun = new QueryRun(packedQueryRun); } break; } default: ret = false; } return ret; } public void getLast() { container packedValues; boolean initParm = true; ; //不调用super(),先设置系统的一些标志 getLastCalled = true; inGetSaveLast = true; //自定义获取值 packedValues = xSysLastValue::getValue( this.lastValueDataAreaId(), this.lastValueUserId(), this.lastValueType(), this.lastValueElementName(), this.lastValueDesignName()); //如果取到了值,判断是否可以unpack,如果没有,则使用默认赋值函数 if (packedValues) initParm = ! this.unpackSysLastValue(packedValues); if (initParm) this.initParmDefault(); inGetSaveLast = false; } public void saveLast() { ; //不调用super() inGetSaveLast = true; xSysLastValue::putValue(this.packSysLastValue(),//保存自定义的值 this.lastValueDataAreaId(), this.lastValueUserId(), this.lastValueType(), this.lastValueElementName(), this.lastValueDesignName()); inGetSaveLast = false; }
- RunBase saveLast and serialization
- XML Serialization and Deserialization
- G3: serialization and deserialization
- MRPT data formats and serialization
- serialization
- Serialization
- Serialization
- Serialization
- Serialization
- Serialization
- Serialization
- Binary Serialization and BinaryFormatter with WebServices
- True Binary Serialization and Compression of DataSets
- Improving DataSet Serialization and Remoting Performance
- Call web service using HttpWebRequest and serialization
- Binary Serialization and BinaryFormatter with WebServices
- JSON Serialization and Deserialization in ASP.Net
- Lintcode - Serialization and Deserialization Of Binary Tree
- Ubuntu 9.04 下MySQL中文乱码的解决
- winform DataGridView最佳多抬头显示方式
- struts常见错误和解决方法
- 凉宫春日的阴谋7
- 凉宫春日的愤慨8
- RunBase saveLast and serialization
- Ubuntu 9.04 Tomcat6.0 全新配置
- SQL开发笔记
- 计算机启动过程详解
- java常见异常
- TCP/IP应用选型
- 如何使用apache mod_proxy和Tomcat搭建基于SSL的loadbalance集群环境
- Linux下Java语言实现简陋Web爬虫
- Linux常用命令