Saturday, July 30, 2011

Changing Skin Version using ADF Shared Library

Using Andrejus's blog about Deploying ADF Applications as Shared Libraries on WLS, I tried to make a shared skin library. I'll try to make this blog quick as Andrejus's blog already says it all.

The only thing I'm trying to figure out though, is how to make the main Running Application change or point to the new Library version without having the need to stop it.

To start with, I created a simple application which already utilizes shared taskflow libraries.

MainApplication - Default

Next I'll create a separate application which contains the CSS file as well as the Trinidad definition (trinidad-skins.xml). We need to create a separate project mainly so that we can deploy it as a shared library which requires it to be a WAR.

sharedDefault.css - Let's keep it simple and obvious, for testing anyway hehe.

Default Shared Skin Project

trinidad-skins.xml

MANIFEST.MF

Shared Skin Library - Deployment Profiles
I created a WAR for my shared library, and an ADF Jar for the application using it. Just a key thing needed for the WAR to work correctly as a shared library, you'll need to configure the MANIFEST as well as the ContextRoot.

WAR Context Root to Empty

MANIFEST.MF Included
So, after running our main application through JDeveloper, we'll get as expected our green screen.

Integrated Run
So that we can see what we could expect when things go wrong, let's try deploying our shared library and deploy our application as well as an EAR without configuring the library reference.

Filter the skin library as part of deployment files


Deployment in Weblogic Console

Here's our FAILED attempt #1.

Console Warning

Failed Attempt

So as you can see, worst thing that could happen is that your application will use simple skin because it can't find the skin you want.

So for this, what we're missing is the weblogic.xml entry for the library-ref. Let's add it now and re-run our page.

weblogic-xml
SUCCESS

Wednesday, July 20, 2011

Simple Implementation of AF SelectManyChoice being used in a clickToEdit Table

I'm making a quick blog for a not-so-obvious solution when using a SelectManyChoice. I complicated the scenario a little bit by using this component in a table.

The Adf SelectManyChoice uses List<String> as its value type. Unfortunately, this stops you from directly using it or binding it to a pageDef attribute bindings.

A solution for this is by using a BackingBean and take a handle on its getter and setter while resolving or pointing the value to-and-from the actual value holder.

In my example, I will present an attribute with attributeName "CODE" and this code value will be read by the selectManyChoice as well as modified. Also, I'm showing the "CODE" attribute as inputText so that I can present how the "read" part works.

First I prepare my selectManyChoice's options by utilizing a pageFlowBean. Oh, I also use this same mBean to hold my table rows.

TestPb.java (PageFlowScope)

Here's my pageFragment which utilizes the List<Map> as my data collection. Take note of my item's scope since I only want to initialize my items once (not that it matter in a prototype hehe).

testFgmt.jsff

Here's my backingBean which handles the manipulation for setting the code value on selection as well as the reading piece of it. (Really think there has to be a more optimized solution though, but oh well).

TestBb.java (BackingBeanScope)

Since we are setting the value and retrieving it using ValueExpression, we are able to evaluate the value at runtime.






Monday, July 4, 2011

ADF Auto-Redirect while still Passing URL Parameters (with ADF Security)

This blog is meant to share my findings in sending URL parameters in the case of a redirect. The main use-case for this setup is when I'm trying to launch a bounded taskflow which can be invoked via url. As you might have noticed, a bounded taskflow url is not really user friendly hehe, so what I did is that I have a page which can be defined in the contextRoot settings of your project and that page will have a pagePhaseListener to redirect the user to the bounded taskFlow. As an added test, I also turned on ADF security to test the same use-case.

I've created a bounded taskflow with a single input parameter and also configured for url invoke.

main-flow-index-xml

main-flow-index.xml (property)

MainFlowIndexPage.jspx

So with this URL:
http://localhost:7101/ParameterRetrieval/faces/adf.task-flow?adf.tfId=main-flow-index&adf.tfDoc=/WEB-INF/main-flow-index.xml&inputParam=myTestInputValue

We would get this page:


So, onward to the how-to redirect. For this I had to use a cool article by Andrejus regarding Security in Oracle ADF and Automatic Page Loading. So basically, we are going to make our own PagePhaseListener and as best practice dictates, we'll extend this object to a backing bean object which we will configure in our proxy's pageDef. So lets start.

