LOV's in humantask (part 2 of 2) figuur50

LOV’s in humantask (part 2 of 2)

In this blog I will describe the use of LOV’s in Humantasks. I will describe three different type of LOV’s.

1. LOV with fixed values

   2. LOV feeded by the content of a database table

   3. LOV feeded via a webservice

 

The blog is devided into two part. In the first part I descibed the first two types (https://technology.amis.nl/2012/04/04/lovs-in-humantask-part-1-of-2/). In this second part I will descibe the third type.

3. LOV feeded via a webservice

As an example I will add a LOV with the values: Male, Female and Unknown to a Gender (geslacht in dutch) field. In this blog the terms Gender and Geslacht are sometimes mixed. In both cases the same thing is meant.
For demo purposes I created a webservice arround the database table create in the first part of this blog. But any webservice return a List Of Values will do.

 

3.1. Create Client Proxy

Create a Generic Project. This project is used to create a Web Service Proxy. A java proxy is gegenerated to make calls to the  webservice. The java proxy offers the possibility to integrate the webservice functionality into the ADF (java) taskscreens.

LOV's in humantask (part 2 of 2) figuur153

 

Specify a name for the project (WsClientProxy).  Press Finish.

LOV's in humantask (part 2 of 2) figuur163

 

Add a Web Service Proxy to the project.
LOV's in humantask (part 2 of 2) figuur173

 

Pick JAX-WS Style. Press Next.

LOV's in humantask (part 2 of 2) figuur183

 

Enter the WSDL Document URL of the consuming webservice.
In the example it is http://LUX164.arnhem.local:8001/soa-infra/services/default/ExposedWS/GenderService?WSDL
Press Next.

LOV's in humantask (part 2 of 2) figuur193

 

Specify ‘Package Name’ and ‘Root Package for Generated Types’. Accept all other defaults in the wizard. Press Finish.

LOV's in humantask (part 2 of 2) figuur203

 

The Java class GeslachtWS_ptClient is opend. Update the main method. Add the following code fragment:

// Add your code to call the desired methods.
List<MoaGeslacht> lovTest =geslachtWS_ptt.geslachtWSSelect(null).getMoaGeslacht();
for (MoaGeslacht lovRegel: lovTest) {
        System.out.println("Afkorting   : " + lovRegel.getAfkorting());
        System.out.println("GeslachtNaam: " + lovRegel.getGeslachtnaam());
}

Run the main method to test the webservice proxy. An output example is shown below:

        Afkorting     : M
        GeslachtNaam  : Man
        Afkorting     : F
        GeslachtNaam  : Vrouw
        Afkorting     : U
        GeslachtNaam  : Onbekend
        Process exited with exit code 0.

 

3.2. Create View Objecten

To make use of the LOV, a View Object to access the data is required. We also need a View Accessor to Access this View Object from the humantask. This View Accessor can add additional filters to the LOV.

Start by creating an ‘ADF Model Project’ for the View object’s.

 

Project creation

Create an ‘ADF Model Project’ in the same application as the humantask is located.

LOV's in humantask (part 2 of 2) figuur212

 

This ‘Model Project’ is used to create the ADF Business Components. Specify the Project name (LOVViews). Press Next.

LOV's in humantask (part 2 of 2) figuur222

 

Specify a Default Package (LOV). Press finish.

LOV's in humantask (part 2 of 2) figuur232

 

Add Webservice dependencies

Before the webservice(s) can be used, we first must modify the dependencies between all related projects. Both theLOVViews project as the Human tasks project have a dependency on the webservice. Here we will add this dependency.

Go the the project properties of the LOVViews project. Select Dependencies and start edit mode by clicking the pencil.

LOV's in humantask (part 2 of 2) figuur242

 

Check the ‘Build Output’ dependency of ExposedWS and WSClientProxy. Press OK.

LOV's in humantask (part 2 of 2) figuur252

LOV's in humantask (part 2 of 2) figuur262

 

Now go the the project properties of the ‘Human task’ project. Select Dependencies and start edit mode by clicking the pencil. Add the ‘Build Output’ dependencies of the ExposedWS project en WSClientProxy project.

LOV's in humantask (part 2 of 2) figuur272

LOV's in humantask (part 2 of 2) figuur282

 

View Object

The first ADF BC will be a View Object. A View Object is used here to select data.
Create the View Object within the LOVViews project.

LOV's in humantask (part 2 of 2) figuur292

The View Object is getting it’s data from a database. For this purpose, the next step will be to setup a connection with this database.

LOV's in humantask (part 2 of 2) figuur302

 

After this. A wizard is started for the creation of the View Object.
Specify a View Object name (GeslachtWSView or GenderWSView) with ‘Rows populated programmatically’. Press Next.

LOV's in humantask (part 2 of 2) figuur311

 

Press New to add the ‘transient view attributes’ Abbreviation/Afkorting and GenderName/GeslachtNaam.

LOV's in humantask (part 2 of 2) figuur321

 

Check ‘Key Attribute’ for the Afkorting / Abbreviation attribuut.

LOV's in humantask (part 2 of 2) figuur33

LOV's in humantask (part 2 of 2) figuur34

LOV's in humantask (part 2 of 2) figuur35

 

Press 2x Next. Check ‘Generate View Row Class’. Press Next.

LOV's in humantask (part 2 of 2) figuur36

 

Now we reached the ‘Application Module’ step.
Check-on ‘Applicatie Module’. Specify an Application Module name (AppModule) and press Finish.

LOV's in humantask (part 2 of 2) figuur37

 

Go to edit mode (pencil) for each attribute of witch the ‘display witdh’ needs to be changed.

LOV's in humantask (part 2 of 2) figuur38

 

Maximum length of Abbriviation/Afkorting is 1 character. Of GenderName/GeslachtNaam it is 20.

LOV's in humantask (part 2 of 2) figuur39

 

View Implementation

During the creation of the View Object in the previous paragraph we specified ‘Rows populated programmatically’. Here we will implement this.

Add the abstracte class WsViewImpl to the LOVViews project.

LOV's in humantask (part 2 of 2) figuur40

LOV's in humantask (part 2 of 2) figuur411

 

Press OK. Source code is shown below:

:LOV's in humantask (part 2 of 2) figuur42

 

Update/replace this source with:

package LOV;

import java.math.BigDecimal;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;

import java.util.Iterator;
import java.util.List;

import oracle.jbo.server.ViewObjectImpl;
import oracle.jbo.server.ViewRowImpl;
import oracle.jbo.server.ViewRowSetImpl;

public abstract class WsViewImpl extends ViewObjectImpl {

    public WsViewImpl() {
        super();
    }

    protected oracle.jbo.domain.Date toOracleDate(java.util.Calendar calendar) {
        oracle.jbo.domain.Date jboDate = new oracle.jbo.domain.Date();
        Timestamp t = jboDate.timestampValue();
        t.setTime(calendar.getTime().getTime());
        return new oracle.jbo.domain.Date(t);
    }

    protected oracle.jbo.domain.Number toOracleNumber(int i) {
        return new oracle.jbo.domain.Number(i);
    }

    protected oracle.jbo.domain.Number toOracleNumber(double d) {
        try {
            return new oracle.jbo.domain.Number(d);
            } catch (SQLException e) {
                 return null;
            }
    }

    protected oracle.jbo.domain.Number toOracleNumber(BigDecimal b) {
        try {
            return new oracle.jbo.domain.Number(b);
            } catch (SQLException e) {
                 return null;
            }
    }

    protected abstract List retrieveArrayFromWebService(Object qc, Object[] params);

    private void storeNewIterator(Object qc, List rs) {
        setUserDataForCollection(qc, rs.iterator());
        hasNextForCollection(qc);
    }

    protected void executeQueryForCollection(Object qc, Object[] params, int noUserParams) {
        storeNewIterator(qc, retrieveArrayFromWebService(qc, params));
        super.executeQueryForCollection(qc, params, noUserParams);
    }

    private Iterator getArrayIterator(Object qc) {
        return (Iterator)getUserDataForCollection(qc);
    }

    protected boolean hasNextForCollection(Object qc) {
        boolean hasNext = getArrayIterator(qc).hasNext();
        if (!hasNext) {
            setFetchCompleteForCollection(qc, true);
        }
        return hasNext;
    }

    protected abstract void fillRow(Object data, ViewRowImpl row);

    protected ViewRowImpl createRowFromResultSet(Object qc, ResultSet resultSet) {
        Iterator iterator = getArrayIterator(qc);
        ViewRowImpl row = createNewRowForCollection(qc);
        fillRow(iterator.next(), row); return row;
    }

    public long getQueryHitCount(ViewRowSetImpl viewRowSet){
        return super.getQueryHitCount(viewRowSet);
    }
}

 

After that change the code of GeslachtWSViewImpl.java. Replace it by:

package LOV;
import java.util.List;
import oracle.jbo.server.ViewRowImpl;
import webservice.proxy.GeslachtService;
import webservice.proxy.GeslachtWS_ptt;
import webservice.proxy.types.MoaGeslacht;

public class GeslachtWSViewImpl extends WsViewImpl {
    private static GeslachtService geslachtService;

    protected List retrieveArrayFromWebService(Object qc, Object[] params) {
        try {
            geslachtService = new GeslachtService();
            GeslachtWS_ptt geslacht_ptt = geslachtService.getGeslachtWS_pt();
            List<MoaGeslacht> geslachtList = geslacht_ptt.geslachtWSSelect(null).getMoaGeslacht();
            return geslachtList;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    protected void fillRow(Object data, ViewRowImpl row) {
        MoaGeslacht geslachtRegel = (MoaGeslacht)data;
        populateAttributeForRow(row, GeslachtWSViewRowImpl.AFKORTING,geslachtRegel.getAfkorting());
        populateAttributeForRow(row, GeslachtWSViewRowImpl.GESLACHTNAAM,geslachtRegel.getGeslachtnaam());
    }
}

 

View Accessor

Create a second View Object with name GeslachtWSAccessor/GenderWSAccessor in the LOVViews project.
Set  ‘Read-only access through SQL query’. Press Next.

LOV's in humantask (part 2 of 2) figuur43

 

Specify a dummy query. Press Next until step 8 is reached.

LOV's in humantask (part 2 of 2) figuur44

 

Check ‘Applicatie Module’ again. Press Finish.

LOV's in humantask (part 2 of 2) figuur45

 

Now extend this View Object with a ‘transient attribute’ . For this, press the green sign.

LOV's in humantask (part 2 of 2) figuur46

 

Specify the attribute (ViewAttr). Set Updatable op ‘Always’. Press OK.

LOV's in humantask (part 2 of 2) figuur47

 

Selecteer this new added attribute and go into Edit mode by clicking the pencil.
Select Control Hints and change the ‘Control Type’ from default into ‘Input Text with List of Values’ . Press OK.

LOV's in humantask (part 2 of 2) figuur48

 

Connecting the View Accessor with the View Object

The created View Object and View Accessor must be connected with each other. To do this, click the green plus sign in the  ‘List of Values’ section.

LOV's in humantask (part 2 of 2) figuur49

 

Press the green plus sign again (now behind List Data Source) in new appearing screen.

LOV's in humantask (part 2 of 2) figuur50

 

Shuttle GeslachtWSView/GenderWSView to the right side. Press OK.

LOV's in humantask (part 2 of 2) figuur51

 

Select Afkorting/Abbreviation as ‘List Attribute’ in the List of Return Values.

LOV's in humantask (part 2 of 2) figuur52

 

Select  the ‘UI Hints’ tab and shuttle both available attributes to the right. Press OK.

LOV's in humantask (part 2 of 2) figuur53

 

As a finishing touch we need to change the datasource reference.
Open the AppModule.xml file and then select the Configurations tab. Go into Edit mode for the AppModuleLocal by clicking the pencil.

LOV's in humantask (part 2 of 2) figuur54

 

Select JDBC Datasource als ‘Connection Type’. Now the ‘Datasource Name’ changes into java:comp/env/jdbc/MOA_UTILSDS. Manually change this into the JNDI name as specified on the WebLogic Server. In my case: ‘jdbc/MOAUtils’.

LOV's in humantask (part 2 of 2) figuur55

 

3.3. Attach the LOV to a taskfield

Open the humantask where the LOV is needed. Drag and Drop the LovTargetViewAttr attribute (from the GeslachtWSAccessor1) on the taskDetails page. A popup menu appears.

LOV's in humantask (part 2 of 2) figuur56

 

Choose ‘ADF LOV ChoiceList‘ (short lists) or ‘ADF LOV input‘ (long lists).
The ChoiceList type show a short list with the posibility to enter a Search(zoeken) popupscreen.  The input type directly start the Search popupscreen.

LOV's in humantask (part 2 of 2) figuur571

LOV's in humantask (part 2 of 2) figuur581

 

The LOV is now connected to the transient attribute. In my case it must be connected to the Gender/Geslacht attribute.

The source code of the ChoiceList type:

<af:inputComboboxListOfValues id="viewAttr1Id"
                              popupTitle="Search and Select: #{bindings.ViewAttr1.hints.label}"
                              value="#{bindings.Geslacht.inputValue}"
                              label="#{bindings.ViewAttr1.hints.label}"
                              model="#{bindings.ViewAttr1.listOfValuesModel}"
                              required="#{bindings.ViewAttr1.hints.mandatory}"
                              columns="#{bindings.ViewAttr1.hints.displayWidth}"
                              shortDesc="#{bindings.ViewAttr1.hints.tooltip}">
        <f:validator binding="#{bindings.ViewAttr1.validator}"/>
</af:inputComboboxListOfValues>

 

Change this into:

<af:inputComboboxListOfValues id="viewAttr1Id"
                              popupTitle="Zoek en Selecteer #{bindings.Geslacht.hints.label}"
                              value="#{bindings.Geslacht.inputValue}"
                              label="#{bindings.Geslacht.hints.label}"
                              model="#{bindings.ViewAttr1.listOfValuesModel}"
                              required="#{bindings.ViewAttr1.hints.mandatory}"
                              columns="#{bindings.ViewAttr1.hints.displayWidth}"
                              shortDesc="#{bindings.ViewAttr1.hints.tooltip}">
        <f:validator binding="#{bindings.ViewAttr1.validator}"/>
</af:inputComboboxListOfValues>

 

What has changed?

–       Title popup search screen
–       Input field lable
–       Attached field

 

3.4. Deployment

Before we can deploy the project, an Application property must change. Open the ‘Application Properties’.

 

LOV's in humantask (part 2 of 2) figuur59

 

Switch off ‘Auto Generate and Synchronize weblogic-jdbc.xml Descriptors During Deployment’ .

LOV's in humantask (part 2 of 2) figuur60

 

Deploy Project.

 

Here you can download a sample project (LOV_Voorbeeld)

3 Comments

  1. Pedro Pereira May 19, 2014
  2. Pedro Pereira June 1, 2012
    • Marcel van de Glind July 1, 2012