首页> 中国专利> 用于解释规范语言文件来实现商务系统的系统和方法

用于解释规范语言文件来实现商务系统的系统和方法

摘要

一种系统,用于控制具有处理器、存储器和硬盘的商务系统的操作。该系统包括:存储在硬盘上的规范语言文件,该文件包含定义商务系统的状态机实现的规范语言语句;解析器,用于从规范语言文件中提取规范语言语句并解释所提取的规范语言语句;商务逻辑应用程序,其包括商务逻辑模块,该商务逻辑模块包括可执行的编译程序语句;以及,解析器调用至少一个商务逻辑模块来处理解析器从规范语言文件中提取的消息。

著录项

  • 公开/公告号CN101192154A

    专利类型发明专利

  • 公开/公告日2008-06-04

    原文格式PDF

  • 申请/专利权人 NCR公司;

    申请/专利号CN200710186641.0

  • 发明设计人 大卫·D.·米勒;

    申请日2007-11-21

  • 分类号G06F9/44;G06Q30/00;

  • 代理机构北京银龙知识产权代理有限公司;

  • 代理人曾贤伟

  • 地址 美国俄亥俄州

  • 入库时间 2023-12-17 20:11:07

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2014-12-24

    授权

    授权

  • 2010-01-27

    实质审查的生效

    实质审查的生效

  • 2008-06-04

    公开

    公开

说明书

技术领域

本发明涉及由计算机实现的商务系统,特别地,涉及由用于在销售点(point-of-sale,POS)处理商务交易的计算机实现的商务系统。

背景技术

商务系统可以被描述成为编程来进行商务交易或功能的计算机系统。例如,计算机可以用于编程来接收用户的输入,检测发生在特殊环境下的事件来记述交易,以及报导交易事件的日志。管理人员使用这些报告来提取关于商务操作的信息或修改商务的不同方面来改善效率。例如,库存管理系统可以由计算机组成,该计算机被编程来验证交易,当接受产品进入库存时对其进行记录,以及依据产品从库存中的出货更新产品累计。用于这些交易的数据可以通过键盘或通过条形码阅读器等输入。该系统可以随后产生一个或多个报告来通知管理人员已发生交易的当前存货水平和容量水平。

另一个常常遇到的商务系统是结账柜台(checkout station),其通常用在零售销售点场所。这些销售点柜台可能简单如电子收银机或复杂如自助结账柜台。更复杂的销售点系统包括用于操作员输入命令的小键盘,用于读取条形码和称重物品的传感器,以及数据库和通信设备,该数据库和通信设备分别用于读取和存储数据并和远程站点进行数据通信。这些POS系统是众所周知的。在这些POS柜台,以扫描来识别购买的商品。终端可以从中心信息库检索价格来支持更有弹性的商品定价。当所有的购买物品被提供到销售点终端时,累加小计,计算税金和折扣,并将应付的总额显示给消费者。POS终端或柜台也可以包括收银机功能,信用卡或借记卡阅读器,或者用于处理交易支付的智能卡接口。在确认所提交的付款后,商品发放给消费者。一旦完成了销售,柜台可以和库存管理系统进行通信来更新售出物品的库存。

POS结账柜台通常包括终端,用于读取单位价格代码并确定商品重量的扫描器/计量器,收银员小键盘垫和显示器,用于付款输入的POS终端,收据打印机,找零装置,以及当商品已被扫描时保存商品的结账区域。POS终端也包括显示器,处理器,存储器,编程指令,以及控制柜台操作的数据外围设备。编程指令可以包含若干模块,这些模块在数据库中查询商品价格,计算总额,执行与通过结账柜台购买商品相关的其他功能。某些结账柜台可能也包括安全应用程序,其使用来自传感器(例如计量器和/或摄像头)的数据,来减少在结账当中发生不正确的商品替换的可能性。

结账柜台由大量不同的公司制造。虽然POS系统的操作一般是相似的,但是每个制造商实现程序代码来执行交易是不同的。例如,由小键盘的键产生的代码或者带有传感器系统的接口,对于不同的制造商可能以略微不同的方式实现。因此,对于不同的制造商,由POS系统的一个或多个处理器执行的程序是不同的。

大多数制造商宁愿以某种模块化编程来实现POS系统控制器,而不采用单一的程序实现结账柜台要求的所有功能性(functionality)。在模块化编程中,由POS系统实现的商务逻辑被分割成子功能。这些子功能可以作为离散的编程对象或模块来实现。向这些模块或对象提供输入数据,该模块或对象处理输入数据来产生输出。使用模块化的编程方法便于实现计算机程序的维护,划分系统的功能性以使其可以被修改而更容易地引入新功能。

虽然上面讨论的模块和对象确实利于程序的维护和适应性,它们通常以分层结构结合在一起来实现交易或其它商务过程。用于将模块结合在一起的分层结构和控制逻辑也以编程语言实现。实现控制逻辑和分层结构的编程语句形成了POS系统的框架。这些编程语句必须编译和安装在计算机上,用来控制用以实现POS系统的不同子功能的程序对象和模块的执行。以这种形式实现POS系统的所有控制逻辑是与模块化编程的理念背道而驰的。在必须改变控制逻辑来处理交易的情况下,商务逻辑的编程语句必须被修改,重新编译,并重新安装在执行POS系统的计算机上。此外,这些改变必须以一种和制造商的执行编程逻辑的平台兼容的形式被重新编程。也就是,必须以一种和制造商的子功能实现相兼容的方式修正商务逻辑。因此,执行POS系统的商务逻辑的控制逻辑的修正需要小心注意系统的硬件环境以及用于实现该系统的编程语言。

发明内容

一种系统,其以提供灵活性而不用必须重新编译可执行的计算机逻辑的形式来控制具有处理器、存储器和硬盘的商务系统的操作。该系统包括:规范语言文件,其存储在硬盘上,该文件包含定义商务系统的状态机实现的规范语言语句;解析器,用于从规范语言文件中提取规范语言语句并解释所提取的规范语言语句;商务逻辑应用程序,其包括商务逻辑模块,该商务逻辑模块包含可执行的编译程序语句;以及,解析器调用至少一个商务逻辑模块来处理解析器从规范语言文件中提取的消息。

一种方法,能通过以提供灵活性而不用必须重新编译可执行计算机逻辑的方式来控制商务系统的操作的这样的系统来实现。该方法包括:以规范语言语句定义商务系统的状态机实现;解释规范语言语句来实现商务系统;以及,调用包含可执行编译程序语句的商务逻辑模块来处理解析器从所解释的规范语言语句中提取的消息。

下面将结合附图和示意性实施例详细讨论本系统和方法的优点和特征。

附图说明

在本发明中描述的系统和方法可以以不同的组成,组成的布置以及在不同的方法来具体化。附图仅出于用于说明优选实施例及其替换方案的目的,不能被认为构成对本发明的限制。

图1示出了结账柜台的透视图,该柜台具有用于实现商务逻辑和结账柜台的规范语言文件解释器。

图2是系统的框图,其使用规范语言解释器来实现系统的商务逻辑。

图3是可扩展标记语言文件结构的例子,其可以用于定义状态机。

图4是库定义的例子,其可以用于图3的文件结构。

图5是定时器定义的例子,其可以用于图3的文件结构。

图6是常量定义的例子,其可以用于图3的文件结构。

图7是变量定义的例子,其可以用于图3的文件结构。

图8是状态定义的例子,其可以用于图3的文件结构。

图9是消息定义的例子,其可以用于图3的文件结构。

图10是动作定义的例子,其可以用于图3的文件结构。

图11是查找表定义的例子,其可以用于图3的文件结构。

图12是if表达式的例子,其可以用于图3的文件结构。

图13是else表达式的例子,其可以用于图12的if表达式。

图14是else-if表达式的例子,其可以用于图3的文件结构。

图15是select表达式的例子,其可以用于图3的文件结构。

图16是when表达式的例子,其可以用于图3的文件结构。

图17是otherwise表达式的例子,其可以用于图3的文件结构。

图18是for表达式的例子,其可以用于图3的文件结构。

图19是while表达式的例子,其可以用于图3的文件结构。

图20是timeout-rule-list表达式的例子,其可以用于图3的文件结构。

图21是break表达式的例子,其可以用于图3的文件结构。

图22是yield表达式的例子,其可以用于图3的文件结构。

图23是断言对话框的例子,其可以用于状态机的实现。

图24是数据模型资源管理器的例子,其可以用于图3的文件结构。

图25是用于状态机实现的非瞬态类的示例集的类图(class diagram)。

图26是用于解析图3的文件结构的瞬态类的类图。

图27是可以用于状态机实现的Java支持的类的类图。

具体实施方式

根据本发明的原理修改的结账柜台如图1所示。结账柜台10可以包括馈送单元14和验货台18。馈送器单元14包括馈送带20和用于放置操作馈送带20的电动机和控制电路的壳体22。馈送单元14可移动地结合在验货台18上以使得馈送带可以和扫描器/计量器单元26对齐。验货台18包括扫描器/计量器单元26,消费者终端34,用于输入付款数据的付款终端38,以及收据打印机44。扫描器/计量器单元26使用照射在玻璃或其他透明的台板(platen)上的激光来输入来自产品或包装上的条形码上的数据。单元26也可以包括用于测量商品重量的计量器,该商品以价格每重量单位为基础销售。消费者终端34当使商品进入通过扫描器/计量器单元26时显示商品数据。付款终端38可以是任何已知的POS终端,其结合阅读器32以支持信用卡,借记卡以及其他支付方法。收据打印机44向消费者提供逐条列记所购商品和支付方法的收据。

