Legal | Privacy
Building ADF Applications Workshop

Building Oracle ADF Applications: Workshop

This workshop shows you how to build applications using Oracle Application Development Framework (Oracle ADF). The technologies that you use are Oracle ADF, Struts, and JavaServer Pages.

In this workshop, you build a Web-based application that provides for maintenance of customer information. You start by building the business services based on Oracle ADF Business Components. You then build the client portions of the application.

Topics

This workshop covers the following topics:


The workshop application is a set of customer maintenance pages that are used to create new customer records, update existing records, and delete existing records. During this workshop, you learn how to create these pages and make them user friendly and robust enough for a multiuser environment.

We need to provide our customer with an application that is easy to use and understand and that provides useful feedback to the user. The user needs to be able to edit or delete customer records as well as create new customer records. Navigation should be easy and intuitive, and feedback needs to be clear and obvious. For example, when a record is updated, the user needs a message that indicates success. The same technique should apply to deleting and creating records as well as handling any errors that may occur. The messages must be internationalizable so that the application can run in multiple languages.

Prerequisites

Back to Topic List

Before starting this workshop, you should have:

1. Installed Oracle JDeveloper 10g
2.Installed the sample schema and created a connection to the OE schema to use in the workshop (see Installing the Sample Schemas and Establishing a Database Connection)
3.

Add a database sequence and database trigger to automatically populate the CUSTOMER_ID column of the CUSTOMERS table.

Open SQL*Plus, connect to the OE schema, and run the following script:

create sequence CUSTOMERS_SEQ start with 1000;
create trigger CUSTOMER_INS_TRIG before insert on CUSTOMERS for each row begin select CUSTOMERS_SEQ.nextval into :new.CUSTOMER_ID from dual; end;

/

Introduction to the Completed Application

Back to Topic List

The Customer Maintenance application provides the functions to maintain customer information. It is built to provide the standard create, retrieve, update, and delete functions. There are four pages in the application:

The Browse page provides a starting point and a way to see a list of all customers. The user can select a row and either edit or delete the row. This page also provides a button that the user can use to create a new row.

The Edit page provides all of the fields that the user can modify. This page is also used for creating a new customer row. When the user creates a new row, the customer ID is not displayed because it is retrieved from a database sequence. You should have created the sequence and database trigger as a prerequisite to this workshop.

The Sure page provides a confirmation opportunity for the user before a delete is finalized. This page shows the customer row that a user is about to delete. The user can click either Yes (to delete the customer row) or Cancel (to abort the delete). In both cases, we display the correct message and navigate back to the Browse page.

The Errors page displays any error messages that are created during the delete cycle.

 

Building the Business Services

Back to Topic List

The Customer Maintenance application is based on a rather simple data model. In includes only one table, the Customers table. Oracle ADF provides a framework that makes creating and managing the persistence layer of an application easy. This framework is Oracle ADF Business Components (ADF BC). The framework provides built-in validation rules and hooks for your customization of the rules and standard behaviors. In most cases, the default behavior is sufficient; when it is not quite what the user needs, you can override whichever behaviors you choose.

Because we use the default behaviors, we can use the ADF Business Components Wizard to create the business components we need for our application. In the next few steps, you create the default business components that you use in the Customer Maintenance application.

If you would like to see a demonstration of the following tasks, click here.

 


Creating the Default Application Workspace and Projects

Back to Topic List

1.

Create a new Application workspace to hold the business model components:

  1. Select File > New, and then select the Application workspace node.
  2. Change the name of the application to CustomerMaintenance and accept the other defaults.

 

2.

When you have completed the wizard, you should have an application named CustomerMaintenance and two projects: Model and ViewController. You use only the Model project for this part of the workshop.

When you are finished, the Application Navigator should appear as follows:

 

 

Creating Default Business Components

Back to Topic List

1.

Because we are using a default set of business components, we use the ADF BC Wizard to create all of the components at the same time.

To create a set of default business components, right-click the Model project node in the System Navigator and select New.

 

2.

From the New Gallery, select the Business Components category and Business Components from Tables.

 

3.

The first step of this wizard is to establish a connection to your database. Select the connection name that connects to the OE schema.

Note: If you have not established this connection to the OE schema, please see the Prerequisites section of this workshop.

 

4.

In the next steps of the wizard, select the Customers table and create default entity and view objects and the default application module.

