系列文章:Oracle ADF 开发必读 — 第 9 部分


使用 Oracle 元数据服务构建可定制应用程序 (II)

作者:John Stegeman

用实例介绍针对个性化和定制的 Oracle ADF 服务(续)— 在本部分中,创建种子定制。

2010 年 5 月发布

下载:

如今,应用程序用户希望他们经常使用的应用程序能够记住他们喜欢的工作方式,从而无需每次登录时都重新设置应用程序。例如,用户希望他们常用的搜索和屏幕布局日复一日地保持不变,以便他们更加轻松直观地使用应用程序。利用 Oracle Metadata Services (MDS) 提供的基础,Oracle Application Development Framework (ADF) 应用程序可以提供这样的持久个性化。本文介绍如何针对设计时定制配置您的应用程序,以及如何为不同用户群设计定制。

前一部分中,您学习了如何允许最终用户在运行时对您的 Oracle ADF Faces 应用程序进行定制。Oracle MDS 还支持另一种称为种子定制 的应用程序定制,它允许应用程序开发人员在开发时设计对应用程序的定制。然后,在运行时根据静态或动态条件将种子定制应用于应用程序。您的应用程序可以同时支持这两种定制,这样您就可以让您的应用程序在设计时针对不同的用户群进行定制,同时也支持在运行时的个人用户定制。种子定制的使用有两种常见情况:

  • 针对特定安装的应用程序定制。 例如,软件供应商可以创建一个所有客户均可使用并实现种子定制的基本应用程序,这样每个客户无需更改基本应用程序即可定制应用程序的安装。这种方法有一些主要优点。首先,每个公司无需更改基本应用程序即可定制应用程序。其次,由于无需更改基本应用程序,因此用这种方法设计的定制更具“升级安全”性;这意味着,交付基本应用程序的一个新版本时,种子定制不会丢失,但可重新应用于新版的基本应用程序(当然,可能需要对定制进行更改,但这比尝试对基本应用程序重新应用定制要方便得多)。
  •  
  • 针对不同用户群的应用程序定制。 这种方法已被 Oracle 用在 Oracle E-Business Suite 中;可以对自助式应用程序进行定制,例如,让来自不同部门的用户以不同的方式看到应用程序的某些屏幕。

本文将介绍如何使用本系列的前一篇文章中开发的示例应用程序开发种子定制,您可以从此处下载这个示例应用程序。

撰写本文时使用的是 Oracle JDeveloper 11g 11.1.1.2 版。如果您使用所提供的示例应用程序,您将需要更改 Application Navigator 中 Application Resources 面板中定义的 HR 连接的连接信息。另请注意,要运行示例应用程序,您应遵循本文所述任何所需配置步骤。

种子定制的概念

为您的应用程序设计种子定制时,需要指定一个或多个定制层。定制层 用于存放一组定制;一个定制层支持一个或多个定制层值,定制层值指定运行时应用哪组定制。通过一个例子更容易理解层的概念,让我们以一个旨在用于整个公司费用报表的应用程序为例。公司内的每个部门对某些字段是否显示、表中各列的顺序等等,可能有不同的要求。在这个例子中,定制层就是部门,而定制层值就是各个部门(例如:人力资源、财务)。一个应用程序可以支持多个定制层,这些定制层以指定的顺序应用于基本应用程序的顶部;例如,一个应用程序可以有公司部门 这两个定制层。在本文中,定制层 这两个术语可互换,定制层值层值 这两个术语也可互换。

定制类是针对某个特定定制层的 Java 类,除此之外,它还指定在运行时应用哪个定制层值。定制类可以使用所需的任何方法确定在运行时应用哪个定制层值;为此,常用的方法可能包括:一个属性文件(例如,针对特定安装的定制)、在数据库中寻找已登录用户的信息,或者其他特定于应用程序的逻辑。注意,虽然常见的情况多是在特定时间应用一个特定的定制层值,但是一个定制类在运行时可以返回多个定制层值。

Oracle JDeveloper 11g 包括一个专门用于设计每个定制层及其层值的定制的角色,称作定制开发人员角色。以定制开发人员角色启动 Oracle JDeveloper 11g 时,将看到 MDS - Customization Context 窗口,您可以在该窗口中选择要编辑的定制层及其层值;您所编辑的定制层与层值的组合称作提示层

