JDeveloper JSP Development Best Practices:                       

Thick Databases Illustrated

Dr. Paul Dorsey, Dulcian, Inc.

Roger Dorsey, DRND, Inc.

The process of building a scalable and maintainable web application has many tradeoffs to consider.  No single approach can handle all of the possible situations. However, after a few years of implementing small, medium and large web applications, several best practices have emerged.

 

The most important of these is to move as much code as possible into the database.  This is a difficult transition for most experienced application programmers to make.  Historically, applications have been built with tools that coded a great deal of complexity into the client-end.  This approach embraces an architecture that views the database as nothing more than a set of tables to hold information.  The complex set of rules for modifying data would be entirely handled by the client application.  Now, with browser-based, internet applications this approach is no longer appropriate.  The current thinking is based around the phrase “thin-client,” which can be leveraged to the point that nearly all data collection, validation, navigation, and error handling is performed in the database.

 

 

Figure 1: Data update and validation path

 

Consider building a simple application that attempts to update a single record.  During the update process, the client code would only capture and submit the information the user wishes to update.  The remainder of the validation and logic for correctly applying the updates would be handled with code in the database.   If the database validation fails, a custom error message is sent back with information that will direct the client to re-display the update record page.  If the validation succeeds, the database directs the client code to a Success Page as shown in Figure 1.

 

The majority of the work required to build this simple web application will be in the creation of the appropriate database objects.  When the database is complete, the remaining work is equally divided between the middle tier (ADF BC) objects, Struts diagram, and page layout.


For this training session, you will do the following:

1.       Analyze a set of business rules to display information for a given employee.

2.       Update the manager to whom the employee reports by selecting one of the managers in the list-of-values (LOV).

 

The completed application will look something like Figure 2.

 

 

Figure 2: Sample Employee/Manager Application

I. Exploring the Human Resource (HR) schema

The application you will build will be based on Oracle’s sample HR schema, plus a few additions. 

The HR schema tables shown in Figure 3 have been created to store simple business organizational information.  The schema has implemented a number of hierarchical relationships between the objects stored in these tables using traditional database constraints.  You can examine the REGIONS table shown in Figure 4 by selecting Tools/SQL Worksheet and typing in the statement shown in Figure 4.

Figure 3: HR Schema Tables

 

Figure 4: HR Schema Regions Table

 

The COUNTRIES table shown in Figure 5 is a child of the REGIONS table.  Notice the Foreign Key (FK) column for the parent table on the right (REGION_ID).

 

Figure 5: HR Schema Countries Table

 

 

Going to the next levels, the LOCATIONS, DEPARTMENTS and EMPLOYEES tables are shown in Figures 6, 7 and 8.

 

Figure 6: HR Schema Locations Table

 


Figure 7: HR Schema Departments Table

 

Figure 8: HR Schema Employees Table

 

Another hierarchical relationship has the JOBS table at the top as shown in Figure 9.

 

 

Figure 9: HR Schema Jobs Table

 

Since employees can have many jobs, and the same job title may be held by many employees, you will need an intersection table to capture the many-to-many relationship between EMPLOYEES and JOBS.  Thus a JOB_HISTORY table was added as shown in Figure 10.

 

Figure 10: HR Schema Job History Table

 

Looking a little deeper at the actual data in these tables, you may discover a few surprises.   Try the following: Collect the Manager IDs that are currently assigned in the EMPLOYEES table as shown in Figure 11.

 

 

Figure 11: Manager IDs

 

Next add JOB_ID   LASTNAME, and FIRSTNAME to your query. You will discover that the employee with EMPLOYEE_ID = 103 is an IT_PROG (Programmer) acting as a manager because his EMPLOYEE_ID is listed in the MANAGER_ID column as shown in Figure 12.

 

 

Figure 12: Manager Names

 

Look the Shipping Dept (Dept 50) shown in Figure 13. It has 5 managers!  All of the managers in this department report directly to the President, but only one (121) is listed in the DEPARTMENTS table (shown in Figure 7).  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Figure 13: Data in the HR Schema

 

The following are the business rules for changing the manager to whom an employee reports:

a)       An organization that allows for multiple managers in each department (or no manager at all)

b)      Employees may report to any of the managers within the department.  (Employees who are acting as Managers, report to a manager in another department)

c)       Only the President may have a null manager_id.

d)      Employees may be managed by a non-manager.

 

When building your business logic to support updating an employee’s manager, you will need to take these business rules into account.  Also, additional database objects will be needed to give the end user appropriate feedback when they select an inappropriate manager.

 

