12月 30, 2009
JDev Ver. 11.1.1.2.0
DB Ver. Oracle 10g(XE)
本文示例使用taskflow中的Router进行有条件的导航。使用Oracle实例Schema HR中的EMPLOYEES表进行实现。
示例代码下载
首先创建ADF应用,及构建EMPLOYEE表的model部分(EO、VO、AM),这里不再赘述。
创建页面MainPage,布局如下截图所示。
本Demo目标为在点击左侧table中action链接时根据当前行雇员salary决定右侧页面显示内容。其中MainPage中PanelSplitter, Table, Link 等创建过程略去。
- 创建两个jsff页面,分别对应Salary大于10000及小于等于10000的情况,显示UPPER/LOWER。
- 创建bounded taskflow,在Overview页面的Parameters中为其添加变量名为SalaryStatus,并勾选Required。注意这里IDE自动生成了表达式为#{pageFlowScope.SalaryStatus}的变量。
- 在 taskflow的Diagram中首先拖放Router(Component Palette -> router),它将作为该bounded taskflow的Default Activity。接着将Upper.jsff及Lower.jsff拖入taskflow,并以Control Flow Case (Component Palette -> Control Flow Case)进行连接,分别将连接命名为toUpper,toLower。拖放TaskFlowReturn(Component Palette -> Task Flow Return),并以Comtrol Flow Case进行连接,命名为default,它将作为router的默认导航结果。
- 点击router1,在Property Inspectory中设置Default Outcome为default,并创建表达式,设定
#{pageFlowScope.SalaryStatus > 10000}时OutputCome为toUpper,
#{pageFlowScope.SalaryStatus <= 10000}时OutputCOme为toLower
- 为 MainPage.jspx设定绑定变量,在MainPage.jspx的binding页面中右键点击executable中的variables,选 择insert inside variables -> variable,Name为salary,Type为java.lang.String,创建的变量可在Structure面板中看到。点击 Bindings上的加号添加类型为AttributeValues类型的绑定,名称为salary1,使其指向刚刚创建的salary变量。再为 Bindings添加另一AttributeValue使其指向EmployeesView1Iterator中Salary字段,名为Salary。
- 将 第2步创建的bounded taskflow拖入MainPage右侧区域,在弹出菜单中选择Region。由于taskflow中设定了required变量 SalaryStatus,需要为其设定表达式为#{bindings.salary1.inputValue}。
- 设置MainPage左侧区域表格中action Link的Action Listener,使其调用BackingBean方法以将第五步创建的Salary值设置入salary1,并执行MainPage右侧区域region的refresh方法,具体代码如下
(需要将右侧区域的region绑定入BackingBean)
[code=java]
FacesContext fc = FacesContext.getCurrentInstance();
Application app = fc.getApplication();
// get current row Salary value
Number salary = (Number)app.evaluateExpressionGet(fc, "#{bindings.Salary.inputValue}", Object.class);
// set salary value to salary1 to effort in taskflow
FacesCtrlAttrsBinding salary1 = (FacesCtrlAttrsBinding)app.evaluateExpressionGet(fc, "#{bindings.salary1}", Object.class);
salary1.setAttributeValue(salary.toString());
// refresh region on the right side of MainPage
this.region1.refresh(fc);
[/code]
示例代码下载
参考OTN Oracle Magazine January/February 2010, The Route to Success
tags: ADF
posted in ADF by | No Comments | 编辑
12月 22, 2009
JDev ver. 11.1.1.2.0
Maven 2.2.1
(本文所述不是严格意义上的maven在Oracle ADF应用开发中的使用,仅尝试使用maven作为ADF开发的每日编译工具。)
JDeveloper 11.1.1.2.0以插件的形式为JDeveloper 11g带来了maven的支持。这种支持在11.1.1.2.0中仅限于对常规开发的maven支持,而对于如何为ADF应用添加maven的支持以解决 诸如ADF应用对于Library的依赖、ADF应用打包为ADF Library Jar File、ADF应用之间的依赖等问题并未提出解决方案。Oracle官方表示在11.1.1.2.0中maven尚属于技术预览,尚未完成。
在 某特定ADF应用中,将ADF应用分为主应用、模块、功能,主应用为不包含BC的ADF应用,用于解决登录、Session管理等内容;应用分为模块进行 开发,如系统管理模块,每个模块具体分为功能进行开发,如用户管理、组管理等。进行应用构建时,将每个功能打包为ADF Library Jar File,将同一模块的所有功能jar包合并为该模块的ADF Library Jar File,再以jar library的形式将该ADF Library Jar File加入主应用,最后将主应用打包为EAR进行部署。出于每日构建的需要及考虑到未来可能的模块间依赖,希望引入maven以解决该问题。
解决问题的基本思路如下:
首先依照maven的设计思想,设置构建结构如下:
如此则每次构建父项目,将自动按序构建功能项目 -> 模块项目 -> 主项目。具体应用中一个主项目依赖于数个模块项目,一个模块项目依赖于数个功能项目。
该结构下功能项目均将具体ADF项目打包为ADF Library Jar File,模块项目将该模块所依赖的所有功能项目打包为一个Jar,而主项目构建时将所有打包的模块项目引入并最终打包为EAR。
由 于不了解ADF Library Jar File/ADF EAR打包的具体内容,故使用Oracle官方提供的命令行打包工具ojdeploy进行ADF Library Jar File及EAR的打包,使用另外开发的Jar合并程序进行ADF Library Jar File的合并。故需要开发Maven插件如下:
- 用于调用 ojdeploy 的 maven-adfdeploy-plugin。
- 用于将 ADF Library Jar File 合并的 maven-jarmerger-plugin。
结 合Maven进行项目管理的构建生命周期,由于本次只使用其作为每日构建工具,则只需实现package阶段即可,考虑到未来解决依赖的需要,亦实现 install及deploy阶段,分别用于将maven项目部署至本地repository及远程repository。
maven-adfdeploy-plugin
maven-jarmerger-plugin
jarmerger(maven-jarmerger-plugin依赖于此)
使用实例:
- 首先将插件安装至本地repository,按照jarmerger -> maven-jarmerger-plugin -> maven-adfdeploy-plugin的顺序进行安装,进入每个目录运行mvn install即可。
- 构建父maven项目pom.xml文件,按照前述图示结构将模块项目、功能项目均作为父maven项目的模块,并指定使用1.6版本JDK进行编译。
- 构建功能项目pom.xml文 件,设定父项目为第2步所创间的项目,设定打包类型为adfdpl.jar,并应用maven-adfdeploy-plugin插件,由于调用 ojdeploy进行编译打包,故需要使用JDeveloper在ADF应用中设定好对应的Deploy Profile,并以据文件中注释所示进行配置。
- 构建模块项目pom.xml文件,设定父项目为第2步所创间的项目,设定打包类型为hadfmerge.jar,并应用maven-jarmerger-plugin插件,设置针对第3步创建的功能项目的依赖,并依据文件中注释进行配置。
- 构建主项目对应的pom.xml文件,同样调用ojdeploy进行实现,设置方式类似于步骤3。
设置成功后,只需在父maven项目的pom.xml所在文件夹运行mvn package即可完成项目打包。结合Hudson等持续集成工具及SVN,即可完成每日构建的任务。
已知的问题:
- 由于调用ojdeploy进行编译及打包,则这种思路下不可能解决项目编译时自动寻找/解决依赖的问题,仍需要手工调整每日构建所用的构建源码所引入的包/库。
- 插件没有实现构建生命周期中的unit test及report阶段,仍需完善。
tags: ADF, Maven
posted in ADF, Maven by | No Comments | 编辑
12月 9, 2009
今天项目的服务器崩了,服务器的风扇不转了,前一阵子只是用服务器的数据库,读写量也小,没发现这个问题。今天更新服务器的Weblogic,估计是 CPU占用量高导致发热后计算错误,磁盘读写错误,先是整个RedHat Read-only file system,后来直接罢半夜凉初透工了,重启出现mount: error 2 ......
---------------------------------------------------------------------
以上是题外话,无奈把数据库备份导入本机XE数据库进行开发,imp时出现错误
[code=sql]
IMP-00017: following statement failed with ORACLE error 604:
"DECLARE SREC DBMS_STATS.STATREC; BEGIN SREC.MINVAL := 'C3020416'; SREC.MAX"
"VAL := 'C3020416'; SREC.EAVS := 0; SREC.CHVALS := NULL; SREC.NOVALS := DBMS"
"_STATS.NUMARRAY(10321,10321); SREC.BKVALS := DBMS_STATS.NUMARRAY(0,1); SREC"
".EPC := 2; DBMS_STATS.SET_COLUMN_STATS(NULL,'"AFWK_FUNCTIONS"','"FUNCTION_I"
"D"', NULL ,NULL,NULL,1,1,0,srec,5,6); END;"
IMP-00003: ORACLE error 604 encountered
ORA-00604: error occurred at recursive SQL level 1
ORA-01653: unable to extend table SYS.HIST_HEAD$ by 8 in tablespace SYSTEM
ORA-06512: at "SYS.DBMS_STATS", line 4858
ORA-06512: at "SYS.DBMS_STATS", line 5081
ORA-06512: at line 1
[/code]
看来问题集中在ORA-01653上,貌似SYSTEM的表空间不足导致。
通过如下语句查询表空间
[code=sql]
SELECT T.TABLESPACE_NAME,
D.FILE_NAME,
D.AUTOEXTENSIBLE,
D.BYTES,
D.MAXBYTES,
D.STATUS
FROM DBA_TABLESPACES T, DBA_DATA_FILES D
WHERE T.TABLESPACE_NAME = D.TABLESPACE_NAME
ORDER BY TABLESPACE_NAME, FILE_NAME;
[/code]
发现各表空间的自增均正常,但SYSTEM这一表空间的BYTES = MAXBYTES,已经不能自增了。
修改SYSTEM的表空间最大值
[code=sql]
alter database datafile '/usr/lib/oracle/xe/oradata/XE/sysaux.dbf' AUTOEXTEND ON NEXT 100M MAXSIZE UNLIMITED;
[/code]
修改后结果如下
问题解决。
tags: Oracle db
posted in Oracle db by | No Comments | 编辑
12月 8, 2009
Part2中 介绍了如何启用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)
[code=java]
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" };
}
}
[/code]
通常将客制化类单独打包为Jar并以library的方式引入需要进行客制化的应用。在将客制化类打包为Jar时,应同时放置 customization.properties文件以保证客制化类和该文件可以被同一个ClassLoader载入。该配置文件配置了运行时具体每个 客制化层使用的值,内容如下:
[code=bash]
#Configured values for the default layer values
industry=financial
site=headquarters
[/code]
同时,当客制化应用部署时,该客制化类的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中可编辑的客户化层/值。而在应用运行时,则直接从客制化类中读取客制化层/值。本例中在该文件中加入如下值:
[code=xml]
<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>
[/code]
- 确保客制化类打包的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下载
tags: ADF
posted in ADF, logs by | No Comments | 编辑
12月 1, 2009
ADF应用的客制化包含两个方面,一方面是允许在运行时,由最终用户对应用进行客制化,如针对用户调整表格的显示状态、查询面板的默认查询、 PanelBox的展开状态等,即Personialization;另一方面是允许针对已开发完成的应用进行定制,如修改页面模板、修改页面字段显示 值、修改页面跳转逻辑等,即Customization。这些客制化内容均不会对已开发完成的应用作出修改,而是存储在MDS中。本文主要介绍如何为 ADF应用启用Personialization。
JDeveloper Ver. 11.1.1.2.0
DB Ver. 10g(XE), Schema HR
启用Personialization步骤:
- 使用默认角色进入JDeveloper
- 设 置应用中ViewController项目的属性,在"ADF View"下勾选"Enable User Customizations","Enable Seeded Customizations",并选择"Across Session using MDS"以使客户化可以保存下来。
- 在 Appliaction Navigator 的 Application Resources 中,修改adf-config.xml
在 MDS Configuration 中增加 Customization Classes UserCC,包路径为oracle.adf.share.config.UserCC,以允许针对用户的客制化。
在 View 中,确认 Tag Library URI 为 http://xmlns.oracle.com/adf/faces/rich,这里是用于配置哪一组标签及其属性将被存储至MDS,这里声明为ADF Rich Components。
而 Tags 中则可新增允许进行客制化的标签类型及属性。这里增加几种常用标签
- 设定页面元素是否允许客制化修改
为 应用完成上述3步骤的配置后,将为整个应用中adf-config.xml中指定的类型控件及属性启用客户化支持。但在实际使用中往往会遇到应用中不同页 面同种控件部分需要客制化,部分不允许客制化的情况。则需对页面控件设置 persist 及 dontpersist 属性。
需要注意的两点:
- persist 及 dontpersist 属性只对于将客制化信息存入MDS的情况有效。
- 在任何情况下如果客制化信息保存至MDS失败,则仅将客制化信息保存在当前Session中。
- 控件默认将所有客制化信息保存至MDS,可以点击persist/dontpersist的edit进行可用属性的编辑。
- dontpersist的优先级高于persist,即当同一属性被设置入persist及dontpersist,则该属性的客制化信息不会保存入MDS。
至此完成应用的客制化定义部分。
由于本示例为针对用户的客制化定义,因此接下来需要定义应用的安全验证及用户,至少定义两个用户用于验证客制化的定义。
- 进 入 "Configure ADF Security" (Application -> Secure -> Configure ADF Security),在Step1中选择 "ADF Authentication and Authorization"。
- Step2,确认需要应用验证的Web项目,选择HTTP Basic Authentication。这里HTTP Basic Authentication即为最常用的Web验证方式,使用浏览器的弹出窗口进行验证。
- Step3,确认选择为 "No Automatic Grants",点击下一步
- Step4,确认没有勾选 "Redirect Upon Successful Authentication" ,并点击Finish完成定义。
- 进行jazn-data.xml的配置,Application -> Secure -> Application Roles,增加Role,此示例使用DjTestRole
- 点击Users,增加两个用户名为user1,user2,密码分别为password1,password2。
- 点击Application Roles,为第五步创建的组增加成员user1及user2
- 点击左下角ADF Policies,将需要访问的页面/taskflow授权给之前创建的Role,并确认勾选Customize, Grant, Personalize
至 此完成应用的配置,运行应用,分别以user1/user2登录,对于表格列的操作,则对于已经定义允许客户化的控件的状态修改将依用户区分保存至 MDS。如使用user1登录后修改表格显示的列及列宽,则user1下一次登录将看到本次的修改结果;而user2看到的表格显示状态不随user1的 修改而改变。
附注:
对于启用基于MDS的客制化支持后QueryPanel不能保存自定义查询,报出异常
[code=java]
oracle.mds.exception.ReadOnlyStoreException: MDS-01273: 未能对资源 /persdef/dj/demo/model/queries/EmployeesVO.xml 执行操作, 因为映射到名称空间 / BASE DEFAULT 的源元数据存储为只读。
[/code]
的问题,Oracle官方在JDeveloper 11.1.1.1.0 的 Release Note 中有提到,需要在应用的adf-config.xml中配置如下内容
[code=java]
<persistence-config>
<metadata-namespaces>
<namespace path="/persdef" metadata-store-usage="MAR_TargetRepos"/>
</metadata-namespaces>
<metadata-store-usages>
<metadata-store-usage id="MAR_TargetRepos" deploy-target="true"
default-cust-store="true"></metadata-store-usage>
</metadata-store-usages>
</persistence-config>
[/code]
则关于查询面板的客制化信息将存储在MDS目录下的/persdef目录中。详见ADF Customization part 1: The MDS。
Demo下载
tags: ADF
posted in ADF by | No Comments | 编辑
11月 29, 2009
星期天在家通过VPN去公司加班,发现VPN后连接公司内服务器正常,但连接其他网站不能。
初步判断为路由问题,首先尝试VPN连接配置中的“忽略自动获取的路由”,后添加公司服务器访问的路由信息。尝试无效。
执行ifconfig -a,看到VPN建立了一dev为ppp0的连接
后执行route查看路由表如下
对 比VPN未连接时的路由表信息可知,该VPN插入一条目标为10.213.0.10的路由记录,并将default路由改为网关*,接口ppp0。按照路 由表规则,、自上向下的方式进行路由匹配,则所有发往外网的请求均会路由至ppp0,而ppp0的VPN只支持公司内网访问,故造成不能访问外网的问题。
修改路由表如下
[code=bash]
sudo route del default #删除默认路由
sudo route del 10.213.0.10 #删除VPN创建的路由,该路由没有效果
sudo route add default gw 192.168.1.1 #重设默认路由,使用网关192.168.1.1,这是我家里的路由器网关
sudo route add -net 10.213.252.0 netmask 255.255.255.0 dev ppp0 #添加一条路由用于访问公司服务器所在网段
[/code]
最终修改结果如下
为了方便使用,将路由修改命令写为脚本以供使用。
tags: Geeker Life, Linux
posted in Geeker Life, Linux by | No Comments | 编辑
11月 25, 2009
JDeveloper 11.1.1.2.0
Oracle 10g EE
在开发中经常遇到的一种情况是需要将Table中某列的两种状态,如Y/N在界面上表现为checkbox的形式。ADF中checkbox默认返回true/false,不符合数据表中存储数据的要求。故需要对true/false进行转换。这里有两种方式完成转换。
- 在ViewController端页面的PageDef.xml文件中添加对应字段的绑定
类型为Button,选择对应的AM,VO,字段名称,如果该字段具有LOV,不需要选择对应LOV而保留None即可。在Selected State Value中填写勾选时需要的值,Unselected State Value中选择飞勾选状态时的值
后将界面控件通过el表达式关联至该绑定即可。通常将属性由Application Navigator中拖动入界面时会自动完成该绑定添加的过程。
- 遵 循MVC的原则,修改VO对应字段的get/set方法,将ViewController返回的true/false转换为需要的字符。具体做法为在对应 VO属性中的Java页生成Java文件,只需勾选Generate View Row Class并勾选Include accessors,后再修改生成的Java文件中对应字段的get/set方法即可。
情 况在RichTable等Collection Component中有所不同。不同于界面上其他控件的属性绑定方式,ADF RichTable等Collection Component通常绑定文件中为tree类型,而控件则使用el表达式访问该tree的collectionModel或treeModel
而Richtable中的列则通过row.bindings.XXX.inputValue的方式来访问该tree中的每一行值
而在页面的PageDef.xml文件中添加tree类型的绑定时,只可以选择绑定到的VO列名称,而没有属性可以设置将该列的值映射为checkbox的true/false。
ADF中使用将tree类型绑定中的树形绑定入另一button类型绑定,并在该button类型绑定中设置Selected/Unselected值的方式完成值的转换。具体内容如下:
- 在PageDef.xml中添加tree类型并包含目标字段,添加button类型的绑定,映射至VO对应字段。
- 设置button类型绑定的Selected/Unselected等属性
- 点击编辑器左下角进入Source模式,找到tree类型绑定的代码,形如
[code=xml]
<tree IterBinding="XXXXX" id="XXXXX">
<nodeDefinition DefName="XXXXX" Name="XXXXX">
<AttrNames>
<Item Value="XXXXX"/>
<Item Value="XXXXX"/>
<Item Value="XXXXX"/>
</AttrNames>
</nodeDefinition>
</tree>
[/code]
修改需要使用Checkbox的字段,将其绑定至第一步创建的button类型绑定(添加Binds="XXX")
[code=xml]
<tree IterBinding="XXXXX" id="XXXXX">
<nodeDefinition DefName="XXXXX" Name="XXXXX">
<AttrNames>
<Item Value="XXXXX"/>
<Item Value="XXXXX"/>
<Item Value="EnabledFlag" Binds="EnabledFlag"/>
</AttrNames>
</nodeDefinition>
</tree>
[/code]
如 此便完成了RichTable等CollectionComponent中checkbox的设置。需要注意的是通常这些设置在开发者将 Application Navigator中的属性拖入界面RichTable中并选择展现为CheckBox时会自动完成,但在某些特定情况下,如该VO中目标属性具有LOV 时,由于IDE本身的BUG(?)导致上述Binds="XXX"及button类型的绑定没有自动生成,则需要手工修正绑定以达到所需效果。
tags: ADF
posted in ADF by | No Comments | 编辑
11月 23, 2009
JDeveloper Ver. 11.1.1.2.0
DB Ver. Oracle 10g EE
BUG发生条件
1. 页面为jsff
2. 页面使用RichTable,绑定某VO,且该VO中某列具有LOV,该LOV以Choice List(下拉列表)的形式展现
3. 页面有Command Button/Link绑定VO的CreateInsert方法,且其Disabled属性绑定为#{!bindings.CreateInsert.enabled}
4. 页面有Command Button/Link绑定VO所在AM的Rollback方法
BUG现象
在页面点击Rollback,发现RichTable中下拉列表内的值消失,且无可选择项。刷新后可选项重新出现。
BUG原因
CreateInsert button的Disabled属性绑定。将其置为Default即可解决。
程序示例,使用Oracle示例HR数据库中Employees表。
tags: ADF
posted in ADF by | No Comments | 编辑
11月 23, 2009
ADF查询面板提供了快速创建查询的功能,本文主题为在ADF查询面板中使用关联LOV,即B LOV的结果依赖于A LOV的选择值,A LOV选择值变动时自动清空B LOV中的值。
示例使用Oracle HR数据库中的Employees, Locations, Departments三张数据表,Departments外键关联至Locations数据表,Employees数据表外键关联于Locations数据表。
使用2009年11月11日发布的Oracle JDeveloper 11.1.1.2.0作为开发环境,经实践其前一版本11.1.1.1.0在查询面板选择时清空LOV存在BUG。
首先从数据库反向创建相关EO、VO
修改DepartmentsView,在Query标签页为其创建Bind Variable,名称为locationId,类型为String。注意将其属性中的Display Hints设为Hide

