This blog is obsolete.
Check new posts at ADF How To! !!

Thursday, May 19, 2011

Moving to a new blog: ADF & Weblogic How to

This blog is abandoned.

I am continuing  blogging on ADF & Weblogic How To.


Spyros

Saturday, March 13, 2010

Disable an af:menu when all of its children are disabled

If your application have a general requirement that a menu which has all of its children (menu items , go menu items , sub menus) disabled then the menu should also be disabled, then instead of writing the same conditions that you had to the children to the menu (boring and error prone) you can just use the following.

1. bind the af:menu to the backing bean, that is the binding prop eg. binding="#{myBacking.myMenu}"
2. set the disable property of the af:menu to a backing bean property e.g. disabled="#{myBacking.myMenuDisabled}"
//The backing bean method
public boolean isMyMenuDisabled() {

return isMenuDisabled(this.myMenu);
}
3.In the backing property method use the following method (you can decide if it should be placed to a generic class eg Backing beans Super class or in a Utils class as a statis method (e.g. like methods in ADFUtils))
/**
* In order to be disabled ALL children (&&) must be disabled
* @param menu
* @return
*/
protected boolean isMenuDisabled(RichMenu menu) {
boolean isDisabled = true;
List children = menu.getChildren();
logger.debug("parse children ");
Iterator iter = children.iterator();
while (iter.hasNext()) {
Object o = iter.next();
if (o instanceof RichMenu) {
RichMenu childMenu = (RichMenu)o;
logger.trace("Found submenu with id: "+childMenu.getId());
boolean isChildMenuDisabledProperty = childMenu.isDisabled();
if (isChildMenuDisabledProperty ) {
isDisabled = isDisabled && isChildMenuDisabledProperty;
logger.trace("submenu with id:"+childMenu.getId()+" returned (prop based) : " +
isChildMenuDisabledProperty);
}
else {
boolean isChildMenuIsDisabled = isMenuDisabled(childMenu);
isDisabled = isDisabled && isChildMenuIsDisabled;
logger.trace("submenu with id:"+childMenu.getId()+" returned (parsed) : " + isChildMenuIsDisabled);
}
} else if (o instanceof RichCommandMenuItem) {
RichCommandMenuItem menuItem = (RichCommandMenuItem)o;
isDisabled = isDisabled && menuItem.isDisabled();
logger.debug("Found menuItem with id: " + menuItem.getId() + " and disabled condition: " +
menuItem.isDisabled());
} else if (o instanceof RichGoMenuItem) {
RichGoMenuItem goMenuItem = (RichGoMenuItem)o;
isDisabled = isDisabled && goMenuItem.isDisabled();
logger.debug("Found gomenuItem with id: " + goMenuItem.getId() + " and disabled condition: " +
goMenuItem.isDisabled());
} else if (o instanceof RichSeparator) {
logger.debug("separator found. ingnoring...");
} else {
logger.info("Not Supported. Menu Item can only have: menu, menuItem, goMenuItem ot separator.");
}
}
logger.debug("NEW implementation returns: " + isDisabled);
return isDisabled;
}
It supports that the menu can have as its children:
° Sub menus
° menuItems
° goMenuItems

You can check other props also like visible and rendered prop.
I ll try to upload a full example when I ll get so time :(
Enjoy
Spido

Sunday, September 13, 2009

Accessing the ADF Client Interface in a JSF Backing Bean when Application is splitted.

And by "ADF Client Interface" I mean the ADF Model layer for UI clients or Application Module, View Objects , Entities etc...

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

Setting mem config is changed in the new WLS 10.3.1. and in the embedded WLS of JDevelper 11.1.1.1.1.0 (actually this is the same thing)

In the previous ver it was setted like this.

Now the only thing you need to do is to the add the following line in setDomainEnv.cmd file right after the comments in the begging:

set USER_MEM_ARGS=-Xms64m -Xmx1024m -XX:MaxPermSize=512m

(of course the above is one line!!)

The file is located in a different folder that the previous release of JDev:

C:\Documents and Settings\spido\Application Data\JDeveloper\system11.1.1.1.33.54.07\DefaultDomain\bin

that is windows user app data folder and of course instead of spido put your username.

Enjoy


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:

  1. commenting SET tags (current solution)
    pros: easy to implement, no low memory problem cons: no labels on page, cannot add/remove/change labels
  2. 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
  3. 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: = "#{adfBundle['com.mni.mednext.view.messages.frame_titles']}"/> -->

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.