收据打印机44和扫描器/计量器单元26可以由在其底面具有安全计量器48的囊井(Bagwell)46分开。用于存放消费者的、已扫描和称重的商品的购物袋挂在囊井46中的悬挂横杆50上。安全计量器48使用从扫描器/计量器26得到的商品重量数据、或者从使用扫描单位商品码(unit product code,UPC)的数据库得到的商品重量数据,来验证仅仅只有已扫描过的商品被放置在安全计量器上。运行在终端34的安全应用程序监视安全计量器48来确定是否将没有扫描的商品增加到安全计量器区域。通过使三色指示器中的警告或告警灯的颜色变亮来发信号告知需要调查的异常情况,该指示器安装在验货台18的指示器杆52的终端的末端上。安全摄像头56可以安装在指示器杆52上用于产生对应于验货台区域的视频数据。数据库,磁盘驱动器,或柜台操作所需要的其他计算机外围设备可以放置在位于验货台18内的外围设备托盘60中。验货台18还包括上部货币模块40,用于接收来自于消费者的纸币和硬币作为交易的付款。模块40还包括硬币分配器36,用于返还消费者找零的硬币部分,而下部货币模块42用于返还消费者找零的纸币部分。模块40也可以包括现金再循环单元(图未示)来以分发给消费者零钱的形式提供从消费者接受的现金。

如图1所示,消费者可以将商品放置在馈送带20上,传送带20被驱动将商品带至馈送带20的末端,在那里关闭机构使馈送带20停止。然后消费者可以从传送带20上取下商品并一次一个地将它们移动到用于商品产品数据的检索和/或称重的扫描器/计量器26上。可任选的,消费者可以拉着装有购买商品的手推车,使其与馈送单元22相邻,并且将手推车中的商品放置在扫描器/计量器26上。然后扫描过的商品被放置在扫描器/计量器26上的购物袋中。一旦完成所有商品的扫描,消费者可以通过支付终端38或货币模块40进行付款,从模块42接受找零,并从打印机44接受收据。然后消费者可以从安全计量器48上取走购物袋,离开柜台10。结账柜台10的操作由通常结合在终端34内的处理器控制。

图2示出了可以用于操作商务逻辑系统的状态机的实现的系统框图。系统100包含状态机定义104,其可以存储在硬盘中;解析器(parser)108,用于从状态机定义104中提取规范语言语句并且解释所提取的规范语言语句;以及,商务逻辑应用程序110,包含商务逻辑模块。商务逻辑模块包括可执行的编译程序语句,其可以被表示为下文更详细描述的动作(action)。解析器调用商务应用程序110的商务逻辑模块来处理由解析器从状态机定义的规范语言语句中提取的消息。规范语言语句优选地包含在规范语言文件中。这些语句定义了商务系统的状态机实现。

更详细地,商务系统(比如将在下面更详细描述的结账柜台)的规范语言定义,使用由销售点(POS)系统的制造商为结账柜台提供的数据链接库(datalink library,DLL)。由规范语言语句定义的状态机实现,使用包含在DLL中的商务逻辑模块来操作结账柜台。这些模块是编译的、可执行的计算机代码,该计算机代码由结账柜台的制造商开发。这些模块实现系统的操作,例如,读取条形码,累计和汇总销售交易,称重货物,处理付款,以及发放收据。在结账系统中组织这些功能的商务逻辑,根据由规范语言语句定义的状态机实现来执行。状态机实现也可以由其他的规范语言文档和/或用户化的DLL来补充。

如下文中更详细地描述的,系统初始化一旦发生,解析器便开始从规范语言文件中提取规范语言语句。解析器解释所提取的规范语言语句。此解释包括通过规范语言语句的标签(tag)识别规范语言语句,如下文中更详细描述的,以及调用对在已解释的规范语言语句中识别的商务逻辑模块的调用。如下文中更详细地描述的,这些商务逻辑模块可以由编程语言对象来实现。这些对象可能包括若干方法,解析器调用这些方法来处理从规范语言语句中提取的数据,例如消息。这些对象用于实现动作,其是用于操作该系统的商务逻辑的最小单元。因此,规范语言文件为定义结账柜台操作所要求的商务逻辑提供框架,DLL的模块或对象则为实现商务逻辑提供必要的可执行的计算机代码。这个结构便于结账柜台操作的修改和维护。特别地,结账柜台的操作可以通过仅仅改变规范语言语句而不用在计算机上重新编译和安装可执行代码来进行修改。

下面将更详细地描述结账柜台的实现。在该实现中,将描述用于控制结账柜台操作的状态机的生成和状态机的初始化。然后提供关于规范语言语句的结构的细节,包括将规范语言语句组织成表达式。为了在规范语言语句中定位表达式标签并根据定位的表达式标签解释对应的标签之间的规范语言语句,这些表达式可以由结合在解析器内的表达式解释器来解释。方法调用器(methodinvoker)也可以结合在解析器中,用于调用商务逻辑模块来处理从规范语言文件中提取的信息。将详细描述关于结账柜台所实现的动作。也会在这里描述额外的特征,这些额外的特征用于调试状态机实现,为实现动作的类提供JAVA支持,以及对状态机实现进行群集(cluster)来扩大商务系统操作。

生成一个状态机的实例来操作商务系统。为了生成状态机的实例,可以通过参数列表来调用CStateMachineFactory对象的静态工厂方法BuildStateMachine。CStateMachineFactory对象是由商务系统平台(例如结账柜台)的制造商提供的编程语言对象。用于该方法调用的参数包括状态机的唯一名称,以及包含状态机定义、库名称和目录路径的统一资源定位符(URL:Universal Resource Locater)。状态机定义用于生成状态机的数据值和规则集。库名称优选地包含返回状态机实例的实际工厂方法(actual factory method)。目录路径包含由工厂在生成状态机时载入的所有文件。BuildStateMachine方法从CStateMachineFactory对象的返回,提供了要求初始化的完全功能状态机。

在生成状态机的过程中,工厂对象使用加载器类的实例,例如CSMLoader或者它的一个派生物,来加载状态机的例子。这个类使用SAX Parser(SAX解析器)实现来将规范语言解析成适当的数据结构,例如表达式。如下面将更充分讨论的,优选的规范语言文件是以可扩展标记语言(XML)编写的。SAXParser用于分析状态机定义文件的XML来操作状态机。一些单独分开的标签由例如为CContentHandler的内容处理器类(content handler class)的实现来处理。在构建时,生成使每个标签和其对应的处理器类相互关联的映射。通过使用XPath表达式作为关键码(key)来实现这个映射。XPath表达式通过将正斜杠“/”和标签名称连接直到检测到停止标签来构建。因此,标签名称和与它相关的正斜杠符号被移除,直到到达最后的停止标签。

随着SAX Parser解析规范语言文件,其证实了语句的结构。在示例的XML规范文件中可能遇到的语句结构将在下面更详细描述。在结构证实中检测到的错误将在错误日志中报道。生成包含在错误日志中的错误消息的处理器可以检测:(1)状态、消息、动作、常量、定时器或变量的重复定义;(2)未定义的状态、消息、动作、常量、定时器或变量;(3)状态、消息、动作、常量、定时器或变量的无效名称;(4)不兼容的标签选项。

由规范语言文件定义的状态机实现可以包括用户化的DLL。状态机的工厂实现在这些DLL中搜索入口点的数目,每个入口点可任选地被提供。工厂对象为DLL没有定义的任何入口点使用默认实现。如下所述,这些入口点可能是C型入口点。这些入口点为以下提供支持:(1)注册/不注册被支持的动作名称;(2)生成/销毁状态机实例;以及(3)生成/销毁任何需要的Plugin对象。也可以使用模板方法来支持动作的生成/销毁。可以提供如下入口点:

入口点名称  是否要求功能RegisterAll  是返回所有支持的动作的名称UnregisterAll  是释放由入口点RegisterAll所使用的任何资源BuildStateMachineFactory  否构造工厂自身的实例ReleaseStateMachineFacotry  否释放工厂的实例BuildStateMachineLoader  否为工厂的使用构造CSMLoader的实例ReleaseStateMachineLoader  否为工厂的使用释放CSMLoader的实例BuildStateMachine  否构造IStateMachine具体实例ReleaseStateMachine  否释放由该DLL创建的IStateMachineBuildCluster  否构造CCluster的具体实例ReleaseCluster  否释放由该DLL创建的CClusterGetPlugin  否构造指定名称的IPluginReleasePlugin  否释放由该DLL创建的IPlugin实例CCreateable<T,IAction>::NewInstance  是创建T动作的实例CCreateable<T,IAction>::ReleaseInstance  是释放T动作的实例

在动作注册/不注册中的第一个入口点,返回由库所支持的所有动作的名称列表。当生成库时的初始化过程中,其被调用一次。入口点的签名是:

HRESULT_declspec(dllexport)RegisterAll(const_TCHAR***,HTRACE)

该调用的第一个参数是指向数组名称的指针的地址。这个数组通过该调用返回,但是不能被释放。第二个参数是追踪对象的句柄(handle)。当状态机处于被销毁的过程中时,释放这些名称。为了便于其实现,状态机调用下面的入口点:

void_declspec(dllexport)UnregisterAll()

可以看到,这个入口点没有携带任何参数,所以不返回值。

状态机工厂创建/销毁类别中的第一个入口点返回指向CStateMachineFacory的实例的指针。其由CStateMachineFacory在初始化的过程中被调用一次。入口点的签名是:

HRESULT_declspec(dllexport)BuildStateMachineFactory(HTRACE hTrace,

STATE_MACHINE_NAMESPACE::CStateMachineFactory**)

该方法采用两个参数,也就是,追踪对象的句柄以及指向新构造的工厂状态机的返回指针的地址。如果在生成的过程中没有发生错误,入口点返回S_OK。任何其他值都是错误。在这一类别的第二个入口点用于在结束时释放状态机工厂。它的签名是:

HRESULT_declspec(dllexport)ReleaseStateMachineFactory(HTRACE hTrace,

STATE_MACHINE_NAMESPACE::CStateMachineFactory*)

