介绍了如何启用ADF应用的客制化功能,以允许最终用户在运行时对于应用作出个性化的配置,并将配置结果保存下来,当用户在一次登陆时,展示用户修改过的
界面元素。ADF应用的个性化除了上述功能外,还提供非运行时的客制化功能,即对于已经开发完成的ADF应用进行二次开发,在不修改原始应用的基础上添加
客制化的元素,改变流程等,并将修改后的应用发布。
首先对ADF客制化开发中的一些基本概念进行描述。
Oracle ADF提供了如下几种客制化的模式:
Seeded customization
将客制化应用在整个程序或组,客制化的生命周期为应用部署的周期。Part3的重点描述即在于此。 User customization (改变持久化)
允许个人持久化的客制化应用。如Part2所述。
Design time at runtime
系统分析师或管理员使用,以客制化程序。Oracle Fusion Middleware Developer’s Guide for Oracle WebCenter中有详细介绍。
ADF在客制化应用上引入了客制化层的概念,所有的客制化内容均在客制化层上完成并存储至MDS,而不对已经开发完成的应用作出修改。在运行时将原始应用
与客制化层的内容进行融合,并将最终结果展示给用户。这种方式最大限度的避免了由于应用的客制而导致的混乱,同时保证了对于原始应用的补丁不会影响到客制
化的内容。
允许进行客制化的ADF应用允许设置多个客制化层,例如industry层及site层;而一个客制化层又允许具有多个客制化值,如industry层可以具有healthcare和financial等。但对于运行时的应用来说,每一个层只有一个客制化值有效。
应用实际使用客制化层的顺序由客制化层的优先级来确定。
使用JDeveloper创建客制化类,指定客制化层及客制化层呢个的值,指定客制化层的优先级,即可完成客制化开发。
客制化的类型:Static/Dynamic,Static类型的客制化值将使用客制化定义的初始值,而Dynamic类型的客制化
值则允许在运行时动态改变。customization类可存在于Model或ViewController,若放入Model则必须为Static,因
为每一个应用中Model通常只会初始化一次。ViewController中则可使用Static/Dynamic。通过设置
customization类中getCacheHint()方法返回值可以设置该客制化是Static/Dynamic,例如该方法返回值为
ALL_USERS则客制化为Static。 ALL_USERS – customization为针对某应用全局有效的,通常用于static类型的customization层。
MULTI_USER – 针对复数用户有效的customization。 REQUEST – 针对当前请求有效的customization。
USER – 针对某特定用户有效的customization,通过用户访问应用的Session来决定具体用户。(在Web应用中session通常指代用户访问应用的servlet session)
进行客制化开发:
首先是客制化类的编写。每一个客制化层对应一个客制化类,而客制化类中可定义多个客制化值。
客制化类的编写:
需要包含四个方法如下 CacheHint getCacheHint();
决定customization的类型,返回值包括ALL_USERS, MULTI_USER, REQUEST, USER四种。
String getName();
返回当前customization类对应customization层的名称。 String generateIDPrefix(RestrictedSession sess, MetadataObject mo);
返回在MDS中对当前customization层元素加的前缀,以使该客制化层的元素在MDS中具有唯一标示。这一前缀在所有customization层中必须是唯一的,出于性能考虑应小于4个字符。
String[] getValue(RestrictedSession sess, MetadataObject mo);
返回反映客户化层加载顺序的列表,按照列表正序加载。通常只需要有一个customization层,故该列表通常只返回一个值。
客制化可被用于修改应用以适应某种行业的需求。每一种行业则象征了一个客户化层,并使用一个具体的客户化类予以实现。
使用客制化类实现Seeded Customization : 应用的adf-config.xml中mds-config部分必须配置要使用的客制化类。
客制化类须放置在JDeveloper的classpath下以供访问。(运行时必须存在于可被EAR级别的classLoader访问的路径下) 客制化值必须设置在CustomizationLayerValues.xml文件中。该文件位于JDeveloper安装路径下的jdev文件夹中。该文件中定义的值必须与进行客制化开发的客制化类中的名称相匹配。
(详细配置下半部分有step by step)
满足上述条件后,当JDeveloper以客制化角色启动时,将显示允许定制的客制化层及客制化值,选择需要的客制化层和客制化值后进行客制化即可。
客制化类实例(来自文档B31974)
package mycompany; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import oracle.mds.core.MetadataObject; import oracle.mds.core.RestrictedSession; import oracle.mds.cust.CacheHint; import oracle.mds.cust.CustomizationClass; public class IndustryCC extends CustomizationClass { private static final String DEFAULT_LAYER_NAME = "industry"; private String mLayerName = DEFAULT_LAYER_NAME; public IndustryCC() { } public CacheHint getCacheHint() { return CacheHint.ALL_USERS; } public String getName() { return mLayerName; } public String generateIDPrefix(RestrictedSession sess, MetadataObject mo) { return new String("I"); } public String[] getValue(RestrictedSession sess, MetadataObject mo) { // This needs to return the appropriate value at runtime. return new String[] { "financial" }; } } |
通常将客制化类单独打包为Jar并以library的方式引入需要进行客制化的应用。在将客制化类打包为Jar时,应同时放置
customization.properties文件以保证客制化类和该文件可以被同一个ClassLoader载入。该配置文件配置了运行时具体每个
客制化层使用的值,内容如下:
#Configured values for the default layer values industry=financial site=headquarters |
同时,当客制化应用部署时,该客制化类的Jar也应置于应用的ClassPath中以供访问。
创建一个允许进行客制化的应用:
* 启用ViewController的客制化
ViewController的客制化,首先需要保证所有的.jspx和.jsff中的元素具有惟一的id,以供存储入MDS。同时由于使用MDS需要保证源文件基于XML,所以不支持.jsp,需要将.jsp转化为.jspx方可生效。
设置ViewController的属性,启用Seeded Customizations。
启用ResourceBundle的客制化
点击Application -> Application Properties,在左边选择Resource Bundles,点击Add加入允许进行客制化的ResourceBundle,并勾选Overridden。
修改adf-config.xml
在Application Navigator中展开Application Resources,修改adf-config.xml。
在MDS Configuration页中点击add,增加需要使用的客制化类,即之前创建并打包的客制化类。
注意,当加入多个客制化类(层)时,客制化类(层)将按照自上向下的顺序生效。
对应用进行客制化开发:
在完成客制化类的创建,并启用目标应用的客制化后,即可以Customization Developer Role进入JDeveloper进行目标应用的客制化开发。首先需要配置JDeveloper如下:
将需要使用的客制化层及客制化值设置入<JDEVELOPER_HOME>/jdev
/CustomizationLayerValues.xml。当以Customization Developer Role
进入JDeveloper时,JDeveloper会读取该文件中的客制化层/值的设置,结合当前工程包含的客制化类,决定在JDeveloper的
Tip Layer中可编辑的客户化层/值。而在应用运行时,则直接从客制化类中读取客制化层/值。本例中在该文件中加入如下值:<cust-layers xmlns="http://xmlns.oracle.com/mds/dt">
<cust-layer name="industry" id-prefix="i">
<cust-layer-value value="financial" display-name="Financial" id-prefix="f"/>
<cust-layer-value value="healthcare" display-name="Healthcare" id-prefix="h"/>
</cust-layer>
<cust-layer name="site" id-prefix="s">
<cust-layer-value value="headquarters" display-name="HQ" id-prefix="hq"/>
<cust-layer-value value="remoteoffices" display-name="Remote" id-prefix="rm"/>
</cust-layer>
</cust-layers>确保客制化类打包的Jar位于JDeveloper的Classpath下,切入Customization Developer
Role时JDeveloper将根据CustomizationLayerValues.xml中配置的值读取该客制化类。通常可将其放置
在<JDEVELOPER_HOME>/jdev/lib/patches/ 目录下。- 在JDeveloper中选择 Tools -> Preferences -> Roles,选择Customization Develoepr并确定后重新启动JDeveloper。
如果如上配置正确,且打开对应的可客制化的工程,则应该在Tip Layer中看到如下内容
(这
里虽然我的CustomizationLayerValues.xml中配置了industry及site两个层,但因为
CustomizationDemo这个项目包含的客制化Jar只含有industry一个客制化类,所以这里能够配置的Tip
Layer中只有industry一个)
配置成功后即可在Customization Developer Role 下进行客制化开发,在Tip
Layer中选择需要使用的客制化层及客制化值,之后按照原有ADF应用开发方式进行开发即可。区别在于对于应用的更改只作用于选择的层次/值生效的时
刻,且所有的更改均不会影响到原应用,而是存储在项目路径下mdssys/cust/<客制化层名称>/<客制化值名称>/下,
以XML形式存储。在应用部署时,这里的XML数据将被部署至服务器MDS内。可以通过上图所示 "View without
Customization" 及 "Edit with following Customization Context"
随时在原始应用/客户化开发应用间进行切换。
客制化应用实例:
以Oracle 数据库自带HR
Schema下EMPLOYEES表为例,创建含有Form的页面用于更新该表,并在EO的Salary字段添加Range类型验证为
2000-25000。后在Customization Developer Role下将范围改为2000-30000,运行测试。
以下为示例链接,注意CustomizationDemo应用需要修改引入的客制化jar包路径,该包位于CustomizationClassDemo应用deploy路径下。
Demo下载