1.概述 | 2.我的第一个项目 | 3.模型 | 4.视图 | 5.列表数据 | 6.对象/关系映射 | 7.控制器 | 8.应用系统 | 9.定制

第8章: 应用系统

应用系统(application)是用户最终使用的软件. 到现在为止你已经学到了如何定义应用的组成部件(主要是业务组件和操作), 下面你将学到如何将这些部件组装成应用系统.
OpenXava应用系统的定义可以在你项目中xava目录下的 application.xml 找到。
该文件的语法是:
<application
    name="name"                   <!-- 1 -->
    label="label"                 <!-- 2 -->
>
    <default-module ... /> ...    <!-- 3  New in v2.2.2 -->
    <module ... /> ...            <!-- 4 -->
</application>
  1. name (required):应用系统名称.
  2. label (optional): 最好使用i18n 文件.
  3. default-module (one, optional): New in v2.2.2. 定义默认(针对每个业务组件自动生成) 模块的控制器.
  4. module (several, optional): 最终用户可以运行的每个模块.
简而言之, 应用系统由一些列模块构成. 下面我们来看如何定义模块:
<module
    name="name"                    <!--  1 -->
    folder="folder"                <!--  2 -->
    label="label"                  <!--  3 -->
    description="description"      <!--  4 -->
>
    <env-var ... /> ...            <!--  5 -->
    <model ... />                  <!--  6 -->
    <view ... />                   <!--  7 -->
    <web-view ... />               <!--  8 -->
    <tab ... />                    <!--  9 -->
    <controller ... /> ...         <!-- 10 -->
    <mode-controller ... />        <!-- 11 -->
    <doc ... />                    <!-- 12 -->
</module>
  1. name (required): 应用系统中模块的唯一标识.
  2. folder (optional): 模块所在的文件夹。这是模块分类的提示信息. 目前只用来生成文件结构用在JetSpeed2上,但将来可能有更多用处。 你可以使用/ 或. 来标识子文件夹(例如, "invoicing/reports" 或"invoicing.reports").
  3. label (optional): 用来显示给用户看的简短名称. 最好使用 i18n 文件.
  4. description (optional): 显示给用户的较长的描述. 最好也使用 i18n 文件.
  5. env-var (several, optional): 允许你定义变量,其值可由动作访问.这样你就可以针对模块来配置动作.
  6. model (one, optional): 模块中所用的业务组件. 如果你不赋值,就需要设置 web-view的值.
  7. view (one, optional): 用来显示细节的视图. 如果你不赋值,就使用默认视图。
  8. web-view (one, optional): 允许你定义 JSP 页面用作视图。
  9. tab (one, optional): 列表视图中用到的tab. 如果你不制定,就采用默认tab.
  10. controller (several, optional): 控制器,提供最初可用的操作。
  11. mode-controller (one, optional): 定义行为将细节模式切换到列表模式或者反之, 还可以定义没有细节和列表的(无模式的)模块.
  12. doc (one, optional): 与其他元素互斥. 允许你定义只包含文档无业务逻辑的模块. 对生成应用系统中说明性的portlets十分有用。

典型模块示例

像这样可以定义一个简单模块:
<application name="Management">
    <module name="Warehouse" folder="warehousing">
        <model name="Warehouse"/>
        <controller name="Typical"/>
        <controller name="Warehouse"/>
    </module>
    ...
</application>
这样你就有了一个模块,用户可以执行增改删查操作,生成PDF报告,导出数据到Excel(这得感谢 Typical 控制器) ,还可以执行只适用warehouses的动作(这得归功于 Warehouse 控制器). 在系统生成模块结构的情况下(如JetSpeed2)模块将在文件夹"warehousing"下.
要执行本模块,你需要打开浏览器指向:
http://localhost:8080/Management/xava/module.jsp?application=Management&module=Warehouse
同时也生成了 JSR-168 portlet你可以发布到 Java portal中.

缺省模块(new in v2.2.2)

