Friday 19 August 2011

OraFormsFaces 3.1.7 and what appears to be a Forms Parameter not passed through

Today I was so relieved when I discovered that the OraFormsFaces Forms Parameter which I've added on my JSF page, is indeed working as it should.

Let me depict the scenario:
I wanted to implement a simple JSF page loading a form via OraFormsFaces with the Forms Instance configured to use the crypto user with the cipher key as stated in the OraFormsFaces 3.1.7 development guide. Obviously, I also implemented a FormsCredentialProvider custom Java class to facilitate the cipher key, username & password (proxy login, of course). However, everytime the form loads I get a Forms error indicating that the Forms parameter was not set.
LATER ON I figured out that this Forms Parameter gets set based on a query which requires a Global Forms Parameter. So, I've changed the Forms Parameter on my JSF page to be a Global Forms Parameter, but still it gave me the same error.
THEN, I've noticed the "100"-sqlerror which forms part of the error and realised the SQL query which needs to set the actual Forms Parameter returns 0 rows. Hmmm...that had me thinking for a minute and it suddenly dawned on me; it must be the proxy user authenticating on behalf of the real user who does not have select privileges for the query to execute and return the expected resultset. So, I corrected that and then all was fine in OraFormsFaces JSF land! :-)

Thursday 11 August 2011

ADF Security : Logout action

ADF Security provides an Authentication Servlet with a logout method in order to invalidate the JAAS Session that was initialised on login. For completeness sake I've listed the java code you can use in your backing bean's action method in order to call this servlet method:
public String onLogout() {
    FacesContext facesCtx = FacesContext.getCurrentInstance();
    ExternalContext eCtx = facesCtx.getExternalContext();
    String url = eCtx.getRequestContextPath() +
        "/adfAuthentication?logout=true&end_url=/faces/index.jspx";
    try {
        eCtx.redirect(url);
    } catch(IOException e) {
        e.printStackTrace();
    }
    facesCtx.responseComplete();   
    return null;
}

Wednesday 10 August 2011

ADF Task Flows and the wildcard (*)-"To Activity ID"

Be careful when you use the wildcard (*) (or nothing for the from outcome or from action properties, for that matter) as ID for the "To Activity ID" to direct the flow back to a Router ADF Task Flow component. Due to the wildcard all activities/actions will be consumed by the Router component and hence only direct the flow as it is configured in the Router component's cases.

I had a case where an action, which originated from outside the page flow scope, did not actually get performed/handled by loading another task flow or page and I eventually figured that the router component consumes the action and makes it ineffective.

Tuesday 2 August 2011

JDeveloper 11.1.2.0 : Looking up a binding reference to inherited/referenced Application Module as Data Provider via the Data Control binding

The whole idea of getting an Application Module reference, programmatically, via the bindings by using the appropriate Data Control name is common practice in ADF. As we all know you do it like this:
DCBindingContainer dcBindingContainer = (DCBindingContainer) getBindingContainer();
DCDataControl dataControl = dcBindingContainer.findDataControl("DataControlName");
ApplicationModule appMod = (ApplicationModule) dataControl.getDataProvider();
// (where 'ApplicationModule' will be a specific ApplicationModule class of yours; i.e. 'CommonAM')
However, if you are trying to find a reference to a referenced/inherited Application Module via its Data Control before you've ever used any bindings on this Data Control, the programmatic approach will return a null reference.
The solution is to drag and drop any sub-element from the given Data Control onto a page of yours and that will ensure that the needed BC4J configuration for the use of the Data Control will be added to the file: "DataBindings.cpx" (of course you can delete the created component on your page afterwards)

Here's an example BC4J config:
<BC4JDataControl id="CommonAMDataControl" Package="com.common.model.am"
                     FactoryClass="oracle.adf.model.bc4j.DataControlFactoryImpl" SupportsTransactions="true"
                     SupportsFindMode="true" SupportsRangesize="true" SupportsResetState="true"
                     SupportsSortCollection="true" Configuration="CommonAMLocal" syncMode="Immediate"
                     xmlns="http://xmlns.oracle.com/adfm/datacontrol"/>


Once this BC4J configuration has been added...your java code will lookup the bindings successfully.