About Timo Hahn

I'm a principal consultant at virtual7 GmbH and work as developer and architect for Java and J2EE applications. Since 2004 I'm working with Oracle tools, starting with JDeveloper on Struts based web application using BC4J JBO Tags, BC4J business components and Oracle DB 10g up to JDeveloper 11.1.2 using ADF Rich Faces and the full ADF technology stack and web services. I'm an active member of hte OTN JDeveloper forum and blog on Oracle, JSF and ADF in special (https://tompeez.wordpress.com). I'm active participant in the local German ADF Community (a group of Oracle partners that strive for improving ADF and FMW sales in Germany and other German speaking countries).

JDev 12.2.1.3: Creating a shared skin jar (Part 2)

In part 1 or the series we created a simple skin, built an ADF-Library from it and tried to reuse it by deploying it to a WebLogic Server. This approach failed. In this part, we try another option to share a jar with

Sharing the skin with other applications

To share the skin with other application we can

  1. Create an ADF Library
    1. Add this library to the other application
    2. Add this library as a shared library to a WebLogic Server
  2. Create a normal jar
    1. Add this library to the other application
    2. Add this library as a shared library to a WebLogic Server

For this blog the way we want to use if 2b. This allows to create the skin once, deploy it to a server and use it in every other application. In the next paragraph, we try out option 1a to show the problems when reading resources from a jar file.

Using a shared skin

Option 2b

Here we create a jar file containing the skin and additional resources like images and deploy it directly to a WebLogic Server as a shared library. The advantage is, that other applications can use the skin and other resources directly and that the jar can be versioned to allow different versions of the same jar on the server.

Option 1a which we discussed in the previous chapter doesn’t work for images. However, the documentation ‘Deploying a Custom Skin File in a JAR File’ and Frank Nimphius pointed it out in e.g. 86. Reading boilerplate images and icons from a JAR or How-to share skin definition files across applications how the jar file must be structured to allow the resource servlet to read the resources. The essential sentence is

‘All image resources and CSS files must also be under the META-INF directory.’

In his article, Frank suggested using the command line jar tool to create the jar. I show how to use JDev to create the jar with the needed structure and how to deploy it to a server as a shared library.

A sample application is used to use the skin and to show an image load from the jar.

The building plan for a skin in a shared Library which can be deployed to a WebLogic server is given in the article as:

To implement the shared library approach, developers need to change their existing skin definition so it can be deployed in a JAR file. The steps for this include

– Creating a META-INF directory – Creating a trinidad-skins.xml file that defines the skins deployed with the JAR file

– Creating an META-INF/adf sub directory for images and icons served from the JAR file

– Changing the image reference in the CSS to include the “adf” directory, which makes sure images and icons are handled by the ADF Faces resource loader, which can read resources from JAR files

– JAR the META-INF directory to create the library file

Looking at the current project for the skin we see a different layout

In the article Frank instructed to create the needed folders yourself and copying or moving the files to the new structure, then to use the command line to build a jar from the structure.

I’ll show how this can be done with a special deployment descriptor from within the project. The image below shows the needed layout of the final jar file.

To transform the folder structure present in JDev to the needed structure of the final jar, we create a new deployment descriptor in JDev

In image 4 we see the first part of the solution: here we set the path inside the jar to ‘MEAT-INF’. This will guarantee the structure we need. Then we add another contributor to the list (public_html) to get everything we need into this folder. Then we use the ‘Filters’ node to select all content we need skin part

Next part is to create another path in the jar for the metadata of the skin

We add another file group for the resources

Now we can deploy the jar using the new deployment descriptor

And the jar file is created in the deploy folder. It holds all files in the right folders

Finally, we can deploy this jar to the WebLogicServer. In this case, I use the integrated WLS, but it can be any stand-alone WLS too.

The error message you see on the 7th image can be ignored. It only tells you that the library can’t be deployed as an application but only as a shared library. This is exactly what we want to do 🙂

Now the jar file is deployed on the WLS as a shared library and can be used for every application on this server.

We use the existing application from part one to consume the jar skin from the shared library and show the images deployed with the jar.

Before we go any further, we have to remove the ADF Library we added to show the problem from the project. For this open the project properties and select the ‘Library/Classpath’ node and remove the ‘ADFLibrary’ entry