When you are finished, the Application Navigator appear as follows:

 

 

Customizing the View Components

Back to Topic List

1.

It is easy to create a default business service layer using the ADF BC Wizard. After you create the default components, it is usually necessary to customize the view components for your specific application.

For our application, we want only the following attributes available to the client application:

  • CustomerId
  • CustFirstName
  • CustLastName
  • CreditLimit
  • CustEmail

Double-click CustomersView to open the View Object Editor. Select the Attributes node on the left side of the editor. On the far-right side, select all of the attributes except the ones listed above. Click the single left-pointing shuttle button to remove these attributes from the list. When you are done, the list should appear as follows:

To see a demonstration of how this was done, click here.

 

2.

Click OK to accept the changes you made to the attribute list.

 

 

Testing Business Components

Back to Topic List

1.

JDeveloper includes a built-in Business Components browser for testing business components. The browser works without requiring you to build any client code.

To invoke the browser, right-click the application module that you just created in the System Navigator, and then select Test from the context menu.

 

2.

The first step of the browser is to select a database connection to use for this test. Select the database connection that you used to create the default objects, and then click Connect.

 

3.

Double-click the CustomersView1 node in the browser to see the results of the components that you just built.

 

 

Building the Basic Page Flow

Back to Topic List

Now that you have a business service model, you can build a basic page flow structure for your application. Building an application can be an iterative process. You have already built the business service layer, so you now create a basic page flow of the application. After that is complete, you develop page content. As you move through the process, you revisit the page flow and make additions and changes to make the application more robust. At the beginning of the process, you create the basic components (or building blocks) that are the foundation of the application.

Creating DataPage Components
Adding Data Components to the editCustomers Page
Connecting the Pages
Adding a Create Function

Creating DataPage Components

DataPages are the basic components of our Web-based Oracle ADF application. The first thing you do is create the basic framework of the application by creating a DataPage for each of the pages in the application. The pages are shown at the beginning of this workshop. As a reminder they are:

  • Browse page
  • Edit page
  • Sure page
  • Errors page

You add these DataPages using the Struts diagrammer in JDeveloper.

Back to Topic List

1.

Open the Struts diagram (if it is not already open) as follows. Right-click the ViewController project and select Open Struts Page Flow Diagram from the context menu.

 

2.

Now create a DataPage for each of the pages in the application.

  • browseCustomers
  • editCustomers
  • sure
  • showErrors

To create the DataPages, click the DataPage icon in the Component palette. The Component palette should be on the right side of the JDeveloper window.

You can either click the icon or click and drag it to the diagram. If you click and drag, you have control over where on the diagram the DataPage is created. Other than that, the two techniques are the same.

When you are done, your diagram should look something like this:

The DataPages you just created are now items in the Struts configuration, but they do not yet reference pages that display data in you application. The next step is to create those pages.

 

3.

In this step, you create and test the browseCustomers page. Double-click the browseCustomers DataPage to create a corresponding JSP. You are prompted for the type of page you want to create. You can select either a JSP, an HTML page, or a UIX page. For this application, select JSP.

You now have a JSP named browseCustomers.jsp. The default page that you just created is blank. The next step is to add some data- aware components.

 

4.

JDeveloper and Oracle ADF make it easy to add data-aware components to a page. There are two tabs at the bottom of the Component palette that you just used. They are the Components tab and the Data Control tabs. The Components tab show all of the nondatabound components, while the Data Control tab shows all of the ADF-databound components.

Select the Data Controls tab to see the databound components. Expand the AppModuleDataControl node to see the ADF View components that are available. In this case, there is only one ADF View component: CustomersView1 (which you created earlier).

If you expand that node, you see all of the individual data controls that are available for your use.

 

5.

The browseCustomers page displays multiple customers in a table layout style. JDeveloper provides drag-and-drop functions to create databound pages.

Make sure you are in the editor window for the browseCustomers JSP. If you are not sure, you can double-click the browseCustomers component on the Struts Page Flow diagram.

Select the CustomersView1 node on the DataControl palette. Notice the "Drag and Drop As" list at the bottom of the palette. This list shows the possible styles you can use for the selected component. Use the Read-Only Table option for this JSP. Now that you have selected Read-Only Table, drag the CustomersView1 component to the browseCustomers.jsp editor window.

