corner imagecorner image
FeaturesPluginsDocs & SupportCommunityPartners

NetBeans UML 自定义代码生成

内置代码生成机制是 NetBeans 6.1 发行版的一个重要的新增 UML 功能。

使用“新建项目”向导创建 Java 类时,NetBeans IDE 使用代码生成模板生成源代码,使用适当的信息代替标记变量:作者名称、创建日期、许可、类名称、构造函数名称和其他属性在 NetBeans 6.1 以前,这些代码生成模板不支持开发人员能够提供的自定义行为。

但是,NetBeans 6.1 利用一个叫做 Freemarker 的开源模板引擎来帮助自定义代码生成。旧的 NetBeans 模板与这些采用 Freemarker 的模板的区别在于,能否在模板中使用脚本代码自定义内容生成。尽管这种能力能够应用于其他 NetBeans 功能,您现在可以使用模板通过 UML 模块代码生成功能自定义代码,从而使利用 UML 功能生成的代码具有出色的灵活性。

目录

本页中的内容适用于 NetBeans IDE 6.0

软件需求

要学习本教程,您需要使用以下技术和资源。

软件或资源 所需版本
NetBeans IDE NetBeans 6.1
BankApp 示例项目 与 NetBeans IDE 绑定
Java 开发工具箱(JDK) 版本 6版本 5
本文的压缩文件,包括模板和项目信息 http://www.netbeans.org/files/documents/4/1942/codegenresources.zip

Freemarker 模板文件和模型驱动开发

