Monday, June 30, 2014

How to use the Deck component (ADF 12.1.3 New Feature)

With the arrival of ADF 12.1.3 many new features has been introduced. One of those features is the brand new deck ui component. In this blogpost I want to give an example on how to use that new component.

Use Case

The use case is quite simple. Arrange pictures of soccer players in a grid. Once clicked on a picture it is flipped. On the backside you can see more details for the given player. Clicking once again on the card it flips back and shows the picture again. Let's look at the result:
Now clicking on the first pic it flips (with an animated transition) and show details.

How to implement

To implement the described use case create a panelGridLayout first with the following properties

  • row: Fixed height
  • cell: Fixed width, halign="stretch" and valign="stretch"

Inside each cell place the new af:deck component with two links as child components and two transition operations.
The commandLinks act as clickable cards on the deck. Each transition operation defines the desired animation when transitioning from one card to another. There are a lot of out-of-the-box transitions available as you can see in the screenshot.
Which card is currently displayed on the deck is controlled by the displayedChild attribute. It expects the component id of the given child ui component (in this case the af:commandLinks). The interesting piece of JSF Code for the sample to work is as follows:

To make the sample complete a backing bean is needed to handle the action events on each command link. Main task of the action listeners is to change the displayedChild attribut on the deck component and repaint it on the client (through a partial refresh)
While implementing the deck sample I did not want to use the deprecated af:commandLink. But converting it to af:link implies a JSF compilation error. So I switched back to the deprecated component.

Looks like the new Link Component is not fully compatible. Is this a bug?

Further Information



Saturday, June 7, 2014

Create RESTful services on top of ADF Business Components


Introduction

Creating SOAP Services on top of ADF Model is for a long time quite easy and convenient. In JDeveloper: Open an ApplicationModule goto WebService Tab and create a Service Interface by exposing some given ViewObject Instances or custom Service methods. See http://www.oracle.com/technetwork/issue-archive/2012/12-sep/o52adf-1735897.html (Consume Early, Consume Often) for more details and great explanation or take a look in the official Oracle documentation http://docs.oracle.com/cd/E23943_01/web.1111/b31974/bcextservices.htm#CJAJGIEB (11 Integrating Service-Enabled Application Modules)

Options to create RESTful Services on top ob ADF BC Model

Creating a RESTful Service Fassade on top of existing ADF Business Components Model is not that straightforward. From different „announcements" we know that Oracle plans to generate RESTful Services ADF BC SDO (Service Data Object) in the future. But for now we need a custom solution.

Exploring various possibilities I came up with the following


Note that the Service Facade is optional but recommended in terms of „separation of concerns", „service virtualization", „clean code", etc. Watch the youtube ADF Insider Essentials for the detailed explanation of the Service Facade Pattern.

Going from top to bottom in the diagram we have the following options
a) ADF BC -> SDO Service Interface -> WebService  -> SOAP 
b) ADF BC -> SDO Service Interface -> Inject EJB in REST-Resource -> REST
c) ADF BC -> Use AM Instance programmatically in REST-Resource ->REST
d) this one is planned for some 12.1.3+ release (and in future will be the default option to expose RESTful Services for a given ADF BC Model).

In this post I am covering case b. I did not find a sample on the web yet. So I give it a try cause it looks like THE pragmatic approach so far.

Howto

For the example I am using JDeveloper 12.1.2 and the corresponding Runtim ADF 12.1.2. In order to understand the next steps I assume you know the basics of ADF and JDeveloper.

1. Create ADF BC SDO SOAP Service for an Application Module:
Open the AM in „Overview", goto "Web Service" Tab. Now open the dialog to create the service interface.

Choose the desired VO-Instances and apply you changes.

JDeveloper should generate some files now. If you take a look in the *ServiceImpl.java Class you will notice that  it is exposed as Stateless Session EJB. This is great!

Because from now on you can use the EJB in a REST-Resource to expose it as RESTful-Service. That's what we are planning to do next.

But before this step test your generated (SOAP-based) service first: Make sure you do not ran into the „StackOverflowException" because the SDO Service will try to traverse the ViewLinks recursively. So the following exception might be the one you will run into.

To fix this, open the corresponding ViewLink and uncheck the property „Generate Property in SDO"


2.  Next: Create a new Project for the RESTful Service
Use the right project template from the NEW-Wizard

Open the NEW-Wizard again and create a RESTful service from new

Deselect the Checkbox in front of GET-Method. We are going to do that later in Sourcecode.

Finish. => This should generate a Java class and configure the project with the Jersey Library.
For the sample to complete the project needs on more adjustment in the project properties. 
- One more Library (Context and Dependency Injection CDI)
and a dependency to the Model-Project because the RESTfulWebService project need access to the application module.

Thats all for the project setup.

3. Add some classes, annotations and the methods you want to expose

import javax.ejb.EJB;

import javax.inject.Singleton;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

import oracle.jbo.service.errors.ServiceException;

@Singleton
@Path("api")
public class HrRESTResource {
   
    @EJB
    HRAppModuleService serviceBean;
   
    public HrRESTResource() {
    }
   
    /**
     * getEmployeesView1: generated method. Do not modify.
     */
    @GET
    @Path("emp/{empId}")
    @Produces(value = { "application/json", "application/xml" })
    public EmpResult getEmployeesView1(@PathParam("empId") Integer employeeId) throws ServiceException {
       
        EmployeesViewSDO empSDO = serviceBean.getEmployeesView1(employeeId);
       
        EmpResult result = new EmpResult();
        result.setEmployee(empSDO);
       
        return result;
    }
   
    @GET
    @Path("depts")
    @Produces(value = { "application/json", "application/xml" })
    public DeptResult findAllDepartments() throws ServiceException {
        DeptResult result = new DeptResult();
        result.setDepartmentList(serviceBean.findDepartmentsView1(null, null));
       
        return result;
       
    }
}

Important note: For what ever reason you need to annotate the REST-Resource with @javax.inject.Singleton. Otherwise the EJB-Injection won't work.

Just reuse the SDO-Entity-classes (eg. EmployeesViewSDO), but wrap them inside a custom „Result"-class which should be annotated with @XmlRootElement (JAX-B Standard). 

@XmlRootElement

public class DeptResult {
    public DeptResult() {
        super();
    }
   
    @XmlElement(name="departments")
    private List<DepartmentsViewSDO> departmentList;

    public void setDepartmentList(List<DepartmentsViewSDO> departmentList) {
        this.departmentList = departmentList;
    }

    public List<DepartmentsViewSDO> getDepartmentList() {
        return departmentList;
    }
}
See attached sample application for the whole source code.

4. Run an see the RESTful service in action

As a result we will get the proper JSON structure


if changing the accept- Header to: application/xml we will get XML-Result. 

This is pretty cool. Because we can reuse the generated ADF BC SDO SOAP Service Layer as EJB for the REST Fassade.

Download sample application, based on Version ADF 12.1.2: enpit.sample.adf12.restadfbc-jdev1212.zip

More Information