Friday 30 May 2008

Oracle ADF: Enriching the actions of a ViewObject

Based on the technique described two posts back regarding creation of a custom ViewObject that offers ready to drag actions, I now give you another simple yet very handy function. The showAllRows() function when added to the AB_BaseViewObject methods, allows you to create a button in a search page that removes all view criteria and executes the current query, very useful for cases when uses enter lots of view criteria and then need to display the entire contents of the entire row with a single click.

    public void showAllRows()
    {
        clearViewCriterias();
        executeQuery();
    }

Remember that in order for the action to appear in the JDeveloper Data Control Palette like in the following picture, you must include the showAllRows() function to the view objects client interface.

Wednesday 21 May 2008

Oracle ADF: Duplicating a ViewObject's current row

I wanted to add a Create Like functionality that would allow a new row to be inserted in a ViewObject then drive the user to an edit page where he or she would make ant changes required for valid insertion of the new row to the database and avoid having to re-enter everything from scratch.

In order to accomplish this I created the following method in the ViewObject's implementation class.

import oracle.jbo.AttributeDef;
import oracle.jbo.Row;
import oracle.jbo.ReadOnlyAttrException;
import oracle.jbo.TooManyObjectsException;

. . .

    /**
     * create and insert a row similar to the current
     */
    public void createLike()
    {
        // get the current row to dublicate
        Row currentRow = getCurrentRow();
        if (currentRow == null)
            return;
            
        // create new one
        Row newRow = createRow();
        
        // get the attribute values for the current attribute
        Object[] myValues = currentRow.getAttributeValues();
        
        for (int i = 0; i < currentRow.getAttributeCount(); i++)
            try {
                AttributeDef d = getAttributeDef(i);
                    
                if (d.getUpdateableFlag() != AttributeDef.READONLY)                
                    newRow.setAttribute( i, myValues[i]);                
            }    
            catch (ReadOnlyAttrException roe) {
                continue;
            }
            catch (Exception e) {
                // it is almost certain that the primary key will be
                // violated so the user must do something in the 
                // page following execution of the method.
                if (!(e instanceof TooManyObjectsException))
                    System.out.println(e.toString());
            }
            
        insertRow(newRow);        
    }

The code works fine and copies the values all columns from the current row into a new one except that of the last column that constitutes the primary key. That way the user will have to make the appropriate changes to the new record, so it can be inserted correctly.

There are a few points worth mentioning in this apprach

  • if your view object contains attributes from multiple entity objects then the the key attributes of the referenced entities that gets inserted by the framework appear to be updatable -- hence the catch (ReadOnlyAttrException roe) line. I have brought this to the JDeveloper forum but got no suggestions.
  • Using the above technique requires that you expose the createLike() method to the ViewObject's client interface. See the previous post for details.
  • The most probable use of this method will be to place a command button into an <af:tableSelectOne> facet in order to drive your users to an edit page with values already set. On most occasions the edit page will contain a commit button that will perform the final post. My suggestion is to use a backing bean to invoke the commit action like I discuss in a previous article named ADF/JSF Avoiding uncaught exceptions after commit that will prevent the controller layer to change back to the browse page in case of any errors.

Thursday 15 May 2008

Oracle ADF: A view object with cancelInsert and cancelEdit operations

I have already discussed the problem of providing a cancel button in an ADF/JSF edit page. Here is an alternative that allows the usage of a base view object that provides both a cancel edit and a cancel insert method.

I have come to believe that this method is the most appealing so here is a brief outline of how to use it :

First create the following class in the queries package of you model application.

package myapp.model.queries;

import oracle.jbo.Row;
import oracle.jbo.server.ViewObjectImpl;

public class AB_BaseViewObject
    extends ViewObjectImpl {

    public AB_BaseViewObject()
    {
    }
    
    /**
     * Refresh the view obejct's current row from the dataset practically 
     * undoing any changes.
     */
    public void cancelEdits() 
    {
        Row r = getCurrentRow();

        if (r != null) 
            r.refresh( Row.REFRESH_WITH_DB_FORGET_CHANGES);
    }
    
    /**
     * Undo changes and get rid of new rows
     */
    public void cancelInsert()
    {
        clearCache();      
    }
}

Next create Java Classes that extend the AB_ViewObject for all the view objects that require editing in your project. Publish the cancelXXX() methods on the view interface like in following picture.

Finally create buttons on the edit or create pages in the ViewController project that call the methods.

Wednesday 14 May 2008

Amarok on CentOS

Today I found the time to compile amarok on my x86_64 CentOS 5.1 machine at work. It was a long time since I compiled any version of amarok, thanks to Packman and openSUSE, but it worked. The truth of the matter is that the sound produced by the xine engine is a bit over bassed, still I enjoy very much the amarok experience that I may very well start getting used to it.

Anyway, here are the steps I followed. After installing the amarok sources in /usr/src I run

[root@lxbakalidis amarok-1.4.9.1]#yum install gcc-c++.x86_64
libstdc++-devel.x86_64 kdelibs-devel.x86_64 alsa-lib-devel.x86_64
zlib-devel.x86_64 taglib-devel.x86_64 ruby-libs.x86_64 ruby.x86_64
xine-lib-devel.x86_64 libXv-devel.x86_64 libXvMC-devel.x86_64
ruby-devel.x86_64 sqlite-devel.x86_64

Then I did a

[root@lxbakalidis amarok-1.4.9.1]# ./configure --disable-debug

Finally I run make and make install and there I have it.

PS 1: Thanks for the tip bmcl

PS 2:When compiling on the new CentOS 5.2 you will additionally need package libutempter-devel. A simple ...

# yum install libutempter-devel

... is enough

.