The following exercises will guide you through the process of implementing the business rules above using the HR Schema.

II. Building the application

In this section, you will learn how to build a simple application using JDeveloper.

 

Database

The following items needed to be added to the database in order to support the proposed architecture of housing all of the validation and complex logic to update a single column in the database.

 

Implement a database View with a multi-table join that represents “Page One” in the application.  (Just use the EMP_DETAILS_VIEW from the HR schema)

3.       Create an INSTEAD OF trigger on the database view, to update the underlying table.

4.       Create a database table to hold custom error messages.

5.       Create a database package to hold package variables that store the current error.

6.       Create a database one-row view to expose custom error messages.

7.       Create a JUNK table for debugging.

8.       Create a Sequence Counter to populate ORDER_NR in the JUNK table.

9.       Create an autonomous_transaction Procedure to populate the JUNK table.

 

1. Create an INSTEAD OF Trigger

INSTEAD-OF Trigger on “PageOne” View (Emp_Details_View)

 

CREATE OR REPLACE TRIGGER t_iu_emp_details_view

 INSTEAD OF

  UPDATE

 ON emp_details_view

REFERENCING NEW AS NEW OLD AS OLD

declare

 current_exception_Id number;

 old_mgr_job_Id varchar2(10);

 new_mgr_Job_id varchar2(10);

 

--cursor to get custom error message

 cursor current_Exception_info(cin_current_exception_Id NUMBER) is

    select exception_CD from brim_exception

    where exception_id = cin_current_exception_Id;

 current_exception_CD_Row current_Exception_info%ROWTYPE; 

 

 --cursor to get job_id for old manager

 cursor old_manager_Info is

    select job_Id from employees

    where employee_id = :old.manager_id;

 old_job_id_Row  old_manager_Info%ROWTYPE; 

 

--cursor to get job_id for new manager

 cursor new_manager_Info is

    select job_Id from employees

    where employee_id = :new.manager_id;

 new_job_id_Row  new_manager_Info%ROWTYPE; 

 

--Now check for updates,

--then apply logic to either update, or throw error messages

Begin

if updating ('manager_id') then

 --Capture Debug Information 

 --p_junkauton('employee_id= '||:old.employee_id||

 --            ',  oldmanager_id= '||:old.manager_id||

 --            ',  newmanager_id= '|| :new.manager_id);

  

 --check rules  

 --get job_id for old manager

 open old_manager_Info;

  fetch old_manager_Info into old_job_id_Row;

  close old_manager_Info;

   

 --get job_id for new manger

 open new_manager_Info;

  fetch new_manager_Info into new_job_id_Row;

  close new_manager_Info;  

 

 --first rule: special case of Deceased managerId =176

 if :new.manager_id = 176 then --managerId =176  Taylor, Jonathon

   current_exception_Id := 20;--Error: This manager is deceased

   

 --else test:   if old manager job_id is different from new manager job_id

 elsif  nvl(nvl(old_job_id_Row.job_Id,new_job_id_Row.job_Id),'zasdfg') =

        nvl(nvl(new_job_id_Row.job_Id, old_job_id_Row.job_Id) ,'zasdfg') then

   --if same   no error

   current_exception_Id := -1;

 else -- if different create error message

   --Error: the manager you have selected is in a different area.

   current_exception_Id := 10;

 

 end if;

 

 --Check current_exception_Id for error  (not equal to -1)

 if (  current_exception_Id != -1) then

   --cursor to get custom error message

   open current_Exception_info(current_exception_Id);

    fetch current_Exception_info into current_exception_CD_Row;

    close current_Exception_info;

 

 --Capture Debug Information     

 --p_junkauton('current_exception_Id= '||current_exception_Id||

 --            ', current_exception_CD_Row.exception_CD= '||

 --            current_exception_CD_Row.exception_CD );       

 

 -- now update package variables that brim_error_view is based

 dml_error.setmessage(10, current_exception_CD_Row.exception_CD);

  

 else

   -- no rules broken proceed with update

   update employees set manager_id = :new.manager_id

   where employee_id = :old.employee_id;

 

   --clear any error message

   dml_error.clearmessage;

  end if;

 end if;

END;

 

 

2. Create a database table to hold custom error messages when validation fails

 

CREATE TABLE brim_exception

(exception_id                   NUMBER NOT NULL,

 exception_cd                   VARCHAR2(200) NOT NULL,

 descr_tx                       VARCHAR2(2000))

/

 

 

 

3. Create a database package to hold package variables that store the current error

 