实施种子定制的步骤

要对您的应用程序实施种子定制,需要执行以下步骤:

  • 创建一个或多个定制类。
  • 配置 Oracle JDeveloper 11g 项目以允许种子定制。
  • 为您的应用程序配置定制类(一个或多个)。
  • 编辑扩展的元数据属性(可选)。
  • 配置 Oracle JDeveloper 11g 以便在设计时查看您的定制类(一个或多个)和定制层及其层值。
  • 编辑每个提示层的元数据。

另一个要求(仅对运行时的最终用户定制)是,您的所有 JavaServer Faces(JSF) 页面必须存储为 XML 格式 (.jspx),并且您将要定制的所有 JSF 组件必须设置了 ID 值。

创建定制类

针对我们的示例应用程序,我们将创建一个非常简单的定制类。我已经选择了“gender”作为我的定制层,“Male”和“Female”作为我的定制层值。示例应用程序已经获得保护并且有两个用户:john 和 josephine;因此不必在定制类中制定任何复杂的逻辑,该定制类在运行时确定层值时,我们只需使用这样的逻辑:John 为男性,Josephine 为女性。当然,实际应用程序的逻辑可能更复杂,可能会从数据库读取配置,但我们将保持现在简单的逻辑。在我们的定制类中,我们需要实现三个方法:

  • getCacheHint()。 此方法将返回是将该层的定制应用于所有用户、一组用户、一个特定 HTTP 请求还是单个用户的有关信息。
  • getName()。 此方法将返回定制层的名称。
  • getValue()。 此方法将在运行时返回定制层值。

开发定制类有多种策略。一个策略是为该定制类创建一个单独的项目,将定制类打包为一个 JAR 文件,然后其他应用程序可以使用该文件。如果使用这一方法,最好是在一个单独的应用程序中创建定制类项目,以避免类加载器问题(如适用于 Oracle Application Development Framework 11g 第 1 版 (11.1.1) 的 Oracle 融合中间件 融合开发人员指南 34.2.1.3 节中所述)。另一种方法是在 Oracle ADF 应用程序的最低级项目中(我们示例中的 Model 项目)创建定制类,这种方法非常适用于不打算在多个应用程序中重用定制类的情况。在本文中,您将使用后一种方法。

要创建定制类,请确保您从示例应用程序中的“第 4 步”文件开始并执行以下步骤:

  1. 在 Application Navigator 中右键单击 Model 项目,启动 New... 向导:

    stegeman-mds2-f1

    图 1 启动新建向导

  2. 选择 General 类别,然后在 Items 列表中选择 Java Class,单击 OK

    stegeman-mds2-f2

    图 2 创建一个新 Java 类

  3. 提供与您的应用程序对应的类名称和程序包名称。确保您的类扩展为 oracle.mds.cust.CustomizationClass。最后,确保选中 Implement Abstract Methods 复选框,然后单击 OK

    stegeman-mds2-f3

    图 3 创建定制类

  4. 编写 getCacheHint() 方法的代码。这个定制层是专门针对用户性别的;因此,我们可以将 MULTI_USER 用作缓存提示(因为层值可用于多个用户,假设我们有多个男性和女性使用该应用程序)。getCacheHint() 方法应如下所示:

    public CacheHint getCacheHint()
      {
         return CacheHint.MULTI_USER;
      }
    
  5. 编写 getName() 方法的代码。我已经选择“gender”作为名称的值,因此 getName() 方法应如下所示:

    public String getName()
      {
         return “gender”;
      }
    
  6. 编写 getValue() 方法的代码。如概述中所述,如果登录的用户是 John,我们将为层值返回“m”,如果登录的用户是 Josephine,则为层值返回“f”。如果登录的用户既不是 John 也不是 Josephine,我们将不返回层值。在一个定制类中,您可以使用 ADFContext 获取安全上下文,从而获得用户名。getValue() 的代码应如下所示(出现提示时,允许 Oracle JDeveloper 导入 oracle.adf.share.ADFContext):
     
    public String{} getValue(RestrictedSession restrictedSession, MetadataObject metadataObject)
      {
        String user = ADFContext.getCurrent().getSecurityContext().getUserName();
        if (“John”.equalsIgnoreCase(user))  return new String[]  {“m”};
        if  (“Josephine”.equalsIgnoreCase(user)) return new String[]  {“f”};
        return new String[0];
      }
    