The page should now look like no skin is used at all.

As we already added a skin (with the ADF Library) we don’t have to do this again. However, we have to add a library reference to configure the application to use the shared library deployed on the server. For this, we open the application descriptors and edit the ‘weblogic-application.xml’ file by double clicking the entry in the application resources section

In the ‘Shared Library Reference’ section, we add a reference to the now deployed shared jar ‘blogsharedskin’

Saving everything we don’t see any change to the page design, as the library isn’t part of the application yet. Starting the application we get

Just what we liked to see. The images are visible, checking the page with Chrome’s Dev Tools shows that the images are correctly loaded

This proves that the shared library with the skin and the images are working correctly.

To make the skin visible in JDev during development, we can add the jar we developed to the server a library. We create a library

and make sure the ‘Deploy by default’ is NOT set. Adding the library to the project

will make the skin visible in design mode

The unset checkmark prevents the jar from being packed into the WAR or EAR file. It’s just used in the IDE. That you can’t see the images is normal as there is no full server to serve the images to the design view.

Summary

In this mini-series, I showed the problem when creating a skin as ADF Library and trying to share it on a Weblogic Server. Then I showed how to create a deployment descriptor for the skin and other resources and how to deploy the resulting jar to a WebLogic Server.

The sample application can be downloaded from BlogSharedSkin. The sample was created by using JDev 12.2.1.3 but the same technique can be used in any 12.2.1.x JDev version. There is no database connection needed.

Advertisements

JDev 12.2.1.3: Creating a shared skin jar (Part 1)

In earlier versions of JDev, skins have been created either by pure code or by using the free Skin Editor. However, since JDev 12.2.1.x the skin editor has been integrated into JDeveloper itself.

A couple of questions in the ODC JDeveloper space are about how to create a skin with JDev which can be deployed as a shared library to a WebLogic Server. I gave this a try and it turned out, that you can build an ADF library jar from a skin project but you can’t use images to this jar which you might want to use in the application.

In this blog, I’ll show how to create a skin with resources like images and how to build a jar file from the skin together with the images and deploy it aa s shared jar to a WeblogicServer.

Building a skin project

The first part is to build a small skin project. The project we use to create a minimal skin, just to show that the skin is changing something. Then we add some images to the skin which we want to use in the application which uses the skin. Such images can e.g. used on an af:button component.

We start by creating a new application as an ‘ADF Fusion Web Application’

As we don’t need the created model project we delete it completely

If you get another dialog, telling you that you can’t undo the action, answer ‘Yes’ to delete the project. Now you should see a workspace with just the one project:

Know that we have a project we add a skin and e.g. add some skin selectors to change to the color of the button text. For this, we right click the ‘Web Content’ folder in the project and select ‘New from Garaly’ and then select ‘ADF Skin’ from the ‘JSF/Facelets’ node and fill in the basic information:

This will create the needed css file and the descriptors which define our skin (trinidad-config.xml and trinidad-skins.xml).

We open the sharedskin.css file if it’s not open already and switch to source mode. Here we add two simple skin selectors

which are changing the color of the text of a button and a link. You can add more sophisticated selectors but for this blog, it’s enough to show the working skin. To make it more interesting, and because that’s the real reason for this blog, we add some images to the skin which we like to use in the application using the skin. We add the images into a new folder like shown below

The reason for this structure is, that to read the images from the jar in the consuming application, we need a special resource loader. In case of ADF it’s the resource servlet which listens to the URL pattern ‘/adf/’’. This servlet is installed automatically for ADF Web Applications and is configured in the web.xml file

The final task for the skin project is to create a jar file which we can use in other applications. The easiest way to get such a jar is to create an ADF Library deployment descriptor. Open the project properties of the skin project and select the ‘Deployment’ node

And click the ‘New Profile’ icon, select to create an ADF Library Jar

and click ‘OK’. The remaining dialogs you can just click ‘OK’ or ‘Finish’.

To create the library we have to execute the descriptor by right-clicking on the project and selecting ‘Deploy’ and choosing the ‘sharedskinadflib’

This will create the jar in the ‘deploy’ folder of the project.

Sharing the skin with other applications

To share the skin with other application we can

  1. Create an ADF Library
    1. Add this library to the other application
    2. Add this library as a shared library to a WebLogic Server
  2. Create a normal jar
    1. Add this library to the other application
    2. Add this library as a shared library to a WebLogic Server

