Getting Started Using Terraform with OCI

Introduction Standing up infrastructure requires building networks, servers and storage entailing complex build and configuration management processes. Traditionally done with scripts or even manually, Terraform gives you a new alternative. Using Terraform you can write a declarative description of your infrastructure. Using the Terraform “compiler” the declaration is converted to a build plan and then […]

Accessing RSS Feeds in JavaScript

Introduction RSS (Really Simple Syndication I always called it but also Rich Site Summary) is an XML document containing headline or summary items. Consuming RSS feeds in JavaScript is more convenient with JSON data so we’ll take a look at tools to convert a feed to JSON. Then we’ll look at examples of using RSS data on […]

Decoding JWT using the API Platform Groovy Policy

Author: Ricardo Ferreira Introduction With the explosion of APIs; most of the today’s computing challenges are being driven by it and therefore, new standards had to emerge to make sure that APIs can be used securely, while allowing developers to avoid having to reinvent the wheel every time they implement aspects such as authorization. One […]

DevOps With Oracle DeveloperCS, Ansible and Docker

This blog shows a sample DevOps cycle using combination of Oracle Developer Cloud Service & Ansible playbook. Scenario: An organization wants to setup DevOps practice with Oracle public cloud for Dev & test. However production still remains on-premise. In such case Oracle Developer cloud service can deploy artifacts(e.g. JAR file) to JCS (Java cloud Service) […]

ICS SOAP Connection – Retrieve File Uploaded WSDL

When working with Oracle Integration Cloud Service (ICS) SOAP Connections, it is common to upload a WSDL file when configuring the Connection Properties: The focus of this blog is how to retrieve/recover the WSDL in the event the original file is not available. This can be accomplished in several ways that include an on-line and/or […]

Everything you Should Know about the API Platform Groovy Policy

Author: Ricardo Ferreira Introduction Developers using the API Platform Cloud Service often make use of the built-in policies that comes with the platform; to implement any logic that needs to be executed before delivering the actual message to the backend service. One common policy used is the Groovy policy, which allows API developers to write […]

Using Process Cloud Service REST API Part 3

Introduction In this the third and final part of the series on using the PCS Rest API we will take the single page HTML application we started with in Part 1 and use Oracle JET (Javascript Extension Toolkit) to create an HTML/js application. Oracle JET is also an MVVM (model-view-viewmodel) architecture as we saw in […]

Using Process Cloud Service REST API Part 2

Introduction In Part 1 we looked at using the Process Cloud Service REST API and making REST calls from an HTML page using jQuery/AJAX. In Part 2 we’ll take the next step by using and presenting data retrieved from PCS. We started out stuffing the string representation of the JSON data into an HTML <div> […]

Automated Deployment to SOA Cloud Services using Developer Cloud Services

Introduction The process of deploying SOA Projects to Oracle SOA Cloud Services (SOACS) can be significantly simplified and streamlined using the Oracle Developer Cloud Services (DevCS) by facilitating the inbuilt Maven and GIT repositories. This article is a walk-through on how create a SOA Project in JDeveloper and get it deployed on SOACS using DevCS. […]

Using Process Cloud Service REST API Part 1

The Process Cloud Service (PCS) REST API provides an avenue to build UI components for workflow applications based on PCS. The versatility that comes with REST enables modern web application frameworks and just as easily, mobile applications. The API documentation is available here. Notice the endpoints are organized into eight categories. We’ll be focusing on […]

Using the Oracle Mobile Cloud Service SDK with AngularJS and Ionic

Introduction Oracle’s Mobile Cloud Service (MCS) can be used with any mobile client development tool. To speed up development for the most popular development tools, MCS comes with a Software Development Kit (SDK) for native Android, iOS and Windows development, as well as a JavaScript SDK for hybrid JavaScript-based development. Oracle’s A-Team has gained experience […]

Java API for Integration Cloud Service

Author: Ricardo Ferreira Introduction Oracle ICS (Integration Cloud Service) provides a set of handy REST APIs that allow users to manage and monitor related artifacts such as connections, integrations, lookups and packages. It also allow the retrieval of monitoring metrics for further analysis. More details about it can be found in the following documentation link. […]

Enhancing ICS Mappings with Custom Java Classes

Author: Ricardo Ferreira Introduction One of the most common tasks performed during the creation of integrations in ICS (Integration Cloud Service) is the implementation of mappings. In a nutshell, mappings are the resources that ICS uses to allow messages coming from the configured source application to be sent to the configured target application. Failure in […]

A Hidden Gem of ADF Faces 12c: The <af:target> Tag