这就是编写一个定制类的所有代码!

配置应用程序使其支持种子定制

现在您已经创建了定制类,下一步就是配置您的 ViewController 项目,使其支持种子定制。您可以执行以下两个步骤实现这一操作:

  1. 在 Application Navigator 中,双击 ViewController 项目以显示项目属性。
  2. Project Properties 对话框中,选择 ADF View 节点,确保选中 Enable Seeded Customizations 复选框,然后单击 OK。如果在此之前您一直跟踪学习此示例应用程序,则此时 Enable User Customizations 复选框是选中的,但种子定制不需要该选项:

    stegeman-mds2-f4

    图 4 在 ViewController 项目中启用种子定制

您还需要注册这个应用程序的定制类。为此,展开 Application Navigator 的 Application Resources 部分;找到 adf-config.xml 文件(它应该位于 Descriptors 文件夹的 ADF META-INF 子文件夹中),双击它打开编辑器。单击 Add 图标,键入完全限定的定制类的类名:

stegeman-mds2-f5

图 5 注册定制类

您还可以在概述编辑器中单击 oracle.adf.share.config.UserCC 定制类,然后单击 Delete 图标从 MDS 配置中删除该定制类,因为上篇文章中曾将该定制类用作默认定制类以支持用户的运行时定制的持久性。完成该操作后,MDS Configuration 部分应如下所示:

stegeman-mds2-f6

图 6 MDS configuration

为您的种子定制配置 Oracle JDeveloper 11g

要为应用程序创建实际的种子定制,需要对 Oracle JDeveloper 11g 进行配置,以便它可以访问类路径上的您的定制类,并且可以了解您要定制的定制层及层值。

Oracle JDeveloper 11g 文档简要介绍了如何创建一个扩展作为构造 Oracle JDeveloper 11g 的类路径上可用的定制类的方法。但是,这需要一些工作量,并且还需要了解创建一个具有扩展创建功能的扩展并不困难,但是这不是本文的主线。让我们采用一个更简单的方法:创建一个包含我们的定制类的 JAR 文件,然后将该文件置于 Oracle JDeveloper 11g 的类路径中。要创建 JAR 文件,执行以下步骤:

  1. 确保已通过在 Application Navigator 中右键单击 Model 项目并从上下文菜单中选择了 Rebuild Model.jpr 而生成了定制类。
  2. 在 Application Navigator 中,双击 Model 项目以显示项目属性。
  3. 选择 Deployment 节点以显示可用的部署配置文件。
  4. 单击 New 创建一个新部署配置文件。确保选中了 JAR File 存档类型,并提供一个有意义的名称。然后,单击 OK

    stegeman-mds2-f7

    图 7 创建一个新部署配置文件

  5. 为了能在设计时定制应用程序,定制类需要在 Oracle JDeveloper 11g 的类路径中可用;实现此目的的一个简单方法就是将包含定制类的 JAR 文件置于 Oracle JDeveloper 11g 安装的 jdev/lib/patches 目录中。将对话框中 JAR File 的位置更改为 <JDEV 主目录>/jdeveloper/jdev/lib/patches,重启 Oracle JDeveloper 后,该定制类将出现在 Oracle JDeveloper 的路径类中:

    stegeman-mds2-f8

    图 8 更改 JAR 文件的位置

  6. 在出现的 Edit JAR Deployment Profile Properties 对话框中,我们将配置部署文件使其只包含我们的定制类。选择 Filters 节点。取消除 GenderCustomizationClass.class 节点外对所有其他节点的选中,以确保其他项目不包括在 JAR 文件中(因为 Merged Contents of this File Group’s Contributorsmodel 的一个或多个(不是全部)子节点被选中,因此这两个复选框显示为部分选中):

    stegeman-mds2-f9

    图 9 筛选项目输出

现在,您可以通过在 Application Navigator 中右键单击 Model 项目并从 Deploy 菜单中选择 GenderCC(您刚才创建的部署配置文件的名称)来创建 JAR 文件了:

stegeman-mds2-f10

图 10 部署 JAR 文件

