Monday, January 27, 2014

Cancelling ADF Action from ActionListener

Sometimes we are faced with a requirement that requires the use of both action and action listener attributes of the command components of ADF.
 It seems that a lot of people advice to use the ActionListener to do some validation on the page level, then if it's okay let the code proceed with the code representing the business requirements in the Action.

but how are we supposed to stop the processing of the current event, so that the action is not invoked?
I will list three different code sample to achieve this.
1)using the setAction of the component:
if (some validation logic here) {
message("Valid");
Class[] parms = new Class[] { };
MethodBinding mb = FacesContext.getCurrentInstance().getApplication().createMethodBinding("#{ClassName.MethodName}", parms);
((RichCommandButton)actionEvent.getSource()).setAction(mb);
} else {
message("Invalid");
((RichCommandButton)actionEvent.getSource()).setAction(null);
}

Note: MethodBinding is a deprecated class, use the code in example 2.
2)using the setActionExpression of the component:
if (some validation logic here) {
message("Valid");
Class[] parms = new Class[] { ActionEvent.class };
FacesContext fctx1 = FacesContext.getCurrentInstance();
ELContext elctx = fctx1.getELContext();
Application app = fctx1.getApplication();
ExpressionFactory exprFactory = app.getExpressionFactory();
javax.el.MethodExpression expr = exprFactory.createMethodExpression(elctx, "#{ClassName.MethodName}", parms);
((RichCommandButton)actionEvent.getSource()).setActionExpression(expr);
} else {
message("Invalid");
((RichCommandButton)actionEvent.getSource()).setActionExpression(null);
}
3)or simply use the javax.faces.event.AbortProcessingException
if (some validation logic here) {
message("Valid");
} else {
message("Invalid");
throw new AbortProcessingException("Invalid");
} 
from the java doc:
public class AbortProcessingException
extends FacesException 
An exception that may be thrown by event listeners to terminate the processing of the current event.

Monday, January 6, 2014

J2EE security - multiple stores

description:
we had a requirement as the following:
1- user names, roles and role memberships are stored in LDAP server.
2- some role memberships are almost static and don's change.3- some role memberships can be changed any time at runtime.

since the customer policies regarding changes in the LDAP were pretty strict, any changes will take some time before they take effect, which will cause problems regarding point 3 above.
so, they requested that some role memberships are to be stored in the application database, so that they can be changed quickly through screens of the application.

solution:
in the security configuration of the weblogic, add two providers. One provider that will lookup  the roles from the database while the other will use the LDAP.

steps:
1- login in to the weblogic console and go to the security realms config screens

2-  click the providers tab, authentication sub-tab, click new button
3- insert any name you want, then choose the type, you can either choose sql or readonly sql authenticator
if you choose SqlAuthenticator, then you can use the weblogic console to edit the username, roles and memberships.
4- after adding the authenticator, you will notice that it's at the bottom of the table, now click reorder
we need to reorder to tell the weblogic to use this authenticator first, then go through the others.
4- after reordering, we are going to configure the authenticator
in the above picture, we will choose optional, which will instruct the weblogic to use this authenticator and if it succeeds then add the roles to the user session, then go through the other authenticators. and if it fails it will not prevent the users from logging in.


in the above picture, we will configure the provider type specific info,
use plain text for password, and give it the data source name, the one display in the weblogic console not the JNDI String, to use to access the database.
for the scripts needed to configure the default tables used be the sqlauthenticator, see https://community.oracle.com/message/10531498