Saturday, February 9, 2013

Assertions: Not so Used but yet so Powerful

Before I do something productive on a Saturday morning, might as well quickly blog about a not-so-commonly used feature in Java (well I practically don't see a lot of people using it that's all)... but they should!

Searching the net will give you tons of result about how to use Assertion so I'm not going to go through that, what I will demonstrate is the use of Assertion in JDeveloper.

I'm currently using JDeveloper 11.1.2.x but it should also work in any version of JDeveloper.

So quickly, let me show you a project specific configuration called Run Configuration. If you're coming from an Eclipse background, this should be one of your "must-know" setup but in JDeveloper, it's a not required setup when running your normal BC App or ADF View App.

Choose and Configure Run Configuraitons
What you'll need to know thought is that this configuration is project specific, in fact, by setting the Assertion command argument in a normal java project - and running it of course - you'll right away see assertions kicking in.

Assertion Argument
The part that kind'a sucks is turning it on in a running ADF View App... ok well it doesn't really suck but it wasn't straightforward to figure out.

Basically, when you're starting up your Weblogic Server (Integrate), part of the domain configuration startup includes a "-da" command which basically says that by default, all assertions are off.

So what does this mean, it means that even if you put "-ea" while booting up, the "-da" will cancel it out.

But this comes with a lot of pros because you don't really want everything to be asserted at that point. So just make sure that when you're asserting in a ViewController - do make sure to point the exact package structure to assert.

You should see something like this in your console on startup, in my case... I'm enabling assertion in all of my model classes (defined by: -ea:model...). Notice how I'm also highlighting the -da argument, you can see this in your setDomainEnv.cmd file - I don't recommend removing it though.


Starting WLS with line:
d:\Oracle\MW\11123~1.0\JDK160~1\bin\java -client   [MORE STUFF...] -ea:model... [MORE STUFF...]  -da [EVEN MORE STUFF...]
.....

IntegratedWebLogicServer startup time: 959 ms.
IntegratedWebLogicServer started.





Tuesday, December 25, 2012

Contextual Event - Interface based Consumer - NO DataControl Yey!

In my last blog, I showed how using an interface as a parameter will allow you to decouple your ADF beans even more.

A couple days before Christmas, somebody in EMG forums asked about ADF utilizing too many pageDefinition files. This led me to a link by Steve Muench's blog #164 - His example basically demonstrates how you can have a manage bean be defined as an instance method in your pageDefinition.

So this gave me the idea to upgrade my earlier blog to use this so that we will ultimately clean up the amount of files generated in our project.

I highly recommend to go through my previous blog since it involves showing the invocation and the initial use case of the listener interface. This time though, I'll be showing the handler interface.

First create an interface which our bean will implement. This interface will be defined by the requestScope bean which will represent the instance name of the pageDef. If you notice in Steve's blog, he pointed out how to use this method binding properly, the instance name has to use the $ notation for its EL Expression oppose to the normal # (I'm still looking for more resources to explain this) - just in case, this means you can't use ${requestScope.<Bean>} you have to call it ${<Bean>}.

Interface Handler

Uhm.. the request scope part is only because there is no point using a bigger scope for something that is only used as needed.

Request Bean

So here's the screenshots.

Event Mapping - pageDef
And just in case you're curious which lifecycle it lands, here's the console logger of the lifecycle.

Invoke Application Phase

Monday, December 10, 2012

Contextual Event - Interface based Consumer

It's no excuse to skip blogging all year but since it's not yet the end of the year, I still have enough time to post one last hoorah for 2012.

And to keep up with all the trend about contextual events, I've decided to publish an article in utilizing contextual events into an Observer Bean design pattern.

A bit of disclaimer here, I only came out with this idea while eating pizza and wondering why I can't publish a pizza order online and have any pizza company in the vicinity to cater it. All this happened an hour ago so I apologize for any small implementations I might miss... but I'll try to be brief and precise as always... moving on!

So, to start with - I'll assume that this is already the n-th time you've read contextual events. If not, I would recommend going through the online Oracle documentation, a couple blogs by some google'able ADF authors (F.Nimphius, A.Baranovskis, and etc.).