在出现的 Deploy customization_class_jar 对话框中,单击 Finish 完成部署。现在,您可以查看 Oracle JDeveloper 11g 中的 Deployment - Log 窗口以确保部署成功:

stegeman-mds2-f11

图 11 部署日志

在您可以使用 Oracle JDeveloper 11g 编辑应用程序的种子定制前,您还需要将设计环境中显示的定制层及层值告诉 Oracle JDeveloper。可通过编辑 CustomizationLayerValues.xml 文件实现此目的,该文件位于您的 Oracle JDeveloper 11g 安装的 jdeveloper/jdev 目录中。可以使用所选的文本编辑器编辑此文件,我这里将介绍如何使用 Oracle JDeveloper 11g 编辑此文件。首先,在 Application Navigator 中单击 Model 项目;然后从 Oracle JDeveloper 11gFile 菜单中选择 Open。最后,在上述位置找到 CustomizationLayerValues.xml 文件并打开:

stegeman-mds2-f12

图 12 打开 CustomizationLayerValues.xml 文件

CustomizationLayerValues.xml 文件的开始有一大段注释部分,说明了如何编辑该文件。对我们的应用程序,只需要为我们的“gender”定制层简单添加一个 cust-layer 标记,为我们的“Male”和“Female”层值添加两个 cust-layer-value 标记。您应该注意,如果您广泛使用种子定制并且有多个定制层,则必须确保标记中的 id 前缀在所有的提示层中均生成唯一的 ID。在我们的示例中,只使用了一个定制层,因此不必担心唯一性问题。为了将我们定制层的标记添加到 CustomizationLayerValues.xml 文件中,需要在该文件的 <cust-layers> 标记中的任意位置放入以下文本:

 
<cust-layer  name=”gender” id-prefix=”g”>
   <cust-layer-value value=”m”  display-name=”Male” id-prefix=”1”/>
      <cust-layer-value value=”f”  display-name=”Female” id-prefix=”2”/>

</cust-layer>

注意,cust-layer 标记的名称对应于我们定制类的 getName() 的返回值,每个 cust-layer-value 标记的值对应于我们定制类的 getValue() 方法的可能返回值。通过单击工具栏中的 Save All 图标保存您的所有更改。

使用定制开发人员角色编辑种子定制

正如前面讲到的,Oracle JDeveloper 11g 包括一个专门用于编辑由定制开发人员角色调用的种子定制的角色。要编辑您的示例应用程序的定制,需要切换到定制开发人员角色。通过使用 Oracle JDeveloper 11gPreferences 对话框,您就可以切换到这一角色;现在,通过选择 Tools 菜单中的 Preferences 打开 Preferences 对话框。接下来,在左侧的 Preferences 列表中单击 Roles。通过在列表中选择 Customization Developer 切换到定制开发人员角色;如果您需要经常变更角色,那么选中 Always prompt for role selection on startup 复选框是很有帮助的,这样,每次启动 Oracle JDeveloper 11g 时系统都会问您以什么角色使用 Oracle JDeveloper:

stegeman-mds2-f13

图 13 选择 Customization Developer 角色

单击 OK,Oracle JDeveloper 11g 将以用定制开发人员角色重启。如果您曾经要求,则 Oracle JDeveloper 11g 重启时系统会提示您选择角色;如果出现这一情况,请确保选中 Customization Developer 角色:

stegeman-mds2-f14

图 14 启动时选择角色

一旦 Oracle JDeveloper 11g 重启,确保在 Application Navigator 中选中示例应用程序,观察一下这个集成开发环境,您将发现相比于默认角色有少许变化。您可能会注意到的第一个变化是不可定制的文件(如 Java 类)现在是只读的。定制开发人员角色只能用于编辑种子定制,因此任何与种子定制无关的内容均被禁用。您可能会注意到的第二个主要不同是显示的 MDS - Customization Context 窗口:

stegeman-mds2-f15

图 15 MDS - Customization Context 窗口

该窗口用于选择您将编辑的提示层。对我们的示例应用程序,我们对 ViewController 项目的 SampleControls.jspx JSF 页面做一个简单的种子定制;该页面上有三个面板框,其下方是一个表:

stegeman-mds2-f16

图 16 SampleControls.jspx JSF 页面

