级别: 中级 Robert Peterson (rrpeters@us.ibm.com), WebSphere Enablement, Austin, TX, IBM
2007 年 6 月 22 日 学习如何使用 IBM Rational Software Architect V7 版本来创建属于自己的、定制化的工具以解决关系软件项目的绝大部分问题。这篇文章介绍了一个新的转换创建(Transformation Authoring)的特性,使您能够创建带有图形界面和基于标准模板的开发工具。
软件开发人员或者构架师的世界是复杂的,在那里您通常需要集成以前从未集成的不同技术。随着新兴的和以往技术的必然改变,甚至使用企业所开发的框架之外的最好的工具也只能帮助您达到一个特定的程度。
IBM® Rational® Software Architect 7.0 包含一个称为转换创建(Transformation Authoring)的新特征,使您能够不需要任何Eclipse框架的知识或者不需要定制代码就能创建定制工具。它使用运用简单的 XPath 语法的绘图工具和模板。(要了解关于 XPath、 XML Path 语言的信息,请参阅 参考资源部分 ) 这篇文章为这一技术说明了业务案例,描述了转换创建(Transformation Authoring)特性是如何起作用的,并且给出了为访问数据库一步步创建一个简单工具的例子。
 |
Rational 软件交付平台 V7 专题
最新版本的 IBM Rational 软件交付平台(IBM Rational Software Delivery Platform) V7 提供了对全球跨地域分布开发团队的支持,并对基于面向服务体系结构(SOA)应用的全生命周期管理提供了更加全面的支持。
您想了解新版本的 IBM Rational 软件交付平台产品的新特性吗?通过“Rational 软件交付平台 V7 专题”,您将可以全面地了解 IBM Rational 软件交付平台 V7 版本产品的最新特性。专题中的 Rational 开发工具入门及进阶教程系列,还将助您快速掌握最新的 Rational V7 开发工具,并将这些由 IBM Rational 专家为您带来的软件开发最佳实践应用到您的工作当中。
|
|
转换创建(Transformation Authoring)的业务价值
Rational Software Architect 的转换创建(Transformation Authoring)特征提供了创建与业务需要相关的定制工具的方法,并且不需要专门技术即可创建。让我们了解一下转换创建(Transformation Authoring)的主要益处。
提高生产力。一个开发团队通常需要集成两个独立的技术或系统。例如,您可能需要集成一个以往的方法和一个前沿的业务过程建模系统。然后,通常没有工具可以处理这一集成。您可以使用转换创建(Transformation Authoring)来创建定制工具以解决这些特殊的问题,因此极大地增加团队的生产力并最终减少软件系统所有权的总成本。
一致性将维护费用降至最低。创建这一定制工具的两个主要益处是惯例和一致性。如果您创建了一个定制工具,您的开发团队能够通过使用遵循最佳实践的一致性模式生产系统组件。这通常会产生一个马力十足的机器系统,因此容易记录和维护。
敏捷、灵活而且满足特定需要。有时,您需要一个工具来解决一个非常特殊的问题,但是市场上没有您需要的那种样式的产品。那可能意味着当您需要一个飞利浦螺丝起子时您必须耗尽资源购买一个瑞士军刀。因此,创建一个带有创建转换工具的主要益处是它是按照您的需要定制的。例如,您可以购买一个产生您的行业特定的网络服务的工具,而不是太通用的或者太复杂的,因为它们是被设计用来处理一般情况的。
易学易用。当涉及创建一个定制工具时,Rational Software Architect 可以提供很多。转换创建是基于一个称作 JET 的 Eclipse 开放源码项目,这是一个成熟的提供(JET始于2002年)并且使用开放标准,例如 XPath,的工具。更为重要的是,它容易使用,因为它提供了一个图形用户界面使得创建工具的人的生活尽可能容易。
 | |