并修改相应SQL语句,添加where条件如下
WHERE Departments.LOCATION_ID=nvl(:locationId, Departments.LOCATION_ID)
修改EmployeesView,在Query标签页修改SQL语句如下
SELECT Employees.EMPLOYEE_ID,
Employees.FIRST_NAME,
Employees.LAST_NAME,
Employees.EMAIL,
Employees.PHONE_NUMBER,
Employees.HIRE_DATE,
Employees.JOB_ID,
Employees.SALARY,
Employees.COMMISSION_PCT,
Employees.MANAGER_ID,
Employees.DEPARTMENT_ID,
Locations.LOCATION_ID
FROM EMPLOYEES Employees,
DEPARTMENTS Departments,
LOCATIONS Locations
WHERE Employees.DEPARTMENT_ID = Departments.DEPARTMENT_ID
AND Departments.LOCATION_ID = Locations.LOCATION_ID
在ViewAccessors页面添加ViewAccessor,分别指向DepartmentsView及LocationsView。

修改DepartmentsView1,将其绑定变量的Value设定为LocationId(这里的LocationId即为上一步修改SQL后EmployeesView中新添加的Attribute名称)。
在Attributes标签页为DepartmentId及LocationId分别添加LOV。
为 DepartmentId添加LOV,设定DataSource为上一步创建的ViewAccessor DepartmentsView1,Attribute为DepartmentId,并添加返回值为DepartmentId,修改UI Hints标签页中的Default List Type为Input Text With List of Values
同样为LocationId添加LOV,设定DataSource为上一步创建的ViewAccessor LocationsView1,Attribute为LocationId,并添加返回值为LocationId,修改UI Hints标签页中的Default List Type为Input Text With List of Values。
在Attribute标签页为DepartmentId设置属性,在其Dependencise中选择LocationId
![]()
最后,创建页面,将Data Controls中EmployeesView的All Queriable Attributes拖入界面,选择Query -> ADF Query Panel with Table。执行测试。
![]()
tags: ADF
posted in ADF by | No Comments | 编辑
11月 23, 2009
JDeveloper 11.1.1.2.0
Oracle 10g (hr schema)
某应用开发中碰到需要根据行状态决定页面元素的显示状态的要求。具体要求如下:
存在页面page1与page2,数据表table1与table2,table1与table2为Master-Detail关系,使用taskflow控制页面跳转。
page1选择新建按钮跳转到page2,此时page2页面指定按钮refresh按钮不允许点击。当用户在page2完成对table1的创建/修改 操作并保存后,页面refresh按钮允许点击;当用户从page1通过修改按钮跳转至page2后,若不对table1的记录进行修改,则 refresh按钮允许点击,否则refresh按钮不允许点击。
按照通常做法,需配置taskflow级别变量用于记录table1中某行状态,在页面跳转及记录值变动时修改该行状态,并根据该行状态变量决定refresh按钮的可用性。这种做法的缺点在于需要定义变量,并在多处操作时对该变量值进行维护。
故直接取EntityObject行状态作为标志位进行判断。下例以hr schema中regions及countries作为示例。
分别创建View页面和Update页面,View页面放置regions表,并允许进行新增和修改的操作。
若通过新增按钮跳转至Update页面,或通过修改跳转至Update页面并对region信息作出修改,则refresh按钮不允许点击,否则refresh按钮允许点击,通过判断当前regions EntityObject的状态完成。
EntityObject在生命周期中具有五种状态
- STATUS_UNMODIFIED - Entity Object源于数据库,且没有被修改过,或者修改已经被提交至数据库。
- STATUS_MODIFIED - Entity Object源于数据库,当前已经被修改且在当前事务中修改没有提交至数据库。
- STATUS_NEW - Entity Object为当前事务中新建的。
- STATUS_DELETED - Entity Object在当前事务中被删除。
- STATUS_DEAD - Entity Object为当前事务中新建的,且没有提交至数据库即被删除。
而各状态对应static值现下表
| oracle.jbo.server.Entity |
| public static final byte |
STATUS_DEAD |
4 |
| public static final byte |
STATUS_DELETED |
3 |
| public static final byte |
STATUS_MODIFIED |
2 |
| public static final byte |
STATUS_UNMODIFIED |
1 |
| oracle.jbo.Row |
| public static final byte |
STATUS_NEW |
0 |
故只需修改Update页面的refresh按钮Disabled属性,通过EL表达式进行行状态判断,进而返回true/false即可。
ADF 中ViewController通过EL表达式绑定取得Model中属性的值,当前IDE只提供了很少数的语法提示,那么根据Java命名规则,在 Model层通过getAbc()取得的值,在ViewController中该Abc作为对象abc存在,则可通过EL表达式# {bindings.XXX.abc}取得Model层XXX.getAbc()取得的值。
故通过查阅Fusion Middleware API,可知EL表达式应写作
#{bindings.RegionsView1Iterator.currentRow.entities['0'].entityState == '1' ? false : true}
示例下载
tags: ADF
posted in ADF by | No Comments | 编辑