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://myfmw.wordpress.com/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.

image1

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

image2

Add a Web Service Proxy to the project.
image3

Pick JAX-WS Style. Press Next.

image4

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.

image5

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

image6

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.

image7

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

image8

Specify a Default Package (LOV). Press finish.

image9

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.

image10

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

image11

image12

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.

image13

image14

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.

image15

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.

image16

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.

image17

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

image18

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

image19

image20

image21

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

image22

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

image23

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

image24

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

image25

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.

image26

image27

Press OK. Source code is shown below:

image28

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);

    protectedViewRowImpl 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 extendsWsViewImpl{
    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.

image29

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

image30

Check ‘Applicatie Module’ again. Press Finish.

image31

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

image32

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

image33

Select 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.

image34

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.

image35

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

image36

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

image37

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

image38

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

image39

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.

image40

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’.

image41

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.

image42

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.

image43

image44

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’.

image45

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

image46

Deploy Project.

Here you can download a sample project (LOV Example)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s