NOTE: Although you have just added data components to a JSP, the starting point of this page is the Struts DataAction. The Struts DataAction prepares the model data with the business service layer so that when the JSP is rendered, the data is available for the binding objects to iterate over. Make sure to follow the instructions in the next step to run your page.

 

6.

You have just created an ADF data-aware JSP. To test your new JSP, go back to the Struts PageFlow diagram and right-click the browseCustomers node. Select Run from the context menu to launch an internal server that runs your page.

You page should look like the following:

 

7.

Now that you have a basic page, add a few navigation buttons to make it a bit more useful. You add buttons to the page the same way you added to databound Read Only Table for the CustomersView1.

Expand the AppModuleDataConrol node in the Data Control palette. Expand the CustomersView1 node and then the Operations node. Select 'Button with Form' as the Drag and Drop as value. Select the Previous Set component and drag it to the browseCustomers.jsp editor window, just below the data table. Repeat these steps for the Next Set component, except select 'Button' as the Drag and Drop as value.

After you have added the buttons, select the Form tag and change the Action property to browseCustomers.do. This property tells Struts what page to run when the form is submitted. In this case (as in most), the form you want to call is the same as the form that contains the buttons. This is the page that contains the built-in methods.

8.

Run the JSP as you did earlier and test the buttons to verify that they navigate through the list of customers.

If you want to see a demonstration of these steps, click here.

 

Adding Data Components to the editCustomers Page

In this task, you add data components to the editCustomers Page. The only difference between the browseCustomers page and this page is the type of data component that you use. On the browseCustomers page, you used a read-only table; on this page, you use an Input Form component.

Back to Topic List

1.

The first step is to create a JSP that corresponds to the editCustomers node in the Struts Page Flow diagram. You do that just as you did for the browseCustomers page: Double-click the editCustomers node and accept /editCustomers.jsp as the page name.

This opens an editor window for the editCustomers JSP.

2.

Add an Input Form data component from the Data Component palette as follows: Select CustomersView1, select Input Form from the "Drag and Drop As" list, and drag the CustomersView1 node to the editor window.

 

3.

Add two buttons to the page. Because this is an edit form, you need to add a button that accepts and processes any user input as well as a button that rejects, or cancels, any changes the user makes. Those two buttons are the Commit and Rollback buttons.

When you added the Input Form component, JDeveloper created a Submit button for you. Because we are adding our own buttons to manage the submit function, delete the default Submit button.

Add the two new buttons: Previous Set and Next Set. Make sure you are in the editCustomers window, select the Commit button from the top-level Operations node, make sure that the "Drag and Drop As" list is set to Button, and drag the button to the page within the Form tag which is highlited with a red dotted line.

Repeat this step for the Rollback button.

4.

Rename the buttons to make the page a little more user friendly. The easiest way to change the label on the button is to double-click the button and change the Value property. You can also change that property in the property inspector.

  1. Change the Commit button value to "OK".
  2. Change the Rollback button value to "Cancel".

 

5.

By default, the code that is created for the buttons includes an expression that tests to see if the button should be enabled or not. Because this is an edit form, we want both of the buttons enabled all the time.

To enable the buttons all the time, remove the following code from the button definitions.

Commit button: <c:out value="${bindings.Commit.enabledString}" />
Rollback button: <c:out value="${bindings.Rollback.enabledString}" />

When you are done, the code should look like the following:

<input type="submit" name="event_Commit" value="OK" />
<input type="submit" name="event_Rollback" value="Cancel" />

Note: To edit the code, click the Source tab at the bottom of the editor window.

 

6.

Test the page just as you tested the browseCustomers page earlier. Right-click the editCustomers node on the Struts Page Flow diagram and select run.

Notice that there is only one row available and that there is now facility to scroll through the customer rows. This is deliberate. In the next few steps, you connect the browseCustomers page and the editCustomers page. After they are connected on the page flow, the user starts and finishes with the browseCustomers page and uses the editCustomers page only for inserting or editing specific rows.

When you are done, close the browser.

Click here to see a demonstration of these steps.

 

Connecting the Pages

You have now created two databound JSPs that display related data in different ways. The next step is to connect those pages in a logical way. The browseCustomers page will serve as the starting point for the users. They will select which row they want to edit from the browseCustomers page. They can also insert a row staring on that same page. The editCustomers page is used for editing and inserting rows. We need to create several connections, called forwards, between these two pages.