CREATE OR REPLACE

PACKAGE dml_error

IS

--****************************************************--

--this package handles all brim exceptions

--*****************************************************--

 

-- Package Variables to store the current error message

Id Number;

Message Varchar2(2000);

 

-- procedures to set and clear the package variables

procedure SetMessage(NewId Number, NewMessage varchar2);

procedure ClearMessage;

 

-- functions to get the current error message

function GetId return Number;

function GetMessage return Varchar2;

 

END;

/

 

CREATE OR REPLACE

PACKAGE BODY dml_error

IS

--****************************************************--

-- Purpose: provide get/set procedures/functions to access package variables

--****************************************************--

  function GetId return Number is

  begin

    return Id;

  end;

 

  function GetMessage return varchar2 is

  begin

    return Message;

  end;

 

  procedure ClearMessage is

  begin

    Message:=null;

    id:=null;

  end;

 

  PROCEDURE SetMessage ( NewId IN Number,

                         NewMessage IN  varchar2)

  IS

  BEGIN

    Id :=NewId;

    Message := NewMessage;

  EXCEPTION

    WHEN OTHERS THEN

      null ;

  END;

END;

/

 

 

4. Create a database one-row view to expose custom error messages.

 

create or replace view brim_error_view (

    code,

    message )

AS

select dml_error.getid Id,

       dml_error.getmessage Message

from dual

 

                                       

5. Create a JUNK table for debugging purposes:

-- sequence counter for JUNK

 

CREATE SEQUENCE junk_seq

  INCREMENT BY 1

  START WITH 101

  MINVALUE 1

  MAXVALUE 999999999999999999999999999

  NOCYCLE

  ORDER

  CACHE 20

/

 

 

-- create table for JUNK

 

CREATE TABLE junk

(junk        VARCHAR2(4000),

 creat_dt    DATE DEFAULT sysdate,

 order_nr    NUMBER DEFAULT 0

)

/

 

 

-- Triggers for JUNK

 

CREATE OR REPLACE TRIGGER ui_junk

 BEFORE

  INSERT

 ON junk

REFERENCING NEW AS NEW OLD AS OLD

 FOR EACH ROW

begin

    select junk_seq.nextval

    into :new.order_nr

    from dual;

end;

 

An autonomous_transaction Procedure to populate the JUNK table:

CREATE OR REPLACE

PROCEDURE p_junkauton

   (in_tx varchar)  is

    PRAGMA AUTONOMOUS_TRANSACTION;

 begin 

   insert into junk (junk) values(in_tx);

 commit;

 

END; -- Procedure

/

 

 

NOTE: You can now add the P_junkauton() procedure in any of your database PL/SQL.  This allows you to capture debug data even if an exception is thrown, due to the autonomous_transaction and associated inner commit.  The sequence counter populating the order_nr guaranties that you can put P_junkauton() in several places and still tell which piece of code executes first.

 

The following code could be included in the trigger used above as an aid to debugging.

--Capture Debug Information 

p_junkauton('employee_id= '||:old.employee_id||

            ',  oldmanager_id= '||:old.manager_id||

            ',  newmanager_id= '|| :new.manager_id);

 

This screenshot shows an example of the debugging information that would be placed in the Junk table to view old and new values.

 

 

 


 

II. Working with JDeveloper Middle Tier - ADF BC

The following is a summary of steps that you will use to explore JDeveloper and build a simple web application module. Each step is explained in more detail with screen shots showing what you should see as you complete each one.

 

A.      Create a database connection (Username: dulcian Password: oracle).

B.      Create a new Application Workspace based on the Web Application (default) template.

C.      Build ADF BC View objects to handle read-only data:

·         Custom error messages (BrimErrorView)

·         List-Of-Values (LOV) to update a given field on “PageOne” (MgrLOVView)

D.     Build ADF BC entity and view objects to handle read/write data:

·         Point to the custom database View for “PageOne” (PageOneEmpDetailsView)

E.      Build ADF BC ApplicationModule to:

·         Expose ADF BC Views to the client.  (AppModule)

·         Expose custom java code in the AppModuleImpl.java to the client. (getBrimErrorMessage)

 

A. Create a database connection

1.       Select the Connections tab of the Navigator. If it is not visible, select View | Connection Navigator from the menu.

2.       Right-click the Database node and select New Database Connection. If the Create Database Connection - Welcome page appears, click Next.

3.       On the Type page of the Create Database Connection wizard, enter “dulcian” for the Connection Name. Leave the Connection Type on the default setting - Oracle (JDBC). Click Next.