For this blog, we want to use option 2b. This allows to create the skin once, deploy it to a server and use it in every other application. In the next paragraph, we try out option 1a to show the problems when reading resources from a jar file.

Using a shared skin

Option 1a

We start with option 1a, just to show the problem when we try to read a resource from a jar. We build another ADF Fusion Web application and add the skin as ADF library from a ‘File System Connection’ which we create and let it point to the ‘deploy’ folder

Right-click on the ‘sharedskinadflib’ and add it to the new sample project. This will make the skin available to the application. To use the skin we have to add a skin to the application like we did to create the skin project. The difference is that we now choose the shared skin as the base skin

Creating a new page and adding a button and/or a link to the page we see the new style introduced by the ‘sharedskin’

So, the shared skin is working. Well, yes, but what about the images we added to the ‘sharedskin’?

Let’s try to add one to the button. In the property editor, we select the icon property of the button and click ‘Edit’ to get

However, we don’t see any image in the whole project. As we know where we put the images (or we can look into the sharedskinadflib) we can just add the path to the image like ‘skins/sharedskin/adf/images/home.png’ and we see the image

Running the application we get the page with the button but don’t see the image

Using DeveloperTools we see that the resource couldn’t be found. Inspecting the button element we see

The path to the image is not found 😦

If we change the address of the image to ‘/adf/images/home.png’ to use the resource servlet we still get an error

The reason is that the resource servlet expects the resources in a different path inside the jar. Every resource which should be read from a jar should be in a folder named ‘META-INF’.

The ADF library did not put the images into the META-INF folder

The problem is that we can’t change the layout of the ADF Library. When you create an ADF Library there is no option to make any changes to the content of the jar.

The conclusion is that using a skin in an ADF Library is problematic if there are other resources which you need to share.

To be continued…

In the final part 2 of the series, we see how the skin can be shared with other applications.

JDev 12c: Badge Button reloaded

In my article JDev: Badge Button I showed how to build a special button with a notification ‘badge’:

The declarative component of this sample was build using JDev 11g (11.1.1.9.0 to be exact).

I received a couple of question on how to work with this declarative component in JDev 12c projects. In general, you can use the same source and build the declarative component in JDev 12c. However, as JDev 12c is using a different document type, Facelets instead of JSP XML, you can use the badge button only on JSPX type pages.

So, in this blog, I show how to create a declarative component which is usable in Facelets type pages. I don’t change the behavior of the badge button but reuse the code. This blog is more about how to create a declarative component in 12c and show the differences to 11g.

JSPX vs. Facelets

With the introduction of JSF 2.0 (JavaServer Faces 2.0 Overview and Adoption Roadmap in Oracle ADF Faces and Oracle JDeveloper 11g) a new document type Facelets was introduced. The difference and the motivation behind this is outlined in the document.

We are only interested in the fact that you can’t mix components designed for JSPX XML pages or fragments with Facelets type pages or fragments. This means that you can’t add the badge button created for 11g to a jsf page of jsff fragment of type ‘Facelet’.

Building a Declarative Component for 12c

We start from the old application workspace I created for the 11g implementation. Opening this workspace will migrate it to the 12c. At the end of the blog, you’ll find a link to download the final workspace for 12c.

After the migration we add a new project ‘BBB12cDeclarativeComponent’ of type ‘ADF ViewController Project’ to the workspace:

After creating a new project for the 12c badge button, we create a new ‘Declarative Component’ in the ‘Web Content’ folder

In the wizard, we now select ‘Facelets’ as the document type. Selecting ‘Facelets’ will create the 12c kind of declarative component.

Once we finished the wizard, we get the skeleton declarative component in the ‘BadgeButton12c.jsf’ file. If you got a file name ‘BadgeButton.jspx’ you did not set the document type to ‘Facelets’.

Now we can copy the code from the original sample written for 11g and copy it after the componentDef tag. Once you copied the code from the original sample you have to change the EL used to address the action and the actionListener to match the componentVar property in the componentDef tag. To make this distinguishable from the 11g sample, I changed the componentVar to ‘compButton’. The other change is to use an af:button tag instead of the af:commandButton tag. While the af:commandButton tag can still be used, 12c application should use the af:button tag.

 