该方法采用两个参数,也就是,追踪对象的句柄以及指向要销毁的工厂状态机的指针。如果在销毁的过程中没有发生错误,则入口点返回S_OK。任何其他值都是错误。如果对这些可任选的方法未加声明,则将生成CStateMachineFactory的默认实例。

状态机加载器创建/销毁类别中的第一个入口点返回指向CSMLoader的实例的指针。其由CStateMachineFacory使用来构建和初始化所要求的状态机实例。入口点的签名是:

HRESULT_declspec(dllexport)BuildStateMachineLoader(HTRACE hTrace,

STATE_MACHINE_NAMESPACE::CSMLoader**)

该方法采用两个参数,也就是,追踪对象的句柄以及指向新构造的CSMLoader实例的返回指针的地址。如果在生成的过程中没有发生错误,则入口点返回S_OK。任何其他值都是错误。在这一类别的第二个入口点用于在结束的时候释放状态机加载器。它的签名是:

HRESULT_declspec(dllexport)ReleaseStateMachineLoader(HTRACE hTrace,

STATE_MACHINE_NAMESPACE::CSMLoader**)

该方法采用两个参数,也就是,追踪对象的句柄以及指向要销毁的状态机加载器的指针。如果在销毁的过程中没有发生错误,则入口点返回S_OK。任何其他值都是错误。如果对这些可任选的方法未加声明,则将生成CSMLoader的默认实例。

状态机创建/销毁类别中的第一个入口点返回指向状态机的实例的指针。其由CStateMachineFacory在初始化的过程中被调用一次。入口点的签名是:

HRESULT_declspec(dllexport)BuildStateMachine(const_TCHAR*HTRACEhTrace STATE_MACHINE_NAMESPACE::IStateMachine**)

该方法采用三个参数,它们是XML文件的URL,追踪对象的句柄以及指向新构造的状态机的返回指针的地址。如果在生成的过程中没有发生错误,则入口点返回S_OK。任何其他值都是错误。在这一类别的第二个入口点用于在结束的时候释放状态机。它的签名是:

HRESULT_declspec(dllexport)ReleaseStateMachine(HTRACE hTrace,

STATE_MACHINE_NAMESPACE::IStateMachine*)

该方法采用两个参数,它们是追踪对象的句柄以及指向要销毁的状态机的指针。如果在销毁的过程中没有发生错误,则入口点返回S_OK。任何其他值都是错误。

群集创建/销毁类别中的第一个入口点返回指向由两个或更多协同操作状态机组成的状态机的实例的指针。其由CStateMachineFacory在初始化的过程中调用一次。入口点的签名是:

HRESULT_declspec(dllexport)BuildCluster(const_TCHAR*HTRACE hTraceSTATE_MACHINE_NAMESPACE::CCluster**)

该方法采用三个参数:XML文件的URL,追踪对象的句柄以及指向新构造的状态机群集的返回指针的地址。如果在构造的过程中没有发生错误,则入口点返回S_OK。任何其他值都是错误。在这一类别中的第二个入口点用于在结束的时候释放状态机。它的签名是:HRESULT_declspec(dllexport)ReleaseCluster(HTRACE hTrace,STATE_MACHINE_NAMESPACE::CCluster**);该方法采用两个参数:追踪对象的句柄,以及指向要销毁的状态机群集的指针。如果在销毁的过程中没有发生错误,则入口点返回S_OK。任何其他值都是错误。

在Plugin创建/销毁类别的第一个入口点返回指向工厂对象的实例的指针,其提供了以新的标签来扩展状态机定义语言的机制。其由CStateMachineFacory在初始化的过程中被调用一次。入口点的签名是:HRESULT_declspec(dllexport)GetPlugin(const_TCHAR*,IPlugin**,HTRACE)。该方法采用三个参数:Plugin的符号名称,指向新构造的IPlugin对象的返回指针的地址,以及追踪对象的句柄。如果在构造的过程中没有发生错误,则入口点返回S_OK。任何其他值都是错误。在这一类别中的第二个入口点用于在结束的时候释放Plugin对象。它的签名是:HRESULT_declspec(dllexport)ReleasePlugin(IPlugin*,HTRACE)。该方法采用两个参数:指向要销毁的IPlugin的指针,以及追踪对象的句柄。如果在销毁的过程中没有发生错误,则入口点返回S_OK。任何其他值都是错误。

对于在DLL中揭露的每个动作都有两个动作工厂方法入口点。这一类别中的两个入口点应该和动作本身一样由包括在相同文件中的注册宏生成。例如,在状态机中有叫做CSendMsg的动作。在Sendmsg.cpp文件的底部有如下代码:REGISTER_SM_ACTION(SendMsg)。宏REGISTER_SM_ACTION本身在文件ActionBase.h中定义为:

#define SM_REGISTRATION_PREFIXSM.

#define REGISTER_SM_ACTION(NAME)\

DECLARE_CLASS_CREATION_DESTRUCTION(NAME)\

DECLARE_REGISTRATION_CLASS(SM_REGISTRATION_PREFIX,NAME)\

DEFINE_REGISTRATION(NAME)

这些宏为动作自动生成所要求的入口点并且将它们揭露给CRegistrationManager。状态机的每个组分用户(component user)创建唯一的注册宏和注册前缀,并且对定义在DLL中的所有动作使用这样的宏。

该类别中的第一个入口点返回指向新创建的类型T的动作的指针。该入口点是静态模板成员功能(static template member function)。它由CXMLStateMachine工厂调用来生成动作。入口点的签名是:IACTION*CCreateable<T, IAction>::Newlnstance()。

在这一类别中的第二个入口点用于释放由上面的入口点生成的动作。它的签名是:void CCreateable<T,IAction>::Releaselnstance(IAction*)。

这个方法将动作的地址作为参数来释放。

根据BuildStateMachine方法的返回,通过调用返回的状态机的实例的Start(启动)方法来完成初始化。该方法由新的工作线程(worker thread)参数调用,该参数用于运行状态机。所有的状态机动作都使用这个工作线程来执行。

状态机处理消息并且执行规则。消息处理可以是异步的,也可以是同步的。消息处理和规则集执行都由状态机元素完成。消息处理,规则集执行,以及执行这些任务的状态机元素将在下面详细描述。

状态机通过接收消息以及响应执行规则集进行操作。通过使用用于异步操作的PostMsg方法或使用用于同步操作的SendMsg方法来在CSynchronizedQueue中放置消息,以此协调状态机的执行。对于异步操作,PostMsg不等待返回代码。对于同步操作,SendMsg方法等到消息的最后一个动作处理完毕,并返回由规则集设定的某一返回代码。工作线程从CSynchronizedQueue中移除消息,并对于处于全局状态的消息,确定是否存在规则集。如果对于消息存在规则集,那么先运行这个规则集。该规则集可以不从当前状态转变。

工作线程然后对于处于当前状态的消息确定是否存在规则集。如果有,则执行该规则集。如果没有,则工作线程对于处于被称为“any”状态的特殊状态的消息确定是否存在规则集,该状态在XML定义中用状态名“*”表示。执行所发现为“any”状态的任何规则集。如果没有发现规则集,则该消息转到可以处理或不处理该消息的默认处理器方法(default handler method)。基本状态机的默认处理器仅仅记录一个条目表示忽略该消息。状态机群集的默认处理器将消息传至群集中能够处理该消息的任何其他状态机。

规则集包括零或多个IAction,以及零或多个至其他状态的转变。IAction为状态机元素,将在下面详细讨论。如果存在IAction,它们将依序执行直到下列情况之一发生:IAction返回假(false),IAction引起异常发生(故障),或者序列中不再有IAction。在IAction返回假的情况下,规则集可以指定要执行的假动作(false action),其也可以指定到另一个状态的转变。当发生异常的情况,状态机捕获该异常,记录该异常,执行规则集指定的任意可任选的故障动作,或者任意地转变到规则集指定的故障状态。当序列中不再有IAction时,规则集可任选地指定转变至新的状态。

异步消息处理是状态机的正常的操作模式。通过调用PostMsg方法可以使消息异步。从PostMsg的返回是即时的。在将来的某一时间,将处理刚发的消息。

也提供了同步消息处理,但是由于潜在的死锁的可能性而只是以受限的方式使用同步消息处理。任何生成消息的动作都可能潜在地引起死锁。通过调用SendMsg来同步处理消息。当在队列中加入同步消息时,调用线程进入等待状态。当对给定消息执行了所有动作时,状态机发信号给正在等待的线程。

状态机使用的所有元素由实现成为抽象基类的一系列接口在外部表示(内部由CAbstractStateMachine表示),每一个接口代表状态机的不同方面。总的来说,所有的外部表示都是只读的,不能提供任何修改机制。现在讨论这些元素。

接口IStateMachine代表状态机本身。它提供了以只读方式访问状态机的不同元素的一组方法。所有的实现细节都不显示给这一类的用户。除非另外提供,动作仅仅通过这一接口访问状态机。

IMessage接口提供状态机输入的只读表示,该状态机用于确定执行的规则集。每个IMessage由其名称唯一识别。该名称为状态机内二维映射提供第一个关键码。IMessage名称可以包含除了已经在XML解析器中用作定界符的字符外的任意字符。无效字符包括‘<’,‘>’和‘&’。

IState接口提供状态的只读表示,状态机可以驻留在这些状态中。每个IState由其名称唯一识别。该名称为状态机内二维映射提供第二个关键码。IMessage名称可以包含除了已经在XML解析器中用作定界符的字符外的任意字符。无效字符包括‘<’,‘>’和‘&’。

IAction接口代表最小的工作单元,也就是,能够响应于状态机中的输入而执行的商务逻辑。该表示是只读的。总的来说,IAction的实现是小型的,并且不能包含一个以上的功能。这个限制允许IAction在其他规则集中的重用。此外,IAction越小,它越容易调试和维护。每个IAction由一个名称表示。该名称在单个ILigrary中是唯一的。IAction名称可以只包含字母数字字符。