Introduction In JDeveloper 12c, the <af:target> tag has been added, a very powerful new ADF Faces tag which can make your life much easier and more productive when building ADF Faces pages. This post discusses how you use this new tag, and explains how specific functional requirements that used to be mind-boggling to implement, are now […]

Programmatically expanding and collapsing an af:panelSplitter

Last week a customer asked me for help to implement a scenario where the search area part, displayed in the top part of an af:panelSplitter should be collapsed when the user presses the search button, in order for the results part, shown in the bottom …

Sorting and Filtering By Model-Based LOV Display Value

If you use a model-based LOV and you use display type “choice”, then ADF nicely displays the display value, even if the table is read-only. In the screen shot below, you see the RegionName attribute displayed instead of the RegionId. This is accomplished by the model-based LOV, I did not modify the Countries view object to include a join with Regions.  Also note the sort icon, the table is sorted by RegionId. This sorting typically results in a bug reported by your test team. Europe really shouldn’t come before America when sorting ascending, right?

To fix this, we could of course change the Countries view object query and add a join with the Regions table to include the RegionName attribute. If the table is updateable, we still need the choice list, so we need to move the model-based LOV from the RegionId attribute to the RegionName attribute and hide the RegionId attribute in the table. But that is a lot of work for such a simple requirement, in particular if we have lots of model-based choice lists in our view object. Fortunately, there is an easier way to do this, with some generic code in your view object base class that fixes this at once for all model-based choice lists that we have defined in our application. The trick is to override the method getSortCriteria() in the base view object class. By default, this method returns null because the sorting is done in the database through a SQL Order By clause. However, if the getSortCriteria method does return a sort criteria the framework will perform in memory sorting which is what we need to achieve sorting by region name. So, inside this method we need to evaluate the Order By clause, and if the order by column matches an attribute that has a model-based LOV choicelist defined with a display attribute that is different from the value attribute, we need to return a sort criterria. Here is the complete code of this method:

public SortCriteria[] getSortCriteria()
{
String orderBy = getOrderByClause();
if (orderBy!=null )
{
// use linkedHashMap to maintain sort order
LinkedHashMap<String,Boolean> sortAttrs = new LinkedHashMap<String, Boolean>();
StringTokenizer tokenizer = new StringTokenizer(orderBy,”,”);
boolean sortByChoiceDisplayValue = false;
while (tokenizer.hasMoreTokens())
{
String orderByPart = tokenizer.nextToken();
boolean descending = false;
if (orderByPart.endsWith(” DESC”))
{
descending = true;
orderByPart = orderByPart.substring(0,orderByPart.length()-5);
}
// extract column name, is part after the dot
int dotpos = orderByPart.lastIndexOf(“.”);
String columnName = orderByPart.substring(dotpos+1);
// loop over attributes and find matching attribute
AttributeDef orderByAttrDef = null;
for (AttributeDef attrDef : getAttributeDefs())
{
if (columnName.equals(attrDef.getColumnName()))
{
orderByAttrDef = attrDef;
break;
}
}
if (orderByAttrDef!=null)
{
String orderbyAttr = orderByAttrDef.getName();
sortAttrs.put(orderbyAttr, descending);
if (“choice”.equals(orderByAttrDef.getProperty(“CONTROLTYPE”))
&& orderByAttrDef.getListBindingDef()!=null)
{
String[] displayAttrs = orderByAttrDef.getListBindingDef().getListDisplayAttrNames();
String[] listAttrs = orderByAttrDef.getListBindingDef().getListAttrNames();
// if first list display attributes is not the same as first list attribute, than the value
// displayed is different fron the value copied back to the order by attribute, in which case we need to
// use our custom comparator
if (displayAttrs!=null && listAttrs!=null && displayAttrs.length>0 && !displayAttrs[0].equals(listAttrs[0]))
{
sortByChoiceDisplayValue = true;
}
}
}
}
if (sortByChoiceDisplayValue)
{
// yes, we need to return sortCriteria
SortCriteria[] sc = new SortCriteriaImpl[sortAttrs.size()];
Iterator<String> attrs = sortAttrs.keySet().iterator();
int index = 0;
while (attrs.hasNext())
{
String attrName = attrs.next();
sc[index] = new SortCriteriaImpl(attrName, sortAttrs.get(attrName));
index++;
}
return sc;
}
}
return super.getSortCriteria();
}

If this method returns a sort criteria array, then the framework will call the sort method on the view object. Note that we loop over all orderBy columns as there might be multiple columns when using the Advanced Sort option in the panelCollection View menu, as shown below.

 

 

The sort method uses a Comparator object to determine the sequence in which the rows should be returned. This comparator is retrieved by calling the getRowComparator method on the view object. So, to ensure sorting by our display value, we need to override this method to return our custom comparator:

public Comparator getRowComparator()
{
  return new LovDisplayAttributeRowComparator(getSortCriteria());
}

The custom comparator class extends the default RowComparator class and overrides the method compareRows and looks up the choice display value to compare the two rows. The complete code of this class is included in the sample application

With this code in place, clicking on the Region sort icon nicely sorts the countries by RegionName, as you can see below.

 

When using the Query-By-Example table filter at the top of the table, you typically want to use the same choice list to filter the rows. One way to do that is documented in ADF code corner sample 16 – How To Customize the ADF Faces Table Filter.The solution in this sample is perfectly fine to use. This sample requires you to define a separate iterator binding and associated tree binding to populate the choice list in the table filter area using the af:iterator tag. You might be able to reuse the same LOV view object instance in this iterator binding that is used as view accessor for the model-bassed LOV. However, I have seen quite a few customers who have a generic LOV view object (mapped to one “refcodes” table) with the bind variable values set in the LOV view accessor. In such a scenario, some duplicate work is needed to get a dedicated view object instance with the correct bind variables that can be used in the iterator binding. Looking for ways to maximize reuse, wouldn’t it be nice if we could just reuse our model-based LOV to populate this filter choice list? Well we can. Here are the basic steps:

1. Create an attribute list binding in the page definition that we can use to retrieve the list of SelectItems needed to populate the choice list

<list StaticList="false" Uses="LOV_RegionId"
              IterBinding="CountriesView1Iterator" id="RegionId"/> 

We need this “current row” list binding because the implicit list binding used by the item in the table is not accessible outside a table row, we cannot use the expression #{row.bindings.RegionId} in the table filter facet.

2. Create a Map-style managed bean with the get method retrieving the list binding as key, and returning the list of SelectItems. To return this list, we take the list of selectItems contained by the list binding and replace the index number that is normally used as key value with the actual attribute value that is set by the choice list. Here is the code of the get method:

 

 public Object get(Object key)
{
  if (key instanceof FacesCtrlListBinding)
  {
    // we need to cast to internal class FacesCtrlListBinding rather than JUCtrlListBinding to
    // be able to call getItems method. To prevent this import, we could evaluate an EL expression
    // to get the list of items
    FacesCtrlListBinding lb = (FacesCtrlListBinding) key;
    if (cachedFilterLists.containsKey(lb.getName()))
    {
      return cachedFilterLists.get(lb.getName());
    }
    List<SelectItem> items = (List<SelectItem>)lb.getItems();
    if (items==null || items.size()==0)
    {
      return items;
    }
    List<SelectItem> newItems = new ArrayList<SelectItem>();
    JUCtrlValueDef def = ((JUCtrlValueDef)lb.getDef());
    String valueAttr = def.getFirstAttrName();
    // the items list has an index number as value, we need to replace this with the actual
    // value of the attribute that is copied back by the choice list
    for (int i = 0; i < items.size(); i++)
    {
      SelectItem si = (SelectItem) items.get(i);
      Object value = lb.getValueFromList(i);
      if (value instanceof Row)
      {
        Row row = (Row) value;
        si.setValue(row.getAttribute(valueAttr));          
      }
      else
      {
        // this is the "empty" row, set value to empty string so all rows will be returned
        // as user no longer wants to filter on this attribute
        si.setValue("");
      }
      newItems.add(si);
    }
    cachedFilterLists.put(lb.getName(), newItems);
    return newItems;
  }
  return null;
}

Note that we added caching to speed up performance, and to handle the situation where table filters or search criteria are set such that no rows are retrieved in the table. When there are no rows, there is no current row and the getItems method on the list binding will return no items. 

An alternative approach to create the list of SelectItems would be to retrieve the iterator binding from the list binding and loop over the rows in the iterator binding rowset. Then we wouldn’t need the import of the ADF internal oracle.adfinternal.view.faces.model.binding.FacesCtrlListBinding class, but then we need to figure out the display attributes from the list binding definition, and possible separate them with a dash if multiple display attributes are defined in the LOV. Doable but less reuse and more work.

3. Inside the filter facet for the column create an af:selectOneChoice with the value property of the f:selectItems tag referencing the get method of the managed bean:

 <f:facet name="filter">
  <af:selectOneChoice id="soc0" autoSubmit="true"
                      value="#{vs.filterCriteria.RegionId}">
    <!-- attention: the RegionId list binding must be created manually in the page definition! -->                  
    <f:selectItems id="si0"
                   value="#{viewScope.TableFilterChoiceList[bindings.RegionId]}"/>
  </af:selectOneChoice>
</f:facet>

Note that the managed bean is defined in viewScope for the caching to take effect.

Here is a screen shot of the tabe filter in action:

 

You can download the sample application here