TestPageRedirect.java

TestPageRedirect.java - Implemented object of the PagePhaseListener where we trigger our redirect at the PrepareModel phase.

TestBacking.java

TestBacking.java - Here's our backingBean object which extends our TestPageRedirect. We've already configured our onLoad to trigger our redirect which is based on F. Nimphius article on How-to efficiently redirect to an ADF Faces view using ADF Controller.

Next, we're going to configure our pageDef, well defined the backingBean in the taskflow as well.

adfc-config.xml

TestRedirect.jspx

TestRedirectPageDef.xml

TestRedirectPageDef.xml - configure the ControllerClass to point to our backingBean.

After all of that is setup, we can now run TestRedirect.jspx and this should redirect us to our bounded taskflow.

Launching:

http://localhost:7101/ParameterRetrieval/faces/TestRedirect.jspx?inputParam=12345

will take us now to our bounded taskflow.


Success! So as an additional, lets add ADF Security :)

Lets launch: http://localhost:7101/ParameterRetrieval/faces/TestRedirect.jspx?inputParam=myHelloWorld

LoginPage

Saturday, July 2, 2011

ADF Region Handled in a RichPopup - Including a Return Value

I used David Giammona's blog about:

So most of the code kind-of goes as what the blog does as well as what Fusion Dev Guide by F.Nimphius on launching a region within popup... or a popup with a region (forgot the topic title).

My project is setup to log on the following areas.
  • Region task flow entry - just so we know that the task flow has started.
  • On popup launch - this is the part that we handle the switch between an empty region to the actual region
  • On regionNavigationEvent - this is where we handle the programmatic handling of closing the popup. I used a java approach in closing the popup oppose to javascript which is published in paper. This is also the place where i handle the response. The reason for this is because a return from the region is tagged as a null viewId so it is the perfect trigger for me to check for the response which the region throws.
  • On popup close - as you probably already know, this is where i handle the switch to an empty region. Also this listener gets triggered on Cancel, Ok and Escape of the popup.
Anyway, i'll start posting codes.

mainFgmt.jsff

mainFgmt.jsff
As you can see, I'm directly using showPopupBehavior which means that the popup itself will be rendered directly at the same level as this page. So the popup and the view would pretty much have a handle on the scope which of course from the region, you shouldn't try to cross the scope. Later i'll explain more how I decided to handle the parameter passing without the use of contextualEvent.

adfPopupUtils.js

adfPopupUtils.js
Javascript file to handle the call to the serverListener.

FormContentPopupVb.java


FormContentPopupVb.java
This bean (viewScope) handles the dynamic region taskflowId. The switching of taskflowId to/from an empty region. Check for a response which I'll explain more.

FormContent TaskFlow (pageFragment)

formContentPopup.jsff
formContentPopup.jsff
This is the fragment as part of the task flow region that is used inside the af:popup. I have an actionListener which not only navigates for return but also configures the response.

ReturnHandlerBb.java

ReturnHandlerBb.java
This backing bean, as noted will look for the calling popup, search for the region that is directly contained with it (since this is the same region which will handle the regionNavigationEvent), and add an attribute to that component. Yes, there is a potential for this to blowup if the task flow is not used in a popup, but that is why the same utility to retrieve the popup will tell us if this taskflow is being rendered inside one. 

PopupUtil.java

PopupUtil.java
Utility class to retrieve the parent popup.

So as you can see based on the code, the flow of the setup goes like this.
  • Link is clicked which triggers ShowPopupBehavior
  • Popup receives the event and launches which triggers the fetchListener
  • FetchListener handles the configuring of the empty to taskflow to our actual taskflow region
  • Region hits an OK or Cancel and triggers the appropriate ActionListener
  • ActionListener looks for the parentPopup and from there, it retrieves the direct region below it.
  • Configure the RichRegion for an extra attribute which in this case we called "Notification".
  • Return is called by the taskFlow.
  • Region in the calling page triggers RegionNavigationHandler.
  • RegionNavigationHandler closes the popup and also check for the response from the taskflow.
  • OnPopup close, the clientScript is triggered which calls our serverListener.
  • ServerListener makes sure that the dynamic region is reset to an emptyTaskflow.
Cool!