The final code looks like

Adding the declarative component to the faces palette

You already know, that to use the declarative component in a project, you first have to add it to the component palette. The difference to the 11g sample is that we have to choose a different node in the project definition to add the library.

First, we need to deploy the declarative component project to an ADF Library. For this, all we need to do is to execute the deployment profile created with the project

Next, we add a ‘File System’ resource which points to the folder the jar is created in

And the jar should show up

To make it usable in the view controller project, we have to add the jar to the project

Now, when we look into the view controller projects properties, we find the new declarative component in the ‘Facelets Tags Libraries’ node. In JDev 11g the tab libraries can be found in the node ‘JSP Tag Libraries’. Again, the difference is where the tags or declarative component are usable. You use JSP tags in JSP XML files and you use Facelets tags in JSF files.

Next step is to create a new JSF Page in the adfc-config.xml, the unbounded task flow.

Again, we make sure to select ‘Facelets’ as document type as we otherwise will not be able to use the declarative component created for ‘Facelets’.

The layout of the page is similar to the one for 11g. 12c uses a panelGridLayout instead of the panelStretchLayout, but that’s all.

As we are now using a JSF page and added the 12c component library and find the BadgeButton in the component palette

and use this on the page. The final layout looks like

Or when running the JSF page

Clicking the button we get the log messages

Sample Application

You can download the sample application from GitHub BlogBadgeButton12.2.1.2

Problems running JDeveloper 12c

In the last couple of weeks, I get more and more reports of problems running JDeveloper 12.2.1.x. (to be exact 12.2.1.1.0, 12.2.1.2.0 and 12.2.1.3.0)

The problems reported are

  • properties editor not working
  • JDeveloper hangs during start
  • showing wireframe instead of page design
  • problems to configure the JDBC connection
  • problems compiling expression on attributes (not 100% verified that this is JDK problem)
  • problems migrating projects created with earlier versions of JDeveloper
  • problems with the groovy script engine
  • deadlocks within JDeveloper when editing multiple java files

to name some. The problems are not ADF related but IDE related. It turned out that they only could be reproduced if the used JDK to run JDeveloper on was newer than JDK 1.8.0_101. All problems are not reproducible when running JDeveloper with JDK 1.8.0_101.

Currently, there is a bug pending (Bug 26766333) with support.oracle.com for some but not all mentioned issues. At the moment of writing this, there is no patch available.

My recommendation is to install JDK 1.8.0_101 and run JDeveloper using this JDK. You can do this by

  1. installing JDK 1.8.0_101 on your machine. The download for this old version is hard to find in the WWW. To make it easier, you can find it on this page: Java SE 8 Archive Downloads
  2. change the product.conf file you’ll find in your .jdeveloper folder inside your home folder. Open the file and set the SetJavaHome property
  3. to be on the safe side, you can recreate the integrated WLS to make it use JDK 1.8.0_101 too. If you know our way in the jungle of script files which are used to start the embedded WLS, you can change those files directly. As there typically are not many changes made on the integrated WLS, I find it easier to delete the integrated WLS and create it again. It’ll pick up the JDK JDeveloper is running on automatically and use it to run the WLS too.

You don’t need to update or change the JDK your standalone server is running on. To my knowledge, the problems are only IDE related, so they don’t affect the running application.

If you find a problem, which is related to using a JDK newer than 1.8.0_101, feel free to leave a comment on this post. I’ll add them to the list for reference.

JDeveloper: Info about the clicked cell in an af:table

JDeveloper allows to easily create tables with the af:table component. The table allows easy access to the selected row or rows. However, if you are interested in which cell of a table has been clicked, ADF needs some tweaking. This blog is about how to tweak an af:table to get exactly this info.

Use Case

You like to know which cell in an af:table a user has clicked, e.g. to get some detailed information about the clicked item or cell in the selected row. The sample I show get the information about the current row, and column of the cell and the value of the cell clicked. The final sample will show the info like

How to do it?

The normal af:table component doesn’t give information about the cell a user has clicked on. The ADF pivot table offers this but is complex to use.

We use JavaScript in form of a clientListener to intercept the click on a cell and a serverListener to call a bean method to get more data on the cell. This article 011. ADF Faces RC – How-to use the Client and Server Listener Component shows how to use clientListener and serverListener in detail.