为了进一步区分动作和防止名称冲突,可以将动作驻留于名称空间。在这种情况下,该名称由两部分组成,名称空间的名称和动作的名称,由字符‘.’分隔。例如在名称空间“tb”中名称为“StartTransaction”的动作称为“tb.StartTransaction”。将在以下提供名称空间的更多信息。

ILibrary是DLL的表示。它为管理状态机中使用的IAction集提供便利。每个IAction被动态地载入,并且按照DLL的需要而生成。如上描述,也可以可任选地提供一系列入口点,用于用户化状态机的行为。

IConstant接口是可以在状态机中使用的常量的只读表示。它可以用于对IVariable的表达式和赋值。每个IConstant由其名称唯一识别。IConstant名称可以包括字母数字字符和‘_’字符。常量的定义将在下面更充分的描述。

StateMachine实现允许按需生成要使用的变量。IVariable接口代表这些变量。不像大多数其他元素,IVariable不是只读的,允许改变它的值。每个IVariable由其名称唯一识别。IVariable名称可以包括字母数字字符和‘_’字符。将在下面更充分的描述变量的定义。

StateMachine实现支持定时器的生成,这些定时器或者周期性地重复或者仅仅单次终止。任何定时器每次终止时,它均产生要由状态机处理的超时消息。ITimer接口代表这些定时器。每个ITimer由其名称唯一识别。ITimer名称可以包括字母数字字符和‘_’字符。值得注意的是,定时器的定义也隐含着生成对应的超时消息。将附加在定时器名称的包含字符串“_timeout”的名称分配给这个消息。将在下面更充分地描述定时器的定义。

StateMachine实现允许对关键码表进行详细叙述。表中的每个入口都有一个相关的关键码。每个关键码指的是单一值。关键码和值可能是字符串数据,或者是整数数据。每个ILookupTable由其名称唯一识别。ILookupTable名称可以包括字母数字字符和‘_’字符。将在下面更充分的描述查找表的定义。

StateMachine实现能以多个方法使用表达式。每个表达式由从IStatMachine接口的GetExpression工厂方法获得的IExpression接口的实例来表示。值得注意的是,由于XML的解析限制,表达式以下面的字符表示作为XML实体。

    字符    XML实体    ‘<’    &It;    ‘>’    &gt;    ‘&’    &amp;

StateMachine实现允许在XML中使用扩展标签。这些标签通过IPlugin的实例处理。IPlugin接口提供处理服务所要求的、但对状态机本身不使用的标签。每个IPlugin由其名称唯一识别。IPlugin名称可以包括字母数字字符和‘_’字符。下面将讨论与对状态机开发的Plugin有关的更多信息。

IProcedure接口代表可以执行的动作集。每个IProcedure由其名称唯一识别。IProcedure的名称以数字字符开始,并可以包括字母数字字符和‘_’字符。将在下面讨论更多状态机中的处理有关的信息。

ISynchTable接口是一种机制,它可以在状态转换之前协调多个事件。每个ISynchTable由其名称唯一识别。ISynchTable的名称以数字字符开始,可能包括字母数字字符和‘_’字符。将在下面讨论更多同步事件有关的信息。

状态机的操作要求两个阶段来终止其执行。在第一阶段,状态机的执行线程通过调用状态机的Stop(停止)方法来停止。该方法直到线程完成且成功终止后才能返回。状态机终止的第二个阶段通过调用CStateMachineFactory对象的ReleaseStateMachine静态方法来初始化。这个静态方法接受参数,包括追踪对象句柄以及指向要释放的状态机实例的指针。

用于有效状态机XML的优选XML规范语言文件的结构以<state-machine>标签开始,如下所示:

<state-machine modal=false>

....

</state-machine>

<state-machine>标签有一个可任选的模型属性(modal attribute)。该属性可以用来改变用于处理未知消息的行为,其将在下面更充分地描述。可以将其值设为假来禁止模型属性。该属性不在正常情况下使用。

XML文件的剩余部分构造成段,段的第一部分定义了元素,这些元素在其所遵循的规则中使用。所有的元素在它们使用在规则中之前定义。这些元素包括:Library(库),Timer(定时器),Constant(常量),Variable(变量),State(状态),Message(消息),Action(动作),以及Lookup Table(查找表)。包括在相关列表标签中的每个元素类型如图3所示。

库定义包括<library>标签,其后为识别DLL的名称的名称属性。该名称可以是完全限定的。如果不是,则使用可执行模块的正常搜索顺序来寻找DLL。可任选的<comment>标签可以包含在其中,图4示出了示例的库列表。

如图5所示,定时器定义包括<timer>标签,其后为识别定时器名称的名称属性。该名称也用于生成用在超时事件中的消息。可任选的<comment>标签可以包含在其中。

如图6所示,常量定义包括<constant>标签,其后为识别常量名称的名称属性和识别常量类型的可任选类型属性。如果没有指定类型属性,常量的类型默认为整型。类型属性可以为下表所指定的值中一个。

    类型值  常量类型    整型  整数    长整型  长整数    字符串型  字符数据    布尔型  布尔值-“真”或“假”

所要求的<value>标签之后为给定的常量值。可任选的<comment>标签可以包含在其中。

变量定义包括<variable>标签,其后为识别变量名称的名称属性和识别变量类型的可任选类型属性。如果没有指定类型属性,变量的类型默认为整型。类型属性可以为下表所指定的值中的一个。

    类型值    变量类型    整型    整数    长整型    长整数    字符串型    字符数据    布尔型    布尔值-“真”或“假”

此外,变量的初始值,最大值和最小值可以如下表所示的定义。

  属性  含义  要求与否  名称  被定义的变量的名称  是  类型  变量类型  否  初始值  赋给该变量的初始值  否  最大值  该变量可达到的最大值,该值只对数字类型有效  否  最小值  该变量可达到的最小值,该值只对数字类型有效  否

图7中的例子显示了名称为my_variable的变量的定义,该变量为整数类型,初始值为0,最小值为0,最大值为100。

如图8所示,状态定义包括<state-definition>标签,其后为识别状态名称的名称属性。也可以包括可任选的<comment>标签。此外,有且只有一个状态必须使用<initial/>标签来识别为初始状态。也可能指定可任选的<global>标签,将该状态识别成为全局状态,以在状态特有规则之前对规则进行检查。如果状态被标识成为全局状态,则其不可以也被标识成为初始状态。

如图9所示,消息定义包括<msg>标签,其后为识别消息名称的名称属性。该定义可任选地包含下面的标签中任一个或全部标签:

    <comment>    识别这个变量的文本    <value>    应用定义值,目前不被StateMachine使用

如图10所示,动作定义包括<action>标签,其后为识别动作名称的名称属性。也可以包括可任选的<comment>标签。参数也可以通过可任选的<parameter>标签指定。可以指定多个可任选的<parameter>标签。如果只需要单个的参数字符串,那么可以使用动作标签的参数属性来指定该参数。

如图11所示,查找表定义包括<lookup-table>标签,其后为如下属性:

    名称属性  识别表    关键码-类型属性  指定关键码的类型,整型或字符串型    值-类型属性  指定值的类型,整型或字符串型

在<lookup-table>标签之后可以是0或更多的<lookup-entry>标签。每一个这样的标签指定关键码属性和值属性。使用该表的查找包括在表中搜索匹配关键码,以及返回对应值。

特性(property)提供在标签的值和属性上由一个字符串取代另一个字符串的能力。特性定义包括<property>标签,其后为识别特性名称的名称属性和识别被取代值的值属性。为了使用该特性,可使用字符‘%’作为首尾字符。以下为特性定义的例子:<property name=”SOMENAME”value=”c:\file\path”>。

名称空间提供一种能力,帮助防止在不同对象定义中的动作名称发生冲突。只要多个动作驻留在不同的名称空间,它们就可以具有相同的名称。例如,叫做StartTransaction的两个不同的动作可以驻留在TB对象和RAP对象中。为了区分它们,它们各自驻留在单独的名称空间tb和rap中,并被引用为tb.StartTransaction和rap.StartTransaction。对于下面作为例子的名称空间,在使用前被定义如下:

<state-machine>

  ...

   <namespace name=”tb”/>

   <namespace name=”rap”/>

  ...

</state-machine>

引用动作StartTransaction的规则可以使用以下语法:

<rules>

   <state name=“State-1”>

      <message name=“Message-1”>

         <message-rule-list>

           <rule action-name=“tb.StartTransaction”/>

           <rule action-name=“rap.StartTransaction”/>

         </message-rule-list>

      </message>

...

   </state>

...

</rules>

规则的定义以定义状态机的有效状态开始,如下例所示:

  <rules>

      <state name=“State-1”/>

...

      <state name=“State-n”/>

  </rules>

每个状态标签有可以在状态标签中被接受的有效消息集:

  <rules>

      <state name=“State-1”>

          <message name=“Message-1”/>

...

          <message name=“Message-n”/>

      </state>

...

</rules>

如果在‘*’状态没有用于信息的处理器,则默认将任何不包括在该状态内的消息予以忽略。<tag>标签也可以包括可任选的timeout属性,用于在进入该状态时启动匿名定时器。如果定时器在离开该状态前超时,则其由定义在这个状态中的<timeout-rule-list>处理器来处理。

对每个消息标签可任选地定义一套规则(规则集)。如果没有定义规则,则不执行动作。规则集有如下格式:

<rules>

    <state name=“State-1”>

        <message name=“Message-1”>

           <message-rule-list>

              <rule action-name=.../>

              <rule action-name=.../>

              ...

              <rule action-name=.../>

                 <success-transition>...</success-transition>

             </message-rule-list>

         </message>

...

     </state>

...

</rules>