即使模块没有在applicaction.xml明确定义,OpenXava 也为应用中的没一个业务组件指定一个业务模块。
这就是说,如果你定义业务组件 Invoice.xml, 你就可以打开浏览器指向:
http://localhost:8080/Management/xava/module.jsp?application=Management&module=Invoice
同时生成一个portlet,你可以将这以模块作为JSR-168 portlet部署到 Java portal.
所有这一些不用在 application.xml定义就可以实现.
默认模块的控制器一般是 Typical, 使用in application.xml中的default-module 元素,你可以对默认值进行定义, 例如:
<application name="Management">
 
    <default-module>
        <controller name="ManagementCRUD"/>
    </default-module>
 
</application>
这种情况下,Management 应用中的所有默认模块都使用指定的 ManagementCRUD 控制器.
如果你想让某个模块不使用默认控制器, 你有两个选择:
  1. 在自己的controllers.xml 中定义与模块同名的控制器.
  2. application.xml中明确定义模块, 上面已进行说明.
总之, 如果你定义一个名为Customer的组件,你就会有一个名为Customer的模块和一个portlet. 模块可以用下面的任何一种方式定义:
  1. 如果你在application.xml中定义了一个名为 Customer 的组件,那么,这个模块是有效的, 或者...
  2. 如果你在controllers.xml 中定义了一个名为Customer的控制器,那么,将生成一个模块:控制器Customer是其控制器, 组件Customer是其模型, 或者...
  3. 如果你在application.xml中定义了default-module 元素,那么将生成一个模块:default-module中的控制器作为器控制器,组件Customer 作为模型, 或者...
  4. 最后,将使用Typical控制器和Customer模型生成模块。

仅细节模块

只有细节模式,而没有列表模式的模块, 这样定义:
<module name="InvoiceNoList">
    <model name="Invoice"/>
    <controller name="Typical"/>
    <mode-controller name="Void"/>        <!-- 1 -->
</module>
Void (1) 模式控制器可以去掉 "detail – list" 链接; 这样默认情况下模块就只使用细节模式。

仅列表模块

只有列表模式,而没有细节模式的模块, 这样定义:
<module name="FamilyListOnly">
    <env-var name="XAVA_LIST_ACTION" value=""/>     <!-- 1  New in v2.0.4 -->
    <model name="Family"/>
    <controller name="Typical"/>
    <controller name="ListOnly"/>                   <!-- 2 -->
    <mode-controller name="Void"/>                  <!-- 3 -->
</module>
Void (3)模式 控制器可以去掉 "detail – list" 链接. 然后定义ListOnly (2) 让模块在初始化时处在列表模式, 这就成了一个仅列表模块. 最后, 将 XAVA_LIST_ACTION 设成空字符床(1) 对应每一行的细节链接就去掉了(new in v2.0.4).

文档模块

文档模块只能显示HTML文档. 这很容易定义:
<module name="Description">
    <doc url="doc/description" languages="en,es"/>
</module>
根据浏览器的语言设定,这个模块将显示web/doc/description_en.htmlweb/doc/description_es.html. 如果浏览器中设定的语言不是英文或西班牙文,一般显示英文。如果不指定任何语言,将显示web/doc/description.html
文档模块作为消息 portlet相当有用,但在 portal 环境以外无效.

只读模块

只读模块,只用来查询数据而不能修改数据, 可以这样定义:
<module name="CustomerReadOnly">
    <env-var name="XAVA_SEARCH_ACTION" value="CRUD.searchReadOnly"/>  <!-- 1 -->
    <model name="Customer"/>
    <controller name="Print"/>                                        <!-- 2 -->
</module>
使用CRUD.searchReadOnly (1) 用户不能修改数据, 只使用Print 控制器(2) (没有CRUDTypical) 保存、删除等操作就不可用. 这样就是一个只读模块.

application.xml 的语法并不难. 在OpenXavaTest/xava/application.xml中你可以找到更多的例子.