4.       On the Authentication page, enter “dulcian” as the Username and “oracle” as the password. Leave the Role field blank. Check the Deploy Password checkbox as shown in Figure 14. Click Next.

 

 

Figure 14: Connection Manager Authentication page

5.       On the Connection page, leave the default settings (thin, localhost, 1521, ORCL) and click Next.

6.       On the Test page, click the Test Connection button. A “Success!” message should appear in the Status window. Click Finish. You will see the new connection listed in the Navigator. If it doesn’t, go back and check the previous steps.

 

B. Build an application workspace based on the Web Application Template

1.       Click the Applications Navigator tab. If it is not visible, select View|Application Navigator from the menu.

2.       Right-click the Applications node and select New Application.

3.       Fill in the Application Name as shown in Figure 15 and select Web Application [JSP, Struts, ADF BC] from the Application Template pulldown. Click OK.

4.       NOTE: The Application Template contains default projects that are oriented toward a certain technology such as Struts. The template affects what options and objects are available by default for use in the projects. Almost all of the lists in 10g are context-sensitive, so inappropriate options are rarely available.

 

 

 

Figure 15: Create Application dialog             

You will now see  _JSP_Struts_HR_DeptEmpView_IOUG in the Applications Navigator along with the Model and ViewController nodes created as part of the Web Application template.

NOTE:  When items in the Navigator are shown in italics, this means that they have not been built (compiled). When you click either the Make or Rebuild icons on the toolbar, the italics will disappear. This is a handy way to tell when something in JDeveloper has been changed since any “unbuilt” items will show in italics.

 

C. Build ADF BC View objects to handle read-only data

The next step is to create the view objects needed for this simple application. There are two basic ways to build ADF BC View Objects that are intended for read-only data.  One way is designed to build the query automatically when it can be based on a database table or view.  The second way presents an empty text box where you must enter the desired code. 

 

1. Create Business Components

The first step is to create the business components needed for the application.

a)       To create the appropriate view objects, right click the Model node in the Applications - Navigator and select New.

b)      In the New Gallery, select the ADF Business Components category (under Business Tier) and Business Components from Tables from the Items list as shown in Figure 16.  Click OK.

 

 

 

Figure 16: New Gallery

 

c)       When the Initialize Business Components Project dialog appears, make sure that the new database connection (dulcian) you created earlier appears in the pulldown. Leave the other settings and click OK.

 

d)      The Create Business Components from Tables Welcome page will appear. Click Next.

 

e)       On Step 1, of the Wizard, Entity Objects, if necessary, uncheck the Tables checkbox and check the Views checkbox. If the Auto-Query checkbox is unchecked, you will need to press the Query button to see the available views. You should see BRIM_ERROR_VIEW and EMP_DETAILS_VIEW.

 

f)        Select EMP_DETAILS_VIEW and click the right arrow to move it to the selected column. Use the Entity Name field to change the Entity Name to “PageOneEmpDetailsView.”  Click Next.

 

g)       On the Updateable View Objects page, select PageOneEmpDetailsView and click the right arrow to move it to the selected window. Click Next.

 

h)       On the Read-Only View Objects page, ensure that the Tables checkbox is unchecked and that the Views checkbox is checked as shown in Figure 17. If you have checked the Auto-Query checkbox on this dialog, JDeveloper automatically read the database to present the database objects; otherwise they may not appear immediately. Select BRIM_ERROR_VIEW and click the right arrow to move it to the Selected window. Note that JDeveloper adds an additional “View” suffix to the name. In the View Name Field, delete the extra “View” as shown in Figure 17. Click Next. 

 

 

Figure 17: Selecting Read-Only View Objects

 

 

i)         On the Application Module page, leave the default settings and click Next. Since this is the first time you used the Business Components from Tables wizard, you are able to create and populate the Application Module.  Later you will clean up the code that is generated, and add the rest of the objects needed for the user interface code.

 

j)         Click Next on the Diagram page.

 

k)       You can review your selections on the Finish page and go Back if needed. Otherwise, click Finish. You will see the additions in the Navigator which should look like Figure 18. Click the Rebuild button to compile the code.

 

NOTE: By default, JDeveloper may name the AppModule view object instances with a trailing number such as 1, 2, 3...etc. as shown in the Structure pane in Figure 18. This is not helpful or useful. It is recommended that you delete these extra instances and rename them appropriately to avoid confusion. You will do this in later in the practice.

 

Figure 18: Application Navigator/Structure pane

 