注:JET过去被认为是Java™ Enabler 模板;尽管如此,这一术语现在仅为 JET 的意思,因为它不再受限于 Java 表达式。基于XML的模板现在可用来生成带有JET程序语言的工具。 |
|
两个权衡
在您停止当前的开发工具并开始使用这一技术尝试创建世界和平之前,有一对权衡。正如我们在下一部分将要探讨的,并不是所有的开发工具能够很快地使用创建转换图形界面来创建(至少没有XML标记形式的重要定制代码或者内嵌的Java代码是不可以的)。而且,为了有效地使用转换创建(Transformation Authoring),您必须在一个精通级别上了解您需要解决的问题。例如,如果您想要创建一个产生XML属性文件的工具,您需要清楚地了解要产生的XML。
因此,转换创建(Transformation Authoring)可以为您的团队节省很多时间,而且它可以在您最需要增加生产力的地方弥补工具组上的差距。尽管如此,但是它不能解决工具上的每一个问题,在您设计工具来解决问题之前您必须十分了解这一问题。
核心概念
该技术具有一个可扩展的特性,广义上说,能够让您扩展 Rational Software Architect 软件包含的标准工具的能力。转换创建(Transformation Authoring)特性是基于称为 JET 的 Eclipse 开放源码技术(参阅 参考资源)。
如 图1 所示, 您建立一个带有转换创建(Transformation Authoring)的工具之前,需要确定所需的工具种类。这就意味着您需要清楚地说明您需要解决的问题。有两种工具可以通过使用转换创建(Transformation Authoring)很容易地创建:
-
生成文件的工具。您可以使用转换创建(Transformation Authoring)快速开发工具,生成任一类型文件的集合。这包括任何语言的源代码,XML文件以及正如您在样例中将会看到的,甚至是整个JAVA2平台,企业版(J2EE)项目。例如,如果有一系列工作流程非常相似而且为数众多,您就能够创建一个工具来自动生成它们。更明确的讲,您能够创建一个工具,为 IBM WebSphere Process Server 生成业务过程执行语言(BPEL),因此您不需要通过手动来一个一个创建。
-
一种用来转换文件到不同文件结构或文件格式的工具。您可以创建执行转换的工具。如果您熟悉XSLT,一个 JET 模板能够转换一种文件格式到另外一种格式,类似于一个XSL 样式表所做的。不同之处在于 XSLT 是一种程序语言,而转换创建(Transformation Authoring)使用的是被称为 样本分析的过程,带有一个可视化界面。此外,转换创建(Transformation Authoring)能够生成任何一种类型的文件,包括二进制的,因此它自然可以创建较大规模的文件结构。这使您能够产生在Eclipse工作区间所描述的任何东西,如JAVA2平台、企业版(J2EE),JAVA归档文件(JARS)及企业应用项目(EARS)。
尽管如此,但是使用转换创建(Transformation Authoring)不能解决所有问题。通常来讲,如果它既不包含生成文件工件,也不含有资源编码,或者也不能够转换一个文件到另外一种格式,就不适合安装。这里有两种不能用转换创建(Transformation Authoring)生成的自定义工具的例子:
-
创建工具。创建脚本,如 Apache Ant,经常需要外部调用,如调用到文件系统、编译器或者资源控制系统。尽管作为转换创建(Transformation Authoring)一部分的JET模板能够完成外部调用,但它们的用途在于转换,而不是这一类型的控制逻辑。
-
可视化编辑器。不久您将看到,转换创建(Transformation Authoring)项目的结果是一种可执行工具。它本来是一个引擎,它处理输入及生成一些输出格式到Eclipse工作区。这就是为什么传统的Eclipse插件开发更适合创建视觉编辑器。
如 图1所示,当您明确了一个相应的问题想去解决,下一步就是创建一个模板,一个模板就是问题解决样例。举例来说,如果您想创建一个工具来生成一个 portlet ,使其从视觉与感观上都符合您的组织的 Web 门户,您需要从建立一个样板 portlet 作为一个样例开始。在您工作区内一个样例可能是文件的任一集合。 一个单独的XML文件或者一个带有一系列 Java 类的文件夹能够作为模板提供,例如,只要他们描绘您想要的,您正在创建的工具就能够最终生成它们。
注:高级用户可以跳过这一步,不用模板可以人为的创建一个输入模型及JET模板,但是即使是对于高级用户来说样本分析过程通常会节省时间。
图1. 转换创建(Transformation Authoring)过程
工作区内有了一个模板之后,下一步就是创建一个JET Transformation Authoring 项目。这个项目允许您执行 样本分析,这是一个向 Rational Software Architect 指示什么是您想与模板的工具输出保持一致的以及什么是应该变更的过程。例如,如果您想建立一个用于创建 Java 类的工具,您可能不想在工具中给这些项目的名称进行编码,相反您可能想生成一些输入到您的工具来详细说明使用什么类名。这正是在样本分析中所做的类型决定。
样本分析的结果就是一个 输入模型及JET模板(实际上尽管也创建了其它一些文件,但这些仅仅是您想了解的)。工具的这一输入模型能够生成几个功能相近的窗体,包括一个XML计划,Eclipse建模框架(EMF) Ecore模型,或者UML模型。因此,例如,如果您想创建一个琐细的工具来生成一个任意的文件夹和一个带有XML计划输入模型的空文件,工具的输入可能看起来像代码表1。
表1.简单的输入样本
<root>
<folder name="bozo-folder">
<file name="im-an-empty-file1.txt"/>
</folder>
<folder name="blueberry-folder">
<file name="im-an-empty-file2.txt"/>
<file name="im-an-empty-file3.txt"/>
</folder>
</root>
|
JET模板也是作为样本分析过程的一部分而创建的。起初,在样本中它们精确复制文件。因此,如果您在样本中提供一个 Book.java 文件,这个样本分析将会产生相应的Book.java文件。可以使用基于 XPath 1.0(参阅参考资源) 的JET标签对JET模板进行修饰,这个标签还能够区别什么应该静态什么应该动态的使用工具做以改变。在 图1当中,这是图中编辑器模板步骤,在本文后面的 Pojo 数据库样本中更详尽地涵盖了这部分内容。
当您完成模板编辑后,这个Transformation Authoring 项目本身成为一个可定制的、可重复使用的工具,如图2所示。您能够运行 JET Transformation Authoring,将任一输入转换为您想要的输出。
图2. 定制工具使用图解
本文后面部分将带您进入简单数据库存取工具的构架中,它将阐明样本分析过程。
先决条件
除了安装标准的 Rational Software Architect 7.0 之外,要确保 转换创建(Transformation Authoring)特性被激活,如图3所示。为了检测是否被安装,在 Microsoft® Windows 中,选择开始> 程序 > IBM Installation Manager。。当 IBM Installation Manager 被打开,选择Modify Packages。
图3.添加 Transformation Authoring 特性
Pojo 数据库样例
这一部分详细讲述的是使用 Transformation Authoring 来生成工具的一步步的样例。您将创建的工具所解决的问题是,在一个大的应用软件中兼容性的数据库存取问题。当您使用面向对象语言访问一个数据库时,您会经常需要将数据库的表映射到对象。完成这个工作的一个通用模式为数据库访问对象(DAO)模式(参见参考资源)。这种模式执行表-对象的映射,每一表都有一个相应的对象类型。尽管如此,但是当您具有了很多数据库表时,为每一表映射相应的对象通常十分乏味。运行 Java 时,将必需映射许多 Java 组件或者简单的老版本 Java 对象(Pojos),以及大量的组件属性。这种样例工具的目标就是要生成 Pojo 数据库,也能够为您的组织带来一致性,因为整个开发团队能够使用标准工具来创建数据库访问对象。
注:当然,除此之外还有更好的工具来解决这类的对象相关的映射问题,如:Apache iBatis 和 Java Persistence API 。我们选择这种简单的工具作为样例,是因为它的用途简单易懂,但也有些复杂面需谨慎使用。
正如之前我们所讨论的,您将需要一个样例来开始创建工具的过程,也就是说,您需要用您的工具来实现最终产品的样例。图4阐述的是将为这个样例服务的 Java 对象。这个Java
对象对应于关系型数据库中的一个 customer 表。
图4.在此样例中使用的 Pojo 模板
图5阐述的是这一样例的 Transformation Authoring 过程。我们将在 Rational Software Architect 工作区中以一个 Web 项目开始,这个项目包含定制者 Pojo 模板。然后样例的大部分详细描述了创建 Pojo 数据库制作工具的样本分析的过程。当工具最终完成时,您将能够修改一个简单的XML文件并运行它产生一些 Web 项目及一个封装的数据库 Pojos 文件。
图5.样例的 Transformation Authoring 过程
创建一个样例
在这一部分,您会引入作为我们的练习样例的 Web 项目。您还会更详细地查看 customer、Pojo 及 Web 项目结构。
- 在 Web 透视图中打开 Rational Software Architect。
- 选择File > Import... > Other > Project Interchange
然后输入Exampleexemplar.zip文件。
- 检查 Web 项目。
注意这是一个带有单独 Java bean 或 Pojo 的 J2EE Web 项目,在里面它称作CustomerDAO (见表2)。这个Pojo含有一些 bean 属性和一个称为 retrieveCustomer 静态方法,通过主键在数据库中查询一个客户,然后返回到一个 CustomerDAO 的实例。
表2. CustomerDAO Pojo
public class CustomerDAO {
/* constants */
private static String SQL = "SELECT CUSTOMER FROM ACME.DB WHERE SOCIAL = ?"; [1]
private static String DATASOURCE = "java:comp/env/jdbc/ACMEDataSource"; [2]
/* attributes */
private int social;
private String name;
private Date joined;
/* getters and setters */
public int getSocial() { return social; }
public void setSocial(int social) { this.social = social; }
public Date getDateJoined() { return joined; }
public void setDateJoined(Date joined) { this.joined = joined; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
/* constructor */
public CustomerDAO(int social, String name, Date joined) {
setSocial(social);
setName(name);
setDateJoined(joined);
}
/* DAO method to retrieve a customer from the database */ [3]
public static CustomerDAO retrieveCustomer(int social) throws ServletException {
CustomerDAO customer = null;
try {
// execute database query
InitialContext ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup(DATASOURCE);
Connection conn = ds.getConnection();
PreparedStatement stmt = conn.prepareStatement(SQL);
stmt.setInt(1, social);
stmt.execute();
ResultSet result = stmt.getResultSet();
// create and populate CustomerDAO object
customer = new CustomerDAO(result.getInt(1), result.getString(2), result.getDate(3));
} catch(NamingException ne) {
throw new ServletException(ne);
} catch(SQLException sqle) {
throw new ServletException(sqle);
}
return customer;
}
}
|
许多人表示感兴趣的几个点归纳在表2中:
- 在类的上面有一个常量字符串用来储存 SQL 查询以重新获取客户。
- 一个常量字符串也被用于储存 JDBC 数据源的上下文引用。
- 一个从数据库中重新获取客户的静态方法。
在DatabasePojo/WebContent/WEB-INF/下双击 web.xml ,然后选择 References标签。注意有一个 Java® Database Connectivity (JDBC) 数据源的外部引用被用于 Web 项目,如图 6所示。记住这一点,因为资源引用会在以后的章节中扮演重要的角色。
图6.JDBC 数据源资源引用
创建一个样本分析项目
该节讲述的是如何创建一个 Transformation Authoring 项目及样本分析项目。在这一过程中,您将创建XML计划来定义工具的输入。您也可以设定这种工具来生成目录结构,并将输出 Web 项目的名称以目录名称的方式归档为动态,如 DatabasePojo,或者以 Customer 开始的文件名称,而不是来自工具使用者提供的输入。
-
创建一个样本分析项目。
- 右击 DatabasePojoWeb 项目,选择 New >Other > Transformation Authoring > EMFT JET Project with exemplar Authoring。
- 输入
MyExamplarAnalysis 给项目命名,然后选择Finish。
-
创建输入模型类型及属性。
- 右击 root,选择New > Type,并命名为
war。
- 右击war,选择New >Attribute,并命名为
datasourceJNDI.
- 如果有必要需要继续创建类型及属性来建立目录结构(目录树)。见图7的右侧。
图7. 定义输入模型
图7右侧指明了建立工具的输入模型,相应的XML计划在MyexemplarAnlysis/schema.xsd文件中。表1描述的是输入模型中各种类型及属性的用途。
表1.输入模型的描述
| 名称 | 描述 |
|---|
|
root
| 这是带有 Transformation Authoring 的所有输入模型默认的基本类型。 | |
war
| 这是指 Web 归档文件(war),是J2EE Web 项目的归档文件格式。用户能够在输入模型中指定他们想要的所有 war 节点,最终通过工具输出相应的 Web 项目。 | | datasourceJNDI | 每一个借助工具生成的 Web 项目都会使用一种由 Java™ Naming and Directory Interface (JNDI)名称指定的不同的 JDBC 数据数据源。您可能还记得,这是模板的jdbc/ACMEDataSource。 | | name | 指的是 Web 项目名称。 | |
daoBean
|
用户能够为指定的 Web 项目指定任意多个由工具生成的 DAO Java bean。 | | key | 用户必须输入主键的名称(这里仅仅假设主键仅仅包括单一属性)。 | | name | 这是用于 DAO Java bean 上的名称。 | | SQL | 这是一种结构化查询语言文本,用于从数据库中取得 bean 的属性。 | |
beanProperty
|
用户能够为 bean 任意数量的属性。 | | name | 属性名称(用小写字母)。 | | type | 属性的 Java 类型。 |
这仅仅是输入模型的样例,可以在任何时间改变。例如,完成这个样例之后,您可以将package 属性添加到 daoBean,因此用户能够指定什么 Java 包被用于每个 Bean 。
-
为 War 项目文件夹命名。
- 将DatabasePojo文件夹拖至右边的 war 类型,如图8所示。
- 选择Create Project: DatabasePojo然后选择 Properties标签栏。
- 在 *name 字段中,从 DatabasePojo 中右击Database text ,然后选择Replace with
Model Reference....
- 在 War 类型下选择 name属性。
图8.Web 项目名称的泛化
-
为 Pojo Java 类配置命名和文件夹结果。
- 将CustomerDAO.java拖至 daoBean,如图9所示。
- 选择Create File: CustomerDAO, 然后选择 Properties标签栏。
- 在 *path字段中,右击Database,选择Replace with Model Reference...并用
name attribute under the war type 来取代它。
- 同样,使用
the name attribute under the daoBean type来替换 CustomerDAO 中的 Customer 文本。
图9. Pojo 路径和文件名称的泛化
-
为其他的文件配置命名和文件夹结构。
- 将 图10左侧高亮的文件拖至右侧的war type 中。
- 选择Create File: .project,然后选择Properties标签栏。
- 在*path字段中,从输入模型中
the name attribute under the war type 来替代Database
文本,如图11所示。
- 重复这一步骤,保存您刚刚拷贝的八个文件。
图10.配置剩下的 Web 项目文件
图11. 泛化 .project 的路径
修改 JET 模板
在这一点上,您的工具知道如何基于输入模型创建合适的文件夹与文件名结构,但不知道如何修改文件的内容。在这一部分,基于范本中的文件编辑模板,来详细说明什么文本需要保持静态,什么文本需要基于使用者的输入。
为了产生 JET 初始模板,需要更新 Transformation Authoring 项目。
- 右击右侧的输入模型并选择Update Project,如图12所示。
图12.项目更新
- 检查MyexemplarAnalysis 项目,您会发现在 templates 下生成了几个新的文件(见图13)。
图 13. JET 模板
在这一阶段,模板精确复制样例项目中的文件。您会首先使用 Web.xml.jet 和 CustomerDAO.java.jet 模板工作,因为基于输入模型它们含有应该由工具来改变的文本。剩下文件的大部分会被拷贝到 Web 项目输出上。
在web.xml.jet 模板中,有两点需要改变。首先,项目的名称<display-name>DatabasePojo</display-name>为硬编码。注意这些数据库标签了蓝色下划线。Rational Software Architect 自动检测到您可能想在输入模型里将数据库变成 war 名称属性,因此您可以不需动手而完成这一变更:
-
编辑 web.xml 模板来泛化显示名称。
- 打开MyexemplarAnalysis/templates/war/web.xml.jet.
- 选择Problems标签栏。
- 下拉并选择Info一栏,作为资源对应 web.xml.jet,如图14所示。
- 右击并选择Quick Fix并点击OK。
图14.基于 Rational Software Architect 提示的置换
您需要做的第二个改变是JDBC数据源的命名。目前,jdbc/ACMEDataSource是硬编码的。这不能被自动检测,所以必须具体指定输入模型中什么属性来改变它,哪一个是 war datasourceJNDI 属性:
-
编辑 web.xml 模板来泛化 JDBC Datasource JDNI 名。
- 选择 jdbc/ACMEDataSource文本。
- 右击并选择Replace with Model Reference...。
- 在 war 类型下使用
the datasourceJNDI 属性替换它。
Web.xml.jet 模板的结果应该像表3。
表3. Web.xml.jet 模板
<web-app id="WebApp_ID" version="2.4">
<display-name>
<c:get select="$war/@name" />Pojo
</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<resource-ref id="ResourceRef_1164745141546">
<description></description>
<res-ref-name>
<c:get select="$war/@datasourceJNDI" />
</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
</web-app>
|
在本章剩余部分讲述更改CustomerDAO.java.jet模板。您需要用标签来替换某个文本,以便 Customer 工具运行时从输入模型中重新取得。尤其,您需要替换涉及 Customer 的文本或者任一 Java bean 属性,如social 或joined。
当您首次打开 Customer 模板时,您会注意到 Rational Software Architect 许多文本下标记了下划线,来建议它已经检测哪些需要替换。我们通过接受所有的建议开始。
-
通过标记使用剩下的建议代替文本。
- 打开MyexemplarAnalysis/templates/daoBean/CustomerDAO.java.jet.
- 选择Problems标签栏。
- 为 CustomerDAO.java.jet 资源右击first Info item 。
- 选择Quick Fix > Replace all instances,如图15所示,然后点击OK。
图15.在 Customer 模板中接受所有的建议
-
Problems标签内仍有一些提示,也要继续并使用它们。
Customer 模板应如表4所示。注意,无论如何,在样本中仍然有许多硬编码的信息需要改变以同步于输入模型。例如,客户的SQL查询仍然是硬编码的,还有一些与social、name及joined属性相关的信息。
表4.Customer 模板应如下所示
public class <c:get select="$daoBean/@name" />DAO {
/* constants */
private static String SQL =
"SELECT CUSTOMER FROM ACME.DB WHERE SOCIAL = ?";
private static String DATASOURCE =
"java:comp/env/<c:get select="$war/@datasourceJNDI" />";
/* attributes */
private int social;
private String name;
private Date joined;
/* getters and setters */
public int getSocial() { return social; }
public void setSocial(int social) { this.social = social; }
public Date getDateJoined() { return joined; }
public void setDateJoined(Date joined) { this.joined = joined; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
/* constructor */
public <c:get select="$daoBean/@name" />DAO
(int social, String name, Date joined) {
setSocial(social);
setName(name);
setDateJoined(joined);
}
/* DAO method to retrieve a customer from the database */
public static <c:get select="$daoBean/@name" />DAO
retrieve<c:get select="$daoBean/@name" />
(int social) throws ServletException {
<c:get select="$daoBean/@name" />DAO customer = null;
try {
// execute database query
InitialContext ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup(DATASOURCE);
Connection conn = ds.getConnection();
PreparedStatement stmt = conn.prepareStatement(SQL);
stmt.setInt(1, social);
stmt.execute();
ResultSet result = stmt.getResultSet();
// create and populate <c:get select="$daoBean/@name" />DAO object
customer = new <c:get select="$daoBean/@name" />DAO
(result.getInt(1), result.getString(2), result.getDate(3));
} catch(NamingException ne) {
throw new ServletException(ne);
} catch(SQLException sqle) {
throw new ServletException(sqle);
}
return customer;
}
}
|
-
泛化 SQL 查询字符串。
- 选择 SELECT CUSTOMER FROM ACME.DB WHERE SOCIAL = ? 这一文本。
- 右击并用输入模型中的 SQL 属性替代。
如果您查看属性部分,您会发现您已经遇到了在输入模型中进行简单替换是远远不够的情况。原因是您不清楚用户会为Pojo提供多少属性(样例中的客户Pojo是3个)。解决方案是在工具的使用者提供 bean 属性上使用 JET <c:iterate/> 标签:
- 使用<c:iterate/> 标签替换social、name及joined属性,如表5所示。
表5.属性部分的修改
/* attributes */
<c:iterate select="$daoBean/beanProperty" var="prop">
private <c:get select="$prop/@type" /> <c:get select="$prop/@name" />;
</c:iterate>
|
为了构建 get 和 set 方法部分,您再次进入了一种新的情形。这一次,需要使用一个循环标签,但问题是为取得方法需要大写这个属性的头一个字母。例如,如果用户为一个 bean 的属性输入 foo 需要构建getFoo()。解决方法是使用称作uppercaseFirst()的 JET XPath 表达式,如下:
- 使用 <c:iterate/> 标签替换social、name和joined的 get 和 set 方法,如表6所示。
表6.get 和 set 方法的修改
/* getters and setters */
<c:iterate select="$daoBean/beanProperty" var="prop">
public <c:get select="$prop/@type" />
get<c:get select="uppercaseFirst($prop/@name)" />() {
return <c:get select="$prop/@name" />;
}
public void set<c:get select="uppercaseFirst($prop/@name)" />
(<c:get select="$prop/@type" /> <c:get select="$prop/@name" />){
this.<c:get select="$prop/@name" /> = <c:get select="$prop/@name" />;
}
</c:iterate>
|
构造方法的实参部分需要一个循环标记,但是需要生成一个逗号分隔的列表。您可以使用循环标记的 delimiter 属性来处理这一点:
- 为表7替换构造方法签名的
(int social, String name, Date joined) 。
表7.构造方法签名的修改
(<c:iterate select="$daoBean/beanProperty" var="prop" delimiter=", ">
<c:get select="$prop/@type" /> <<c:get select="$prop/@name" />
</c:iterate>)
|
- 替换构造方法体,见表8。
表8.构造方法体的修改
<c:iterate select="$daoBean/beanProperty" var="prop">
set<c:get select="uppercaseFirst($prop/@name)" />(<c:get select="$prop/@name" />);
</c:iterate>
|
在 Customer 模板中有 3 个word customer的实例。再一次使用 JET XPath 表达式,lowercaseFirst(),确保第一个字母为小写字母:
- 用<c:get select="lowercaseFirst($war/@name)" />替换3个 customer 实例。
Customer 模板中静态的找回方法使用主键作为实参。考虑到您必须首先检查主键的名称,然后与 beanproperty 相匹配,决定主键的类型需要更多先进的 XPath,如图16 所示。
图16. 在哪里决定主键的类型
为了实现这一点,您所使用的需涉及 XPath 断言。一个断言包括限定 XPath 路径的布尔型语句,以确保选择出特殊节点或者节点设置:
- 为(int social)的找回方法替换实参,如表9所示。
表9.恢复方法签名的修改
(<c:get select="$daoBean/beanProperty[@name
= $daoBean/@key]/@type" /> <c:get select="$daoBean/@key" />)
|
- 替换
stmt.setInt(1, social);文本如表10所示。
表10 JDBC 语句的修改
stmt.set<c:get select="uppercaseFirst($daoBean/beanProperty[@name
= $daoBean/@key]/@type)" />(1,
<c:get select="$daoBean/@key" />);
|
当从JDBC ResultSet 中找回信息时,您会碰到一个新问题,因为 ResultSet 需要数据访问的数字索引(在样例中,您用过数字1-3)。当反复在结果集上调用position()时,一个标准的XPath功能返回到当前节点位置。因此,您可以用这个位置填充这些索引:
- 替换
(result.getInt(1), result.getString(2), result.getDate(3))文本,如表11所示。
表11. JDBC ResultSet 访问的修改
(<c:iterate select="$daoBean/beanProperty" var="prop" delimiter=", ">
result.get<c:get select=" uppercaseFirst($prop/@type)" />
(<c:get select=" position()" />)
</c:iterate>>)
|
这里我们已经完成样本分析过程和定制工具的开发。如果您遇到问题或者有关如何修改模板的问题,您可能会发现导入Solution.zip项目交换并检查里面的内容(参见参考资源)是十分有帮助的。
运行转换
既然您完成了样本分析,您准备运行定制工具。您将创建输入 XML,然后执行这个转换。
-
定义这个您想转换的输入。
- 打开MyexemplarAnalysis/test.xml。
- 填写
<root/>节点,如表12所示。
表12. 输入的实例
<root xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:noNamespaceSchemaLocation='schema.xsd'>
<war name='MyResult' datasourceJNDI='jdbc/MyDatasource'>
<daoBean name="Boat" sql="SELECT BOAT FROM ACME.DB WHERE ID = ?' key='id'>
<beanProperty name='d' type='int'/>
<beanProperty name='desc' type='String'/>
</daoBean>
<daoBean name='Plane' sql="SELECT PLANE FROM ACME.DB WHERE ID = ?' key='id'>
<beanProperty name='id' type='long'/>
<beanProperty name='color' type='String'/>
</daoBean>
</war>
</root>
|
-
运行转换。
- 右击test.xml。
- 选择Run As > Input for JET Transformation,如图17所示。
图17.运行 JET 转换
结果,您将在工作区内看到一个叫作MyResultPojo的新的 Web 项目,如图18所示。
图18.转换结果
注意创建了两个 Pojos、一个是 BoatDAO,另一个是 PlaneDAO,如 图19所示。
图19.产生的数据库访问对象
当然这仅仅是一个您已创建的定制工具可能的输出。花费一些时间变更XML输入将产生不同可能的输出。例如,您可能想在同一时间内产生更多的 Web 项目。
避免冗长乏味的集成和迁移问题
这篇文章介绍了转换创建(Transformation Authoring) 并提供了一个现成的实例使您能够很好地使用 Rational Software Architect V7.0 按照您的方式来创建有用的定制工具。阅读说明并经过练习之后,您可能已经想出许多应用可以立即使用 转换创建(Transformation Authoring) 。您将会注意到冗长乏味的集成问题、迁移问题以及相似问题的普通模式。在这种情况下,您和您的团队应该从创建定制工具中受益匪浅,使您的工作变得更简单、更快捷、更高效。
下载 | 描述 | 名字 | 大小 | 下载方法 |
|---|
| Examples | ExampleExemplar.zip | 6KB | HTTP |
|---|
| Examples | Solution.zip | 25KB | HTTP |
|---|
参考资料 学习
获得产品和技术
讨论
关于作者
对本文的评价
|