使用 NetBeans 6.1 UML 功能,一个 Freemarker 模板文件集合会被添加到 IDE 中。(关于 Freemarker 的信息请参见 http://freemarker.org/ 。关于可以与 Freemarker 源代码一起使用的 NetBeans Freemarker 插件的信息请参见 http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp?pluginid=3755)。

这些模板支持使用标准 Java 源文件模板从模型元素生成标准 Java 源文件(类、接口和枚举类型)。与 NetBeans 中的其他模板一样,Freemarker 模板可用于自定义用途。另外请参见 http://wiki.netbeans.org/FaqFreeMarker

模型驱动开发

将 UML 与 Freemarker 配对使用的主要好处在于能够进行模型驱动开发(MDD)。MDD 表示您可以通过将元素属性映射到 Freemarker 模板的方式进行开发,然后可以创建标记为构造型的模型元素,从而允许您生成复杂的编程设计模式。

例如,可以使用一个带有构造型 ejb-stateless 的 Class 元素生成 Bean 类,以及 EJB 应用程序的 Home 接口和 Remote 接口源文件。

可以为独立的方法添加构造型 business,以指示将这些方法向客户端公开。要想更见特定于域,可以使用构造型 shopping-cart 来表示一个购物车 EJB 的完整实现。这些构造型中的每一个都可以映射到用于生成所需代码的特定模板。

成功创建 Freemarker 模板的背景知识

尽管本文不会关注脚本本身,但是以下三种技巧对于成功编写自定义脚本和相应的模板创建很有帮助:

  • Freemarker 脚本编写知识
  • 源数据模型知识
  • 熟悉目标输出格式域

Freemarker 脚本编写

第一种技巧也就是熟悉 Freemarker 脚本语言。Freemarker 与其他脚本语言很相似。可以查阅 SourceForge Web 站点上的 Freemarker 在线手册 获取 Freemarker 的信息。

源数据模型

使用的各种源数据模型的复杂性各不相同。在 UML 数据模型中,有两个元素。一个元素的类型为 ClassInfo,而 classInfo 是另一个模型元素的名称,该元素类型为 Classifier,modelElement 是该模型的名称。这些元素可以在通过模板查看可用的脚本时看到。

目标输出格式域

输出格式是代码生成的结果。选择目标编程语言并不是一件简单任务。需要从语言解析器的角度来考虑。对于 Java,必须确保以一个包声明作为目标语言的开始,然后导入语句。类声明有许多变量需要考虑:作用域、类名称、扩展子句和实现。

类声明还可能带有注释。还需要考虑属性和方法,以及它们的签名和注释。空白也需要考虑。

然而,如果您正在研究建模,并且明白了目标输出是什么,那么在生成源代码时就能够轻松地进行实现,从而从模型驱动开发中获益。

使用 BankApp 示例项目和自定义代码生成

继续之前,必须确保已经获得了“软件需求”一节中列出的压缩的发行版,此发行版包括 Freeemarker 代码生成模板和 NetBeans 项目。还将使用与 IDE 绑定的 BankApp 示例项目。

本文包含一个自定义代码生成的教程。要建立自定义代码生成教程的起点,可以使用 IDE 中与 UML 功能绑定的示例项目。

开始之前,需要创建为绑定的 BankApp 示例项目创建一个 Java 和 UML 项目。

  1. 从 IDE 的主菜单中,选择“文件”>“新建项目”。
  2. 在“选择项目”页面中,展开“类别”面板中的“示例”节点,并选择 UML 节点。“项目”面板更新为可用的 UML 示例项目。
  3. 在“项目”面板中,选择“UML 空白应用程序示例”并单击“下一步”。
  4. 在“名称和位置”页面中,将 Java 项目名称保留为默认值 UMLBankAppSample,如果该项目已经存在,可以修改项目名称。
  5. 单击“完成”按钮。NetBeans IDE 创建两个项目:一个 Java 项目和一个 UML 项目。如果选择默认名称,则 Java 项目的名称为 UMLBankAppSample,UML 项目的名称为 UMLBankAppSample-Model
  6. 展开 UML 项目以显示“模型”节点的所有子节点。其中有一个包、bankpack,几个 Class 元素和一个 Interface 元素。这些元素是从 Java 项目逆向工程得来的。
  7. 右键单击这些元素中的任何一个并选择“导航至源”,Java 项目中的源文件将会在 NetBeans 编辑器中打开。
  8. 对这些元素进行更改并执行“生成代码”—— Java 项目中的源文件会适当地更新。(了解 Java 项目和 UML 项目之间的关系会很有帮助)。现在的重点是如何生成每个元素的代码,以及如何自定义代码生成。

创建了将要使用的 Java 和 UML 项目之后,就可以查看 UML 代码生成过程中要使用的工具了。

UML 代码生成过程中使用的 NetBeans UML 工具

开始创建自定义模板并将其映射到模型元素之前,理解 NetBeans IDE 中将要使用的工具及其之间的关系非常重要。

这些工具包括面板、自定义器和一个对话框:

  • NetBeans 模板管理器:使用此工具访问文件夹中的模板。
  • NetBeans UML 模板选项面板:使用此工具将模板文件映射到模型元素。
  • NetBeans UML 项目自定义器(用于项目属性):使用此工具启用域模板
  • “生成代码”对话框:使用此对话框从模板创建代码。

这些工具中的每一个都在 UML 代码生成过程中扮演着模板的配置和使用中的一个特定角色。

使用 NetBeans 模板管理器管理模板文件

NetBeans 6.1 中的所有模板都基于 Freemarker 模板引擎。

在 IDE 中,可以使用 NetBeans 模板管理器管理 Freemarker 模板。要访问模板:

  1. 从 IDE 的主菜单中,选择“工具”>“模板”。IDE 打开“模板管理器”对话框。您将会看到许多文件夹,用于对模板进行分类。
  2. 展开 UML 文件夹及其子文件夹。
“模板管理器”对话框

添加到 IDE 中的模板文件不需要包含 Freemarker 脚本,因此在模板管理器中添加文件时没有预期的文件格式。用于生成 Java 代码的模板设计用于最大化代码重用。

添加模板文件时,请记住:

  • CompilationUnit.java 文件是用于生成 Java 类、接口和枚举源文件的惟一模板文件。
  • 附加的文件(*Declaration.java 文件和 DeclLib.ftl)链接自 CompilationUnit.java 文件内部。
  • 其他文件夹中还有许多其他模板。一些模板可能包含有价值的脚本示例,您可以将其用于 UML 代码生成的自定义模板中。但是,UML 代码生成过程仅使用“UML/代码生成”文件夹及其子文件夹中列出的模板。
  • 您可以在“UML/代码生成”文件夹下创建自己的自定义子文件夹来存储您的模板,这些模板也可以用于 UML 代码生成。

在本文中,将使用非常简单的 Freemarker 模板脚本,这些脚本利用 NetBeans UML 代码生成过程为 Freemarker 模板引擎提供的默认功能。

使用 NetBeans UML 选项面板映射域模板

创建自定义 Freemarker 模板文件只是第一步。一些模板已经可以用于 Java 代码生成。

但是,在使用模板文件时,还需要将这些模板文件映射到您的模型中的模型元素。可以在“NetBeans UML 选项”面板中配置此映射,方法如下:

  1. 从 IDE 的主菜单中,选择“工具”>“选项”。
  2. 单击“UML 选项”类别。
  3. 单击“模板”标签。
  4. 在树中选择“基本类”节点。

IDE 显示 Java/Basic Class 域模板的属性,显示模型中类型为 Class 并且没有构造型的任何元素都被映射到 UML/Code Generation/Java/CompilationUnit.java 下的模板文件,而且输出文件的名称与文件扩展名为 .java 的元素的名称相同。

域模板

使用自定义代码模板文件生成域对象代码

UML 功能拥有几种元素类型(比如 Class、Interface、Actor)。可以为这些元素添加上构造型来标识用于特定用途或拥有特定行为的元素。域对象是特定于域的语言(DSL)的专用对象。

例如,在 ATM 机器域(本教程未使用这个域)中,域对象可能包括:

  • Customer
  • Account
  • Deposit
  • Withdrawal
  • Bank

这些域对象可以在 UML 类图中表示为分别带有以下构造型的 Class 元素:

  • customer
  • account
  • deposit
  • withdrawal
  • bank

要生成域对象的代码,必须创建自定义代码模板文件。自定义代码模板文件包含将会生成到源文件中的必要属性和方法。

创建了模板文件之后,需要在代码生成过程中将元素/构造型对映射到合适的模板文件。域模板提供了模型元素类型和构造型到一个或多个模板文件的映射。

借助 UML 模板选项面板,可以根据需要创建分类文件夹,然后将域模板添加到它们的类别中。您自己可以确定组织类别和域模板的方法,但是需要遵循在 NetBeans 模板管理器中创建的布局,您要从 NetBeans 模板管理器访问模板文件。

使用 UML模板选项面板启用 UML 项目的域模板

创建域模板之后,需要根据每个 UML 项目启用或禁用它们。默认的 Java 域模板是自动对每个 UML 项目启用的。但是,如果在 UML 模板选项面板中创建自定义域模板,默认情况下这些域模板不会为任何 UML 项目启用。

可以使用 UML 项目定制器(项目属性)来定制 UML 项目的启用的模板。

要为 UML 项目启用域模板:

  1. 右键单击 UML 项目节点(默认名称为 UMLBankAppSample-Model)。
  2. 选择“属性”打开 UML 项目定制器。
  3. 在出现的定制器对话框中选择“代码生成”类别。
  4. 展开底部面板中的 Java 节点。

了解和使用项目属性面板

在此示例中,Target Project 字段是空的。这是因为您从 Java 项目 UMLBankAppSample 对 UML 项目进行了逆向工程。

第一次生成代码时,IDE 不会配置目标项目,而且底部的状态消息会提示必须选择一个有效的目标项目。

要使用项目属性面板:

  1. 单击“确定”按钮保存属性,无需指定目标项目。(您稍后会在“代码生成”对话框的工作流中看到相同的用户界面,但是在那时,工作流中包括 Target Project 在内的所有必需字段都必须填写,然后才能单击“确定”按钮生成代码。)
  2. 展开底部“模板”面板中的 Java 节点,查看三个默认的域模板:
    • Basic Class
    • Basic Interface
    • Basic Enumeration
  3. 可以根据每个模板关闭特定元素的代码生成。例如,如果不希望为在模型中没有构造型的 Enumeration 元素生成代码,可以在属性面板中取消选择该域模板。
  4. 如果已经有了自定义域模板,可以在这个面板中为代码生成启用它们。所有这些选项都可以在调用代码生成过程时进行动态配置,假设您在项目中启用了“生成代码之前提示”选项。(默认情况下,IDE 会打开此对话框选项。)

从模型生成代码

所有域模板就绪之后,它们就会为您的 UML 项目启用,您可以从模型中生成代码。为此,

  1. 右键单击 UML 项目节点并选择“生成代码”操作。IDE 显示“生成代码”对话框,以确认正确配置了属性。默认情况下,模板面板是隐藏的。
  2. 单击“显示模板”按钮显示域模板,如图所示。
  3. 单击“确定”按钮启动代码生成。消息将会在 NetBeans 输出窗口的 Generate Code Log 选项卡中显示。生成代码过程状态在这里显示。查看这些消息以确认正确生成了代码。

在下一节中,将使用通过流线化当前 Java 模板创建的 EJB 模板。此处未讨论创建这些模板的步骤,但是完成的、流线化的模板能够提供比 Java 模板更简单的示例。

创建 Enterprise Java Bean 3.0 自定义模板

配置默认 Java 代码模板从 UML 项目生成 Java代码之后,可以使用自定义模板为应用程序工件(比如典型的无状态会话 EJB)生成源文件。

创建健壮的代码生成模板是一个复杂的任务。为了方便您学习如何使用自定义模板,已经为您创建了无状态会话 EJB 的三个必要的代码生成模板,建并在压缩的发行版中提供。这些模板并不是生成无状态会话 EJB 的完整解决方案。它们仅生成 bean 类、Home 和 Remote 接口,如果标记恰当,还会带有来自 Class 元素的方法。

更完整的实现能够为每个独立操作添加构造型 local 和/或 remote,以指示该操作应该在哪个接口中声明。

获取代码生成模板并将其添加到 IDE

要将代码生成模板添加到 IDE,需要下载模板并使用模板管理器将其添加到 IDE:

  1. 请确保解压了本文提供的源文件,以获得一下模板:
    • StatelessBean.flt
    • StatelessRemote.ftl
    • StatelessLocal.ftl
  2. 将模板添加到 IDE。从主菜单中,选择“工具”>“模板”。NetBeans 模板管理器打开。
  3. 导航到文件夹 UML/Code Generation 并将其选中。
  4. 单击“新建文件夹”按钮并将其命名为 EJB 3.0
  5. 单击“添加”按钮。
  6. 导航到模板文件解压到的文件夹位置。
  7. 选择一个文件添加到 IDE。
  8. 对其他两个模板文件重复第 5-7 步。
  9. 选择所有三个模板。单击“在编辑器中打开”按钮。IDE 在 NetBeans 编辑器窗口中打开新模板文件。
  10. 浏览模板脚本,了解正在执行什么操作。这三个模板文件是通过组合用于生成 Java 类的三个独立模板文件的方式创建的,并被链接到一起,以使脚本可以重用。通过将脚本组合到一个模板,很容易执行脚本流程。

    再次地,使用了三个基本的默认模板。它们是:

    • DeclLib.ftl
    • CompilationUnit.java
    • NormalClassDeclaration.java

之所以有三个独立模板文件,是因为您将在 UML 项目中使用一个单一的模型元素来生成三个独立的源文件,而且每个生成的源文件必须至少有一个模板文件。一个模型元素直接使用一个模板文件生成一个源文件。

借助标准 Java 类型,每个类型使用 CompilationUnit.java 模板文件,该文件引用其他模板文件(DeclLib.ftl 和其他三个 *Declaration.java 文件之一)生成一个源文件。

生成 EJB 模板

压缩文件包含三个模板,它们可用于生成 EJB。借助这些模板,一个模型元素将直接使用三个不同的模板文件生成三个源文件。

下图将会帮助您可视化标准 Java 类代码生成与 EJB bean 类生成之间的关系和区别。

在下图中:

  • 模型中有三个元素:一个 Class、一个 Interface 和一个 Enumeration。
  • 每个 Class 元素被映射为使用基本类域模板(没有构造型的任何 Class 元素),而后者使用 CompilationUnit.java 模板文件。
  • CompilationUnit.java 模板文件中的脚本确定此元素的类型为 Class 并链接到 NormalClassDeclaration.java 模板,以执行特定于 Java-Class 的代码生成。
  • 类似地,对于 Interface 和 Enumeration 元素类型,CompilationUnit.java 中的脚本确定元素为一个特定的类型并连接到合适的模板,以方便特定于 Java、Interface 或 Enumeration 的 代码生成。

映射无状态类元素

带有无状态构造型的 Class 元素被映射到 Stateless 域模板,该模板拥有三个模板文件。

每个模板文件生成一个独立的源文件:一个 Java 类和两个 Java 接口。参见下图。

添加新模板

将新模板添加到 IDE 之后,需要通过选项面板将它们添加为域模板。为此:

  1. 从 IDE 的主菜单中,选择“工具”->“选项”。
  2. 单击“类别”
  3. 单击“添加”添加新的类别。
  4. 将默认类别重命名为 EJB 3.0。
  5. 单击“添加”按钮添加一个新域。
  6. 将默认域命名为 Stateless。
  7. 选择 Stateless。
  8. 从元素类型下拉菜单中选择 Class。
  9. 在 Stereotype 字段中输入 stateless。
  10. 选择“添加模板”。
  11. 使用以下建议条目填充对话框:
    • 文件名格式:{名称}Bean
    • 扩展名:.java
    • 文件夹:保留为空,除非您想要在某处生成该文件
    • 模板文件:EJB 3.0/StatelessBean.ftl
  12. 重复这些条目,但是提供其他两个模板的名称。

映射 EJB 模板

将模板添加到 IDE 并通过选项面板添加它们之后,需要使用 UML 选项面板将模板映射到您的模式中的模型元素。

  1. 从 IDE 的主菜单中,选择“工具”>“选项”。
  2. 单击“UML 选项”类别。
  3. 单击“模板”标签。
  4. 在选项面板中展开 EJB 3.0 节点。

IDE 显示 EJB 域模板的属性。如下面的演示所展示的,在 EJB 3.0 域模板下,将有一个元素类型为 Class 的无状态域模板,带有构造型 Stateless。

有三个输出参数:Bean、Local 和 Remote,每个参数的扩展名都是 .java

单个模型元素的多个域模板

一个模型元素可以映射到多个域模板。例如,Java 类别中的基本类域模板可以映射到类型为 Class 且没有构造型的任何元素。

现在可以创建另一个称为 C++ 的类别,其中包含名称也为 Basic Class(或者您想使用的任何名称)的模板,该模板也映射到类型为 Class 且没有构造型的元素。模板文件可以生成 C++ 类,而不是 Java。

如果在调用“生成代码”操作时同时调用了两个模板,那么您将从一个元素获得两个文件,一个是 Java 类,另一个是 C++ 类。尽管后一个示例很少见,但仍然有可能发生。

创建 Calculator 无状态会话 RJB

在 NetBeans 中正确创建了模板并配置了合适的域模板之后,可以创建一个 UML 模型项目,该项目将利用新的模板为 Enterprise Java Bean 生成 Enterprise Java Bean 代码。

创建 UML 模型项目之后,创建一个 Calculator 元素并向其添加方法。

首先创建 UML 项目:

  1. 从主菜单中,选择“文件”>“新建项目”。
  2. 选择 UML,然后选择 Java 平台模型
  3. 单击“下一步”和“完成”。
  4. 在出现的“创建图”对话框中选择“类图”并单击“完成”。现在创建了一个带有一个类图的 UML 项目。

接下来,将要创建 Calculator 元素。要创建 Calculator 元素:

  1. 将一个 Class 元素添加到图中并将其命名为 Calculator(模板将会保证后缀被正确创建:也就是说,模板创建 Bean、Local 和 Remote 作为合适的源文件名称)。
  2. 对于选择的 Calculator 元素,编辑 Stereotype 属性并添加 stateless。

生成代码过程现在会识别 Calculator 元素,将其映射到 Stateless 域模板。但是,在执行代码生成之前,需要将一些方法添加到 Calculator 元素。

向 Calculator 元素添加方法

在 UML 图编辑器中为 Calculator 元素创建下面列出的三个操作。要创建一个元素,单击 Operation compartment 区域中的 Calculator 元素并选择“添加操作”。添加以下操作:

  • public int add(int a, int b)
  • public int subtract(int a, int b)
  • public int multiply(int a, int b)

您可能想让所有三个操作在两个接口中都公开。只有公共方法能在这两个接口中声明,所以,如果不想让所有这些方法都公开,则需要过滤掉非公共方法。

而且,您可能不想让所有的公共方法在两个接口中都声明,或者在其中一个中声明。您需要一种脚本机制来确定在三个源文件的每一个中应该生成哪些方法。再一次,您可以使用构造型来指示应该添加哪些方法。

创建 Java 项目

现在 Calculator 元素已经完成了,您需要创建一个 Java 项目,以向其中生成代码。为此:

  1. 从 IDE 的主菜单中,选择“文件”>“新建项目”。
  2. 选择“Java、Java 应用程序”并单击“下一步”。
  3. 在“选择项目”页面,选择“Java 和 Java 应用程序”。
  4. 取消选择“创建主类”选项并单击“完成”。
  5. 右键单击 Calculator 元素并选择“生成代码”。
  6. 选择新创建的 Java 项目作为目标项目。
  7. 单击“显示模板”按钮并展开树中的 EJB 3.0 节点。
  8. 选择 Stateless 域模板。单击“确定”按钮开始生成代码。

输出窗口显示消息,通知您 IDE 使用三个独立模板文件为 Calculator 元素生成代码。

生成代码过程运行完成之后,展开 Java 项目的源文件夹检查新的 Calculator 源文件。您将会看到三个生成的文件:

  • CalculatorBean.java
  • CalculatorLocal.java
  • CalculatorRemote.java

打开每个文件确认您在类和两个接口中生成了所有三个方法。您可能会看到编译错误或其他错误,因为标准 Java 项目会自动包含 Java Enterprise 库或其他类。可以忽略这些错误,因为本教程的目标既不是编译也不是运行您创建的项目。

在生成的代码中观察图编辑器更改

您可以看到在使用图编辑器对元素进行更改时,生成的代码是如何与 Calculator 元素保持同步的。在图编辑器中:

  1. 添加一个新操作:
     public float divide(int a, int b)
     
  2. 删除相乘操作。
  3. 向相加操作添加第三个参数:
     int c
     
  4. 右键单击 Calculator 元素并选择“生成代码”。

检查这三个源文件,就像之前检查新的源文件一样。注意,IDE 更新了所有的源文件,以与您在图编辑器中对 Calculator 元素所做的更改保持同步。

结束语

Freemarker 脚本环境为 NetBeans UML 代码生成提供了一个强大的附加功能,使您能够自定义生成的代码。本文提供了概念性的背景知识和教程信息,使您能够创建、添加和自定义代码生成模板、普通代码生成和引用了特定的 EJB 工件的代码生成。通过使用代码生成模板,可以在 NetBeans UML 代码生成的框架中利用模板的强大功能并轻松地修改一些特性,以维护许多源文件的源代码。自定义的代码生成模板为您提供了一个有效、轻松的代码生成方式,可以用于您的应用程序项目中。

未来计划

  • 要发送意见和建议,获取支持,了解关于 NetBeans IDE UML 开发特性的最新发展,请加入 邮件列表。


返回顶部

Companion
Projects:
MySQL Database Server   GlassFish Community: an Open Source Application Server   Open Solaris  Open JDK: an Open SourceJDK   Mobile & Embedded Community     Sponsored by 
Sponsored by Sun Microsystems