《电子技术应用》
您所在的位置:首页 > 其他 > 业界动态 > 基于XML和JAVA构建程序生成器

基于XML和JAVA构建程序生成器

2008-12-27
作者:冯少荣
1 引言
    程序生成器可以加快程序编码产生的速度,产生规范和正确的代码,编写一个程序生成器,它意味着不仅仅是写一个程序,而是要写一个可以写出许多程序的程序。在用户界面、数据库、中间件、语法分析" title="语法分析">语法分析和词法分析等方面,程序生成器是其开发环境中的重要部分。程序生成器的思想已经使用了很多年了。比如:
. 语法分析器:语法分析器读入一个标记序列,并且创建一个称为语法树的描述信息的数据
结构。典型的为UNIX使用程序yacc,它读入一个语言的形式描述(用某种语法表示)连同看
作是语法规则的动作,然后输出一个语法分析器程序。
. 有限状态机:可以用显示不同状态、事件及状态转移的表和(或)图对程序进行描述和说明。
典型的为UNIX实用程序lex,就是一个有限状态机的程序生成器,并且用yacc来解析语言
的标记。
. 用户界面:现在大多数代码都是由GUI构造器和直观的编程工具自动生成。
. 数据库中的程序生成器:给出数据表、关系、事务逻辑及报表模式的描述,就能生成依照指定的规格构造的数据库程序。如:报表生成器、菜单生成器、屏幕生成器等。
. Web页面生成:Java服务器页面JSP是一种在Web上创建动态内容的工具。
    而XML作为一种完全可移植的数据格式,将成为跨平台的不同系统之间的数据交换及数据显示、描述的标准。Java具有面向对象、跨平台、分布式、简捷、健壮、安全等特点,功能强大且简单易学,正在逐步成为新一代网络编程的主要开发语言,Java将是网络上的“世界语”,今后所有用其它语言编写的软件统统都要用Java语言来改写。XML和Java的结合对已有的程序生成器技术提供了新的应用背景,并且两者相互协调补充。以更简单而且优雅的风格、可靠的性能,提高程序生成器的开发效率。
2 程序生成器的结构
    作为程序生成器的典型结构,它由获取数据、分析/转换数据、生成程序3个部分组成。规范程序生成器经过如图1所示三种约束时间,完成程序的生成。