As we are interested in the selected cell, we add a clientListerer to each af:outputText which shows the column value in the af:table which fires on the click event. The clientListener calls a JavaScript method. In the JavaScript method, we build a payload of the UIComponent which is used to show the column value and the column name of the cell. To get this information we have several possible ways:

  1. We can use our knowledge of the DOM tree and get the column via the parent of the component which fired the event. The parent component should be the af:column.
  2. We add a client attribute to the component which shows the cell value adding the column name from the af:column as EL

In this sample, we choose the second solution. With this information, we call the serverListener from the JavaScript method. The serverListener method is implemented in a request scope bean and uses the information passed to get the details about the clicked cell we show in the UI.

Implementation

The sample uses the HR DB schema and only needs one table, Employees in this case. We create a simple page with the table in read-only mode, sortable and filterable. As you see in the image above the table is just build be dragging the Employees VO onto the page and drop it as a read-only table.

Now we add a clientListener and a serverListener to each outputText component which is used to show the cell value

In the image above we see the listener for two columns. In addition, we add an af:clientAttribute with the name ‘columnName’ which we pass the EL of the af:column headerText property.

Next, we add an af:resource component to the af:document where we specify the JavaScript for the clientListener method ‘clientCellSelectionCall’. We use a JavaScript file to code the method. We could have added the method to the page directly, but if we want to reuse the pattern, it’s better to use a JavaScript file

The file is located in the public_html folder (Web Content) in a subdirectory ‘javascript’

The method code is

The click event on the af:outputText component triggers a call to the javascript method ‘clientCellSelectionCall’ (via the clientListener) with the source of the event, the af:outputText component. The method reads the clientAttribute added (line 3) and calls the serverListener of type ‘cellSelection’. This event is defined by the af:serverListener on the af:outputText. The component which triggered the event and the column name added as client attribute are passed to the serverListener.

The serverListener is a bean method defined in a request scope bean on the af:outputText component as

method="#{TableCellSelectionBean.handleTableCellSelection}"

In the bean, the method looks like

public void handleTableCellSelection(ClientEvent event) {
  // get payload which is the ui component which fired the event
  UIComponent ui = (UIComponent)event.getParameters().get("payload");
  // get the column from the event which is sent too
  String column = (String)event.getParameters().get("column");
  RichOutputText rt = (RichOutputText)ui;
  // get current row key
  DCBindingContainer bindingContainer = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
  DCIteratorBinding binding = bindingContainer.findIteratorBinding("EmployeesViewIterator");
  Row currentRow = binding.getCurrentRow();
  Key key = currentRow.getKey();
  // compile info about clicked cell
  String out = "Payload:" + ui + "
  column: "+ column + "
  val: " + rt.getValue() + "
  key: "+key.toString();
  logger.info(out);
  setCellInfo(out);
}

Here we get the component which triggered the event (as payload) and the name of the column. Using this information we can get e.g. to the value of the column (via the UI component). The row of the cell we get via the current row of the iterator. With this information, we get the key of the row. We can get much more information here, like historical data about the current employee’s salary, if the salary cell was clicked.

We just create a string from the information which we show in the UI to the user

Here are some images of different cells clicked in the UI:

Download

You can download the sample, which was built using JDeveloper 11.1.1.9, from GitHub BlogTableCellSelection. The sample uses the HR DB schema.

JDeveloper: Skin Radio Buttons

In this blog article, I like to share how to use a skin to alter the look of radio buttons in ADF. The use case was a question on the ODC space JDeveloper & ADF which asked about how to provide more space for the radio buttons.

Here is an image of the default and the resulting radio buttons:

As you see, in the first radio group the space between the selectItems is narrower than in the second group.

In my older post about JDeveloper: Advanced Skin Technique I showed how to find out which style to change, so I spare this here.

The image above shows the standard “radiogroup” in Chrome Developer Tools. As you can see the radiogroup consists of “div” elements, each specifying one of the selectItem.

To change the spacing, we add a style class to the skin file like

.mysor af|selectOneRadio::content div {
  padding: 0px 0px 10px 0px;
}

The “.mysor” is the name of the style class which we later use on the page. The magic is done by specifying the base style as af|selectOneRadio::content and from there style each “div” element having the base style as a parent. This way we style the blue marked div in the image above.

