Jason Bennett's Developer Corner

 






Click to see the XML version of this web page.

>


View David Jason Bennett's profile on LinkedIn

 

 

A Little About Jason Bennett ...

I've had an interest in publishing technical articles and HELPFUL code for a few years.  I am (by trade and hobby) a developer who specializes in Oracle technologies and web based architectures.  I have been an employee of both TUSC and Oracle Corporation.  My intent here is to share my ideas and coding experiences with the developer community as a whole.  As with all developers some of my ideas are great and some of them are ....  well you know.  Anyway, I hope you find something here that will aid in your endeavor, or spark a new idea. 

I am more than happy to assist with technical issues and will even write a little code if need be. If you find something on the site that is really useful and you'd like to make a contribution (absolutely up to you and absolutely not required), just click the "Make a Donation" button on the left!

Good luck and good coding !




  Thursday, June 05, 2008


ADF Faces: How To Use a Single JSP for both INSERTING and UPDATING

   In this entry, I'll go over my technique for using a single JSP for both inserting and updating data.  This technique utilizes custom methods in the target ViewObjectImpl class, and Page Definition action methods in the Page Definition associated with our ADF/JSF JSP.  There are probably other ways to do this, but this one is fairly straight forward. (Note: I believe Steve Muench recommended a similar technique using methods in the ApplicationModuleImpl class)

Preparing the View Object

Most of the View Objects in my applications (that are used for data entry) contain a bind variable in the WHERE clause that is associated with the target table's primary key (I use dumb keys versus natural keys).   In order to put the page in update mode, we need to pass a PK value to the View Object and pre-populate it prior to rendering the page.  Otherwise, the page is rendered in insert mode.  This is pretty much a universal concept.  How do we go about passing the PK value (or parameter) to the View Object?  First, we need to create a couple of custom public methods in the View Object's ViewObjectImpl class.   One method will take the PK param value and pre-populate the View Object instance, and the other method will clear the state of (empty the data from) the current instance of the View Object.   The first method looks like this:

    /***
     * This method will be used to pre-populate the view object using a passed value.
     */
    
     public void queryViewById(String p_id) {
    
      /*setp_emp_id is ADF generated method for setting the bind variable
        value defined in my View Object (p_emp_id). */


       setp_emp_id(p_id);
       executeQuery();
      
     }

 

The second method (used to clear the data from the view object) looks like this:

 

    /***

     * This method will clear any data out of the existing VO.

     */

    public void clearView() {

      if (getWhereClause() != null) {

        setWhereClause(null);

      }

     

      executeQuery();

    }

Add these two methods (modified to fit your View Object) to the ViewObjectImpl class associated with your View Object.  Some might say that you could combine the two methods (since both will be end up being called to put the page in update mode).  I chose to keep them separate in case I wanted (or needed) to call one without the other at some point.

Preparing the Page Definition File

ADF Faces JSPs use an XML based Page Definition file to bind data to the user interface and to perform some actions prior to rendering the page (overly simplified definition ...).  Each View Object referenced by an ADF Faces JSP component is represented in that page's Page Definition file.  ADF Faces comes with some canned page actions (such as Create and Delete) that can be "dropped" into the page definition file and then applied to event (or actions) that occur later in JSP page.  We can also create custom actions (known as method actions) that are mapped to methods we have created.  The two methods we created in the last section (queryViewById and clearView) will be included as custom method actions the Page Definition file for our ADF/JSF JSP page.  The method action entries go in the "bindings" section of the page, and look like this (I have my own View Object referenced in the example):

    <methodAction id="clearView"
                  MethodName="clearView"
                  RequiresUpdateModel="true" Action="999"
                  IsViewObjectMethod="true" DataControl="AppModuleDataControl"
                  InstanceName="AppModuleDataControl.MyemployeeView1"/>

    <methodAction id="queryViewById"
                  MethodName="queryViewById" RequiresUpdateModel="true"
                  Action="999" IsViewObjectMethod="true"
                  DataControl="AppModuleDataControl"
                  InstanceName="AppModuleDataControl.MyemployeeView1">
      <NamedData NDName="p_id" NDValue="#{param.p_emp_id}"
                 NDType="java.lang.String" />
    </methodAction>