您可以通过种子定制改变几乎所有的页面可视外观;对于本示例,我们将做如下更改:

  • 男性用户将看到黑暗背景的面板框,并且顺序是相反的。
  • 女性用户将看到明亮背景的面板框。

要编辑 Male 提示层的种子定制,执行以下步骤:

  1. 确保在 MDS - Customization Context 窗口中选中了 Male 提示层:

    stegeman-mds2-f17

    图 17 选择 Male 提示层

  2. 在 Application Navigator 中,双击 SampleControls.jspx 文件打开它进行编辑。
  3. 使用 SampleControls.jspx - Structure 窗口通过拖放面板框将它们以相反的顺序重新排列。完成该步操作后,SampleControls.jspx - Structure 窗口应如下所示:
  4. stegeman-mds2-f18

    图 18 重新排列的面板框

  5. SampleControls.jspx - Structure 窗口中选择标记为 Number 3 的面板框。使用 Property Inspector 将 Background 属性改为 Dark

    stegeman-mds2-f19

    图 19 更改背景属性

    对其他两个面板框重复这一过程。完成后,该页面应如下所示:

    stegeman-mds2-f20

    图 20 所有面板框都使用黑暗背景

  6. 保存您的更改,关闭 SampleControls.jspx 页面。将提示层更改为 Female 层,在 Application Navigator 中双击 SampleControls.jspx 页面打开。您应该会看到对 Male 提示层所做的更改还没有反映出来。在 SampleControls.jspx - Structure 窗口中,选择标记为 Panel Box Number 1 的面板框,使用 Property Inspector 将 Background 属性更改为 light。对每个其他面板框重复这一过程并保存您的更改。完成后,该页面应如下所示:

    stegeman-mds2-f21

    图 21 所有面板框都使用明亮背景

如果您现在看一下 Application Navigator,您会看到 Oracle JDeveloper 11g 已经在 ViewController 项目中创建了两个新文件来反映 Male 和 Female 两个定制层值的定制。

stegeman-mds2-f22

图 22 种子定制的 MDS 文件

这两个新文件将存储在 Oracle MDS 信息库中,在运行时会检索和使用这两个文件以便通过修改基本 JSF 页面应用相应的种子定制。这确保了用户按照定制开发人员的希望看到该页面。如果您想下载进行了上述所有改变的示例应用程序的副本,可以从此处获得。(参见第 5 步。)

在集成的 Oracle WebLogic Server 中测试种子定制

现在您可以使用集成的 Oracle WebLogic Server 测试种子定制了。您不需要安装基于数据库的 MDS 信息库,因为集成服务器将使用基于文件的本地 MDS 信息库进行测试。您可以使用定制开发人员角色测试应用程序,也可以使用默认角色测试应用程序。和往常一样,只需在 Application Navigator 中右键单击 SampleControls.jspx 文件然后选择 Run 来启动应用程序。

stegeman-mds2-f23

图 23 运行 SampleControls 页面

应用程序启动后,浏览器将提示您输入登录凭证。我们的示例应用程序有两个用户:john 和 josephine,他们的口令都是“weblogic1”(不带引号)。您应该尝试以 john 用户身份登录观察反序的黑暗面板框,因为这是为 Male 种子定制层指定的:

stegeman-mds2-f24

图 24 具有 Male 种子定制层的 SampleControls 页面

接下来,关闭所有打开的浏览器窗口,通过单击 Oracle JDeveloper 11g Log 窗口中的 Target URL 返回应用程序;以 josephine 用户身份登录,观察按原始顺序排列的明亮面板框:

stegeman-mds2-f25

图 25 具有 Female 种子定制层的 SampleControls 页面

总结

现在,您了解了如何为您的应用程序进行种子定制、如何创建定制类,以及如何在 Oracle JDeveloper 11g 中设计和测试种子定制。本系列的下篇文章将介绍如何创建和注册 MDS 信息库并将您定制的应用程序部署到 Oracle WebLogic Server 上。

转到第 10 部分 | 返回目录

资源



John Stegeman
(stegemanoracle.wordpress.com) 是一位 Oracle ACE 总监(Oracle 融合中间件),也是 Xchanging 这个全球性业务流程外包和 IT 服务公司的一位架构师。他从 1990 年开始就使用 Oracle 产品工作,从版本 3 开始就使用 Oracle JDeveloper 了。