One question remains. Why do we use a skin and don’t add the code right into the page?

Well, using a skin is the preferred method. The skin is created once and can be used everywhere in the application. If you need to make changes, you don’t have to search for the pages where the style has been added, but you just change the skin file and you are done.

Download Sample

You can download the sample which is build using JDev 12.2.1.2.0 and uses the HR DB schema from GitHub BlogAdvancedSkin

 

 

JDev: Badge Button

In this article, I describe how to build what I call a ‘Badge Button’. This is a button we know from many mobile applications which shows, e.g., how many new messages have arrived since the last visit.

The image above shows what I have in mind. We see a standard button with a badge indicating the number of new items. The badge can be used to display text as well

The idea behind this came from a question on the ODC JDev & ADF space. When I first read the question I wanted to answer “No, there isn’t such a component in ADF”, but after thinking about it, I decided to build one myself.

The Problem has two parts:

  1. How to build the badge
  2. How to create the component looking like a button with a badge

Solution Part 1

Making the badge turned out to be very easy. Searching the web, you find plenty of solutions for such components using CSS. As you might know, it’s not very straightforward to add a CSS solution to ADF. However, there are ways to do this. In the end, I used the following CSS to generate the badge:

.badge {
 background: radial-gradient( 5px -9px, circle, white 8%, red 26px );
 background: -moz-radial-gradient( 5px -9px, circle, white 8%, red 26px );
 background: -ms-radial-gradient( 5px -9px, circle, white 8%, red 26px );
 background: -o-radial-gradient( 5px -9px, circle, white 8%, red 26px );
 background: -webkit-radial-gradient( 5px -9px, circle, white 8%, red 26px );
 background-color: red;
 border: 2px solid white;
 border-radius: 12px; /* one half of ( (border * 2) + height + padding ) */
 box-shadow: 1px 1px 1px black;
 color: white;
 font: bold 15px/13px Helvetica, Verdana, Tahoma;
 height: 16px;
 padding: 4px 3px 0 3px;
 text-align: center;
 min-width: 14px;
 margin: 0px 0px 20px -10px;
 position: relative;
}

Solution Part 2

ADF uses CSS which is built from skin files. It’s not straightforward to add any other CSS to a component as you don’t see the generated HTML where you need to add the CSS. So adding the CSS class just as style to the button doesn’t work, as you can’t add new properties to ADF components. You will get an error like

To create a badge, you need to create a span or div with the CSS class and some data which is put into the badge like
Selection_474

This can’t be added to an existing component easily. However, ADF has a component which renders as a div tag, the af:outputText. If you add an af:outputText to a page and look at the resulting HTML you get
Selection_475
So, the value of the outputText is just surrounded by a div tag. The problem still is that you can’t add your own property to the ADF component, but we can add the div with the needed style and the data as the value you the af:outputText component. All we have to do, other than to add the div is to set the escape property of the outputText to false. This setting avoids that ADF encodes the value which would transform the ‘<’ into ‘<’, essentially making a string out of the value. The reason for that is to prevent security issues (injection), so be aware of this!

Putting this on a page would look like

And generates

The solution works somehow, if we put an af:button on the page instead of the af:spacer. However, it looks ugly or ‘uncool’ to see the ‘div’ in the af:outputText.

Final Solution

The final solution is to hide the ‘how to build it’ in a declarative component. The use case is a perfect fit for an ADF declarative component. We move the CSS, the button and the outputText in such a component and can use the component in the page to get

The new solution looks clean, as the CSS and odd looking outputText isn’t visible. Here are some images of the running test application.

The input field is used to set the data to be shown on the badge. It can be numbers, text or both. Clicking on the button calls the action listener and the action.

And this is the log output.

Building the Declarative Component

There are many other blogs about how to create a declarative component so I will not do this in detail. However, I like to point out some things you should keep in mind when you create such a declarative component.

To make the component work, it’s not enough to just add a button and the outputText holding the CSS. We have to make properties available for the action and the actionListener of the button. If we don’t do this, all we get is a button, which is looking good but which can’t be used to start a navigation or to call an actionListener. The same is true for other properties of the button inside the declarative component. We have to add a property for the button text at least. If you like to enable/disable the badge button, you have to expose an attribute in the declarative component interface to get the value from the outside, your page See later).