如果规则集中的所有动作在执行时时返回“真”,则<success-transition>标签指定状态机所转换到的状态的名称。如果没有指定<success-transition>标签,则不发生转换。

规则标签定义包括<rule>元素。规则的所有其他部分是可任选的。规则的可任选部分包括:

·  要执行的动作

·  在上面第一个动作返回为假的情况下要执行的动作

·  在上面第一个动作处于异常时所要执行的动作。

如果没有指定上面的任何可任选的动作,则规则执行CNullAction,其在调用Execute()方法时不进行任何操作。

规则定义如下:

<rules>

    <state>

        <state-name>State-1</state-name>

        <message>

           <message-name>Message-1</message-name>

           <message-rule-list>

                 <rule action-name=”...”/>

                    <on-failure-action>...</on-failure-action>

                    <on-exception-action>...</on-exception-action>

                 </rule>

                 <success-transition>...</success-transition>

               </message-rule-list>

          </message>

...

     </state>

...

</rules>

动作标签定义指定要使用的动作的名称,并且可以指定由该动作使用的零或更多的<parameter>标签。如果动作仅仅需要单个参数,则可以使用<action>或<rule>标签的参数属性来指定。动作标签格式具有如下形式:

   <rules>

<state>

   <state-name>State-1</state-name>

   <message>

     <message-name>Message-1</message-name>

     <message-rule-list>

           <rule action-name=“SomeAction”>

              <parameter value=“SomeAction”/>

              ...

              <parameter value=“SomeAction”/>

              ...

           </rule>

           <success-transition>...</success-transition>

        </message-rule-list>

     </message>

...

   </state>

...

</rules>

状态也可以具有入口和/或出口标签规则集,其可以在进入状态或这从状态退出时执行。规则集的唯一限制是它可能不能从进入/退出的状态转换出来。该入口列表标签可以具有如下形式:

   <rules>

<state>

   <state-name>State-1</state-name>

...

       <entry-rule-list>

               <rule action-name=“SomeAction”>

                  <parameter value=“SomeAction”/>

                  ...

                  <parameter value=“SomeAction”/>

              </rule>

          </entry-rule-list>

          <exit-rule-list>

                     ...

          <exit-rule-list>

      </state>

...

</rules>

任何状态机规范文件可以嵌入其他状态机规范文件。例如,状态机XML可以嵌入其他XML文件,以合起来处理。StateMachine提供<include>标签来包括嵌入的文件,它的URL由名称属性指定。文件可以嵌入在状态机规范文件中来提供动作、状态、消息的共有集合(common set),以及提供一组优先于基本文件中元素的用户专用集元素。例如,下面的原始文件包含需要四个要处理的嵌入文件:

<state-machine>

   <include name=”other-document-url.xml”>

   <include name=”other-document2-url.xml”>

   <include name=”other-document3-url.xml”>

    <include name=”other-document4-url.xml”>

...

</state-machine>

嵌入的文件必须具有顶层(top level)<state-machine>标签。例如,包括在上个例子中的other-document-url.xml必须是合法的状态机XML文件,而且必须以状态机标签开始。

状态机提供了新过程(procedure)能力,允许消息处理器(message handler)执行一组共有规则。过程是可以从任何消息处理器调用的规则的集合。一旦这个规则的集合的执行结束,执行返回到原始消息处理器。

使用<procedure>标签来定义过程标签,如下例所示:

            <procedure name=”Null”>

        <procedure-rule-list>

           <rule action-name=...>

...

      <procedure-rule-list>

  </procedure>

过程可具有使用<argument>标签定义的零或更多的自变量标签,其具有所需要的名称属性。在使用名称属性上的名称的过程中的任何地方,可以将自变量参考为变量。当从过程返回时,自变量的值是未定义的。自变量可被定义如下:

   <procedure name=”Null”>

<argument name=”arg1”type=”string”default-value=””>

   <procedure-rule-list>

      <rule action-name=...>

...

   <procedure-rule-list>

</procedure>

  属性    含义  要求与否  名称    在过程内引用的自变量名称  是

类型  自变量类型。有效值与用于变量的一样    否默认值  在<call>中没有指定对应的参数的情况下所用的值    否

使用<return>标签使执行返回至调用程序。返回标签的例子为:

      <procedure name=”Null”>

  <rule action-name=...>

...

  <return>

  </procedure>

当过程返回时,执行以在<call>规则之后的下一个规则重新开始。

如下例中使用<tag>标签执行过程:

<call name=”Null”/>

名称属性是必要的,并且其指定原来定义的过程名称。<call>规则可以放置在可以放置<rule>标签的任何地方。

过程的<call>标签也可以指定参数标签值。在下面的例子中,这些值由<parameter>标签表示:

       <call name=”Null”>

   <parameter type=”string”value=”Hello World!”>

<call name=”Null”>

如果省略了参数,则取由对应的<argument>标签指定的任何默认值。参数是有定位的,例如,第一个参数和指定的第一个自变量相匹配,第二个参数和指定的第二个自变量相匹配。

有时,在一个状态转换成另一个状态之前,需要等待多个事件发生。当接收特定的事件时,持续追踪所有的事件或者需要等待每个事件的多个状态,或者需要一系列标志集(flag set)。习惯用语普遍说成为:状态机提供了特别的构造来持续追踪多个事件。对象ISynchTable提供了所期望的事件的列表。当接收到事件时,ISynchTable持续追踪所接收到的事件。一系列内部动作提供了管理和监控ISynchTable状态的能力,它们是:

    reset    将ISynchTable重新设置为已知状态    update    以当前的事件更新ISynchTable

  is_all_complete    如果接收到所有的事件,返回“真”  is_any_complete    如果接收到列表中的任何事件,返回“真”  is_complete

使用标签<synch-table>定义SynchTable如下例所示:

           <synch-table name=“Stable 1”>

        <entry>Message 1</entry>

        <entry>Message 2</entry>

...

        <entry>Message n</entry>

    </synch-table>

某些标签在确定要执行的动作时使用表达式。这些标签提供条件逻辑并包括<if>,<else-if>,<select>,以及<while>。表达式由左边,即可任选的操作符,以及可任选的右边组成。左边和右边可以是变量,常量,或者值。所支持的操作符为:

  操作符作为有效XML的操作符  支持的数据类型  用法  ====  所有  左边和右边是相等的  !=!=  所有  左边和右边是不相等的  >&gt;  整型,长整型  左边大于右边  <&It  整型,长整型  左边小于右边  >=&gt;=  整型,长整型  左边大于等于右边  <=&It;=  整型,长整型  左边小于等于右边  !  整型,长整型,  布尔型  返回布尔表达式的相反值。  如果数据类型是整型或长整  型:当值不为零,返回“真”,  当值为零,返回“假”。

如果表达式仅仅由左边组成,当表达式的值不是零或空的时候,表达式的值为“真”。否则,表达式的值为“假”。此外,实现接口IEvaluateable的任何动作可以用作表达式。调用动作的执行方法,并返回用作表达式结果的布尔值。操作符!可以应用于任何表达式。这个操作符将随后的表达式求值的结果取反。表达式是使用表达式标签以及在标签之间提供的规范语言语句来定义的。示例的一组表达式可能包括现在所述的逻辑结构。

<if>标签求取给定表达式的值,如果为“真”,则执行包含在其中的规则集。在图12中示出了if表达式的例子。<else>标签可以可任选地出现在<if>标签之后。如果表达式的值为“假”,则执行<else>标签内的规则集。图13中示出了else的定义。同样,<else-if>标签可以可任选地出现在<if>标签之后。该标签包含表达式属性。如果表达式的值为“真”,则执行<else-if>标签中的规则集。图14中示出了else-if的定义。

基于一系列表达式的求取值,<select>标签允许一系列规则集之中的一个规则集的执行。图15示出了select的定义。基于在<when>标签中提供的一系列表达式的求取值,<select>标签允许一系列规则集之中的一个规则集的运行。图16示出了when的定义。使用<otherwise>标签可以指定默认选择。如果所有以前的表达式都失效,则执行<otherwise>标签中的规则集。图17示出了otherwise的定义。

<for>标签允许一组动作的重复执行。图18示出了for的定义。在“for”表达式中的variable属性指定了用于控制循环的控制变量。仅仅整型变量可以用于此目的。Initial-value属性指定启动控制变量的初始值。Limit属性指定控制变量的最大值。当控制变量的值超过了该值时,循环终止。Increment属性指定对于循环的每个重复控制变量的增量。<while>标签允许一组动作的重复执行。图19示出了while的定义。只要expression属性保持为“真”,就再一次执行动作。

<timeout-rule-list>标签提供了方便快捷的机制,该机制用于对来自定时器的超时消息定义处理器。可任选的timer-name属性允许通过名称来识别定时器。如果没有指定这个属性,被处理的定时器必须根据状态而与一个集合相对应。超时规则列表和<message>定义驻留在同一层次。图20示出了超时规则列表的例子。

<break>标签提供一种机制,该机制使消息处理器对当前的消息停止执行规则。其在任何驻留<rule>标签的地方均有效。图21示出了break标签用法的例子。

<yield>标签提供一种机制,该机制使消息处理器对当前的消息停止执行规则。此外,如果当前的状态机是状态机协同群集的一员,将在下面更充分的描述的,那么其可以将焦点(focus)转移到该组中的其他状态机。如果当前的状态机不是状态机协同群集中的一员,那么它和<break>标签一样操作。其在<rule>标签可以驻留的任何地方有效。图22示出了yield标签用法的例子。