In this task, you will add a few buttons to the browseCustomers page so the user can click either Edit or Create and automatically navigate to the editCustomers page. You will also add forwards from the editCustomers page back to the browseCustomers page. Those forwards relate to the user clicking either the OK or the Cancel buttons.

Back to Topic List

1.

JDeveloper and Oracle ADF provide a number of data-aware functions that make data navigation easy. In the next few steps, you will add some default behaviors, test them, and then modify them to meet specific needs.

The first thing you will do is add a function that will set the current row to any row the user clicks. The ADF Business Components model that you created earlier will synchronize all of the data without any coding on your part.

To add the method that sets the current row:

  1. Open the browseCustomers editor window.
  2. Scroll to the right side of the page.
  3. Right-click inside the last column in the table.
  4. Select Table > Insert Rows Or Columns from the context menu.
  5. Insert two columns after the selection.

These two columns will hold the links, and later the buttons, that you will add to edit a customer row.

2.

Next, add the setCurrentRowWithKey method from the data model as a link.

To add this method:

  1. Expand the CustomersView1 node in the Data Control palette.
  2. Expand the Operations node.
  3. Select setCurrentRowWithKey(String).
  4. Select FindRowLink in the "Drag and Drop As" list.
  5. Drag the setCurrentRowWithKey(String) to the first empty column in the bottom row of the data table.

You will now have the text select in that column that is a link. The link won't take the user anywhere yet, but it will set the current row to the row that they click.

 

3.

Test the page by running it from the Page Flow diagram.

Click the select link and notice that the * in the first column is displayed in the row that you click. This shows the current row changing as you click.

Click here to see a demonstration of these steps.

4.

Now that you know that the setCurrentRowWithKey method is working, you can make the link a little nicer by replacing the select text with a button. One of the nice features of the JDeveloper IDE is that you can drag an image from almost anywhere to the editor window and JDeveloper will incorporate it in your page.

Add the Edit button by saving this button to your local disk drive (right-click the image and select Save Picture As). Open Windows Explorer to the directory where you saved the image. Now drag the image to the editor window and drop it in the middle of the select text.

The IDE will prompt you to add it to the document root of the application. Click Yes and pick or create an images directory in the public_html directory.

The result should appear like the following:

In the next step, you remove the select text and set the border for this image button.

 

5.

Next, delete the select text from around the button. You can do this from either the Design window or the Source window.

After you have deleted the text, click the image to select it. Now go to the Properties palette and set the border property to 0. This will ensure that the image does not appear with a blue border around it (indicating that it is a link).

 

6.

Test the page just as you tested it earlier. Notice that when you click the image, the current row changes just as it did when it was a text link.

Click here to see a demonstration of these steps.

 

7.

Now that we have the links and buttons on the pages, it's time to add the forwards to the Struts Page Flow diagram.

The Struts controller manages page navigation by using events and forwards. The event notification is specified in the JSP, while the forwards are defined within the Struts configuration. The Page Flow diagram in JDeveloper manages the Struts configuration file so you don't have to modify the file directly.

In the next few steps, you will add forwards to the Page Flow diagram and modify one link to add an event.

 

8.

Let's start by adding the forwards to the Page Flow diagram. Open the Page Flow diagram, then go to the Component palette. Click the Forward component. To draw a forward from the browseCustomers node to the editCustomers node, click inside browseCustomers, then click inside editCustomers. If you want more control over where the line is drawn, you can click anywhere on the diagram between the two nodes.

The default name for a forward is success. Change the name of the forward to Edit.

Click here to see a demonstration of these steps.

9.

Now that you have an Edit forward on the page flow, you need to add a reference to it on the browseCustomers page.

Open the Source editor for the page. Find the Edit button link that you added earlier. Add the following event code to the link:

&event=Edit

The link should now look like:

<a href="browseCustomers.do?event=setCurrentRowWithKey&Arg0=<c:out value='${Row.rowKeyStr}' /> &event=Edit">
<img height="21" width="39" src="images/button_edit.gif" border="0"/></a>

 

10.

By adding this event reference, Struts will call the setCurrentRowWithKey method, set the current row, and then navigate through the Edit forward to the editCustomers Page.

You now need to add forwards to get back to the browseCustomers page.