l)        Double click BrimErrorView in the Navigator to open the View Object Editor. Select the Java node. Under ViewRow Class: BrimErrorViewRowImpl, check the Generate Java File checkbox. Click Apply and OK.

 

2. Create a New View Object

The next step is to create a new view object to support the manager LOV.

 

a)       Right-click the top level Model node in the Applications Navigator and select New. Select the ADF Business Components category and the View Object item. Click OK.

 

b)      Click Next if the Welcome page of the Create View Object Wizard appears.  Leave the default package name and enter “MgrLOVView” for the Name. Ensure that the “Rows Populated by a SQL Query with” radio button is selected.  Select the Read-only Access radio button and click Next.

 

c)        On the SQL Statement page of the Create View Object wizard, manually add the following query in the Query Statement window:

SELECT a.employee_id, job_ID ||'      '||

a.last_name ||', '||a.first_name AS mgr_name

FROM employees a

WHERE a.employee_id in(

SELECT 176 as manager_id FROM dual

UNION ALL

SELECT DISTINCT emp.manager_id

FROM employees emp)

 

d)      It is a good idea to click the Test button to test your code. You should receive a “Query is valid” message. Click OK and Next.

 

e)       Accept the default settings on the Bind Variables page and click Next.

 

f)        Review the information on the Attribute Mappings page and click Next.

 

g)       Click Next on the Attributes page.

 

h)       On the Attribute Settings page, verify that EmployeeId shows in the Select Attribute pulldown.  Ensure that the Queryable and Mapped to Column or SQL checkboxes are checked. The Employee ID must also have the Key Attribute checkbox checked as shown in Figure 19.

 

Figure 19: Attribute Settings

 

i)         Use the Select Attribute pulldown to select the MgrName attribute. Ensure that the Queryable and Mapped to Column or SQL checkboxes are checked. You do not need to select the Key Attribute checkbox for this attribute. Click Next.

j)         Click Next on the Java page and Finish to complete the Create View Object Wizard.

 

k)       Click the Rebuild icon on the toolbar to compile the project. Make sure that the status bar at the bottom of the screen and Messages Log show a successful compilation.

 

l)         If desired, you can use the query above in the JDeveloper SQL Worksheet (Tools | SQL Worksheet) to retrieve the Manager Names for each Employee ID in the HR database as shown in Figure 20.

 

 

Figure 20: Retrieving Manager Names

 

 

3. Remove extra columns to pass only data needed and remove generated RowID

 

a)       Double click PageOneEmpDetailsViewView to open the View Object Editor. Click the Attributes node (not the plus sign). In the Selected pane, hold down the Ctrl key and highlight the following unnecessary attributes: JobId, LocationId, CountryId, Salary, CommissionPct, CountryName, and RegionName. Click the left arrow to move these out of the Selected pane. Click Apply and OK.

 

b)      Double click PageOneEmpDetailsView to open the Entity Object Editor. Click the Attributes node (not the plus sign). In the Entity Attributes pane, hold down the Ctrl key and highlight the following unnecessary attributes: JobId, LocationId, CountryId, Salary, CommissionPct, CountryName, RegionName and click the Remove button. You should now have the following entity attributes: EmployeeId, ManagerId, DepartmentId, FirstName, LastName, DepartmentName, JobTitle, City, StateProvince and RowID. Click Apply.

 

c)       If not already expanded, click the plus sign next to the Attributes node. Click the EmployeeId attribute. Check the Primary Key checkbox. Ensure that the Persistent, and Mandatory and Queryable checkboxes are also checked as shown in Figure 21. Click Apply.

 

 

Figure 21: Entity Object Editor

 

d)      Select RowID from the Attributes List and uncheck the Primary Key checkbox to allow you to delete it. Click Apply and OK.

 

e)       Double click PageOneEmpDetailsViewView in the Navigator. Click the RowID attribute in the Selected column and click the left arrow to remove it. Click Apply and OK.

 

f)        Double click PageOneEmpDetailsView in the Navigator. Select the RowID attribute and click the Remove button. Click Apply and OK.

 

g)       Click the Rebuild icon in the toolbar to compile the project.

 

 

4. Update the ADF BC Application Module

a)       Double click AppModule in the Navigator to access the Application Module Editor.  Select the Data Model node.

 

b)      Move all of the items from the Data Model side out of the pane one at a time using the left arrow.

 

c)       Using the right arrow and the Name and Instance Name fields, move and rename the View Objects so that the Application Module Editor Data Model window (right side) looks like Figure 22. You can either rename the object in the Available View Objects side before moving it to the Data Model side or rename the Instance after it is moved to the Data Model side. Click Apply after each name change to save it.

 

 