I do want to thank Jobinesh for pointing out a cool implementation in invoking contextual events. There are a couple of ways to invoke it, but I really like this one, particularly because it actually has a "contextualEvent" keyword in it. Why I like it? Well it's because of readability, and in the programmatic world - readability is key. Well good-code > readability > less-code.

I've setup a starting project that runs with a single entry point page (mainIndex.jspx).

mainIndex.jspx
The mainLayoutRegion is a simple bounded taskflow that has one fragment called mainFlowFgmt.jsff. This fragment will be our main fragment that wraps other regions as defined in the project structure. Please refer to the project structure as reference to the defined region.

BoundedTaskFlows: main-layout-flow, sub-flow-alpha, sub-flow-omega

mainFlowFgmt.jsff


Project Structure

If I run everything, things will basically look like this (Take Note, I've labeled where the region starts).

Running Sample
So here's the plan:

  • Wire up (queue the event) from the two buttons defined in Alpha. Both events will be unique so that we can test a couple scenarios. (Haven't got the chance to code the 2nd event but you'll get the gist of it soon)
  • Both events will have a unique eventName with a no parameter definition (meaning no-payload).
  • Calling this event mockEvent!
  • Listen for the event in mainFlowFragment.
  • Listen for the event in mainIndex page.
  • Listen for the event in Omega region.
  • Use a common handler for all of these BUT each of these fragments's backingBean will be the listener to a common event handler.
  • Let me repeat that last one... Handler (DataControl) one-is-to-many Listener (Beans). 
  • One more time... One datacontrol method... many backingBeans listening and being utilized by the same datacontrol method in different levels.
Here's a utility that invokes/queues the event to start the bubble of the contextualEvent. Again, code is thanks to Jobinesh.

Util.java
Going back to Alpha fragment. Here's the pageDef binding definition as well as the backingBean which invokes it.

Alpha pageDef - Contains the Event Declaration
AlphaBb.java

Here comes the fun part. I'll define a class to represent the datacontrol handler for the event but this class will cater a listener interface (Observer) so that whenever there is a listening pageDef (consumer) I will be able to define a/the oberserver (bean/method) which will handle the event. I'll also show in the code, a single backingBean handling two consuming definition from a single event (whoo!).

Quick ADF talk here: To be able to handle/consume an event, an event mapping has to be made. Part of the event mapping is to define the consumer as well as the method binding to handle the event. This method binding is defined by converting a class into a datacontrol (more in the developer guide).

Technically, the datacontrol (class) will still be the real listener, but because I want to allow the interface to start with the beans rather than the main listener - I am going to distribute the event with the observing beans.

What's the advantage?
  • Beans will be well defined in the xml of the event map.
  • Bean methods can provide the interface. 
  • So yes, you can actually point to use the pageFlowScope or any scope beans in that taskflow to handle it without touching the datacontrol again.
Less talk more code.

Interface Class - MockEventListener.java

DataControl Class - MockEventHandler.java

And here's a sample mapping to my mainLayoutBb.

Event Mapping pageDef - Double Consumer Same Bean!!! Notice the value.

Two Anonymous Implementation of listening!

So far is it making sense? If not consider the Observable pattern in java and see if it explains the idea. To expand it a bit, we'll make the MainIndex.jspx have it's own backing bean and use the same datacontrol.

MainIndexBb.java (defined in adfc-config)

mainIndex.jspx PageDefinition

Here's the console output when I hit the event - I'm also printing the lifecycle so that you can see that the invocation is all happening in InvokeApplication phase. It is worth noting though that the order of the events can vary a bit. I'm still trying to figure it out myself - but then again it shouldn't matter because you shouldn't rely on the order of the queued events. All the events should be nothing but observing factors.

console
So real quick, I've show you how to use/define one datacontrol to cater several listening interfaces. This is basically an application of the observable pattern in a contextual event framework. Things to keep in mind is that all of these is happening in one request - so ideally you wouldn't want to place too much logic when listening to events because it can get really complicated really fast. You would also want to keep a solid event handler that you'll rarely change that's why keeping it interfaced is always a plus.

Saturday, May 12, 2012

Task to Refresh a Task Flow

First 2012 post I guess? Due to some really really busy time in the office, I have to apologize for not being able to blog for quite some time.

With that said, I recently notice how a lot of developers tries to play it safe when using Task Flows by sticking with the obvious. So, to start my 2012 blog, I am going to clear out one item in the bucket list of task-flow-bewilderness.

Task Flow Refresh

So the most obvious way of refreshing a task flow is based on the initial design which is:

"When there is a change in the data, the task flow needs to refresh."

Simple definition of terms.
Refresh - Restarts the task flow as if the entire flow was reentered from the start. That seems explanatory but trust me, such a word strives to be confusing at times.
TaskFlow Binding (TFB) - Page definition ADF task flow bindings.
TaskFlow == or === (in javascript) Task Flow - enough said.

Moving on.

The simplest solution for the above "dilemma" is to use the TFB's properties refresh=ifNeeded and simply feed the taskFlow parameters with the changing data.

As per ADF 11.1.2.1.0 Fusion Middleware Documentation - 21.5.1 How to Configure the Refresh of an ADF Region .... well let's just test it shall we.

#1. Reconfig - Does nothing but hits an ActionEvent
#2. Reconfig-Refresh - Hits the ActionEvent but also changes a viewScope parameter
#3. Reconfig-Refresh-Again - Same as #2 with different value.

ToolBar Buttons

Initial Run
MainPage - Containing Region - PageDef

So yes everyone already knows what's going to happen. Since the variable is an input parameter, combined with refresh=ifNeeded then it will DEFINITELY restart the task flow.

So let's complicated things a bit by looking at it in a different requirement.

"When the data changes, not by something direct in the screen but rather as triggers in the data themselves, the task flow needs to refresh."

With that said, data is not the trigger, but the event is the trigger.

Ironically, I got a suggestion where all they'll do is do exactly what I previously explained earlier (with the refresh=ifNeeded) and simply send an Integer which increments on eventChange. Might fly... but let's try to find a more logical solution.

Which goes back to the ADF 11.1.2.1.0 Fusion Middleware Documentation - 21.5.1 How to Configure the Refresh of an ADF Region.

Let's use the refreshCondition this time. The only thing with the refreshCondition that you need to be aware of, is that you would probably want to contain the implementation with its own bean handler/manager rather than mixing it with simply any available beans.

So here goes with the simple demo.

I'm still going to use the above mainFragment while simply using the boolean flag, and here's the new pageDef.

RefreshCondition Used
A boolean flag? In a backingBeanScope? Yes a boolean flag and yes in the short lived scoped. I initially tried it in a viewScope but with the simple way of changing a flag from true to false, why not go with something even more "compact". So here's the bean.

BackingBean - Handles Simple Refresh Condition

So what do we have here.. Bean does nothing but handles the refreshCondition of the taskFlow by always returning FALSE and only, ONLY TRUE once something tried to change it.

Since I have no better way of explaining this visually, I'll print the console of what we have. So what do we have, we have  a simple task flow with a finalizer and initializer and also an initial method call as entry point. Enough?

TaskFlow BackingBean

Simple TaskFlow Fragment
Here are the logs when doing anything but refresh:


----- DEBUG: Initializer Firing
----- DEBUG: Initial Task Flow Method Call
----- DEBUG: testReConfig -- This is the ToolBar ActionEvent
----- DEBUG: Checking isRefrehRegion[false]

And here's the log when I triggered the refresh:

----- DEBUG: Initializer Firing
----- DEBUG: Initial Task Flow Method Call
----- DEBUG: testReConfig -- This is the ToolBar ActionEvent
----- DEBUG: Checking isRefrehRegion[true]
----- DEBUG: Reconfiguring
----- DEBUG: Finalizer Firing
----- DEBUG: Initializer Firing
----- DEBUG: Initial Task Flow Method Call

There goes a technical 2012 blog!

Sunday, October 30, 2011

Common Multi-Configuration Question Popup

While this might not be the most common use-case, but it is still quite interesting and the month is about to end - so I gotta post something cool for a change right? Hehehe.

Let's say you are in a complex editable form where after clicking the big Save/Confirm button, you would like to ask some follow up questions to the user.
  • Do you want to apply changes?
  • Are you sure?
  • Choosing OK will change X data.
Along with these questions, there are even scenarios (rare) where you need to ask questions next to each other.

Because of these scenarios, I designed a simple demo in the power of ADF declarative components. (note: if there is a design flaw in my implementation as well as class handling, I wouldn't mind suggestions or feedback on it. Feedback is highly encouraged "woooot".

Oh, before I forget, a small constraint that I had to go through is having the button (SAVE/CONFIRM) which triggers the launching of popup will be coming from the the consuming project. So what does this mean? This basically means that the caller or the starting event to launch this question popup will not be part of the component itself. The reason behind this is because the Popup Question might be used by not just a button. It might be a link, a selection event or can even be as simple as a client/server event. So because of this constraint, I had to leave the trigger to be outside of the bean and the component itself will just offer hooks, lots of them if needed.

Starting with our declarative model, let's design an iterator based set of questions where each question has the possibility of having 3 types of answers.

CustomDialog.jspx
A quick explanation of the output:
  • Display All questions as left aligned
  • Display Confirm/Reject response on the right side
The component bean for this component is as follows.

CustomDialog.java
The only implementation this bean directly calls is the reset, which is called on every popupLaunch, and the onConfirm, which is called during the confirmation.

Next come the bread and butter which gets this thing going. DialogItems.java contains all the accessors needed for the generation of the dynamic question/answers. The main thing to note down for this bean is the abstract methods which will make sure that the consumer will have to code those implementation for handling the questions as well as answers where events starts to manipulate.

DialogItems.java
Let's start with playing with this starting with our fragment.

testFgmt.jsff
test-flow.xml
Take note how I kept the items in the pageFlow scope, for longer life in its context.

TesterBb.java

The launch method in this class is the entry point of calling the component.

SampleItemsPb.java
All the hooks are implemented here.

  • initializeItems - This is where I insert question data
  • onConfirm - I check for at least one affirmative answer before I return a yey' to the super class
  • configureAnswer - Just an extra hook before setting the values (think of it as setAttributeInternal :) )
  • resetItems - I directly set the answers back on their initial state which is unanswered.

So let's start putting it to the test.




Kudos to declarative components.

Sunday, October 9, 2011

Remote Task Flow as a List-of-Values (LOV) Selection Dialog

Terms:
Remote Task Flow = RTF

I'd like to share a small demo in using a remote task flow configuration to be used as my list-of-input-values. Along with this demo, I'll present it while taking templates as well as a generic wrapper task flow. The generic wrapper task flow is only needed to allow us to directly expose the RTF to be configured as a NON-Page Fragment task flow. More explanations later on.

RTF is a pretty cool ADF feature which is presented in one of ADF Code Corner's presentation:

#43 How-to integrate remote task flows in your ADF applications (POJO DC Example)


So to start with, let me create my template project with my URL LOV Task Flow template as well as my wrapper task flow. Ow, also there is my LOV Page Template.

PageLovTemplateDef.jspx

url-lov-util.xml - I'd like to point out how I'm transferring the return parameters of the RTF to the wrapper's pageFlowScope.


url-lov-util.xml - InputParameters
url-lov activity's task flow configuration. Take note, this part is exactly what the code corner article will teach you :)


Here's my project structure for the LOV Dialogs. Only thing you definitely need for this project is the template project (mentioned above). For my sample, I'll be creating two kinds of LOV, Locations and Departments, care of HR Schema.


TaskFlow design for both are pretty much the same so I'll just describe the Department scenario.

url-lov-departments.xml
DepartmentsView.jspx
UrlLovBb.java
DepartmentsLovBb.java

Couple notes to explain the functionality. The base class simply enforces a signature as well as a utility to directly throw parameters to the PageFlowScope starting with suffix "A". The taskflow is based on the taskflow template thus consuming taskflow would already expect the output parameters. (which really is the wrapper taskflow anyway). Besides that, everything else is still quite in the realm of adf :)

Next step is the consuming page as well as the usage of the wrapper taskflow.

Consuming Project
main-index.xml - departmentsLov activity parameters
mainIndexFgmt

Let's go for testing already!




And here's Location:



And that's the beginning of October.