3 域工程技术
    域工程是一个用于高效创建一个应用(程序或软件组件)族成员的过程。它是一个确定某个专业的重要组成与需求的系统方法,对如何高效地建立一个满足用户需要的程序生成器是非常必要的。程序的自动创建依赖于对语法和期望目标的精确描述,域工程技术将此概念延伸到时间基础上分析一系列相关的程序,并能够生成和修改它们。生成系统的构造过程就是一个解决问题产生软件程序过程。因此,域既是一个有关联的问题的集合,也是一个有关的软件应用程序" title="应用程序">应用程序的集合。域工程分为两个过程:域分析及域实现。
    域分析:是一个用于确定域的术语、范围、共性及变性的过程。
    域实现:是指在域中按照指定的要求高效构造应用及创建工具, 在域分析结束时即开始。这其中包括程序生成器。
    任何开发过程都要经历一系列的决策。在需求分析、软件结构、界面开发、软件设计(算法、数据结构" title="数据结构">数据结构和数据表示)、软件编码与测试以及软件的使用过程中都需要做出决策。有关的最艰难的工作是做出决策而不是编码。对于域工程,最困难的是判断哪些是重要的决策,由谁来制定,什么时候制定。并且要能区分其中的重要决策和不重要决策。决策的制定,要考虑域工程的过程中下列三种重要角色的作用及其作用时间(约束时间)。
    域工程师:定义并建立如程序生成器那样的过程和工具。
    应用工程师:利用如程序生成器那样的工具创建应用程序。
    应用程序用户:使用应用程序。
    域工程时间:由域工程师为每个应用程序族做出决策的时间。包括:域分析时间,域执行时间。
    约束时间:由应用工程师为每个应用程序做出决策的时间。包括:规划时间,生成时间,编译时间,设计时间,链接时间。
    运行时间:由应用程序用户为每个特定的使用做出决策的时间。包括:安装时间,初始化时间,真正运行时间。
    决策分解是域实现的基本概念,它简单地分解每个独立的决策,并将其作为一个独立元素或系统组件。如决策的物理分解可产生3种信息:域信息、用户信息、应用信息。有效的决策分解将产生一个既易于改变、又易于构造的软件结构。决策分解基于抽象化。抽象化是一种使软件更具有一般性、灵活性、可理解性和可重用性的主要技术。
    决策分解技术主要包括:
(1) 物理分解:如,应用程序可以分解出不依赖于机器的部分和依赖于机器的部分。
(2) 典型过程的抽象化:如,子程序、宏及可重用软件包的创建。
(3) 面向对象的抽象化:如,隐含在对象中的隐藏决策。
(4) 继承方法:公共关系在父类和子类中被共享使用。
(5) 应用程序框架:可看作一个软件重用的自顶向下的方法。
(6) 规范驱动技术:应用规范层信息创建或直接执行应用程序
    域工程是创建应用程序族的过程,因此,不仅要考虑单一的应用会如何随时间而改变,而且也要注意到域领域应用的整个范围,从而确定这些应用之间的差别。这些差别称为域工程的可变性,它是域工程的核心。对于域工程需要理解一个应用族中什么是不变的,什么是可变的。不变的成分称为共性,最困难的就是确定并组织一个域的所有共性与可变性。
共性:是一个在域工程期间关于什么是整个域的共同性问题所做出的决策或假设。共性可以确定域的范围、软件的功能、与其它域的分界面、操作环境、软件的限制标准以及应用软件公共部分实现的细节。共性和标准有许多共同点。标准是做某件事情的共同方法。许多为标准所做的努力根本上就是一个域分析。相反域分析工作附带产生一些标准,以帮助创建更大的将为一大群人所接受的共性集合。
    可变性:是一个在域分析期间确认但直到建立或运行时间才确定的决策。
共性和可变性经常可以相互转化。而使域分析保持平衡。如图2所示

    可变性包括:建立时的可变性、运行时的可变性,编译时可变性、生成时可变性、预处
理时可变性。
    ① 建立时的可变性
    表示程序族的全部程序中的差别是什么。建立时的可变性集合是为建立一个程序生成器所需要的信息中最重要的部分,它可以用于定义一个规范语言和一个支持可变性的结构框架。
    ② 运行时的可变性
    是在运行时间内确定的决策。运行时的可变性建立在应用软件的公共部分。由许多方法表示和控制。比如:
. 资源和配置文件:这些文件包含信息并在运行时间内读入一般保存在一个外部文件
. 数据库:查询数据库获得读入信息
. 用户界面:通过与用户交互获得信息。
. 动态加载类:常见的变化可以被确定、创建、编译,并且直接加载到一个正在运行的Java程序中。
    ③ 编译时可变性
    是在编译时间确定决策。可以由许多方式实现。比如:
. 编译时的常量:可以利用好的编译器来优化程序。
. 面向对象技术:基本类定义共性,子类提供可变性。特别是编译时的可变性。
    ④ 生成时可变性
    信息通过一个创建定制程序的程序生成器读入。
    ⑤ 预处理时可变性
    预处理发生在编译时间前,预处理器用于扩展宏功能。依据分开的头文件给程序构造可变性。
    域工程经常从应用工程周期获得适当的反馈而不断展开。形成域工程周期。应用工程周期和域工程周期的关系如图3所示。

4 程序生成器的实现方法
4.1 利用DOM生成程序

    使用XML文件和DOM构建一个程序生成器如图4所示。

    使用XML语法分析器读入和存储规范, 读入XML文件并对其进行语法分析,创建DOM对象。XML语法分析器需要三种分析和存储规范的输入方法:
. 由W3C提供的DOM接口的输入(纯DOM方法);
. 针对IBM的语法分析器的输入(自定义DOM方法);
. 用于读入文件的标准的Java输入数据包(自定义SAX方法);
    以上三种分析和存储规范方法的选择可以结合下面的判定要求加以确定。
(1) 判定代码生成器能否用自定义数据结构获得规范的信息,若不能,则使用纯DOM方法;若能,则进一步判定自定义数据结构是否应该从DOM中创建,若是,则使用自定义DOM方法。否则,使用自定义SAX方法;
(2) 根据性能要求确定。大的XML文档上使用DOM数据结构可能会花费昂贵,尤其是当仅仅使用文档的一小部分生成程序时。这时将不得不创建自己的自定义数据结构,并且还将使用SAX。
(3) 如果使用DOM效率很低,也可以根据实际情况加以考虑。这种情况最有可能发生在程序的规范仅为大的XML文档的一小部分的地方。使用SAX将允许忽略XML文档中的大部分,而仅仅只为代码生成器提取必要的信息。
    一旦XML文档进行过语法分析并且作为一个对象使用时,就可以在该对象上执行分析和判断。分析包括:
. 检错:在规范中查找句法错误。
. 警告:查找公共错误或潜在的不明显的错误。
. 模型分析:分析规范更深层的语义。
. 性能分析:决定生成一个优化程序结构或代码途径的规范。
. 缩写的扩展:规范中常提供缩写或快捷方式。
. 扩展成标准形式:有些规范允许以各种方式说明同一件事情。
. 优化:转换对象。
    一旦DOM数据结构存储于内存中,就可以把基于XML文档的代码用于分析和转换结构,最终代码生成器直接从DOM数据结构中获取信息。读入XML文件并对其进行语法分析的程序段如下:
import  com.ibm.xml.parser.Parser;
import  org.w3c.dom.*;
import  java.io.*;
public  class  DOM_Utill {

/** read  and  parse  an  XML  files */
public  static  Document  readDocument (String  filename)
throws Exception {
InputStream is=new FileInputStream(filename);
Parser parser=new Parser(filename);
Return Parser.readStream(is);
}
}
    使用DOM的程序生成器,首先要提供一个基本实用工具类,该类定义利用DOM树中信息的实用方法,如用于获取与语法分析树中的节点相关联的数据的方法,用于获取元素属性值的方法,如果使用自定义DOM方法。这种方法是程序将把XML规范作为一个自定义的数据结构读入,然后将该规范转换为一个自定义的数据结构,XML规范既可以在运行时间读入,也可以在生成时间读入。标准的代码生成器是一系列简单的打印语句,这些语句是具有重复代码或条件代码的控制语句的状态流。
4.2 利用JSP(Java  Server  Pages)生成程序
    JSP是普遍应用于Internet中的重要的程序生成器。JSP是一种非常简单的规范语言,包含了输出到Web页面的静态文本和调用基本实现语言的转义符" title="转义符">转义符,它没有高层次的抽象化并且不涉及语言结构。转义符提供很大的灵活性,同时又只产生最小的影响。JSP是一种既简单又强有力的技术,用于在Web服务器端生成动态的HTML页面。JSP提供了一个非常简单的利用“模板”创建程序生成器的途径。尽管JSP是用于设计和实现Web页面的,但原则上可以传送任何其它内容,特别是它可以传送Java程序。
一个简单的程序生成器是JSP翻译器,JSP翻译器是程序生成器广泛使用的一个示例。它把一个JSP文件(规范)转换成一个JAVA文件。从一个JSP文件到Java程序的转换由Java服务器页面规范来定义。过程示例如下:
Mydate.jsp

 

   

4.3 利用Xpath和XSLT生成程序
    XSLT和Xpath能够不利用任何Java代码就可以创建程序生成器。
    Xpath是一种用于从XML文档提取信息的语言,用于在XSLT中选择一个XML文档的不同部分。
    XSLT又称可扩展的样式表转换语言,可以将XML文档翻译成其它不同结构的XML文档或纯文本文件。XSLT提供了一种转换和操作XML数据的机制。如图5所示。
    XML构成了信息互交换标准的基础。XML提供了信息构成的结构,XSLT与Xpath(XML路径语言)提供了提取、重建和熟练使用XML中信息的手段。Xpath使用一种简单的路径语言来对XML文档的各个部分进行寻址,XML提供一系列的操作和操作方法。而Xpath保证了选择和寻址的准确度。

    利用Xpath和XSLT生成程序举例
play.xml



XML document
 
    Go up the hill
   
 


    Fetch a pail of water
   
 

 
    Fall down, break crown
   
 

 
    Tumble down