Figure 22: Application Module Editor

 

d)      Click OK. The Structure pane should look like Figure 23. Click Rebuild to compile the project.

 

Figure 23: AppModule Structure pane

 

e)       In the AppModule - Structure pane, double click AppModuleImpl.java to access the code editor.

NOTE: AppModuleImpl.java file is where you add custom Java code.  This file works with the ADF data bindings to provide you with drag & drop access for your custom code.

 

f)        To add the following code (methods) at the top of the AppModuleImpl.java file just below the class declaration: public class AppModuleImpl extends ApplicationModuleImpl, click after the curly bracket and press Enter to add a new line. Paste or type in the following code:

 

public String getBrimErrorMessage()

{

  //Clear any previous error messages

  this.getTransaction()

      .executeCommand("Begin dml_error.clearmessage(); End;");

  

  //send data down to the database

  this.getTransaction().postChanges();

 

  //check for any error messages

  this.getBrimErrorView().executeQuery();

  if( this.getBrimErrorView().first()!=null && 

          ((BrimErrorViewRowImpl)this.getBrimErrorView().first())

          .getMessage()!=null &&

          (((BrimErrorViewRowImpl)this.getBrimErrorView().first())

          .getMessage()).length()>0)

  {

    //refresh clean data from database

    int currentRowIndex = this.getPageOneEmpDetailsViewView()

                             .getCurrentRowIndex();

    this.getPageOneEmpDetailsViewView().executeQuery();

    this.getPageOneEmpDetailsViewView().setRangeStart(0);

    this.getPageOneEmpDetailsViewView()

       .setRangeSize(getPageOneEmpDetailsViewView().getRowCount());

    this.getPageOneEmpDetailsViewView()

       .setCurrentRowAtRangeIndex(currentRowIndex);

    this.getTransaction().commit();

 

    return "isError";    

  }

 

  //when no errors are found – return success

  return "success";

}

 

 

public void setPageOneToEmp125()

{ //get all employee rows

  this.getPageOneEmpDetailsViewView().executeQuery();

  //set all rows to be in the current “Range”

  this.getPageOneEmpDetailsViewView().setRangeStart(0);

  this.getPageOneEmpDetailsViewView()

      .setRangeSize(getPageOneEmpDetailsViewView().getRowCount());

  //for testing - select an employee from the shipping department

  this.getPageOneEmpDetailsViewView().setCurrentRowAtRangeIndex(25);

}

 

g)       Click the Rebuild icon to compile the code.

NOTE: If there are errors when you compile the code, they are likely due to a problem with the view    names. Check to make sure that the view names in the Navigator match the names in the code.

 

h)       Double click AppModule in the Navigator to access the Application Module Editor. Expose the custom methods by clicking the Client Interface node and moving both of the available methods into the Selected panel using the double arrows. Click Apply and OK.

 

i)         Click the Rebuild icon and make sure that the project compiles with no errors. Close the AppModuleImpl.java window by clicking the X on the tab.

 

 

III. Build the JSP Struts Client

Now you are ready to create the JSP/Struts portion of your application.

 

Create the Struts Page Flow Diagram

j)         Right-click the View Controller node in the Navigator and select Open Struts Page Flow. The Component Palette or the Data Control Palette will be displayed on the right side of the screen (In version 10.1.3 the tabs will be shown on the far right-hand side of the IDE) and the blank diagram will be in the center. If the palettes are not displayed, go to View |Component Palette and select the appropriate one.

 

k)       If necessary, click the Components tab and select Struts Page Flow in the pulldown to display the Struts Page Flow components. Drag an Action component from the Component Palette on to the struts-config.xml diagram.

 

l)         Click the name area and rename it “/startHere”. Press Enter.

 

m)    Click the Components tab again. Add a “Welcome” page by dragging the Page icon on to the diagram. Click in the name area to rename the page “/welcomePage.jsp”. Press Enter.

 

n)       Add a Data Page and rename it “pageOneDP”. Press Enter. This page actually consists of the components shown in Figure 24.

 

 

Figure 24: Data Page components

 

 

o)      Add another Page and rename it “/successPage.jsp”. Arrange the diagram as shown in Figure 25.

 

Figure 25: struts-config.xml diagram

 

p)      You will need to double click each of the components to create them. Click OK on the Struts Action dialog for the /startHere Data Action. You will then see the code file in the main window. An additional tab will be added to the work area. Click the X in the right corner of the tab header to return to the struts-config.xml diagram.