由<assert>规则标签识别的断言支持(assertion support),指定了在XML规则之中的某些特定点期望保持“真”的条件。如果该条件不能保持为“真”,则该断言失效。在断言失效的事件中执行的动作取决于状态机如何编译。如果状态机以Release模式编译,则在断言产生处于异常状态时,该异常将被作为规则集的故障来处理,执行故障处理器(failure handler)。如果状态机以Debug模式编译,中断状态机的运行,出现如图23所示的断言对话框。通过按断言对话框中的按钮,进行如下动作:

  按钮所执行的功能  中止(Aborr)立即终止应用  忽略(Ignore)如同断言没有失效一样继续该应用  重试  (Retry)如同断言没有失效一样继续该应用;然而,出现状态机调试对话,允许检查/修改状态机数据模型。注意:这个动作仅对Java支持有效。如果Java支持没有处于使用状态,则其动作和忽略一样。

数据模型资源管理器可以提供有状态机实现,来提供用于显示由状态机所保留的数据对象的机制。存储在状态机内的每个对象都具有元数据的相关集。这个元数据包括:

    对象名称    用于引用该对象的xpath表达式    对象值    对象值的字符串表示    创建日期    对象创建的日期/时间    上一次修改日期/时间    上一次修改对象的日期/时间    读计数    对象被访问的次数    写计数    对象被修改的次数

目前,数据模型资源管理器可以仅仅和Java支持联合使用。将在下面更充分地描述Java支持。图24示出了数据模型资源管理器窗口的例子。

环境变量文本可以被替换成为XML语句内的值和属性。举个例子,假设生成了下面的环境变量:

SCOT_BASE=c:\scot

这个变量可以由两个‘%’符号之间的变量名替代,如下例所示:

<tag attribute=”%SCOT_BASE%\filename.txt”>

所得的文本等效于:

<tag attribute=”c:\scot\filename.txt”>

属性值可以被替代成为规范语言语句中的值和属性。它们可以被看作为环境变量。如果属性和环境变量共享相同的名称,则属性值优先于由环境变量设定的值。例如,假设下面的属性已在XML语言语句中以如下的<property-list>语句定义:

<property name=”SCOT_BASE”value=”c:\scot”>

这个值可以由两个‘%’符号之间的属性名替代,如下例所示:

<tag attribute=”%SCOT_BASE%\filename.txt”>

所得的文本等效于:

<tag attribute=”c:\scot\filename.txt”>

基本状态机实现提供了许多动作。下面示出了内建动作的列表的例子:

内建动作名称  目的assign-variable  为变量赋值clean-state  将所有推到堆栈之上的状态移除Decrement-variable  自减(decrement)变量值delete-object  删除对象Evaluate-expression  对表达式求值。不赞成使用该动作,使用标签<if>替代goto-state  用于迫使下一状态为给定状态。这一动作仅用于<if>标  签,<else-if>标签,以及<else>标签Increment-variable  整数变量的值的自增(increment)is_all_complete  如果所有的事件由ISynchTable实例接收,返回“真”

  is_any_complete  如果任何事件由ISynchTable实例接收,返回“真”  is_complete  如果任何要求的事件由ISynchTable实例接收,返回“真”  is_timer_timing  如果给定的定时器正在运行,返回“真”  log  在日志中记入追踪线(trace line)  log-event  在事件日志中记入事件  match  如果字符串表达式和常规表达式相匹配,返回“真”  pop-state  从堆栈中弹出一个状态  push-state  向堆栈中推入一个状态  resend-msg  重发当前消息  reset  重新设置ISynchTable实例  send-msg  将给定消息发送至状态机  set-return-code  设定同步消息的返回代码  start-timer  启动给定的定时器  stop-timer  停止给定的定时器  Update  更新在ISynchTable实例中接收事件的列表  wait-timer  等待给定的定时器超时  Yield  对群集中的另一个状态机进行处理。如果这是唯一的状  态机,则进行空操作。

Assign-variable内建动作用于给指定的变量赋值。它接受如下参数:

    属性名称    用法    变量名称    将给定的表达式的值指定给要赋值的变量的名称    表达式    对变量求值并赋值的表达式

Clean-state内建动作,用于从状态机堆栈移除所有状态,它没有参数。

decrement-variable内建动作用于自减指定的变量的值。它有如下参数:

    属性名称    用法    变量名称    指定变量名称,以便把表达式的值赋给该变量

goto-state内建动作,用于强制状态机转换成为给定的状态。它具有如下参数:

    属性名称    用法    状态名称    指定状态机转换到的新状态的名称

increment-variable内建动作用于自增指定的变量的值。它具有如下参数:

    属性名称    用法    变量名称    指定要自增的变量的名称

如果接收到了ISynchTable实例中的所有事件,is_all_complete内建动作返回“真”。它具有如下参数:

    属性名称    用法    同步名称    指定要检查的同步表的名称

如果接收到了ISynchTable实例中的任一事件,is_any_complete内建动作返回“真”。它具有如下参数:

    属性名称    用法    同步名称    指定要检查的同步表的名称

如果ISynchTable实例已接收到的参数列表中指定的所有事件,is_complete内建动作返回“真”。它具有如下参数:

    属性名称    用法    同步名称    指定要检查的同步表的名称    事件    指定要检查的事件。可以按需要指定多次

is_timer_timing内建动作,用于表达式中来确定特殊的定时器是否正在定时。它具有如下参数:

  属性名称    用法  定时器名称    指定要测试的定时器的名称

log内建动作,用于在调试日志中加入输出行。它具有如下参数:

    属性名称    用法    文本    指定要加入到日志中的文本

log-event内建动作,用于在应用事件日志中加入输出行。它具有如下参数:

  属性名称    用法  源(source)    指定库名称源

类(class)如下字符串值之一:basic,advanced,operational,checker,以及external类型(type)如下字符串值之一:error,warning,information,audit-success,以及audit-failure类别(category)期望的消息的类别标识(id)期望的消息的标识号字符串(string)可任选的:用于消息的一个或多个替代字符串

match内建动作,用于对给定的常规表达式测试字符串。它具有如下参数:

    属性名称    用法    模式    指定常规的表达式模式    表达式    指定常规表达式应用的字符串表达式

pop-state内建动作,用于将状态机转换至原来存在堆栈中的状态,如果堆栈为空,动作记录一个错误,并且终止执行链。这个动作没有参数。

push-state内建动作,用于将当前的状态或者给定的状态保存到堆栈中。它具有如下参数:

  属性名称用法  状态名称指定要推入的状态名称。如果省略,则将当前状态存入堆栈

状态机使用resend-msg内建动作来重新发送当前消息给它自己。这个动作没有参数。

reset内建动作用于将ISynchTable实例重新设置为一个已知状态。它具有如下参数:

  属性名称    用法  同步名称    指定要重新设置的ISynchTable实例的名称

状态机使用send-msg内建动作来发送消息给它自己。它具有如下参数:

  属性名称    用法    要求与否  消息名称    指定消息名称    是  Immediate    是-同步操作    否-异步操作(默认)    否  Copy-plist    是-从当前msg中拷贝参数列表    否

    否-没有参数(默认)

Start-timer内建动作用于启动定时器。它具有如下参数:

    属性名称    用法    定时器名称    指定要启动的定时器的名称    持续时间    在超时发生之前以毫秒为单位的时间长度    周期性    是-超时在特定的间隔重复发生    否-超时单次发生(默认)

stop-timer内建动作用于停止定时器。如果给定的定时器当前没有在使用,则动作失效。它具有如下参数:

    属性名称    用法    定时器名称    指定要停止的定时器名称

update内建动作,用于更新ISynchTable实例中的入口。默认的,它使用当前的消息作为事件。可以可任选地指定事件。它具有如下参数:

    属性名称    用法    同步名称    指定要重新设定的ISynchTable实例的名称    事件    指定要更新的事件的名称

wait-timer内建动作用于等待定时器超时。如果给定的定时器当前没有在使用,则动作失效。它具有如下参数:

    属性名称    用法    定时器名称    指定要等待的定时器名称

注意:该动作在主状态机线程上执行硬等待。因为该动作不允许处理任何其他消息直到等待结束,它应该被谨慎地使用。

yield内建动作,用于放弃对群集中的一些其他状态机的控制。如果这个群集中没有定义其他的状态机,那么动作仅用于停止当前的执行链。这个动作没有参数。

在状态机内定义两种不同的类。第一种是没有参数且所有的方法定义为纯虚拟的抽象基类。用于这些类的类名称的第一个字母是‘I’,例如IClassName。第二种类或者是具体的实现,或者是具有属性和/或定义的方法的抽象基类。这些类的类名称的第一个字母是‘C’,例如CClassName。下表提供了典型的类名称和每个类的简要描述的列表:

类名称职责主类CAbstractStateMachine给出特殊状态的消息,确定要执行的动作集CExpressionFactory用于创建IExpression对象的工厂类CMessageObject消息的具体实现CPluginFactory用于创建IPlugin的实例的工厂对象CSMLoader用于读取XML文件和建立所有的内容对象的工厂对象CStateMachineFactory用于构建IStateMachine实例的工厂对象CXMLRule由XML状态机创建的规则的具体实现CXMLStateMachine从XML文件读取规则的状态机实现IAction在XML中定义的<action>的抽象表示IConstant在XML文件中定义的<constant>的抽象表示IEvaluatable为能够提供值的对象提供功能的共有集的接口IExpression表示能够求值的表达式的接口ILibrary表示动作DLL,允许动态地载入IAction实例ILookupTable表示查找表,为基于某个关键码来查找值提供接口IMessage在XML中定义的<message>的抽象表示IPlugin为CSMloader不知道如何处理的用户标签提供处理器IRule用于给定状态下的给定消息的指令集的抽象表示IRuleProxy包含规则集的描述的临时抽象对象。由SMLoader创建IState在XML中定义的<state>的抽象表示IStateMachine由这个包所展现的外部接口IStateMachineObject在XML文件中定义的对象的抽象基类ITimer在XML中定义的<timer>的抽象表示