Add two forwards just as you did for the browseCustomers page. This time add them from the editCustomers page to the browseCustomers page.

Name the two forwards as follows:

Commit
Rollback

Recall that these were the names of the built-in methods that you added to the page earlier. The Page Flow diagram should look something like this:

 

11.

Test the application. You should now be able to edit rows, commit the changes, and see them on the browseCustomers page. You should also be able to make changes, cancel the transaction, and see the unchanged row on the browseCustomers page.

 

 

Adding a Create Function

So far, you have created a couple of databound JSPs within a Struts-controlled application. Those pages enable browsing and editing customer information. The next step is to add the ability to create customers. JDeveloper and Oracle ADF provide a built-in function to make this task easy.

Back to Topic List

1.

Open the browseCustomers.jsp in the editor window. Select the Create operation from the data control palette. Drag it to the edit window and drop it on the form tag that contains the Previous and Next Set buttons.

2.

If you run the page now and click the Create button, Oracle ADF inserts a new blank row into the rowset iterator and stays on the browseCustomers page. The insert works but it does not do users much good: they can't add values to the row.

We really want two things to happen: insert a blank row into the rowset, and navigate to the editCustomers page so that the user can add values to the new row.

The good thing is that we have already have the capability to control navigation through Struts.

Add a forward to the Page Flow diagram from browseCustomers to editCustomers and name it Create.

 

3.

You now have the buttons and navigation in place to insert a new row. However, we want to use a sequence to populate the customerId attribute. This eliminates requiring users to create a unique value for this field; we'll do it for them.

Because we used Oracle ADF Business Components for the data model, using a database sequence for this is fairly simple.

Expand the Model node in the Application Navigator. Within the Model node, expand Application Sources > model. Double-click the Customers entity object.

In the Attributes node, select the CustomerId attribute. Change the Type property to DBSequence. Make sure the Updateable option is While New, and then click Refresh After Update.

4.

Test the new functions by running the browseCustomers page and creating a new row. Notice that when you create a row, the CustomerId field is populated with a number that doesn't look like a valid CustomerId. This is because ADF Business Components is showing you a place holder for the CustomerId. This placeholder is used by the framework until the row is committed. After a successful commit, the field is repoplulated from the value stored in the database.

Later in this workshop, you will change the display properties of the field to make it more user friendly. For now, we'll leave it the way it is.

 

5.

Click here to see a demonstration of these steps.

 

 

Adding the Delete Function with a Confirmation Page

Back to Topic List

In this task, you will add the delete function to the application. We could add the delete function in the same way that we added the create function, but the default behavior doesn't give the user a place to confirm the delete. Most applications require that the user be given the opportunity to confirm a delete action before a row is permanently deleted.

In this task, you will add a remove button and a confirmation page.


Adding a Remove Link

The first step is to create a button on the browseCustomers page. This button will look like a button, but it won't actually remove a row. It will do the same thing that the Edit button does: it will simply set the current row to the row that the user clicks. Next, it will navigate to the Delete Confirmation page. The delete confirmation page will hold the delete function.

Back to Topic List

1.

Add the Remove button to the browseCustomers page just as you added the Edit button in an earlier step:

  1. Open the browseCustomers JSP.
  2. Drag a setCurrentRowWithKey operation as a Find Row Link to the last column in the table.
  3. Add the Remove button by saving this button to your local disk drive (right-click the image and select Save Picture As). Open Windows Explorer to the directory where you saved the image. Now drag the image to the editor window and drop it in the middle of the select text.

The IDE will prompt you to add it to the document root of the application. Click Yes and pick or create an images directory in the public_html directory.

The result should look like the following:

In the next step, remove the select text and set the border for this image button.

 

2.

Next, delete the select text from around the button. You can do this from either the Design window or the Source window.

After you have deleted the text, click the image to select it. Now go to the Properties palette and set the border property to 0. This will ensure that the image does not appear with a blue border around it (indicating that it is a link).

3.

Test the page to make sure that when you click the remove button , the row is set to the current row.

4.

Now that the button sets the current row, you need to add an event (a chained event) to the link so that when the user clicks the button, Struts will navigate to the next page in the flow. In this case, you will navigate to a Delete Confirmation page that you will create shortly.

Open the Source editor for the page. Find the Remove button link that you just added. Add the following event code to the link:

&event=Delete

The link should now look like:

<a href="browseCustomers.do?event=setCurrentRowWithKey&Arg0=<c:out value='${Row.rowKeyStr}' /> &event=Delete">
<img height="21" width="39" src="images/button_remove.gif" border="0"/></a>

 

7.

The button will now set the current row and navigate to the delete event.

In the next task, you will create the Delete Confirmation page and add the forward to the Struts diagram.

 

 

Creating a Delete Confirmation Page and a Forward

The next task in building the delete process is to create a Delete Confirmation page and incorporate it into the flow of the application. Recall that in the previous task you added a button to the browseCustomers page that sets the current row and navigates to the Delete forward in the Struts page flow. In this task, you will create the Delete Confirmation page.

Back to Topic List

1.

The confirmation page in our application is named sure.jsp. The page will be a databound page with a Read Only Form based on the CustomersView1 view object.

Create the page just as you created the Edit page earlier.

If you need help with this step and would like to see a demonstration, click here.

 

2.

The page needs two buttons to make it complete: confirmation and cancel. The confirmation button is a databound delete button. Remember that users access this page only if they click the Remove button on the browseCustomers page

Although this is a real delete button, we'll disguise it by changing the label to Yes. It will look to users as if the Remove button on the browseCustomers page is the delete and that the Yes button is the confirmation, which is exactly what we want.

Add a Delete button from the Operations node (within CustomersView1). If you need help, refer to the earlier steps where you added the Create button.

Change the value property of the button to Yes.

Next add a Cancel button. An easy way to create another button is to copy and paste the button you just added. After you paste it, double-click the button to open the edit window. Change the name of the button to event_Cancel and the value to Cancel.

Add some text to the left of the button that says "Are You Sure?" Set the style to Heading 4.

 

3.

You also will need an action binding named 'Commit' that will be bound to the built-in commit operation of your UI model.

To add the Action:

  1. With your JSP page active in the Visual Editor, click the UI Model tab of the Structure window.
  2. Right-click the root node in the tree and select Create Binding > Actions > Action from the context menu.
  3. Select your data control in the Data Collection list.
  4. Select Commit as the action using the Select an Action drop-list.
  5. Click OK to continue.
4.

You can now run and test the form.

Note: Remember that this is a delete confirmation form. If you click Yes, the row will be deleted.

 

5.

Now that the confirmation page is functionally complete, we can incorporate it into the page flow.

Open the Page Flow diagram and add a Forward named Delete from the browseCustomers page to the Sure page.

Next add a Forward named Delete from the Sure page to the browseCustomers page.

The Delete forward from browseCustomers will get the user to the confirmation page. The Delete forward from the Sure page will get the user back to the browseCustomers page after a delete.

Next add a Forward named Cancel from the Sure page to the browseCustomers page. This will take the user back to the browseCustomers page after clicking Cancel.

6.

The Page Flow diagram should now look something like the following:

7.

Run the browseCustomers page. You can now edit rows, create new customer rows, and delete customers. You can also change your mind and click Cancel from the Edit and Delete confirmation pages.

All of the basic application functions are now in place. There are a couple of areas that we still need to address. First, we need to issue and handle messages that will keep the user informed. Messages like "Customer nnn has been updated," "Customer nnn has been deleted," and "Transaction canceled" will keep users from guessing what just happened and whether they were successful.

We also need to make the pages a a bit more attractive as well as internationalizable. Struts makes both of these tasks easy.

In the next task, you will address both of these issues.

 

Creating and Displaying User Messages

Back to Topic List

The application that you have created covers all the basic functions we need. We now need to add some messages that will help users know the status of any actions they choose. If they delete a row, we want to display a message showing what row was deleted. If they insert a row, we want to show them that it was successful. Likewise, it they modify a row or cancel a transaction, we need to display the appropriate message.

Because the messages are transaction-type specific, we need a way to know and keep track of which button the user clicked. We will override, or augment, some standard methods in the Struts action to maintain the transaction type as a session variable. We will also override a method to interpret the transaction type and create and store the appropriate message.


Creating Session Variables with onEvent() methods

The first step in managing the custom methods for our application is to store the type of transaction or button click that caused Struts to forward to a new page. In our case, the starting point (and ending point) of the application is the browseCustomers page. You will override the dataAction class and add code to store the transaction type.