q)      Double click /pageOneDP. The Create JSP Wizard will start. Click Next on the Welcome page.

·         On the JSP File page, leave the radio group default selection and File Name and click Next.

·         On the Error Page Options page, leave the “Do Not Use and Error Page to Handle Uncaught Exceptions in This File” radio button selected and click Next.

·         On the Tag Libraries page, select Struts HTML 1.0 and Struts Logic 1.0 libraries and move these to the Selected Libraries pane using the right arrow. Click Next.

·         On the HTML Options page, click Next and Finish to complete the wizard.

·         Close the pageOneDP.jsp page by clicking the right corner X of the page tab.

 

r)       Double click the welcomePage. Click the X in the right corner of the page tab to close it.

s)       Double click the successPage. Click the X in the right corner of the page tab to close it.

 

1. Add Navigation and custom logic

 

Use the following steps to add the page navigation and logic to the application.

 

a)       Click Page Link in the Component Palette. Then click the welcomePage and pageOneDP to connect them as shown here:


NOTE: If needed, you can right click on the line and select Straighten Lines to clean up the diagram.

 

b)      Expand the ViewController, Application Sources, and view nodes in the Applications - Navigator. Double click the ApplicationResources.properties node to view ApplicationResources.properties for the Link’s displayed text:
       Change “link.pageOneDP=link to /pageOneDP.do” to “Go to Page 1.” Close the window by clicking the X on the ApplicationResources.properties tab. Click Yes on the Save Files dialog.

c)       On the struts-config.xml diagram, add a Page-Link from the Success page back to PageOne as shown here.

NOTE: You can create nodes in the lines you draw by simply clicking and changing directions as you draw.




d)      Add a DataAction and place it as shown in Figure 26. Rename it /getBrimError. Press Enter

e)       Add a Forward from pageOneDP to getBrimError. Double click the “success” word and rename the Forward “Submit”. Press Enter.

f)        Add a Forward from getBrimError to pageOneDP, rename to “isError”. Press Enter.

g)       Add a Forward from getBrimError to successPage.jsp, leave name as “success” Your diagram should look something like Figure 26.

 

 

Figure 26: Dragging & Dropping from the Data Control Palette

 

h)       Switch from the Component Palette to the Data Control Palette or use View | Data Control Palette to redisplay it. Expand the AppModuleDataControl and Operations nodes. Drag & drop getBrimErrorMessage( ) from the Data Control Palette on top of the /getBrimError data action on the struts-config.xml diagram. You will not see any change in the diagram but you will see additions in the Navigator.

 

i)         Double-click /getBrimError to open the ADF PageController dialog. Click OK to create the GetBrimErrorPageController class. The GetBrimErrorPageController.java file will open.

 

j)         Place cursor after the first open bracket following PageController. Select Source | Override Methods from the JDeveloper menu. In the Override Methods dialog, select the checkbox next to the prepareRender method. Click OK. You will see the new code added to the file.

 

k)       Click the + sign next to the import code line (import will be highlighted in blue). You should see the following:

import oracle.adf.controller.v2.context.LifecycleContext;

import oracle.adf.controller.v2.lifecycle.PageController;

 

Add the following import statement under the statement shown above:

import oracle.adf.controller.v2.struts.context.StrutsPageLifecycleContext;

 

l)         Locate the following  line in the new code:

     super.prepareRender(context);

     

m)    Insert the following code between the above line and the closing bracket for the prepareRender method:

 

  String myMethodResult = (String) context.getBindingContainer()

                     .getOperationBinding("getBrimErrorMessage").getResult();

  StrutsPageLifecycleContext myContext = (StrutsPageLifecycleContext)context;

  myContext.setActionForward(myMethodResult);

           

n)       Press the Rebuild icon to compile the code. Make sure it compiles with no errors.

 

o)      Close the GetBrimErrorPageController.java file by clicking the X on the tab.

 

p)      Click the Components Palette tab and add a DataAction between the startHere dataAction and the welcomePage as shown in Figure 27.

 

q)       Add a Forward from startHere to dataAction1

 

r)        Add a forward from dataAction1 to the welcomePage. The diagram should now look like Figure 27.

Figure 27: struts-config.xml Diagram

 

s)        Click the Data Control Palette tab. If needed, expand the AppModuleDataControl node. Drag and drop the setPageOneToEmp125( ) operation onto the /dataAction1 component in the struts-config.xml diagram. You will not see any change in the diagram.

 

t)        Click the Rebuild icon to compile the project.

 

