Sunday, September 13, 2009
Accessing the ADF Client Interface in a JSF Backing Bean when Application is splitted.
Solution:
"The problem was solved when I made a method call that had its own pageDef. Then the code worked like a charm (see initialBadCall_with_pageDef in the task-flow-definition-remote). ...
In the demo app, the use of the Client interface is also demonstrated. Client interface is the API that ADF BC exposes in order to be used in the client side, in our case the backing bean."
Story (or how I got there...):
Based on the excellent post of Andrejus for splitting the ADF Application, I was trying to find why when accessing AppModule through
RemoteModuleImpl am = (RemoteModuleImpl)ADFUtils.getApplicationModuleForDataControl("RemoteModuleDataControl");
the splitted application was breaking.
Specially, cos ADFUtils were written by Duncan Mills and Steve Muench and these guys know what there're doing!
One thing that seemed not good, is that in the above code there trying to accessing the implementation of the Client Interface and not the interface it self. And maybe this was forbidden by the ADF framework (as it should be cos it is not...).
First, I tried to access the Client interface "RemoteModule" and not the implementation. This SHOULD be accessible in the backing bean, at least that's what the ADF documentation says!?!
But this was not the problem that caused the splitted application to break (cos in a not-splitted app this code works fine).
The problem was solved when I made a method call that had its own pageDef. Then the code worked like a charm (see initialBadCall_with_pageDef in the task-flow-definition-remote). The only thing need it to access it in both ways (from ADFUtils or the way that is given in Fusion Developer's Guide) is to have a pageDef probably in order to be able to resolve the expression through FacesContext (see code for more).
In the demo app, the use of the Client interface is also demonstrated. Client interface is the API that ADF BC exposes in order to be used in the client side, in our case the backing bean.
The demo app is a modified demo app of Andrejus' (thank you again Andrejus for providing the original sample). Other options a also there which can be tested by changing the Default Activity of the task-flow-definition-remote. It is "shipped" with the initialBadCall_with_pageDef as the Default activity.
Enjoy
spido
PS:
Here's a sneak peak:
and some code:
/**
*bad call. Breaks the split.
* @return
*/
public String direct_action() {
RemoteModuleImpl am = (RemoteModuleImpl)ADFUtils.getApplicationModuleForDataControl("RemoteModuleDataControl");
am.initMethod();
return "open";
}
/**
* Uses the ADF utils to get App module, that means resolving an expression
* through FacesContext. ADFUtils were written by Duncan Mills and Steve Muench and these guys know what there're doing!
* @return
*/
public String direct_action3() {
ApplicationModule am = (RemoteModule)ADFUtils.getApplicationModuleForDataControl("RemoteModuleDataControl");
// 5. Cast the AM to call methods on the custom client interface
RemoteModule rs = (RemoteModule)am;
//the following line break with no pageDef
exploitClientInterface(rs);
return "open";
}
/**
* Uses FacesContext to get bindings and from them it gets an iterator and
* then tah app module.
* @return
*/
public String direct_action2() {
ApplicationModule am = (ApplicationModule)this.getApplicationModuleFromIterator("EmployeesView1Iterator");
// 5. Cast the AM to call methods on the custom client interface
RemoteModule rs = (RemoteModule)am;
// 6. Call a method on the client interface
exploitClientInterface(rs);
return "open";
}
/**
*Method to demonstate how we can exploit the Client interface that ADF BC provide.
* @param rs
*/
private void exploitClientInterface(RemoteModule rs) {
System.out.println("In backing bean!!!");
//use api of ApplicationModule (default) client interface
oracle.jbo.ViewObject vo = rs.findViewObject("EmployeesView1");
//use api of Custom implementation of ApplicationModule (your implementation) client inteface
rs.initMethod();
//use api of VO client interface
vo.setOrderByClause("Employees.FIRST_NAME");
//use api of Custom implementation of VO (your imlementation) client interface
EmployeesView employees = (EmployeesView)vo;
employees.exposeMe();
//use api of RowSet client interface
vo.executeQuery();
System.out.println("Estimated # of employees= " + vo.getEstimatedRowCount());
//use api of RowSetIterator client interface
//...
}
/**
* Helper method to get the bindings. Fusion Develop's Guides way to get the bindings.
* @return
*/
private BindingContainer getBindings() {
if (this.bindings == null) {
FacesContext fc = FacesContext.getCurrentInstance();
this.bindings = (BindingContainer)fc.getApplication().evaluateExpressionGet(fc, "#{bindings}", BindingContainer.class);
}
return this.bindings;
}
/**
* Get the App module from iterator. The Fusion Develop's Guides way to get the AppModule interface.
* @param iteratorName
* @return
*/
private ApplicationModule getApplicationModuleFromIterator(String iteratorName) {
DCBindingContainer bc = (DCBindingContainer)getBindings();
// 2. Find a named iterator binding
DCIteratorBinding iter = bc.findIteratorBinding(iteratorName);
// 3. Get the data control from the iterator binding
DCDataControl dc = iter.getDataControl();
// 4. Access the data control's application module data provider
return (ApplicationModule)dc.getDataProvider();
}
Thursday, July 9, 2009
Setting memory config in Weblogic 10.3.1
Friday, June 12, 2009
A different way...
Hi all J
We were very interested in Resource Bundle files problem. And in a past few days we discovered that there are at least 3 workarounds:
- commenting SET tags (current solution)
pros: easy to implement, no low memory problem cons: no labels on page, cannot add/remove/change labels - using SET tags with one additional backing bean (our solution)
pros: labels visible on a page, using the same SET tag, can add/remove/change labels (not trough wizard), no low memory problem cons: not so easy to implement - using LOADBUNDLE tag (solution we found on web, not ours L)
pros: easy to implement, labels visible on a page, can add/remove/change labels (not trough wizard), no low memory problem cons: not using SET tag (in our opinion not a problem at all)
As much as it hurts us to admit, we think that third solution is the best. Pls let us know if it works for u as it works for us. If u need us to explain it in details how to implement (which is just one more line in page J), pls don’t hesitate to ask.
Hope u like it J
Milos Rebic (milos.rebic@gmail.com) & Spiros Dougeridis
P.S. Details: First comment all SET tags. LOADBUNDLE tag is JSF core library tag. When u drag&drop it on a page u should just specify the same things as for SET tag (copy/paste J).
SET tag:
LOADBUNDLE tag:
PS2: Example:
*important*important*important*
USE SAME VARS FOR SAME BUNDLES !!!!!!!!!!!!
Don’t use wizard for adding new labels (it will again create SET tag, and u don’t want that J), do it manualy
*important*important*important*
Easy, isn’t it J And all tags are visible on page. When u finish with development, erase LOADBUNDLE tags, and uncomment SET tags.