Back to Topic List

1.

To override the Struts data action:

  1. Right-click the browseCustomers node on the Page Flow diagram.
  2. Select Go To Code from the context menu.
  3. Accept the default name and click OK.

You now have a class that you can use to augment or override standard methods and behaviors.

 

2.

In our application, we need to store the transaction type when the user clicks a button. The way to intercept the button click event is to add a method to this class with the name onEventName, where EventName is the name of the event associated with the button or link.

For example, the Edit button includes event=Edit in the href. Struts will do several things based on this event. First, it will look for a method named Edit and execute it if it exists. Second, it will look for a method named onEdit and execute that method. And finally, it will look for a forward named Edit and navigate through that forward.

We can use this pattern and add an onEdit to our override of the DataAction class.

Create a new method in the BrowseCustomersAction class as follows:

public void onEdit (DataActionContext actionContext)
{


}

The argument for this method is a DataActionContext object. When you enter this code into the class, JDeveloper will prompt you to import oracle.adf.controller.struts.actions.DataActionContext. Press [Alt] + [Enter] to add the import statement.

 

3.

Add an onEdit method to the BrowseCustomersAction.java that you created in the first step. You will do only two things in this method:

  • Store the transaction type in the session variable.
  • Perform the standard action.

The code to store the transaction uses the DataActionContext to get the HTTP Servlet Request and the Session and set an attribute within the session. The attribute name is type and the value is create. The code is:

actionContext.getHttpServletRequest().getSession().setAttribute("type", "edit");

Add this code to the onEdit method.

 

4.

Next, you need to execute the default behavior of the class. You do that by adding a call to method called doIt(). Before making the call, you want to make sure there is a good EventActionBinding. The code is:

if (actionContext.getEventActionBinding() != null) actionContext.getEventActionBinding().doIt();

Add this code to the onEdit method.

The complete method should look like the following:

public void onEdit (DataActionContext actionContext)
{

actionContext.getHttpServletRequest().getSession().setAttribute("type", "edit");

if (actionContext.getEventActionBinding() != null) actionContext.getEventActionBinding().doIt();
}

 

5.

Next, add a method to handle the Create button, name the method onCreate.

Add the same code you used for the onEdit method except set the attribute type value to create. The code should look something like the following:

public void onCreate (DataActionContext actionContext)
{

actionContext.getHttpServletRequest().getSession().setAttribute("type", "create");

if (actionContext.getEventActionBinding() != null) actionContext.getEventActionBinding().doIt();
}

 

6.

You can test the application with these changes to make sure you haven't introduced any errors, but you won't see any change in the application behavior.

In the next tasks, you will add code to interpret the session variable and create and store an appropriate message.

 

Building a Message Stack with a findForward()Method

You have added code to the browseCustomers action to store a session variable that indicates the button that the user clicked. We now need to add code to the Edit page that interprets the event and builds and stores a standard Struts message based on the event.

In this task, you will also add code to get some values from the data binding context so you can use them in the messages. We want to make our application internationalizable, so you will add the messages to the ApplicationResources.properties file in the ViewController project.

Back to Topic List

1.

The first thing we need to do is create the EditCustomersAction class. You do this just as you did in the previous step for the BrowseCustomersAction class.

2.

In this class, you will override the findForward() method to build the message stack.

The findForward() method is one of the last methods run in the DataAction class lifecycle. This makes it the best place to check the transaction type and build the message stack. The findForward()method is also where you would set the forward to a specific event based on application logic. For example you could use this method to set the forward to a notAuthorized page if certain conditions were true.

JDeveloper provides a menu option that will add method signatures and help for methods that you want to override.

First open EditCustomersAction.java in the editor window. Put the cursor in the code where you want to add the method. Select "Tools > Override methods" from the menu. Select the check box for the findForward(DataActionContext) method and click OK

This will insert the method with the proper signature into your class. Now you can begin adding the code to interpret the transaction type and build a message stack.

The complete findForward() method is included at the end of this section for your reference.

 

3.

You should carry out several housekeeping actions before you check and interpret the transaction type variable that you set earlier. Add all of the following code after the call to super.FindForward(actionContext).

First, create a List object that contains the events from the DataActionContext.

List events = actionContext.getEvents();

JDeveloper will prompt you to import the List class. Choose java.util.List for the proposed list of classes.