IVariable在XML中定义的<variable>的抽象表示内在的状态机动作CActionBase用于IAction的所有具体实现的抽象基类。对与状态机交互作用提供功能的共有集CCleanState清理状态堆栈CEvaluateExpression对XML中的给定逻辑表达式求值,并且返回“真”或“假”CGotoState强迫状态转换。要求使用<if>,<else-if>,<else>,<when>,以及<otherwise>CNullAction在调用Execute()方法时不进行任何操作的动作CPopState将状态弹出堆栈,重新将其存储为当前状态CPushState如果没有指定参数,则将当前状态推到堆栈上。任何参数可以指定要推到堆栈上的状态的名称CResendMsg重新发送当前消息至状态机CSendMsg发送新消息至状态机CSetRetumCode将来自消息的返回代码设定为给定值。和同步消息一齐使用CTimerOperations为ITimer提供起始和结束动作CVariableOperations为IVariables提供自增,自减和赋值操作用于表达XML中定义的实体的具体实现CActionImpl表示在XML的<constant-list>段中的<action>定义。由CXMLStateMachine使用。由CSMLoader创建。CConstantImpl表示在XML的<constant-list>段中的<constant>定义。由CXMLStateMachine使用。由CSMLoader创建。CExpressionImpl表示在动作中定义的逻辑表达式XML。由CXMLStateMachine使用。由CSMLoader创建。CLibraryImpl表示在XML的<library-list>段中的<library>定义。由CXMLStateMachine使用。由CSMLoader创建。

CLookupTableImpl表示<lookup-table>定义。由CXMLStateMachine使用。由CSMLoader创建。CMsgImpl表示在XML的<message-list>段中的<message>定义。由CXMLStateMachine使用。由CSMLoader创建。CRuleImpl表示在XML中的<rule>定义。由CXMLStateMachine使用。由CSMLoader创建。CStateImpl表示在XML中的<state-list>段中的<state>定义。由CXMLStateMachine使用。由CSMLoader创建。CStateObjectProxy表示在XML的<rule>段中的<state>定义。由CXMLStateMachine使用。由CSMLoader创建。CTimerImpl表示在XML的<timer-list>段中的<timer>定义。由CXMLStateMachine使用。由CSMLoader创建。CVariableImpl表示在XML的<variable-list>段中的<variable>定义。由CXMLStateMachine使用。由CSMLoader创建。在载入过程中使用的类CActionHandler解释在<action-list>中的<action>定义。由CSMLoader使用。CConstantHandler解释在XML的<constant-list>段中的<constant>定义。由CSMLoader使用。CElseHandler解释在XML的<rules>段中的<else>定义。由CSMLoader使用。CElseifHandler解释在XML的<rules>段中的<else-if>定义。由CSMLoader使用。CIfHandler解释在XML的<rules>段中的<if>定义。由CSMLoader使用。CLibraryHandler解释在XML的<library-list>段中的<library>定义。由CSMLoader使用。

CLookupTableHandler解释在XML中的<lookup-table>定义。由CSMLoader使用。CMsgHandler解释在XML的<message-list>段中的<message>定义。由CSMLoader使用。COtherwiseHandler解释在XML的<rules>段中的<otherwise>定义。由CSMLoader使用。CPluginHandler解释在XML的<plugin-list>段中的<plugin>定义。由CSMLoader使用。CPropertyHandler解释在XML的<properties>段中的<property>定义。由CSMLoader使用。CRuleHandler解释在XML中的<rule>定义。由CSMLoader使用。CSelectHandler解释在XML的<rules>段中的<select>定义。由CSMLoader使用。CStateHandler解释在XML的<state-list>段中的<state>定义。由CSMLoader使用。CTimerHandler解释在XML的<timer-list>段中的<timer>定义。由CSMLoader使用。CVariableHandler解释在XML的<variable-list>段中的<variable>定义。由CSMLoader使用。CWhenHandler解释在XML的<rules>段中的<when>定义。由CSMLoader使用。

图25示出了非瞬态状态机类的类图。每个类包含和类相关的方法。在图中通过三角与其他类相连接的类表示更高的类的继承。在图中通过菱形和其他类相连接的类表示相关类。

下面的表格包含用于标签映射的XPath表达式的罗列。SMLoader使用这些表达式来确定哪一个CContentHandler类处理当前的XML标签。

标签名称XPath表达式<state-machine>/state-machine由CSMLoader使用的XPath表达式

<include>//include由CLibraryHandler使用的XPath表达式<library-list>/state-machine/library-list<library>/state-machine/library-list/library<library-name>/state-machine/library-list/library/library-name<comment>/state-machine/library-list/library/comment由CVariableHandler使用的XPath表达式<variable-list>/state-machine/variable-list<variable>/state-machine/variable-list/variable<var-name>/state-machine/variable-list/variable/var-name<comment>/state-machine/variable-list/variable/comment<initial-value>/state-machine/variable-list/variable/initial-value<max-value>/state-machine/variable-list/variable/max-value<min-value>/state-machine/variable-list/variable/min-value由CTimerHandler使用的XPath表达式<timer-list>/state-machine/timer-list<timer>/state-machine/timer-list/timer<timer-name>/state-machine/timer-list/timer/timer-name<comment>/state-machine/timer-list/timer/comment由CConstantHandler使用的XPath表达式<constant-list>/state-machine/constant-list<constant>/state-machine/constant-list/constant<constant-name>/state-machine/constant-list/constant/constant-name<comment>/state-machine/constant-list/constant/comment<constant-value>/state-machine/constant-list/constant/constant-value由CStateHandler使用的XPath表达式<state-list>/state-machine/state-list<state>/state-machine/state-list/state-definition

<state-name>/state-machine/state-list/state-definition/state-name<comment>/state-machine/state-list/state-definition/comment由CMsgHandler使用的XPath表达式<msg-list>/state-machine/msg-list<msg>/state-machine/msg-list/msg-definition<msg-name>/state-machine/msg-list/msg-definition/msg-name<comment>/state-machine/msg-list/msg-definition/comment<value>/state-machine/msg-list/msg-definition/msg-value由CPropertyHandler使用的XPath表达式<property-list>/state-machine/property-list<property>/state-machine/property-list/property由CLookupTableHandler使用的XPath表达式<lookup-table>/state-machine/lookup-table<lookup-entry>/state-machine/lookup-table/lookup-entry由CActionHandler使用的XPath表达式<action-list>/state-machine/action-list<action>/state-machine/action-list/action<action-name>/state-machine/action-list/action/action-name<comment>/state-machine/action-list/action/comment由CRulesHandler使用的XPath表达式<rules-list>/state-machine/rules<state>/state-machine/rules/state<state-name>/state-machine/rules/state/state-name<global>/state-machine/rules/state/global<exit-rule-list>/state-machine/rules/state/exit-rule-list<entry-rule-list>/state-machine/rules/state/entry-rule-list<message>/state-machine/rules/state/message<message-name>/state-machine/rules/state/message/message-name

<message-rule-list>/state-machine/rules/state/message/message-rule-list<success-transition>/state-machine/rules/state/message/message-rule-list/success-transition<failure-transition>/state-machine/rules/state/message/message-rule-list/failure-transition<on-failure-action>/state-machine/rules/state/message/message-rule-list/on-failure-action<exception-transition>/state-machine/rules/state/message/message-rule-list/exception-transition<on-exception-action>/state-machine/rules/state/message/message-rule-list/on-exception-action由CRuleHandler使用的XPath表达式<rule>//rule<action>//rule/action<action-name>//rule/action/action-name<parameter>//rule/action/parameter<value>//rule/action/parameter/value<failure-transition>//rule/failure-transition<on-failure-action>//rule/on-failure-action<action-name>//rule/on-failure-action/action-name<parameter>//rule/on-failure-action/parameter<value>//rule/on-failure-action/parameter/value<exception-transition>//rule/exception-transition<on-exception-action>//rule/on-exception-action<action-name>//rule/on-exception-action/action-name<parameter>//rule/on-exception-action/parameter<value>//rule/on-exception-action/parameter/value

在图26的类表中的多数类只用于解析XML文件的目的,它们在解析完成之后被释放。那些不是瞬态的类由StateMachine使用。

状态机的最新版本提供了Java应用的支持。该状态机由类com.ncr.statem.StateMachine的实例表示。这个Java类和底层的C++CJavaStateMachine对象相互作用,该对象允许Java动作结合C++动作执行。状态机Java支持被提供来作为单独分开的、调用statemj.dll的可执行DLL。这个DLL为Java提供所有的支持类,以及支持Java动作的Java原生接口(JavaNative Interface,JNI)代码。Java支持已被实现为到状态机的plugin。结果,以下面的语句在XML定义中加入了Javaplugin:

            <plugin-list>

        <plugin name=”Java.Factory”/>

    </plugin-list>

类com.ncr.statem.StateMachin的所有实例经由com.ncr.statem.StateMachineFactory类来生成。Create方法返回充分载入的状态机实例。其有如下签名:

Public static StateMachine create(String_name

                                 ,String_url

                                 ,String_dllName

                                 ,String_configDir);

在这个调用语句中,_name参数指定状态机的唯一名称。_url参数指定包含状态机的XML定义的URL。_dllName参数指定包含Java支持的共享DLL的名称。_configDir参数指定用于URL相关搜索的目录。

Java中可以定义动作,该动作可以和C++中定义的动作并存。实际上,所有的内部动作都是C++动作。不像C++动作,Java动作在使用之前没有登记。替代的,它们通过使用Java映像设施(reflection facility)来生成。已命名的类的实例在第一次遇到它时按照需要而生成,并且在状态机的整个使用期限内保持。当状态机结束,Java动作被销毁。下面显示了Java动作定义的例子。附加的<class>标签识别该动作为Java动作。在<class>标签上的名称属性指定完全限定的动作的类名称。

       <action-list>

    <action name=”SomeAction”>

         <class name=”com.ncr.ActionName”>

    </action>

</action-list>