Notice the "#{param.p_emp_id}" in NDValue attribute above.  Any request parameter passed to the your page can be accessed using "#{param.<parameter name>}".  The only caveat is if you use the <f:param> tag in conjunction with a command link or command button and the navigation rule behind your navigation action specifies a "redirect" ... the parameters will not be passed.  Here is a quick break down of the attributes for the "methodAction" tag above:

  • The "id" attribute represents the identifier of this methodAction tag as it relates to other components (tags) in the current Page Definition file.

  • The "MethodName" attribute defines the binding name for this method action when called from the "invokeAction" tag ( tag that is responsible for executing the code).
  • The "RequiresUpdateModel" attribute specifies whether or not the model needs to be updated prior to executing the method.
  • The "Action" attribute identifies the internal class for which the data control is created.  Always seems to be 999 for custom class.
  • The "IsViewObjectMethod" attribute indicates whether the method being invoked is defined within a View Object.
  • The "InstanceName" attribute points to the View Object instance as defined by the application data control.
  • The "NamedData" tag is used to map any parameters that the method might take. It contains attributes "NDName" (method parameter name), "NDValue" (value being passed), and "NDType" (data type of the parameter).

 

In order for the page to be rendered in INPUT mode, we have to include a "Create" action in the page definition.  Place the following tag in the "bindings" section (before or after the "methodAction" tags):

 

    <action id="Create" IterBinding="MyemployeeView1Iterator"
            InstanceName="AppModuleDataControl.MyemployeeView1"
            DataControl="AppModuleDataControl" RequiresUpdateModel="true"
            Action="41"/>

 

(Note:  The instance name references my View Object ... you would replace the reference with yours.)

The next step in preparing the Page Definition is to add "invokeAction" tags to the "executables" section.  The "invokeAction" tags define what actions will be executed and under what conditions they will be executed.  The invoke actions for our methods look like:


    <invokeAction id="clearViewObject"
                  Binds="clearView"
                  RefreshCondition="#{adfFacesContext.postback == false and not empty param.p_emp_id}"
                  Refresh="prepareModel"/>

    <invokeAction id="queryViewObject"
                  Binds="queryViewById"
                  RefreshCondition="#{adfFacesContext.postback == false and not empty param.p_emp_id}"
                  Refresh="prepareModel"/>

    <invokeAction Binds="Create"
                            id="invokeCreate" Refresh="renderModel"
                           RefreshCondition="${adfFacesContext.postback == false and empty param.p_emp_id and empty bindings.exceptionsList}"/>

The "RefreshCondition" condition attribute determines whether or not the action will be triggered. The three action invocations below determine how the page will be rendered to the user. If  the call to the page is not a post back from the current page, and the "p_emp_id" param is not null, then associated View Object(s) will be cleared of existing data, passed the p_emp_id param and will execute and populate. This will put the screen in UPDATE mode.  Otherwise, if the "p_emp_id" param is null and the call to the page is not a post back, the screen will be presented in INSERT mode.

Passing a Parameter to the Page

   Passing a parameter is a fairly simple matter.  You could pass it via a command link or command button with a param tag (NOTE: The navigation rule definition for the "action" can not contain a redirect reference.):

<af:commandButton text="Some Text" action="SomeAction">
   <f:param name="p_emp_id" value="123"/>
</af:commandButton>

or

 <af:commandLink text="Some Text" immediate="true"
                               action="SomeAction">
     <f:param name="p_emp_id" value="#{somebinding.value}"/>
  </af:commandLink>


You can also pass a parameter via a standard URL:

http://someserver.some.domain:7778/myapp/faces/somepage.jsp?p_emp_id=123

Passing no parameters will result in the page rendering in INPUT mode.

Wrapping It Up ...

As always, if you have questions, or input, please shoot me an email.


 





9:50:12 PM    

Click here to visit the Radio UserLand website. © Copyright 2008Jason Bennett.
Last update: 8/28/2008; 9:46:15 PM.

June 2008
Sun Mon Tue Wed Thu Fri Sat
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30          
Apr   Aug