ODC Appreciation Day: Rapid Development Kit(s)

In 2016 Tim Hall had the great idea to introduce the ‘OTN Appreciation Day’ where bloggers should write a short blog about their favorite Oracle feature. This year’s name is ‘ODC Appreciation Day’ as Oracle rebranded the community to Oracle Developer Community.

As last year the question is which was or is the feature you like best?

Currently, there is a clear number one from my point of view:

Rapid Development Kit(s)

The Cloud User Experience Rapid Development Kit is available for a couple of years already, but with version V13 of the RDK we get a new look and feel representing the current SaaS Applications look. The RDK give developers and designers a tool to quickly design and program applications which are looking like Oracle’s SaaS Applications in the cloud.

There are currently two RDKs available, one for ADF (12c) and one for MAF (2.4.1). The design allows consistent design across devices:

Here is an image of a SaaS application build using the new RDK

But wait, an RDK for JET is in the pipeline. The OAUX Team presented the JET RDK before the OOW to selected partners and ACE Directors. It should be available in the near future.

And an image of a JET application build using the new JET RDK:

As you see there is almost no difference. You develop your application in and get the same look and feel regardless of the technology you use.

Finally, to round things up, Oracle provides an RDK for Conversational UI – or actually the first half of the RDK – the part that deals with designing the conversational UI.

Conversational UI for the enterprise adds to and maybe replaces the current Web&Mobile UI – for quick, simple, mini transaction and smart capture.

Conversational interfaces are initially most likely to be used for:

  • quick decisions, approvals, data submission (do)
  • get information (lookup),
  • conversation as starting point for a context-rich navigation to an application or component (go to)
  • provide recommendations and guidance to users (decision making).

The part about the actual implementation will follow with the launch of the Oracle Intelligent Bot Cloud Service.

References:

The Cloud User Experience Rapid Development Kit

Enhancements give OAUX team’s Cloud UX RDKs a jump on fast and innovative solutions

Oracle Intelligent Bots – Oracle Cloud

OAUX Conversational UI RDK

Advertisements

Train Stop Status Handling

A question on the Oracle Developers Community was about how to handle a train stops visited status.

Use Case

The use case behind this was that a train can be used as a workflow visualization. A normal user starts the train, but at one point a manager has to approve something. This approval is one or more stops on the same train. If the manager picks up the workflow he should automatically start with the approval stop. There is no need for him to see the data accumulated in the stops before.

The use case has multiple challenges:

  1. Securing train stops for different user roles
  2. Allow starting the train from any stop
  3. Handling the state of the train stops

The first two challenges are handler by All Aboard, 97. How-to defer train-stop navigation for custom form validation or other developer interaction, and 82. How to programmatically navigate ADF trains.

The missing part is how to handle the train stops ‘visited’ state (see image above). If you start the train directly with ‘Stop 3’ you get this state

UI

To implement this use case, we use a simple UI. It contains an input field, a button and the train which is added to the page as a region.

In the input field names label 1 you can enter the stop where the train should start. If no number is given, the train starts with the first stop. We use this input field to mimic the different starting stop for different users. This is the page when we start the application:

This is the page when we start the final application:

You can navigate between the train stops by using the ‘Back’ and ‘Next’ button, or by clicking the next stop in the train bar. As the stops are set to sequential, you can’t directly click on the 4th stop. You have to go through the stops 1 to 3 first.

Enter a number between 1 and 5 into the input field and tab out of the field will set the parameter for the train task flow and restart the task flow. The navigation is done via a router in the task flow. In the image below the stop number 3 is set as the starting stop for the train

And as you see the stops 1 and 2 are looking like they have visited before.

Implementation

To show how to implement this we start with a simple bounded task flow which builds the train

The start builds a router which we use to navigate to the stop where we want to start the train. The starting stop is passed as parameter to the task flow

In the router, which is marked as default activity, the parameter is used to execute the navigation

The Magic

If you look at the train stop properties in the properties inspector you’ll notice, that there is no property for the visited state

This option is not available in the UI. Oracle has missed or deliberately missed to make this property accessible via the properties. If you dig into the implementation of the train task flow (see the articles provided at the begin of the blog), you’ll see how to access the train and its stops by code:

ViewPortContext currentViewPortCtx = controllerContext.getCurrentViewPort();
TaskFlowContext taskFlowCtx = currentViewPortCtx.getTaskFlowContext();
TaskFlowTrainModel taskFlowTrainModel = taskFlowCtx.getTaskFlowTrainModel();
// get the stop from the map
TaskFlowTrainStopModel currentStop = taskFlowTrainModel.getCurrentStop();

The TaskFlowTrainStopModel doesn’t provide any access to the visited state. If you look at the class definition you’ll notice, that it’s only an interface

which doesn’t provide access to the visited property. Setting a breakpoint in the debugger we can inspect an instance of this interface

and we get the class implementing the interface as:

 oracle.adfinternal.controller.train.TrainStopModel

This class has the visited property we are looking for.

Solution

Now we can implement a method which we call before a train stop gets rendered and which sets the visited property of all previous stops to true.

CAUTION

THIS IN AN INTERNAL CLASS WHICH YOU SHOULD NOT USE!

However, it’s the class we need to get to the property. You have to understand, that the usage of the class has its risks, but that it’s not forbidden. The risk is that Oracle can change or delete the class without notifying you beforehand. So, in later versions, your code might break.

The method checks the task flow parameter if it’s null to set to a number less or equal to 0. In this case, the method returns an empty string. We do this check to avoid that the method does it’s work every time we navigate the train. It should be done only once when the train starts.

If the check finds a positive number, it sets the task flow parameter to zero (line 37).

It then gets the task flow information from the Context (lines 39-43). In line 50 we acquire the current stop before we loop over all previous stops and set their visited property to true (lines 53-59).

The missing part is how to call this method when a train stop is rendered. For this, we use a technique called Lazy Initalizing Beans. The trick is to use a hidden af:outputText and set e.g. the value property of the component to a bean property.

When the page or fragment is rendered, the method getInitStatus() in the bean is called. This is exactly the method shown above. We add this hidden af:outputText to each train stop before the af:train component.

Sample

You can download the sample from GitHub BlogTrainStopStatus. The sample is build using JDev 12.2.1.3 and doesn’t need a DB connection. You can use the same technique in other JDeveloper versions.