When we build the declarative component, we start by adding another ‘ADF View Controller Project’ to the workspace. Declarative components should be developed in a separate project. They are deployed as adfLibrary jar files. We add a new JSF Declarative Component to the project.

And fill out a dialog with necessary data. This data can be changed later if needed. Here is a sample

Once we click OK, a jspx page with the selected name will be created alongside a meta-data file holding the information about the tag library.

In the JSPX page, we create the layout of the component. We already know how to add the badge, all we need to do is to put an af:button onto the page and add the code to the badge to it. The resulting declarative component looks like

Select the af:componentDef tag and open the property editor. There you can define metadata like attributes and methods you want to pass to the component from the outside.

And the methods to activate the button.

The data you specified in the property editor is added to the af:componentDef tag.

A special case is the partialTrigger property. You can’t set a partialTrigger from the outside to a component used in the declarative component. However, you can surround the declarative component with another component which has a partialTrigger property and use this outer component to send a ppr. In the code above I surrounded the declarative component with an af:panelGroupLayout which listens for ppr send from the af:inputText with the id “it1”. This partial refresh is needed in the sample to refresh the button with a new value entered in the field.

If you need more attribute to control the behavior of the component, you can add them via the property editor. For this simple test case, the attributes and methods are enough.

The sample application and declarative component is build using JDev 11.1.1.9.0 and can be downloaded from GitHub BlogBadgeButton. The sample doesn’t need a DB.

JDev 12c: Debug Application Module Tester (BC4JTester) Problems

When you develop ADF Web Application you often use the ADF ApplicationModule Tester (BC4J Tester) to quickly test your business components data model and your self-written code in any EntityObject, ViewObject or ApplicationModule. For more information about how to do this look at JDeveloper & ADF: Use the Application Module Tester (BC4J Tester) to Test all your BusinessLogic.

Users who use one of the latest JDeveloper versions 12.2.1.1.0 and newer may have noticed, that the BC4J Tester application starts without an error, but doesn’t show the dialog. I run into this a couple of times lately and decided to dig into this problem. On the Oracle Development Spaces, I saw some threads about this too.

The reason for this behavior is that any EO, VO or other methods in the application module have an error, which can’t be found during compile time.

Use case

To show the effect, we start with a simple Workspace and a model project which only has one ViewObject in the Application Module’s data model

We implement a small use case where we want to see the total salary of all rows retrieved by the query behind the VO. Without any added where clause we get the total salary of all employees. If we add a filter e.g. by DepartmentId=90 we only get the total salary of all employees of department 90. Here are some images of the final running model in the BC4J Tester

Implementation

OK, so how do implement this use case?

We do this by adding a transient attribute to the EmployeesView and use a SQL default expression to do the calculation

sum(Employee.SALARY) OVER (PARTITION BY NULL ORDER BY NULL)

In the image below we see the definition of the transient attribute in the ViewObject

Problem

This should do the trick. However, when we try to test this in the BC4J Tester we get

In the log window, but no dialog where we see the application module. We don’t get any hint about what went wrong. The tester is up and running, but we don’t see anything.

Shay Shmeltzer mentioned in one of the ODC threads, that the reason for this is that there is an error in the application module (ViewObject, EntityObject or AM method). As the only thing we added is the SQL statement for the transient attribute, it’s clear that the statement must have an error. It’s simply a missing ‘s’ character, as the DB table we use is named ‘Employees’ and not ‘Employee’. So the correct statement is

sum(Employees.SALARY) OVER (PARTITION BY NULL ORDER BY NULL)

This will solve this problem and the BC4J Tester will start up and show (see the images above). But what if we added more things to multiple objects?

How to find the error then?

Older versions of JDev, the BC4J Tester did show an error message which showed the error and made solving the problem easy. Here is an image of the same application running using JDev 12.1.3.0.0

Solution

I did not manage to get the same output using JDev 12.2.1.1.0 or newer, but you can get the same message in the message window.

For this, you need to start the BC4J Tester with the java option

-Djbo.debugoutput=console

The option is added in the model projects ‘Run/Debug’ option in the project’s properties

Whenever you start the BC4J Tester and don’t get any dialog, you can assume that there is an error in the application module. To find out what the problem is, add the java option to the model project and you get the detailed information in the log window.

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

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.