2. Edit the JavaServer Page

You can now edit the Java Server Page you created.

 

a)       Double click /welcomePage.jsp to edit the Welcome page.  Click next to the link.pageOneDP marker, press Enter and type “Welcome”.  If desired, you can use the pulldowns and other text edit buttons to change the look of the text.  For this practice, select Heading 1 from the first pulldown (showing Paragraph). Note the font change.

 

b)      Click the struts-config.xml tab. Double click successPage.jsp, click next to the message link.pageOneDP, press Enter and type “Success!” If desired, you can use the pulldowns and other text edit buttons to change the look of the text.  For this practice, drag over the word and click the B to make the text bold.

 

c)       Close both of the JSP pages by clicking the X on each tab. Answer Yes to the Save Files dialog for both.

 

3. Edit pageOneDP

In this section you will edit the data page.

a)       Double click pageOneDP to open the blank page. From the Data Control Palette, if needed, expand the AppModuleDataControl and select PageOneEmpDetailsViewView.  Drag and drop the PageOneEmpDetailsViewView onto /pageOneDP.jsp. When the menu appears, select Create>Forms> InputForm. You will see something like this:




b)      Add Navigation buttons by selecting PageOneEmpDetailsViewView in the Data Control Palette again and Drag and Drop under the Submit button. When the menu appears, select Create>Forms> Navigation Buttons. Be sure to drop the navigation buttons inside of the red dotted line.

 

c)       In the Application Navigator, expand the ViewController|Application Sources| view.pageDefs nodes and select the pageOneDPPageDefs.xml file. Then in the Structure pane, expand the pageOneDPPageDef|executables nodes and select PageOneEmpDetailsViewViewIterator, and change the range size to -1 in the Property Inspector. (If the Property Inspector is not showing, go to View|Property Inspector). Press Enter to save the change.

 

4. Construct the ManagerID LOV

a)       In preparation for creating the ManagerID LOV it is necessary to delete the ManagerID Input Field from the JSP page. Select the field next to the {$bindings[‘ManagerID’].label} in the pageOneDP.jsp and press the Delete key. The page should look like this:




b)      Expand the PageOneEmpDetailsViewView node in the Data Control Palette. Select ManagerID and Drag and Drop As List of Values into the blank cell next to Out-${bindings[‘ManagerId’] label}. A drop down arrow will appear as shown in Figure 28.



Figure 28: Adding a List of Values (LOV)

5. Edit the ManagerId with the List Binding Editor

a)       In the Application Navigator, expand the ViewController/Application Sources/view.pageDefs nodes and select the pageOneDPPageDefs.xml file. Then in the Structure pane, expand the pageOneDPPageDef/ bindings nodes and double-click PageOneEmpDetailsViewViewManagerId to open the List Binding Editor as shown in Figure 29.

b)      Set the List Data Source by clicking the Add button on the right, and then select the MgrLOVView data control. Click OK.

c)       Set the List Items | Display Attribute to MgrName using the LOV.

d)      Set the “No Selection” Item: to Include Blank Item. Click OK.

Figure 29: List Binding Editor

e)       On the Data Control Palette, expand the BrimErrorView node. In order to add error feedback to pageOneDP, drag and drop Message as a Value just above EmployeeId as shown in Figure 30.

 

 

Figure 30: Adding error feedback message

 

f)        Change the bindings.Message color to red by selecting it and clicking the color text Icon (the one with the A).

 

g)       Close the pageOneDP.jsp window by selecting the tab and clicking the X. Answer Yes in the Save Files dialog.

 

h)       In the Application Navigator, expand the ViewController/Application Sources/view.pageDefs nodes and select the pageOneDPPageDefs.xml file. In the Structure pane,  if not already done, expand the pageOneDPPageDef | executables nodes and select ManagerLOVViewIterator, and verify the range size is set to -1 in the Property Inspector.

 

i)         Click the Rebuild icon to compile the application. Make sure there are no errors showing in the Messages window.

 

IV. Test the Application

You are now ready to test the application. 

 

a)       In the struts-config.xml diagram, right click startHere and select Run. The Embedded OC4J Server will start and the messages window will display the progress.  Depending upon your setup, this may take some time.

 

b)      The default browser will open to display the Welcome page with a link to the pageOneDP.do. Click the link to display the page shown in Figure 31.

 

Figure 31: Completed JSP page

 

c)      Test the application by clicking the First, Next and Last buttons. You can also view the list of Managers using the pulldown.

d)      Test the error checking by selecting a manager from a different department and click the Submit button.