存储在如下描述的共享数据模型内的Jave对象的任何字段,可以在由状态机使用的表达式中被访问。通过调用字段的存取器方法(accessor mehtod)可以访问这些字段。只可以调用getXXX()形式的存取器方法,其中XXX是要访问的字段的名称。对象本身可通过它的XPath名称从共享数据模型被引用。在表达式中使用的语法是:

$(xpath-expression)[.method-name()][[index]]

其中,

Xpath-expression是期望的Java对象的XPath表达式。

仅仅那些以字符‘/,开头的简单绝对(simple absolute)XPath表达式可以被支持。

Method-name是存取器方法名称。该方法名称是可任选的。如果没有指定方法名称,则使用对象本身作为值。

Index指定数组的索引。这个参数要求从数据模型返回的对象或者是数组,或者是Java集合(Java collection),该数组或Java集合通过索引(例如ArrayList)指定访问其成员的能力。

仅仅那些由Java支持的原生类型可以被直接操作。这些原生类型包括整型,长整型和布尔类型。Java.lang.String类是特殊的,其也可以被直接访问。用户定义的所有其它Java对象均通过调用对象的toString()方法来间接操作。

在下面的例子中,表达式“$(/transaction/current-instance).getTotalDue()&gt;0”首先使用xpath表达式“/transaction/current-instance”从共享的数据模型执行对象的查找。然后,该表达式定位和调用对象的getTotalDue方法。最后,该表达式将从该方法返回的长整型值和零做比较。如果该值大于零,返回值为“真”。如果该值小于或等于零,返回值为“假”。

图26示出了用于支持Java的类的类图。同样,图中指出了每个类中可用的方法。下表识别了JAVA支持的类并且在表后给出了每个类的简要描述:

类名称职责Javacom.ncr.statem.StateMachine提供对状态机设施的访问的基本类com.ncr.statem.StateMachineCluster提供对成组协作的多个状态机实例进行访问的基本类com.ncr.statem.ActionJava动作的基本类com.ncr.statem.Message等效于C++中的IMessagecom.ncr.statem.LookupTable等效于C++中的ILookupTable

com.ncr.statem.StateMachine类是主要的状态机类。该类为访问状态机的功能性提供多个机制,其提供如下机制:

●对下层的数据结构(例如查找表和动作)的访问

●向状态机发送/发布消息的能力

●对DataModel对象的访问,该DataModel对象用于为动作的使用提供对象的键控存储(keyed storage)。

对于com.ncr.statem.StateMachine的每个实例,均存在底层C++CJavaStateMachine对象。

com.ncr.statem.StateMachineCluster类表示协作的com.ncr.statem.StateMachine实例的集合。它本身是com.ncr.statem.StateMachine的实例,并且可以用在任何可有效使用com.ncr.statem.StateMachine的地方。它提供和上面提到的com.ncr.statem.StateMachine相同的能力,并且将消息发送至当前有效的状态机实例。对于com.ncr.statem.StateMachineCluster的每个实例,均存在底层C++CJavaCluster对象。

com.ncr.statem.Action类是所有Java动作必须实现的接口。提供了两种方法-execute和getResult。前者对应于C++IAction接口的执行方法。后者提供了获得“真”或“假”的返回值的能力。在C++领域中,这一能力通过设定pResult参数来实现。在Java中参数由值传递,所以不使用该方法。对于生成的每个com.ncr.statem.Action类,均存在底层CJavaAction C++对象。

com.ncr.statem.Message类用作对状态机的输入。这个类等效于C++实现中的IMessge。对于这个类中的每个实例,均存在C++侧(C++side)上的底层CJavaMessage。

com.ncr.statem.LookupTable类等效于C++实现中的ILookupTable。com.ncr.statem.LookupTable和ILookupTable实例之间一一对应。对于com.ncr.statem.LookupTable的每个实例,均存在底层ILookupTable对象。

下表识别了C++Java的原生类,这些类简要描述如下:

  类名称    职责  非瞬态C++Java相关类  CJavaStateMachine    为Java提供接口的扩展CXMLStateMachine实例  CJavaAction    Java动作的基本类  CJavaMessage    Java消息的基本类  瞬态C++Java相关类-仅在载入时使用  CJavaActionProxy    CJavaActionProxy  CActionClassHandler    CActionClassHandler  CJavaPluginFactory    CJavaPluginFactory

CJavaStateMachine类源自CXMLStateMachine,并且提供被要求来允许从状态机执行Java动作的功能性。

CJavaAction类为保存类路径和其他消息提供备份存储,该类路径和其他消息与调用对应的com.ncr.statem.Action的执行方法有关。

CJavaMessage类为保存JNI信息提供备份存储,该JNI信息与使用在状态机中对应的com.ncr.statem.Message有关。

CJavaActionProxy类在载入处理过程中保存类信息。这一信息稍后用于生成CJavaAction及其对应的com.ncr.statem.Action。

CJavaPluginFactory类提供将Java支持钩入状态机所必要的IPlugin接口。

上面描述的代码用于实现Java原生方法。但是,因为JAVA原生接口由C编程语言实现,所以没有实际的类(real class)。下表列出了类及其功能:

类名称  职责C++JNI支持代码StateMachineJavaInterface  为com.ncr.statem.StateMachine提供JNI代码LookupTableInterface  为com.ncr.statem.LookupTable提供JNI代码

  ActionBaseInterface    为com.ncr.statem.Action提供JNI代码

状态机也支持一种配置,在该配置中,多个状态机以协作的模式操作。在这个配置中,一个状态机被指定为基本状态机,且被授予“焦点”。所有的消息首先导向到带有焦点的状态机。如果该状态机不处理消息,则询问其他状态机看是否有一个可以处理该消息。如果另一个状态机可以处理该消息,则该状态机获得焦点,变成当前执行的状态机。

每个状态机具有在XML定义文件中定义的休眠状态。当进入这一状态时,状态机失去焦点,除非该状态机是基本状态机。通过将状态机放在堆栈上来对它们进行追踪。堆栈的顶端是当前执行的状态机,并具有焦点。在新的状态机获得焦点时,将其加入堆栈。当状态机失去焦点时,它被从堆栈的顶端移除,返回到可用池(available pool)。堆栈的新的顶端重新获得焦点并且在其离开的地方重新开始执行。

当前执行的状态机可能以两种方式失去焦点。通过执行yield动作,状态机自愿地放弃焦点给另外一个状态机。失去焦点的另一个方法是接收状态机不能处理的消息。这种无效性致使具有焦点的状态机产生焦点给能够处理该消息的另一个状态机。协作状态机组通过CCluseter类的实例来管理。这个类负责维护堆栈以及向组分状态机委派任务。

定义群集的XML语句有顶层的<state-machine-cluster>标签,其后为一个或多个用于识别组分状态机的<state-machine>标签。这些标签上允许如下属性:

●两个标签的name属性是用来引用组分的唯一名称。

● url属性识别文件的URL,该文件包含要用于状态机的XML定义。

●library属性识别包含相关状态机元素的库的名称。这个库必须在状态机能被载入之前载入。

在XML语句中的群集定义可能看起来如下:

<?xml version=”1.0”?>

<state-machine-cluster name=”Fastlane”>

    <state-machine-name=”CustomerMode”

                              url=”FastLaneCustomerMode.xml”

                               library=”statemj”default=”true”/>

     <state-machine-name=”StoreMode”

                               url=”FastLaneStoreMode.xml”

                               library=”statemj”/>

     <state-machine-name=”AssistMode”

                               url=”FastLaneAssitMode.xml”

                               library=”statemj”/>

     <state-machine-name=”MaintenanceMode”

                               url=”FastLaneMaintenanceMode.xml”

                               library=”statemj”/>

     <state-machine-name=”ErrorMode”

                               url=”FastLaneErrorMode.xml”

                               library=”statemj”/>

     </state-machine-cluster>

模式状态机是一种状态机,在该状态机中,用于处理未知消息的默认行为已被改变。模式状态机宁愿将消息排队直到遇到明确的<yield>标签,也不将控制和消息传送给群集中的另一个成员。此时,模式状态机对另一个状态机产生控制,并重新发送排好队的所有消息。模型状态机通过在<state-machine>标签中加入modal=属性来定义:

<state-machine modal=”true”>

...

</state-machine>

为了准备操作,以规范语言(例如为XML)设计并编写状态机实现。在定义中的规范语言语句包括调用可执行计算机代码的动作,该计算机代码可在例如结账柜台的商务平台上实现系统功能。包含规范语言语句的规范文件存储在商务平台的硬盘或者类似设备中。解析应用程序也存储在该硬盘中或存储在由控制商务系统的处理器运行的商务平台的存储器中。

初始化状态机以及向状态机提供工作线程来开始操作。解析器开始解释状态机定义的规范语言语句。这个解释包括调用商务平台的商务逻辑模块,以及对返回值求值来继续解析规范语言语句。状态机实现定义的解析持续进行直到状态机到达终止点。此后,状态机实现要求在再次开始实现的解析之前重新初始化。

为了修改商务系统的操作,除非已经修改了商务平台,所要求的唯一改变就是为商务逻辑所要求的那些改变。因为商务逻辑以规范语言编写,规范文件内部的结构可以改变,而不要求在系统中对计算机代码进行重新编译和另外的安装。替代的,可将新版本的规范语言文件写入硬盘。在初始化时验证这个新的版本,然后开始新的规范文件的解析以控制商务系统。

尽管通过对示例的处理和系统部件的说明来对本发明进行了描述,并且,尽管以值得考虑的细节描述了各种处理和部件,但申请人并非试图将所附权利要求的范围限制于这些细节。对于本领域普通技术人员而言,其他的优点和修改也容易显现。因此,在本发明的最主要的方面是,本发明的范围不限于那些给出并进行了描述的特定细节,实现或示意性的例子。相应地,在不偏离申请人的总体的发明理念的情况下,可以对这些细节作出变更。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号