Here I am user edwin which has the administrator role
Now I am the user scott which does not have Menu 2 and page 2 in Menu 1
This is the data model I used for this example.- Menu table is used for the menus in the menubar.
- Menu_items table is used for the menu items in the menu. the action column must match the control flow case in the unbounded taskflow.
- Roles table must match the roles used in ADF security
- Role_menu_items is a intersection table of roles and the menu items, so the bean can determine which menu items are used for the menu.
Every menu items in the dynamic menu must be a view in the unbounded task flow and has a control flow case. The name of the control flow case must match the action column in the menu_items tables.
Here you can see how my menu_items table looks like.
Here is the dynamic menu bean code
package nl.ordina.menu.backing;
import java.io.IOException;
import java.util.Iterator;
import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.MethodExpression;
import javax.el.ValueExpression;
import javax.faces.application.Application;
import javax.faces.component.UIComponent;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.PhaseEvent;
import javax.servlet.http.HttpServletResponse;
import nl.ordina.menu.model.dataaccess.MenuItemsViewImpl;
import nl.ordina.menu.model.dataaccess.MenuItemsViewRowImpl;
import nl.ordina.menu.model.services.MenuModuleImpl;
import oracle.adf.share.ADFContext;
import oracle.adf.view.rich.component.rich.RichMenu;
import oracle.adf.view.rich.component.rich.RichMenuBar;
import oracle.adf.view.rich.component.rich.nav.RichCommandMenuItem;
public class MenuBean {
private RichMenuBar initMenu;
public void createMenus(PhaseEvent phaseEvent) {
// check the menu is already added
boolean addMenu = true;
for (Iterator iterator = initMenu.getChildren().iterator(); iterator.hasNext();) {
UIComponent component = (UIComponent) iterator.next();
if ( component.getId().startsWith("menuId")){
addMenu = false;
}
}
if (addMenu) {
// get roles
String[] roles = ADFContext.getCurrent().getSecurityContext().getUserRoles();
// get application module
MenuModuleImpl menuAM = getAm();
MenuItemsViewImpl menuView =
(MenuItemsViewImpl)menuAM.getMenuItemsView();
menuView.executeQuery();
while (menuView.hasNext()) {
MenuItemsViewRowImpl menuItem = (MenuItemsViewRowImpl)menuView.next();
// check if the user has this role
boolean roleFound = false;
for (int i = 0 ; i < roles.length ; i++ ) {
if ( roles[i].equalsIgnoreCase(menuItem.getRoleName()) ){
roleFound = true;
}
}
if (roleFound) {
Boolean menuFound = false;
RichMenu menu = new RichMenu();
String menuId = "menuId" + menuItem.getMenuId().toString();
// check if the main menu is already added
for (Iterator iterator = initMenu.getChildren().iterator();
iterator.hasNext(); ) {
UIComponent component = (UIComponent)iterator.next();
if (component.getId().equalsIgnoreCase(menuId)) {
menuFound = true;
menu = (RichMenu)component;
}
}
if (!menuFound) {
// new main menu
RichMenu newMenu = new RichMenu();
newMenu.setId(menuId);
newMenu.setText(menuItem.getMenuName());
newMenu.setIcon(menuItem.getMenuIcon());
initMenu.getChildren().add(newMenu);
menu = newMenu;
}
Boolean menuItemFound = false;
String menuItemId = menuItem.getName();
// check if the menu item is already added
for (Iterator iterator = menu.getChildren().iterator();
iterator.hasNext(); ) {
UIComponent component = (UIComponent)iterator.next();
if (component.getId().equalsIgnoreCase(menuItemId)) {
menuItemFound = true;
}
}
if (!menuItemFound) {
RichCommandMenuItem richMenuItem = new RichCommandMenuItem();
richMenuItem.setId(menuItemId);
richMenuItem.setText(menuItem.getName());
richMenuItem.setActionExpression(getMethodExpression(menuItem.getAction()));
richMenuItem.setIcon(menuItem.getIcon());
menu.getChildren().add(richMenuItem);
}
}
}
menuView.remove();
}
}
public void setInitMenu(RichMenuBar initMenu) {
this.initMenu = initMenu;
}
public RichMenuBar getInitMenu() {
return initMenu;
}
private MethodExpression getMethodExpression(String name) {
Class[] argtypes = new Class[1];
argtypes[0] = ActionEvent.class;
FacesContext facesCtx = FacesContext.getCurrentInstance();
Application app = facesCtx.getApplication();
ExpressionFactory elFactory = app.getExpressionFactory();
ELContext elContext = facesCtx.getELContext();
return elFactory.createMethodExpression(elContext, name, null,
argtypes);
}
private MenuModuleImpl getAm() {
FacesContext fc = FacesContext.getCurrentInstance();
Application app = fc.getApplication();
ExpressionFactory elFactory = app.getExpressionFactory();
ELContext elContext = fc.getELContext();
ValueExpression valueExp =
elFactory.createValueExpression(elContext, "#{data.MenuModuleDataControl.dataProvider}",
Object.class);
return (MenuModuleImpl)valueExp.getValue(elContext);
}
public String doLogOut() throws IOException{
ExternalContext ectx = FacesContext.getCurrentInstance().getExternalContext();
HttpServletResponse response = (HttpServletResponse)ectx.getResponse();
FacesContext fctx = FacesContext.getCurrentInstance();
String currentPage = "/faces/about";// + fctx.getViewRoot().getViewId();
String url = ectx.getRequestContextPath()+"/adfAuthentication?logout=true&end_url=" + currentPage;
try {
response.sendRedirect(url);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
}
the next step is to create jsf template where we will add a menubar which binds the menu bean.
<?xml version='1.0' encoding='windows-1252'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
<jsp:directive.page contentType="text/html;charset=windows-1252"/>
<af:pageTemplateDef var="attrs">
<af:panelStretchLayout topHeight="49px">
<f:facet name="center">
<af:facetRef facetName="body"/>
</f:facet>
<f:facet name="top">
<af:panelGroupLayout layout="scroll"
xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
<af:facetRef facetName="menu"/>
<af:menuBar id="menu" binding="#{Menu.initMenu}">
<af:commandMenuItem text="Log off" action="#{Menu.doLogOut}"/>
</af:menuBar>
</af:panelGroupLayout>
</f:facet>
</af:panelStretchLayout>
<af:xmlContent>
<component xmlns="http://xmlns.oracle.com/adf/faces/rich/component">
<display-name>templateMenu</display-name>
<facet>
<facet-name>menu</facet-name>
</facet>
<facet>
<facet-name>body</facet-name>
</facet>
</component>
</af:xmlContent>
</af:pageTemplateDef>
</jsp:root>
Create a new view in the unbounded task flow and create a new jsf page based on the just created jsf template. Be sure to make a new control flow case from the wildcard control flow case to this view and give this control flow case a name.
<?xml version='1.0' encoding='windows-1252'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:af="http://xmlns.oracle.com/adf/faces/rich">
<jsp:directive.page contentType="text/html;charset=windows-1252"/>
<f:view beforePhase="#{Menu.createMenus}">
<af:document>
<af:form>
<af:pageTemplate viewId="/templates/templateMenu.jspx"
value="#{bindings.pageTemplateBinding}">
<f:facet name="menu"/>
<f:facet name="body">
<af:panelHeader text="Page 2"/>
</f:facet>
</af:pageTemplate>
</af:form>
</af:document>
</f:view>
</jsp:root>
Very important to add the createMenus method in the beforephase of the view component. Add this page to the menu items table and use the control flow case name in the action column.
The last step is to configure ADF Security ( the roles in ADf security must match the roles in the database ) and voila we are finished.
Here is the example project and the tables script.
I used the following users in this example. edwin ( password Welcome01 ) which has the administrator and user role. The second user is scott ( pasword Welcome01 ) which has the user role.








Now we can go the project explorer where we will create a new Project called TestDrive. 















Route the default case to the C drive business service and we are finished with the JMS proxy. Activate the project so we can test our services
Just add a message to the queue or launch the test console of the JMSproxy. 