Check that the List is not null and that the size is greater than 0.

if (events != null && events.size() > 0)
{

 

4.

We'll work on handling errors a little later, but for now make sure that there are no errors on the DataActionContext object.

if ( !hasErrors(actionContext))
{

Your code should now look like:

protected void findForward(DataActionContext actionContext)
throws Exception
{
// TODO: Override this
// oracle.adf.controller.struts.actions.DataAction method
super.findForward(actionContext);

List events = actionContext.getEvents();
if (events != null && events.size() > 0)
{
  if ( !hasErrors(actionContext) ) // check for context errors
  {
   } // end of if ( !hasErrors(actionContext)
} // end of if (events != null && events.size() > 0)
} // end of findForward()

 

5.

If there are no errors, create an ActionMessages object to hold the user messages. A Struts application has built-in access to this object so it is easy do display messages in an ActionMessages object.

Add to following code within the if ( !hasErrors) test.

ActionMessages messages = new Action Messages();

Import the ActionMessages class as JDeveloper prompts you.

You now have an object in which to store the transaction specific messages.

 

6.

As part of the housekeeping, or preparation, for building the message, you need to get the Customer name from the Data Context. You will use this as part of the message to make it more informative. You could simply send a message like "Edit successful," but it would look better to show which customer was changed.

To get data from the context, you need to get the BindingContainer from the DataActionContext, then get the binding for a specific attribute and store the String value. The following code sets two local variables. One is set to the value of CustFirstName, and the other is set to the value of CustLastName.

DCBindingContainer bindings = actionContext.getBindingContainer();
DCControlBinding binding = bindings.findCtrlBinding("CustFirstName");
String firstName = (binding != null) ? binding.toString() : "";

binding = bindings.findCtrlBinding("CustLastName");
String lastName = (binding != null) ? binding.toString() : "";

You can now use firstName and lastName in the messages.

Your code should now look like:

protected void findForward(DataActionContext actionContext)
throws Exception
{
// TODO: Override oracle.adf.controller.struts.actions.DataAction
super.findForward(actionContext);

List events = actionContext.getEvents();
if (events != null && events.size() > 0)
{
if ( !hasErrors(actionContext) ) // if there are errors, don't create messages
{

ActionMessages messages = new ActionMessages();
DCBindingContainer bindings = actionContext.getBindingContainer();
DCControlBinding binding = bindings.findCtrlBinding("CustFirstName");
String firstName = (binding != null) ? binding.toString() : "";

binding = bindings.findCtrlBinding("CustLastName");
String lastName = (binding != null) ? binding.toString() : "";


} // end of if ( !hasErrors(actionContext)
} // end of if (events != null && events.size() > 0)
} // end of findForward()

7.

You stored the transaction type in a session variable in a previous step. In this step, you will retrieve that variable and build a message based on the value.

First, get the transactions type variable from the session variable. The code to get the session and variable is:

String type = (String)actionContext.getHttpServletRequest().getSession().getAttribute("type");

Now that you have the type, you can add logic to test for the type of transaction and set the appropriate message.

8.

Add an if statement for each of the transaction types you want to test for. So far, we have edit and create. Later in this exercise you will add a cancel transaction type, so add that test as well.

Inside each of the if statements, add a message to the message object that uses entries in the ApplicationResources.properties file along with the firstName and lastName variables you just created. The code should be as follows:

if (type == "edit")
{
messages.add("feedback",
new ActionMessage("customers.message.update.success",
firstName, lastName));
}

The first argument to the messages.add() is just a name for the entry. The second argument is an ActionMessage object. The ActionMessage() accepts a string that it uses as a key to a value stored in the ApplicationResources.properties file. At run time, the message is built and stored using the values found in the ApplicationResources.properties file. You can also append arguments to the ActionMessage which will be substituted for arguments in the ApplicationResources.properties entry.

9.

Add the following else if statements with a reference to the associated message in the resources.properties file:

"create" customers.message.insert.success, firstName, lastName
"cancel" general.message.transactionCancelled

With this addition, your code should look like the following:

protected void findForward(DataActionContext actionContext)
throws Exception
{
// TODO: Override oracle.adf.controller.struts.actions.DataAction
super.findForward(actionContext);

List events = actionContext.getEvents();
if (events != null && events.size() > 0)
{
if ( !hasErro