Professional Documents
Culture Documents
D53979GC20
Edition 2.0
July 2010
D68162
Authors
Kate Heap, Patrice Daux
Oracle Tutor
If this documentation is delivered to the United States Government or anyone using the documentation on behalf of the United
States Government, the following notice is applicable:
Table of Contents
Practices for Lesson 1 .....................................................................................................................................1-1
Practices for Lesson 1: Introduction to Oracle Fusion and Oracle ADF .........................................................1-3
Oracle Fusion Middleware 11g: Build Applications with ADF I Table of Contents
i
Oracle Fusion Middleware 11g: Build Applications with ADF I Table of Contents
ii
Oracle Fusion Middleware 11g: Build Applications with ADF I Table of Contents
iii
Oracle Fusion Middleware 11g: Build Applications with ADF I Table of Contents
iv
Chapter 1
Chapter 2
In the practices for this lesson, you start JDeveloper, set preferences for the IDE, and create a
JDeveloper application, project, and database connection. You then view the course application
in a browser and identify the functionality of the pages.
2.
c.
Entity
EO
View Object
VO
Application Module
AM
Select Packages in the list at the left and set the following values:
Entity
entity
View Object
uiview
Application Module
module
a.
b.
c.
d.
d.
Click OK.
a.
2)
3)
4) Click Next.
On the Name your project page of the wizard:
1) Enter StorefrontModel as the project name.
On the Project Technologies tab, shuttle ADF Business Components and
Database (Offline) from the Available list to the Selected list. (This also selects
the Java technology.)
3) Click Finish.
Note that the Application Navigator displays your application and project.
2)
b.
c.
Also, note that the application overview page, Storefront Overview, is open in the
editor. This page enables you to see all the aspects of your application at a glance, to
obtain related help, and to create new objects. You can spend some time exploring this
overview if you want to, but it is not used in these practices.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
In this practice, you begin developing the Storefront application by creating an application and
project.
1. Create an application named Storefront in the oracle.fod.storefront package. Do
not use an application template. Create the initial project with the name StorefrontModel.
a. In the Application Navigator, click the New Application link.
b. On the Name page of the Create Application Wizard:
1) Enter Storefront as the application name.
When you have finished looking at the overview, close it by clicking the X on its tab.
(The X is not visible until you move the cursor over the tab.) If you want to display it
again, right-click a project and select Show Overview.
In this practice, you initialize the StorefrontModel project for business components. In the
process of doing so, you create a database connection to use for the business components.
You also add any libraries that it requires.
1. Initialize the StorefrontModel project for business components. This requires a database
connection, so create that as part of this initialization.
a. Double-click the StorefrontModel project (or right-click it and select Project
Properties).
b. In the Project Properties dialog box, select Business Components from the tree at the
left.
c. In the Business Components panel, select the Initialize Project for Business
Components check box.
d.
e.
2)
3)
Connection Name
FOD
Connection Type
Oracle (JDBC)
Username
Password
fusion
Save Password
In the lower half of the page, Oracle (JDBC) Settings, leave the Driver field at its
default, thin, and enter the Host Name, JDBC Port, and SID as given to you by the
instructor if using a shared database, or localhost, 1521, and XE if using a local
XE database.
Click Test Connection. You should see that the Status box displays the word
Success!.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
g.
h.
Click OK to dismiss the Create Database Connection dialog box and return to the
Business Components page of the Project Properties dialog box.
Click OK to set the project properties and dismiss the Project Properties dialog box.
Click Save All
to save your work. You should get into the habit of frequently
saving your work.
f.
OR if there is an open application, you can invoke the drop-down application list by
clicking the down arrow at the right of the application name in the Application
Navigator, and then selecting Open Application
b.
When you select to open a new application, a file dialog box enables you to navigate to
the directory where the application resides:
1) Navigate to your courses \Labs directory and open the StorefrontCompletedApp folder.
2) Select Storefront-CompletedApp.jws and click Open.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
In this practice, you run the completed application and explore its functionality.
1. Open the Storefront-CompletedApp application in JDeveloper. There are several ways to
open an application.
a. If there is no open application currently, you can click the Open Application link in the
Application Navigator
3.
2.
5.
Examine the connection information and change it if necessary to point to your database.
a. Right-click the StorefrontModel project and select Project Properties. (You can also
double-click StorefrontModel to display the Project Properties Editor.)
b. Select Business Components in the tree at the left.
c. Next to Connection, click Edit.
d. Edit the connection information to your database connection (FOD) (see Practice 2-3,
step 1(e)).
e. Test the connection, and if successful, click OK.
f. Click OK to close the Project Properties Editor and save the settings.
To run the application, in the adfc-config diagram, right-click the
FODShoppingDashboard view and select Run. Test the functionality of the shopping
application.
a. JDeveloper starts an integrated Oracle WebLogic Server, deploys the application to it,
and runs the requested page in a browser. A tree of categories appears at the left, with
a table of categories and descriptions at the right. In the tree, expand the Media
category and click the Music subcategory.
b.
A list of Music products appears in the right panel. Note that there are breadcrumbs
along the top of the table that enable you to navigate to the Media subcategory, or to
the main-level list of categories if you click Store. For now, click the name of one of
the products.
4.
Details about the selected product are shown. Buttons enable you to add the item to
your cart, to search for products, or to return to the shopping page. For now, click
Search.
d.
On the Search page, enter Pla in the ProductName field and click Search. A list of
products beginning with Pla is returned.
e.
Click the Playstation Portable link to display details about this product.
c.
Click Add Item to Cart to add the Playstation Portable to the shopping cart and display
the cart.
g.
The shopping cart is displayed. It is populated with the shopping cart items of a default
user, and the Playstation Portable has been added. Resize the right panel of the page
so that the line total is visible, and then change the quantity of the Playstation Portable
to 2. Click Update to show the updated line total.
h.
With the Playstation Portable selected, click Delete to remove it from your cart.
i.
Click Details to display details about the selected product in a separate pop-up
window.
j.
Click OK to close the pop-up window, and then click Checkout to begin the checkout
process.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
f.
The first page of the checkout process displays the shipping information. Navigate to
the next page either by clicking Next or by clicking the Billing train stop at the top of
the panel.
l.
The second page of the checkout process displays the billing information. Navigate to
the next page either by clicking Next or by clicking the Confirmation train stop at the
top of the panel.
k.
6.
b.
m. The final page of the checkout process displays all the informationshipping, billing,
and order items. Click Submit to submit the order and return to the shopping page.
Note: The Submit button does not actually do anything except perform navigation, but
in a complete application, it could fire off some additional services, such as creating an
order in the database, sending information about the order to the shipping department
and the billing department, and sending an email confirmation to the customer. This
functionality is outside the scope of the course application.
The New Supplier page initializes. Enter any supplier name and select a supplier status
from the drop-down list, and then click Save.
d.
The new row appears at the top of the list, with a supplier ID that is automatically
assigned. Click Delete to delete the supplier.
e.
f.
g.
h.
i.
c.
2)
j.
7.
The application is undeployed when the log window displays the message: [Application
Storefront-CompletedApp stopped and undeployed from Server Instance Instance
IntegratedWebLogicServer].
Close the Storefront-CompletedApp application. You should continue to work in the
Storefront application that you created.
a. Invoke the application menu by clicking the right-most down arrow at the top of the
Application Navigator.
b. Select Close Application from the IDE.
Chapter 3
Practices Overview
2.
In the Create Business Components from Tables Wizard, create entity objects for the
ORDERS, ORDER_ITEMS, and PERSONS tables. Name them OrderEO, OrderItemEO, and
PersonEO.
a. On the Entity Objects page of the wizard, ensure that the schema from the connection
that you created previously is the selected schema.
b. Ensure that the package name is oracle.fod.storefront.entity.
c.
Enter ORD in the Name Filter field. Click Query to see the available tables (ORDERS
and ORDER_ITEMS).
d.
In this practice, you create some default business components that compose part of the
business model for the Storefront application. In the practices for subsequent lessons, you
create more customized business components and refine the default components as well.
1. Invoke the Business Components Wizard.
a. Right-click the StorefrontModel project in the Application Navigator and select New.
b. Select Business Tier > ADF Business Components in the Categories list.
c. Select Business Components from Tables in the Items list.
d. Click OK.
Select ORDERS in the Selected pane and change the Entity Name to OrderEO
(instead of OrdersEO).
3.
VO Based
on
ShoppingCartVO
OrderEO
ShoppingCartItemVO
OrderItemEO
a.
On the Updatable View Objects page of the wizard, ensure that the package name is
oracle.fod.storefront.uiview.
b.
c.
d.
e.
Click Next.
The next page is for creating read-only view objects. These are based on SQL queries
rather than on entity objects. For now, you will not create read-only VOs, so click Next.
Continuing in the Create Business Components from Tables Wizard, create an application
module to provide access to your components. You will later create application modules
that are customized for your application, but you can use a default application module for
testing your components. Create an application module named TestAM in the
oracle.fod.storefront.test package.
f.
g.
4.
b.
On the Application Module page of the wizard, ensure that the Application Module
check box is selected.
To separate this test application module from those that you customize for the
Storefront application, change the package name to
oracle.fod.storefront.test.
c.
a.
5.
d. Click Next.
Complete the wizard to finish creating the business components. Do not create a business
components diagram.
a. On the Diagram page of the wizard, ensure that the Business Components Diagram
check box is not selected.
b. Click Next.
e.
The last page of the wizard shows the components that you have chosen to create. It
should show the following components to be created:
d.
e.
f.
Click Finish to create the business components. This may take a few moments.
Click Save All to save your work.
The StorefrontModel project in the Applications Navigator should look like this:
Note that the wizard created not only EOs, VOs, and an AM, but also two associations
and a view link based on the foreign key relationships that are defined in the database.
c.
In this practice, you examine and test the components you just created.
1. Use the editor to examine the OrderEO entity object.
a. In the Applications Navigator, double-click the OrderEO entity to open the entity in the
editor.
b. Click the Attributes tab or panel to see the attributes. From this view, you can doubleclick any of the attributes to open the Attribute Editor.
c. Each of the other panels (General, Business Rules, Java, Business Events, and View
Accessors) shows different aspects of the OrderEO entity. Click and examine each
panel.
d. Click the Source tab at the bottom of the editor to view and examine the XML source.
2. Test the default components by running the application module in the Business
Components Browser.
a. In the Application Navigator, right-click the application module (TestAM) in the
oracle.fod.storefront.test package and select Run.
b.
The Business Components Browser may take a few minutes to appear, and it may
appear behind other windows. You can click its icon
on the taskbar to display it.
The Browser should initially look similar to the following (the objects can be in a
different order):
c.
e.
f.
In the top portion of the page, click Move to the next row
to navigate through rows
in the Orders view. Note that the order items change as you move to a new order.
Open the other views and examine the contents as you choose.
When you have finished, close the Business Components Browser.
d.
Chapter 4
Practices Overview
1.
a.
b.
c.
In the Application Navigator, right-click the StorefrontModel project and select New
from the context menu.
In the New Gallery, expand the Business Tier node in the Categories list and select
ADF Business Components. Select View Object in the Items list and click OK.
On the Name page of the Create View Object Wizard:
1) Change the package name to oracle.fod.storefront.view and enter
LookupCodeVVO as the view object name. (Note that the suffix is VVO rather
than VO that you used for the updatable view objects, and that you are placing the
read-only VOs in a separate package.)
d.
e.
f.
Specify that the view object should have Read-only access through SQL query.
3) Click Next.
On the Query page of the wizard:
1) Enter the query statement shown in step 1. (You can copy from
LookupCodes.txt, or click Query Builder to build the query if desired, but make
sure that the finished query is as shown above.)
2) Click Test to verify that the query is valid.
3) Click Next.
On the Bind Variables page of the wizard:
1) Click New.
2) On the Variable tab in the lower section of the page, enter BindLookupType as
the name for the variable, leaving all other values at their defaults.
3) Click Next.
Continue clicking Next until you reach the Application Module page:
1) Select the Application Module check box.
2) Click Browse next to the Package field.
3) Click the Hierarchy tab in Package Browser and browse to and select the oracle
> fod > storefront > test package. Click OK.
2)
5)
2.
f.
USAGE_TYPE_CODE
PRODUCT_STATUS_CODE
PERSON_TITLE_CODE
CARD_TYPE_CODE
MEMBERSHIP_TYPE_CODE
ORDER_STATUS_CODE
ID_TYPE_CODE
SUPPLIER_STATUS_CODE
When you have finished testing, close the Business Components Browser.
4)
VO
COUNTRY_CODES
CountryVVO
PERSONS
CustomerVVO
PAYMENT_OPTIONS (optional)
PaymentOptionVVO
PRODUCTS (optional)
ProductVVO
WAREHOUSES (optional)
WarehouseVVO
Note: Creating all of these view objects is optional. You can create them all if you
want to, but you may choose to create only the first two. If you create only a
subset of the objects, you must begin the practices for the next lesson by opening
the starter application.
a. As you did in Practice 3-1, step (1), invoke the Create Business Components from
Tables Wizard.
b. Click Next to navigate to the Read-Only View Objects page of the wizard:
1) Set the package name to oracle.fod.storefront.view.
2)
3)
4)
Click Next.
In this practice, you use the Create Business Components from Tables Wizard to create
multiple read-only view objects at once.
1. Create the following read-only view objects (note the VVO suffix) in the
oracle.fod.storefront.view package:
c.
d.
e.
On the Application Module page of the wizard, place the view objects in your
application module as you did before by using the Browse buttons to navigate to, and
select the proper package (test) and application module (TestAM).
Click Finish to create the view objects.
Save your work. The Application Navigator should look like this:
a.
To invoke the Entity Object Wizard, you could use the New Gallery. However, there is
an even easier way to invoke the wizards:
1) In the Application Navigator, expand the StorefrontModel project.
2) Expand the Application Sources and oracle.fod.storefront nodes.
3) Right-click the entity node and select New Entity Object.
b.
3)
Ensure that the Database Schema Object option is selected and that the
database schema is FOD.
4)
5)
c.
d.
On the Attributes page, click Next to accept all columns. This wizard enables you to
remove or add attributes if necessary.
On the Attribute Settings page:
1) Select CategoryId from the Select Attribute drop-down list.
2) Select the Primary Key check box.
3) Click Finish to create your ProductCategoryEO entity object.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
Although it is easy to create multiple EOs at once with the Create Business Components from
Tables Wizard, there are cases where you may want to use the Create Entity Object Wizard to
create EOs individually, because that enables a greater degree of customization at the time of
creation.
This application has some EOs that are based on database views, and it is necessary to
designate a primary key for such EOs. You can do that with the Create Entity Object Wizard.
In this practice, you create several database viewbased entity objects and designate their
primary keys.
1. Create an entity object named ProductCategoryEO and base it on the
Product_Categories database view. Set the CategoryId to be its primary key.
Optional step (If you choose not to create these objects, you must begin the
practices for the next lesson by opening the starter application.)
Similarly, create the following entity objects that are based on database views:
EO
Primary Key
PersonInformationEO
PERSON_INFORMATION
CustomerId
ProductEO
PRODUCTS
ProductId
2.
AddressEO
ADDRESSES
AddressUsageEO
ADDRESS_USAGES
CountryEO
COUNTRY_CODES
LookupCodeEO
LOOKUP_CODES
PaymentOptionEO
PAYMENT_OPTIONS
SupplierEO
SUPPLIERS
WarehouseEO
WAREHOUSES
WarehouseStockLevelEO WAREHOUSE_STOCK_LEVELS
Note: Creating all of these entity objects is optional. You can create them all if you
want to, but you may choose to create only the first two. If you create only a
subset of the objects, you must begin the practices for the next lesson by opening
the starter application.
a. In the Application Navigator, right-click the oracle.fod.storefront.entity package, and
select New Business Components from Tables.
b. On the Entity Objects page of the Business Components from Tables Wizard, check
whether the package name is oracle.fod.storefront.entity and the schema is
FOD. Click Query.
c.
d.
As you did in an earlier practice, Ctrl-click to select multiple tables for which to create
entity objects, and rename the entity objects, according to the table shown above.
Click Finish to create the entity objects.
EO Based
d.
3) Click Next.
On the Entity Objects page of the wizard:
1) Expand ProductCategoryEO in the Select Source Attribute list and select the
CategoryId attribute.
2) Expand ProductCategoryEO in the Select Destination Attribute list and select the
ParentCategoryId attribute.
3) Click Add, and then click Next.
a.
b.
2.
Optional step (If you choose not to create these associations, you must begin the
practices for the next lesson by opening the starter application.)
In a similar manner, create the following additional associations, with accessors in both
source and destination (leave both check boxes selected):
Name Source
Destination
OrdersOrderItemsAssoc
OrderEO.OrderId
OrderItemEO.OrderId
3.
4.
Optional step (If you choose not to create this association, you must begin the
practices for the next lesson by opening the starter application.)
In a similar manner, create an association named OrderItemsProductsAssoc between
the ProductId fields of the OrderItemEO and ProductEO entity objects. The application
needs to access the product for a particular order item, but never needs to access order
items that pertain to a particular product, so expose accessors only in the destination
entity for this association. (Deselect the check box in the Source Accessor section.)
Save your work. Including the optional steps, the entity package in the Application
Navigator should now look like this:
a.
b.
d.
e.
c.
1.
In the oracle.fod.storefront.uiview package, create two view objects that are based on
ProductCategoryEO: RootCategoryVO for those rows whose ParentCategoryId is null, and
SubCategoryVO. Place the view objects in your TestAM application module.
g.
h.
Click Test to ensure that the query is valid, and click OK to acknowledge the
message.
3) Click Next.
Navigate through the subsequent pages until you reach the Application Module page:
1) Add the view object to the TestAM application module as you have been doing.
2) Click Finish to create the updatable view object.
Similarly, create the SubCategoryVO view object based on the same
ProductCategoryEO entity object, with all attributes.
1) Use the following WHERE clause:
ProductCategoryEO.PARENT_CATEGORY_ID IS NOT NULL
2.
The two view objects that you just created should be related by
ProductCategoriesSubProductCategoriesAssoc in a view link named
RootCategoriesSubCategoriesLink. Create this view link.
a.
b.
c.
d.
f.
Click Add.
Click Next several times until you reach the Application Module page. Select the
Application Module check box and browse to select the TestAM application module
in the oracle.fod.storefront.test package. Click Finish to create the view link.
Optional step (If you choose not to create this object, you must begin the practices
for the next lesson by opening the starter application.)
Similarly, create one more updatable view object named SupplierVO in the
oracle.fod.storefront.uiview package. Base it on SupplierEO, including all
attributes. Do not include a WHERE clause. Add the view object to the TestAM application
module.
Save your work, and then test the view objects and view link that you just created.
a. Run TestAM as before.
b. Check whether the RootCategory1 view object instance displays the data you expect
(only those categories without a ParentCategoryId should display).
c. Check whether the SubCategory1 view object instance displays the data you expect
(only those categories with a ParentCategoryId).
d. Test that RootCategoriesSubCategoriesLink displays the master-detail relationship
between root categories and subcategories, similar to the following:
f.
3.
4.
e.
Close the Business Components Browser when you have finished testing.
e.
c.
In the Move Business Components dialog box, enter the Package name of
oracle.fod.storefront.assoc and click OK.
d.
Confirm that you would like to create the package by clicking Yes.
If you inadvertently create objects in the wrong package, or if you want to reorganize the
created objects into different packages, you can use refactoring. In this practice, you move
existing associations and links into a separate package.
1. Move all associations into the oracle.fod.storefront.assoc package.
a. In the Application Navigator, multiselect (Ctrl-click) all associations in the
oracle.fod.storefront.entity package.
b. Right-click and select Refactor > Move. Note that depending on the optional steps you
have or have not done, your application might look different from the following images.
JDeveloper creates the assoc package and moves the associations into it. This may
take several minutes.
2.
3.
Test the application module to ensure that all view links still function correctly.
e.
Chapter 5
Practices Overview
In this practice, you create the application module to display categories. It contains the two VOs
that are based on ProductCategoryEO and the view link that establishes a master-detail
relationship between root categories and subcategories.
1. Create an application module named FODCategoryAM and put it in the
oracle.fod.storefront.module package. It should contain RootCategoryVO and
also the VO for the subcategories, accessed through the view link.
a. Right-click the oracle.fod.storefront package and select New Application Module.
b. On the Name page of the Create Application Module Wizard, ensure that the package
name is oracle.fod.storefront.module. Enter the name FODCategoryAM and
click Next.
c. On the Data Model page, in the Available View Objects pane, expand
oracle.fod.storefront.uiview and RootCategoryVO.
d. Select RootCategoryVO and shuttle it to the Data Model.
e. With RootCategoryVO1 selected in the Data Model panel, shuttle SubCategoryVO
via RootCategoriesSubCategoriesLink to the Data Model.
f. Click Finish to create the application module.
g. Save your work.
2. Test the application module and then close the Business Components Browser when you
have finished.
2.
c.
Chapter 6
In this set of practices, you make declarative modifications to your business components.
If you successfully completed all sections of the previous practice, you can continue working in
the same project. However, if you prefer to start with a clean application that contains everything
completed up to the start of this lesson, open Storefront-06.jws and edit the database
information as described in step 4 of Practice 2-4.
This practice contains some optional steps that are similar to steps already done. If you want to
build the entire application yourself, you can complete the optional steps. However, in the
interest of time, you may want to skip them. If you do so, you must begin the practices for the
next lesson by opening the starter application for that lesson.
c.
d.
e.
f.
g.
Control hints on entity object attributes enable you to globally define labels, tool tips, and
formatting for any views that are based on those entity objects. In this practice, you define and
test several control hints.
1. In the OrderEO entity object, format the OrderTotal as currency and set the labels of
OrderTotal, OrderDate, and OrderShippedDate to have spaces between the words.
You also set some tool tips.
a. In the Application Navigator, in the entity package, double-click OrderEO to open it in
the editor.
b. Click the Attributes tab at the left of the editor.
h.
i.
Enter the following in the Description field: Tooltip for the Order
Total attribute.
c)
Note: Whether or not the instructions specifically direct you to do so, you can use
a text resource in a resource bundle for any translatable text throughout these
practices, as you would need to do for a real application. However, in the interest
of time, you may choose to simply enter the hard-coded text.
Click OK to dismiss the attribute editor for OrderTotal.
Optional step: Using a resource bundle, enter appropriate Label Text and Tool tip
Text for OrderDate and OrderShippedDate. For example:
2. Optional step: Similarly, edit OrderItemEO to format UnitPrice as Currency and set its
Label Text to have a space between words.
3. Test the changes by running TestAM in the oracle.fod.storefront.test package.
a. Double-click ShoppingCart1 > OrderItemsOrdersFkLink1.
b. Look at the labels and formatting that you defined.
c. Position the cursor over OrderTotal, OrderDate, and OrderShippedDate to see the
tool tip text.
2)
d.
g.
Value
While New
Selected
Persistent
Selected
Primary Key
Selected
Queryable
Selected
Insert
Selected
Click OK.
f.
There are several mandatory attributes in many of the entity objects that record information
about the record: who created it and when it was created, who last updated it and when it was
last updated, and a version number. These attributes can be automatically populated if you
designate them as history columns.
In this practice, you modify three of the entity objects so that the history columns are populated
automatically.
1. In the SupplierEO entity object, designate the following columns as history columns and
ensure that they are automatically populated at run time: CreatedBy, CreationDate,
LastUpdatedBy, LastUpdateDate, and ObjectVersionId.
a. In the Application Navigator, double-click SupplierEO to open it in the editor, or click
its tab if it is already open.
b. Click the Attributes tab.
c.
d.
e.
f.
g.
h.
2.
3.
4.
Attribute Name
LastUpdateDate
modified on
ObjectVersionId
version number
To populate the history columns for created by and modified by, there must be a
logged-in user. You later designate these attributes as history columns, but to test with
the Business Components Tester with no logged-in user, you simply give these
columns default values. Set the default Value of the CreatedBy and LastUpdatedBy
attributes to anonymous. (Ensure that Literal is selected as the option for Value Type.)
Optional step: (If you choose not to complete this step, you must begin the practices
for the next lesson by opening the starter application.)
Similarly, modify the same five attributes for OrderItemEO and for OrderEO.
Save your work.
Test SupplierVO to ensure that you can actually insert and commit a record.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
c.
d.
Click Insert
.
Ensure that a temporary SupplierId appears (it should be a negative number) and that
the history columns are populated.
e.
f.
g.
Click Save
.
Ensure that the SupplierId value is populated from the database sequence.
Optional step: (Perform this step only if you added history columns to these entities.)
Test OrderEO and OrderItemEO, making sure that when you insert a record the history
columns are populated.
a. Double-click ShoppingCart1 > OrderItemsOrdersFkLink1.
b.
c.
d.
e.
Click Insert
in the lower portion.
Ensure that the history columns are populated in the new row.
5.
a.
b.
g.
Click Delete
in the lower and then in the upper sections of the panel to delete the
new rows without committing them.
Close the Business Components Browser when you have finished.
f.
b.
c.
d.
In the Create View Criteria dialog box, click the Criteria Definition tab and click the
Add Item button.
a.
2.
In the Criteria Item section of the Create View Criteria dialog box, select the following
values from the drop-down lists:
List Name
Value
Attribute
CustomerId
Operator
Equal to
Operand
Bind Variable
Parameter
Validation
Optional
.
In the PaymentOptionV1 window, click Specify View Criteria
In the Business Component View Criteria dialog box, select
PaymentOptionVVOCriteria in the Available list and shuttle it to the Selected list, and
then click Find.
e.
In the Bind Variables dialog box, enter a value of 110 and click OK.
f.
g.
h.
Close the Business Components Browser when you have finished testing.
e.
Join views are those that include more than one entity object. One serves as the basis for the
view object, whereas additional entity objects are for reference.
For example, the OrderEO contains information about an order, including the CustomerId,
whereas PersonEO contains information about persons, including customers. In the
ShoppingCartVO view object, you may want to display the customer name or other customer
information, which is part of PersonEO. To accomplish this, you can include PersonEO in the
view object as a reference entity, creating a join view.
You can create join views when using the Create View Object Wizard. If you already have a
view object to which you want to add a reference entity, you can do so by editing the view object
to create the join view. That is what you do in this practice.
1. Add all the attributes from PersonEO as an inner join to be used as reference in the
ShoppingCartVO view object.
a. In the Application Navigator, in the oracle.fod.storefront.uiview package,
double-click the ShoppingCartVO view object to open it in the editor.
b. Click the Entity Objects tab to the left of the editor.
c. Expand oracle.fod.storefront.entity and shuttle PersonEO to the Selected list.
d. Select PersonEO in the Selected list. Ensure that the Association is set to
OrdersPersonsFkAssoc.Person and that the Join Type is set to inner join. Ensure
that the Updatable check box is not selected, and that the Reference check box is
selected.
e.
f.
2.
In the Attributes Editor, select PersonEO in the Available list and shuttle it to the
Selected listthis adds all of its attributes.
3) Click OK.
Optional step: (If you choose not to create these objects, you must begin the
practices for the next lesson by opening the starter application.)
Similarly, add reference entities and attributes to ShoppingCartItemVO as follows:
a.
Entity Object
Attributes
ProductEO
ProductId
ProductName
Description
AdditionalInfo
ListPrice
ProductCategoryEO
CategoryId
CategoryName
2)
3.
Add the reference entities and attributes shown in the table above, accepting the
default join types. If all attributes are added automatically, delete all attributes that are
added except for those shown in the table above.
Optional step: (Perform this step only if you added history columns to the
ShoppingCartItemEO entity.):
Delete the history attributes from ShoppingCartItemVO. You do not need these mandatory
attributes in the view object because you have set their values in the entity object.
a. If it is not already open, double-click the ShoppingCartItemVO view object in the
oracle.fod.storefront.uiview package of the Application Navigator to open it in the
editor.
b. Click the Attributes tab and delete the following attributes: CreatedBy,
CreationDate, LastUpdatedBy, LastUpdateDate, and ObjectVersionId.
c.
b.
2.
1.
d.
Expand the List of Values section in the editor and click Add list of values
e.
3)
Click OK.
2)
c.
d.
e.
f.
3.
Chapter 7
This practice contains some optional steps that are similar to steps already done. If you want to
build the entire application yourself, you can complete the optional steps. However, in the
interest of time, you may want to skip them. If you do so, you must begin the practices for the
next lesson by opening the starter application for that lesson.
2.
a.
b.
c.
Click Edit
.
Select the Generate Entity Object Class check box and click OK.
c.
Note that the Structure window shows the methods that are included in the class. (If
the Structure window is not visiblethat is, the default location is at the lower left of the
IDEthen you can select View > Structure to open it.) You can see accessors (getters
and setters) for all the OrderEO attributes. You can double-click any method to
In the application that you are building, users add items to their shopping carts and may also
perform other operations on their shopping carts. In this exercise, you add the Java code to add
an item to the cart; you must first generate a Java class for OrderEO where you can add the
code. Because the code uses methods from OrderItemEOImpl.java, you first generate that
Java class without adding any code to it.
1. Generate the Java class for OrderItemEO.
d.
In the editor, scroll to the bottom of the file and just above the closing right brace, add
the code shown below. You can copy the code from the addItemToOrder.txt file in
the \files subdirectory of your \labs directory.
/**
* Add an item to the order. Typically used to add items to the
shopping cart.
*
* @param productId
*/
public void addItemToOrder(Number productId) {
if (productId == null) {
System.err.println("NO PRODUCT ID!!!");
throw new NullPointerException();
}
RowIterator orderItems = getOrderItem();
assert orderItems != null;
OrderItemEOImpl row;
boolean found = false;
for (row = (OrderItemEOImpl)orderItems.first(); row != null;
row = (OrderItemEOImpl)orderItems.next()) {
if (row.getProductId().equals(productId)) {
found = true;
break;
}
}
if (found) {
Number qty = row.getQuantity();
if (qty == null)
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
EntityImpl productEO =
productEODef.findByPrimaryKey(getDBTransaction(), new Key(new
Object[] { productId }));
Number unitPrice =
(Number)productEO.getAttribute("ListPrice");
newItem.setProductId(new Number(productId));
newItem.setQuantity(new Number(1));
newItem.setUnitPrice(unitPrice);
try {
getDBTransaction().validate();
} catch (TxnValException e) {
System.out.println(e.getMessage());
for (Throwable t : e.getExceptions()) {
System.out.println(t.getMessage());
}
} catch (JboException e) {
System.out.println(e.getMessage());
}
}
}
e.
f.
Right-click the editor and select Make from the context menu, and then save your
work.
d.
e.
You had previously set a declarative type for an EO attribute to use a database sequence. This
technique results in few (if any) gaps in the numbers that are assigned. However, it may be
confusing for users to see a negative number until the record is committed. Another
disadvantage is that there must be a database trigger to assign the actual value.
Another technique for using a database sequence is to programmatically assign the database
sequence value as the default value for an attribute. No database trigger is required, but if the
record is never committed, this results in gaps in the numbers. In this practice, you implement
this eager assignment of values from a database sequence.
1. Set OrderItemEO to use a database sequence for the line item ID by supplementing the
initDefaults() method with the following code: (You can copy the code from the
initDefaults.txt file in the \files subdirectory of your \labs directory.)
Right-click the method name initDefaults, and then select the Quick JavaDoc option
from the context menu. JDeveloper displays an explanation of the method. Click
outside of the doc window to close it.
g. Right-click the editor and select Make and make sure that no compilation errors are
reported in the Compiler Log pane.
h. Save your work.
Test the assignment of the line item ID.
a. Run the FODShoppingCartAM application module.
b. Double-click OrderItemsOrdersFkLink1. This opens the master-detail window for
Orders and OrderItems.
2.
c.
d.
e.
f.
Because there are a number of mandatory columns, do not commit the new row.
Close the BC Browser without committing the row.
f.
2.
3.
4.
a.
b.
Open the SupplierEO entity object, and click the Attributes tab.
For both attributes, delete the anonymous default value.
c.
CreatedBy
created by
LastUpdatedBy
modified by
Optional step: (If you choose not to complete this step, you must begin the practices
for the next lesson by opening the starter application.)
Similarly, designate the same columns as history columns in OrderEO and OrderItemEO.
As you did previously for OrderEO and OrderItemEO, generate the entity object class for
SupplierEO.
In the entity object class for SupplierEO, override the
getHistoryContextForAttribute() method with the following code, which you can
copy from the getHistoryContextForAttribute.txt file in the \files subdirectory
of your \labs directory:
protected Object getHistoryContextForAttribute(AttributeDefImpl
attributeDefImpl) {
Object value =
super.getHistoryContextForAttribute(attributeDefImpl);
// If value is null and is modify user or create user
// history column then return "anonymous"
if (value == null && (attributeDefImpl.getHistoryKind() ==
AttributeDefImpl.HISTORY_MODIFY_USER ||
attributeDefImpl.getHistoryKind() ==
AttributeDefImpl.HISTORY_CREATE_USER))
{
return "anonymous";
}
return value; }
a.
b.
You previously designated some attributes as history columns in the OrderEO, OrderItemEO,
and SupplierEO entity objects. However, because there was no logged-in user in the Business
Components Tester, you were not able to designate the CreatedBy and LastUpdatedBy
attributes as history columns.
In this practice, you add code to entity objects to automatically populate the CreatedBy and
LastUpdatedBy history columns.
1. In SupplierEO, modify the CreatedBy and LastUpdatedBy columns as follows:
6.
In the Override Methods dialog box, select the check box to the left of the
getHistoryContextForAttribute(AttributeDefImpl) : Object method
and click OK. (You can use the filter field.)
d.
Substitute the code shown above for the generated code. You can copy the code from
the getHistoryContextForAttribute.txt file in the \files subdirectory of
your \labs directory.
Optional step: (If you choose not to complete this step, you must begin the practices
for the next lesson by opening the starter application.)
Similarly, override the getHistoryContextForAttribute() method with the same
code in the entity object classes for OrderEO and OrderItemEO.
Run the TestAM application module and perform the same tests as you did in step 4 of
practice 6-3, (Supplier1 and also ShoppingCart1>OrderItemsOrdersFKLink1) except
that if you test the shopping cart, you will not be able to see how the history columns
appear in the shopping cart item record because the history columns are no longer part of
the ShoppingCartItemVO view object.
5.
c.
a.
b.
c.
2.
3.
Make sure that only the Main Method check box is selected, and then click OK.
Add code to print the number of rows in the PaymentOption view object, to execute the
query on the PaymentOption view object, and to print CustomerId and
PaymentTypeCode for all rows. Use the TestAM application module.
a.
In the stub client code that is generated in the test client, modify the lines:
String amDef = "test.TestModule";
String config = "TestModuleLocal";
Change them to:
String amDef = "oracle.fod.storefront.test.TestAM";
String config = "TestAMLocal";
b.
In this practice, you create a Java client to experiment with some of the view object APIs.
1. Create a test client class named StorefrontTest in the
oracle.fod.storefront.test package.
ViewObject vo = am.findViewObject("PaymentOptionV1");
After the line:
// Work with your appmodule and view object here
and above the line:
Configuration.releaseRootApplicationModule(am, true);
add the following code: (You can copy it from the TestClient.txt file in the \files
subdirectory of your \labs directory.)
System.out.println("The table contains " +
vo.getEstimatedRowCount() + " rows:");
vo.executeQuery();
while (vo.hasNext()){
Row paymentOptionRow = vo.next();
System.out.println(" CustomerID: " +
paymentOptionRow.getAttribute("CustomerId") +
" Payment Type Code: " +
paymentOptionRow.getAttribute("PaymentTypeCode"));
}
Your code should look like the following:
c.
Right-click the editor and select Run. The test client runs and should display the data in the
log window. It ends when the log displays the message: Process exited with exit
code 0.
4.
The Storefront application currently does not implement security. When the application is
eventually finished, security will be implemented and there will be a login module. However, for
testing and development purposes in the meantime, there must be a way to identify which
customer is using the application, so that shopping cart and checkout information for only that
customer appears in the application.
In the Java class that you create in this practice, the customer name is hard coded to simulate a
name that would ordinarily be retrieved from a login module.
1. Create a new Java Class named BaseApplicationModuleImpl in the
oracle.fod.storefront.module package, extending the default base application
module.
a. Right-click the oracle.fod.storefront.module package and select New.
b. In the New Gallery:
1) Select General in the Categories list.
2) Select Java Class in the Items list.
3) Click OK.
c. In the Create Java Class dialog box:
1) Enter a name of BaseApplicationModuleImpl.
2.
2)
3)
b.
c.
c.
3.
4.
}
return mCurrentUser;
c.
d.
e.
f.
Click Edit
next to Java Classes.
In the Select Java options dialog box:
1) Select the Generate Application Module Class check box.
2) Because you must use the method in the BaseApplicationModuleAMImpl class
that you created earlier, this application module class must extend that one, so
click Classes Extend.
3) In the Override Base Classes dialog box:
a) Click Browse next to the Object field.
b) In the Find Superclass dialog box, click the Search tab and enter BA in the
Match Class or Package Name field. This should populate Matching Classes
and Packages.
c) Select the BaseApplicationModuleImpl class and click OK.
d) Click OK again to close the Override Base Classes dialog box.
Click OK to generate the application module class.
Save your work.
In this practice, you edit the shopping cart application module so that it extends the base class
that you just created.
1. Edit FODShoppingCartAM and generate a Java class for it that extends
BaseApplicationModuleImpl.
a. Open FODShoppingCartAM in the editor.
b. Click the Java tab.
b.
2.
You can see that the view objects and some operations are exposed to the client. Now
you add some service methods and expose them to the client as well.
Add a method to the shopping cart application module to initialize the shopping cart to that
of the current user of the application (remember that you hard coded the username in
BaseApplicationModuleImpl.java). The code is shown here: (You can copy the code
from the ShoppingCartInit.txt file in the \files subdirectory of your \labs
directory.)
public void init() {
DBTransactionImpl trx = (DBTransactionImpl)getDBTransaction();
ApplicationModuleImpl am =
(ApplicationModuleImpl)trx.getRootApplicationModule();
String user = am.getUserPrincipalName().toUpperCase();
System.out.println("The session user is: " + user);
ViewObjectImpl vo;
vo = getShoppingCart1();
String bindUser =
(String)vo.getNamedWhereClauseParam("CurrentUser");
if (! user.equals(bindUser)) {
vo.setNamedWhereClauseParam("CurrentUser", user);
/* The ShoppingCart is guaranteed to only have one row.
* However, we may not always properly initialize this
* from the UI because the actual row from ShoppingCart is
* not really needed. The following initializes the view
* object so that the view link to the shopping cart items
* properly works.
*/
vo.executeQuery();
Row cart = vo.first();
if (cart == null) {
cart = vo.createRow();
// TODO: Need to finish this off.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
The shopping cart application module in the completed application contains several methods for
initializing and managing the shopping cart. In this practice, you add two of these methods and
expose them to the client interface.
1. Examine the client interface for the application modules that you have created.
a. Expand the Data Controls panel and expand each of the FOD application modules.
a.
b.
c.
3.
Now add a method that adds an item to the users shopping cart. This method should call
an entity object method that you added earlier to OrderEOImpl.java. Use the following
code (you can copy from addItemToCart.txt):
public void addItemToCart(Number productId) {
init();
ViewObject shoppingCartVO = getShoppingCart1();
assert shoppingCartVO != null;
ViewRowImpl shoppingCartRow =
(ViewRowImpl)shoppingCartVO.first();
assert shoppingCartRow != null;
OrderEOImpl orderEO =
(OrderEOImpl)shoppingCartRow.getEntity(0);
orderEO.addItemToOrder(productId);
}
4.
a.
b.
c.
The code shows an error when calling the addItemToOrder() method. To fix it,
manually add the following import statement to the import section of the file:
import oracle.jbo.domain.Number;
cart.setAttribute("OrderDate",
((DBTransactionImpl)getDBTransaction()).getCurrentDbTime());
cart.setAttribute("OrderStatusCode", "CART");
vo.insertRow(cart);
}
}
}
b.
c.
d.
e.
f.
2)
Examine the Data Controls panel again. Click the Refresh button. You can now see the
service methods that you added. These methods are now available for use in a client,
such as the Storefront UI that you build later in this course.
g.
2)
3)
4)
2.
Test the shopping cart. Execute the init() method, but do not supply a value for the bind
variable, because that comes from the init() method.
a. Run FODShoppingCartAM.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
Now that you have added a method to initialize the shopping cart, in this practice, you modify
the shopping cart to display only the cart for the current user.
1. Edit the shopping cart view object to restrict the shopping cart to display only the status
CART order belonging to one user. Use a bind variable named CurrentUser.
c.
d.
e.
f.
Double-click ShoppingCart1.
In the Bind Variables dialog box, click Cancel, because the init() method already
assigned the value to the bind variable.
b.
One record should be returned by the query: the status CART order for DRAPHEAL.
h.
g.
Chapter 8
In this practice, you add several types of both declarative and programmatic validation to entity
objects.
If you have successfully completed all sections of the previous practice, including the optional
steps, you can continue working in the same project. However, if you prefer to start with a clean
application that contains everything completed up to the start of this lesson, open
Storefront-08.jws and edit the database information as described in step 4 of Practice 2-4.
In this practice, you define a List validator for the status code of an order.
1. Add validation to the OrderStatusCode attribute of the OrderEO entity object to ensure
that the value entered is valid. Display a meaningful error message to the user when
validation fails, using the resource bundle.
Hint: Use the LOOKUP_CODES table.
a. In the Application Navigator, in the oracle.fod.storefront.entity package, right-click
the OrderEO entity object and select Open OrderEO from the context menu.
b. In the Entity Object Editor, select the Attributes node, and then select the
OrderStatusCode attribute.
c. You can invoke the Add Validation Rule dialog box either from the Attribute Editor, or
with the attribute selected, from the Validation Rules accordion of the Entity Object
Editor. Invoke the Add Validation Rule dialog box in one of the following ways:
1) With the OrderStatusCode attribute selected, click Edit. Then in the Attribute
Editor, select Validation in the tree at the left, and then click New.
2)
d.
e.
Click Test to test the query. A message should inform you that the query is valid.
Click OK to close the validation message.
On the Failure Handling tab, check whether the Validation Failure Severity option
button is set to Error, and then, to define a translatable string in a resource bundle,
click
in the Message Text section. If you do not choose to do so, in the interest of
5)
3)
4)
Click OK to save your validation definition, and then click OK to close the Attribute
Editor if you used it to invoke the Add Validation Rule dialog box.
Save your work. You will test this validation after all validations are defined.
g.
2.
f.
c.
3)
validator
to add a new rule. (Note that this is another way to define attribute
validation if you expand the Attributes node and select an attribute.)
2.
Click OK to save your validation definition. You should see the new validation rule
in the Validation Rules section of the OrderEO editor.
Save your work. You will test this validation after all validations are defined.
4)
c.
In the editor for the OrderEO entity, select the Attributes node, and then select the
OrderShippedDate attribute.
Invoke the Add Validation Rule dialog box as you did previously for the
OrderStatusCode attribute.
In this practice, you add a programmatic validation method for the OrderShippedDate
attribute of the OrderEO entity.
1. Add a Method validator to verify that the shipping date of an order is not prior to the order
date, and display a meaningful error message when validation fails. You can use the
following code: (You can copy the code from the ShippedDateAfterOrderDate.txt
file in the \files subdirectory of your \labs directory.)
d.
e.
Click OK to save your validation definition. (Click OK again to dismiss the Attribute
Editor if you used it to invoke the Add Validation Rule dialog box.)
In the Application Navigator, expand the OrderEO node and double-click
OrderEOImpl.java to open it in the editor (by adding the Method validator, this file
would have been automatically generated if it did not already exist).
In the Structure window, double-click the validateShippedDateAfterOrderDate
method to locate it in the editor.
f.
g.
3)
i.
j.
h.
c.
d.
e.
f.
3) Ensure that the Domain for an Oracle Object Type check box is not selected.
4) Click Next.
On the Settings page of the wizard:
1) Select String from the Type drop-down list.
2) Click Next, and then click Finish.
In the Application Navigator, double-click PhoneNumber.java to open it in the editor. It
is located under the oracle.fod.storefront > domain > PhoneNumber node.
2)
2.
3.
3) Click OK.
Save your work.
In this practice, you test all the validation that you have defined.
1. Run FODShoppingCartAM and test the List validator that you defined for the OrderEO
entity object. Be sure to initialize the cart first to bring up the status CART record for
DRAPHEAL.
a. In the Application Navigator, right-click FODShoppingCartAM and select Run.
b. If necessary, click Connect to establish the connection.
c. When the Business Components Browser appears, double-click the
FODShoppingCartAM node, select init from the Method drop-down list, and click
Execute to execute the init method.
d. Double-click ShoppingCart1 and in the Bind Variables dialog box, click Cancel to
leave the bind variable at the value that was set by the init() method.
e. Change the OrderStatusCode to XXXX and tab out of the field. You should receive the
error message that you defined.
Note: If you defined the validation error message by entering hard-coded text, the error
message text looks the same, but the JBO error is a rather cryptic generated key
instead of INVALID_VALUE.
f.
g.
2.
3.
Tab out of the field. You should receive the error message that you defined.
b.
Enter the same value in Order Shipped Date that is in Order Date. You should be able
to tab out of the field with no error.
c.
Enter a value in Order Shipped Date that is earlier than the value in Order Date. You
should receive the warning message that you defined. (The JBO key is different if you
entered hard-coded message text rather than defining a text resource.)
c.
Click OK to acknowledge the message. You should notice that navigation to the next
field was successful, because you defined failure handling to be an informational
warning rather than an error.
e. Close the Business Components Browser.
Run TestAM to test the domain that you defined and applied to the SupplierEO entity
object.
a. In the Application Navigator, right-click TestAM and select Run.
b. If necessary, click Connect to establish the connection.
c. When the Business Components Browser appears, double-click the Supplier1 node.
d. Navigate to a supplier with a phone number. Change the phone number in various
ways, such as by deleting the dots (.) or by making the phone number longer. Each
time that the phone number does not conform to the format xxx.xxx.xxxx, you
should not be able to tab out of the field. Doing so should result in receiving the error
message that you defined.
4.
e.
d.
Chapter 9
Most of the techniques for troubleshooting are used mainly for debugging a user interface.
However, you can run the JDeveloper Debugger with the Business Components Browser, which
enables you to troubleshoot problems with your ADF BC model apart from running a Fusion
Web application. In the practices for this lesson, you debug a client method in an application
module, and you explore the features of the JDeveloper Debugger.
Note: This practice is optional, and does not affect subsequent practices. Do this practice only if
you have extra time.
b.
c.
d.
e.
f.
g.
h.
In this practice, you test the Storefront application and discover a problem at run time.
1. Open the StorefrontDebug application from the StorefrontDebug folder. As you have
been doing, run the FODShoppingCartAM application module and initialize the shopping
cart, and then display the shopping cart.
a. From the JDeveloper application menu, select Open Application.
c.
2.
To set a breakpoint, click in the left margin of the code editor next to the first line of
executable code in the init() method.
You know that there is a record in the shopping cart, but it did not appear in the Business
Components Browser. Now that you have discovered a run-time problem, in this practice, you
prepare to use the JDeveloper Debugger.
1. You know that the init() method of the FODShoppingCartAM application module sets
up the shopping cart. Set a source breakpoint in that method.
a. In the Application Navigator, select FODShoppingCartAMImpl.java.
b. In the Structure window, right-click init():void and select Go to Source.
3.
In the Structure window, click the Show Fields button, and then right-click
mCurrentUser:String and select Create Watchpoint.
b.
The Breakpoints window shows the breakpoints that you have set, in addition to those
persistent breakpoints that are set by default.
c.
Right-click the Breakpoints window to see the options that are available in the context
menu (but do not make any changes).
b.
a.
b.
Before the Business Components Browser appears, the debugger is invoked in the
JDeveloper IDE. Examine the information in the IDE.
1) BaseApplicationModuleImpl.java is shown in the editor with a watchpoint icon
and a pointer displayed to the left of the line setting mCurrentUser to null. This
is because the application has hit the watchpoint breakpoint that you set on this
variable.
2)
c.
If the Stack window is not visible, from the JDeveloper main menu, select View >
Debugger > Stack. You can see in the Stack window that the
BaseApplicationModuleImpl class is in the process of being initialized, and
that it was called by the initialization of FODShoppingCartAMImpl.
Step through the code and use the debugger features to figure out the problem.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
Now that you have some breakpoints, in this practice, you run the application in debug mode
and use some of the features of the JDeveloper Debugger.
1. Run FODShoppingCartAM in debug mode.
2)
3)
4)
5)
6)
7)
8)
Click Resume
on the toolbar to continue the execution until the next time a
breakpoint is encountered. No breakpoint is encountered, so the Business
Components Browser appears.
Now set up the shopping cart as you have done before by executing the init()
methoddouble-click FODShoppingCartAM in the browser, select the init()
method from the Method drop-down list, and then click Execute. The control
passes to the debugger again, so click back within the JDeveloper window to
continue the actions.
FODShoppingCartImpl.java is shown in the editor with a source breakpoint icon
and a pointer displayed to the left of the line in the init() method where you set
the breakpoint.
If you step into the code at this point, you would need to have the ADF source
because ADF source classes are called in the next lines. Because you do not have
the source, click Step Over
to advance to the next line of code in this class
everything still executes, but you just do not step into the called classes. Note: Be
sure to click Step Over and not Step To End of Method, whose icon looks similar.
Click Step Over again to advance to the line of code that assigns a value to the
user variable. This assignment calls the getUserPrincipalName() method of
the application module base class, which is overridden in
BaseApplicationModuleImpl.java.
You are interested in two variable values: user and mCurrentUser. Click the
Smart Data tab. (If it is not available, use the View > Debugger menu to invoke
it.)
1)
On the Smart Data tab, collapse all nodes, and then right-click user and select
Watch.
The Watches tab now shows both the this.mCurrentUser and user variables
so that you can easily track their values.
10) Click Step Into
to step into the getUserPrincipalName() method in
BaseApplicationModuleImpl.java. Note that when you do so, on the
Watches tab the user variable has question marks for value and type because it
is out of scope.
11) Click Step Into
again twice. The pointer should now be on the line that assigns
a value to mCurrentUser, but that line of code has not yet been executed. You
can see that the value of the variable userPrincipal is about to be assigned to
mCurrentUser.
12) Click the Smart Data tab and notice that the value of userPrincipal is
"DRAPHAEL"this username is misspelled.
13) In the Smart Data panel, right-click the userPrincipal variable and select
Modify Value.
14) In the Modify Value dialog box, change the value to DRAPHEAL, which is the
correct spelling for the username of the user whose shopping cart you want to
display, and then click OK.
9)
16) Click Step Out to execute the remaining lines of code in this method and return
to the FODShoppingCartAMImpl class.
17) Click the Watches tab, and then click Step Into
and then Step Over
should see the value DRAPHEAL being assigned to user.
. You
four times until the pointer is at the line of code that sets the
18) Click Step Over
named WHERE clause parameter. This should set the bind variable of the view
objects query to return only the cart order belonging to the user DRAPHEAL.
19) Click the Smart Data tab and expand vo.mViewRowSet, and then place
mWhereParams on your watch list.
20) Click Step Over
twice, so that the VO query executes, and then in the Watch
panel, expand mWhereParams and [0]. You should see that the Current User
parameter has been set to DRAPHEAL.
(you
15)
Click Step Into
may have to click it twice). On the
Watches tab, you should see that
mCurrentUser now has the value
DRAPHEAL, the correct spelling.
Chapter 10
Chapter 11
In this set of practices, you create a databound JSF page. You then examine the data bindings
and manipulate the data binding files.
Even if you successfully completed all sections of previous practices, do not continue working
in the same project, because there was no time to create all the elements required for the UI.
You must open Storefront-11.jws and then edit the database information as described in
step 4 of Practice 2-4.
b.
c.
2.
With your StorefrontUI project selected in the Application Navigator, select File > New
to invoke the New Gallery. (Alternatively, you can right-click StorefrontUI and select
New from the context menu, or click New
on the toolbar.)
In the Categories list, select Web Tier > JSF. Select JSF Page in the Items list and
click OK.
In the Create JSF Page dialog box:
1) Enter a file name of Products.
2)
3)
Ensure that Create as XML Document (*.jspx) is selected, and then click OK.
After the designer initializes, the new blank page opens in the editor. Add to the page two
databound tables for product categories and subcategories as master-detail tables.
a. In the Data Controls panel, expand FODProductAMDataControl >
BrowseCategory1.
a.
3.
By default, all attributes of the view objects were added to the tables. You want to display
only the category name and description. Delete the ones that you do not want to display,
and set the master table to enable row selection.
a. To edit the master table, select the top table (BrowseCategory) in either the visual
editor or the Structure window and click Edit in the Property Inspector. (If the Property
Inspector is not visible, use the View menu to display it.)
b.
Delete the columns that you do not want to display by selecting them and clicking
Delete
, and you can use the arrows at the right of the Edit Table Columns dialog
box to reorder the columns. Set the column list to match the following:
CategoryName
CategoryDescription
Hint: When you select an attribute, it is best to select the first column, Display Label,
because that is the only column that does not invoke a pop-up list.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
b.
d.
e.
f.
4.
Select the second table (BrowseSubCategory1) in either the visual editor or the
Structure window and click Edit in the Property Inspector.
Set the column list to match the following (remove the extra columns and reorder as
needed):
CategoryName
CategoryDescription
Deselect the Row Selection check box and click OK. The page should now look
similar to the following screenshot, in which some of the extra white space has been
cut out:
Note: Although this short list of attributes is easy to reorder, a quick way to reorder
attributes is to select the one that you want last in the list (in this case,
CategoryDescription), and then click the up
arrow to move it to the top of the list.
Then working from the bottom up, repeat for each desired attribute (in this case,
CategoryName). Finally, select all the attributes below the desired attributes and delete
them.
c. Make sure that Row Selection is selected in the Enable ADF Behavior section at the
top of the window, and then click OK to apply the changes.
d.
Select one of the Categories and note that the SubCategories change to reflect the
selected row. Select another category and note the change. You may have to scroll
down to see the SubCategories.
The page should look similar to the following screenshot, in which some of the extra
white space has been cut out:
Note that the table does not fill the page. In the practice for the lesson titled Achieving
the Required Layout, you modify the layout so that the table fills the page.
Leave the browser window open to refer to in the next task.
c.
2.
3.
4.
5.
For example, select the first column in the upper table in the JDeveloper editor, and then
look at the Property Inspector. What is the Header Text property set to?
__________________________________________________________________
__________________________________________________________________
Answer: #{bindings.BrowseCategory1.hints.CategoryName.label}
Select the CategoryName output text under the column header. What is its value?
__________________________________________________________________
__________________________________________________________________
Answer: #{row.CategoryName}
The reference to row is to a variable that is defined on the table.
Select the table in the Structure window, and then click the Source tab in the editor. How
is the row variable defined?
__________________________________________________________________
__________________________________________________________________
Answer:
var="row" value="#{bindings.BrowseCategory1.collectionModel}"
At run time, what appears in the browser for the first columns heading?
__________________________________________________________________
__________________________________________________________________
Answer: The column heading is Category Name.
In JDeveloper, in the StorefrontModel project, open the ProductCategoryEO entity object
and edit the CategoryName attribute. Where does the Category Name label in the UI
come from?
__________________________________________________________________
__________________________________________________________________
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
In this practice, you examine the data bindings that JDeveloper automatically created on the
page when you dragged a data control to the page.
1. Note the difference in the way the table columns appear in the JDeveloper editor and the
way they appear at run time.
7.
8.
9.
10.
11.
12.
13.
6.
Answer: Category Name comes from the entity object attributes control hints for
Label.
At run time, what appears in the browser for the first columns values? Where do these
values come from?
__________________________________________________________________
__________________________________________________________________
Answer: Office, Electronics, and Media are the category names in the rowset;
they are the input values for the category names in the rows.
In the Application Navigator, right-click the page and select Go to Page Definition. What is
the name of the page definition file? (You can also view data bindings by clicking the
Bindings tab of the page itself.)
__________________________________________________________________
Answer: ProductsPageDef.xml
In the Model section of the page definition file, trace the source of the BrowseCategory1
binding. Where does the data come from?
__________________________________________________________________
__________________________________________________________________
Answer: The data comes from the BrowseCategory1 view object instance in the
FODProductAMDataControl. The data is held in the entity object on which the
BrowseCategory view object is based, and the values ultimately come from the
database.
At the top of the page, click the link to the Data Binding Registry. What is the name of this
file?
__________________________________________________________________
__________________________________________________________________
Answer: DataBindings.cpx
When does this data binding registry file get created? Hint: The answer is right at the top of
the Overview page for the data binding registry file.
__________________________________________________________________
__________________________________________________________________
Answer: The file is created the first time that you bind a UI component to data in the
application.
What does the Page Mappings section of this file show?
__________________________________________________________________
__________________________________________________________________
Answer: It shows the mapping of pages to the IDs of their associated page definition
files.
What does the Page Definition Usages of this file show?
__________________________________________________________________
__________________________________________________________________
Answer: It shows the mapping of page definition file IDs to paths of their page definition
files.
What does the Data Control Usages section of this file show?
__________________________________________________________________
__________________________________________________________________
Answer: It shows the data controls that are used in the application.
14. Close the browser and the files that you have open in the JDeveloper editor. As you add
pages to the application, you can reexamine the data-binding registry to see how page
mappings, page definition usages, and data control usages are shown for the additional
pages.
d.
e.
f.
2.
From the Create menu, select Table > ADF Read-only Table.
Do not enable Row Selection.
Include the following attributes in order, deleting the other attributes, and then click OK:
ProductName
Description
ListPrice
Run the page to test it. Now, when you run the page, the log window shows that the
application is undeployed and then redeployed to the default server.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
1.
a.
b.
You should note that although the top two tables are coordinated with one another, the
products that appear in the bottom table are those of the first category/subcategory,
and the display of products does not change when different categories or
subcategories are selected. In the practice for the lesson titled Achieving the Required
Layout, you use partial page rendering to refresh the Products table so that it
coordinates with the record that is selected in the Subcategory table.
Close the browser when you have finished and undeploy the application as described
in step 6(i) of Practice 2-4.
2.
When you have finished, close the browser and undeploy the application as described
in step 6(i) of Practice 2-4.
The Access Denied error that you received is indicative of a problem with data bindings.
Fix the problem without re-creating the tables on the page.
a. Click the Bindings tab in the editor of the ProductCatalog page to see that there are
no data bindings for the page.
b. In the Application Navigator, navigate to StorefrontUI > Application Sources >
oracle.storefront.ui and open DataBindings.cpx.
c. Map the existing page definition file to the renamed page: In the Page Mappings
section of DataBindings.cpx, edit the path. Change Products in the path to
ProductCatalog. You can do this by selecting the page mapping, and then editing
the path in the Property Inspector.
d.
3.
c.
5.
c.
d.
e.
Reopen JDeveloper.
In the Application Navigator, navigate to StorefrontUI > Application Sources >
oracle.storefront.ui > pages and select ProductCatalogPageDef.xml.
4.
In the Structure window, right-click the ProductsPageDef node and select Refactor >
Rename.
g.
h.
i.
This changes the ID of the page definition. Alternatively, you could change the ID in the
Property Inspector.
In the Application Navigator, navigate to StorefrontUI > Application Sources >
oracle.storefront.ui and open DataBindings.cpx.
Map the renamed page definition file to the path of the existing page: In the Page
Definition Usages section of DataBindings.cpx, select the path, and then in the
Property Inspector, change the value of the path from ProductsPageDef to
ProductCatalogPageDef.
f.
3)
4)
j.
k.
Chapter 12
Practices Overview
b.
Drag ProductCatalog.jspx from the Application Navigator to the task flow that is open
in the editor.
In this practice, you create activities and control flows in an unbounded task flow. The
application that you are developing is for a storefront, where the main activity is shopping. Users
can peruse a product catalog and add products to their shopping cart. They can then check out
to complete the order.
1. You have already started developing the ProductCatalog page. To begin planning the
rest of the application, add the ProductCatalog page to the applications unbounded task
flow.
a. Open the unbounded adfc-config.xml task flow. For convenience, JDeveloper
displays a node for this task flow in two places in the Application Navigator. Expand
StorefrontUI and WebContent. You can then open adfc-config.xml from the
node located under WEB-INF or the one located under Page Flows.
2.
Select the view activity in the task flow editor and look at its Property Inspector. You
can see that it is linked to the ProductCatalog page that you created.
Create two additional view activities in the unbounded task flow named ProductSearch
and ProductDetails.
a.
In the Component Palette, ensure that ADF Task Flow is selected in the drop-down list
at the top. Expand the Components category and drag a View activity to the editor.
c.
Change the name of the view activity to ProductSearch by entering the new name
either directly on the diagram or in the Property Inspector.
c.
Note the yellow warning symbol on the view activities that you just created. This
means that they do not yet point to pages.
b.
Add a Control Flow Case from ProductSearch to ProductDetails and name it detail.
a. Click Control Flow Case in the Component Palette.
b. Click inside ProductSearch, and then click inside ProductDetails.
c.
4.
Enter detail as the name of the case. You can enter directly on the diagram, or it
may be easier to use the Property Inspector and enter the name as the fromoutcome of the control flow case.
In the same way, add a Control Flow Case from ProductDetails to ProductSearch and
name it search.
3.
Add a Control Flow Case from ProductCatalog to ProductSearch and name it search.
6.
You can move the view activities to make the diagram look better. For example, you can
arrange the view activities as shown:
7.
8.
Create a fourth View activity named ProductCategory. The page is to display a category
tree for user navigation.
10. Finally, create a View activity called FODShoppingDashboard. The page for this view
activity will be the main page of the application from which all parts of the application are
accessed.
9.
5.
a.
b.
c.
d.
5)
Click OK.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
In this practice, you create bounded task flows for tasks that have defined entry points.
1. Create a bounded task flow for the shopping cart. Create the task flow in the
oracle\storefront\ui\flow subdirectory of Page Flows.
Note that the newly created task flow appears in the Application Navigator in two
places, both under WEB-INF and under Page Flows.
f.
The Shopping Cart flow opens in the editor. Add a view activity and name it
ShoppingCart.
Note that the view activity is surrounded with a green halo. This indicates that it is the
default activity, or entry point, of the task flow. A bounded task flow must have one, and
only one, default activity. Only bounded task flows show default activities, because
unbounded task flows do not have a defined entry point.
g. Add a Task Flow Return and name it Shop.
e.
In the Property Inspector for the Shop task flow return activity, set the Outcome name
to shop. This means that when the task flow returns to the one that called it, it
navigates by using a control flow case whose from-outcome is named shop.
i.
Add a Control Flow Case from ShoppingCart to the Shop task flow return activity
and name it too as shop.
h.
Similarly, add another task flow return activity called Checkout, with the outcome
name checkout.
k.
Add a control flow case also named checkout from ShoppingCart to Checkout.
2.
j.
A task flow return activity named Save whose outcome is named done
3)
A task flow return activity named Cancel whose outcome is also named done
4)
2)
b.
Name
SupplierUpdate
Save
save
Wildcard
Cancel
cancel
5)
b.
c.
Right-click one of the selected objects and select Extract Task Flow.
d.
On the Extract Task Flow warning, click Yes to accept and proceed.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
a.
In the Extract Bounded Task Flow dialog box, enter a file name of ShoppingFlow,
add \oracle\storefront\ui\flow to the directory path, and then click OK.
f.
In the editor, arrange the ShoppingFlow activities in a visually pleasing manner, such
as shown below:
g.
Right-click the ProductCatalog view activity and select Mark Activity > Default
Activity.
e.
i.
The ProductCatalog activity is now surrounded with a green halo indicating that it is the
default activity, or entry point, for the task flow.
h. When you extract a bounded task flow, a task flow call activity is created on the task
flow from which the bounded task flow was extracted. (You may need to look for it in
the diagram, if not visible.) This is not needed, so you can delete it from the adfc-config
task flow.
1) Open or switch to adfc-config.xml.
2) In the visual editor, right-click the ShoppingFlow activity and select Delete, or you
can delete task-flow-call-ShoppingFlow in the Structure window.
Chapter 13
This practice contains some optional steps that are similar to steps already done. If you want to
build the entire application yourself, you can complete the optional steps. However, in the
interest of time, you may want to skip them. If you do so, you must begin the practices for the
next lesson by opening the starter application for that lesson.
In the practices for this lesson, you begin to add functionality to pages by using ADF Faces
components. You create search and detail pages and another page that displays a hierarchical
tree of categories and subcategories. You also create several pages that display input
components as a list of values.
If you successfully completed all sections of the previous practice, including the optional steps,
you can continue working in the same project. However, if you prefer to start with a clean
application that contains everything completed up to the start of this lesson, open
Storefront-13.jws and edit the database information as described in step 4 of Practice 2-4.
2.
Create a read-only table on the page to display the users cart, showing the product name,
list price, quantity, and line total of items that are ordered. Users should be able to use a
mouse to select a line item.
a. The ShoppingCart page opens in the editor. From the Data Controls panel, drag
FODShoppingCartAMDataControl > ShoppingCart1 > ShoppingCartItem1 to the
page as a Table > ADF Read-only table.
e.
3.
Note: Select and remove the other attributes by clicking Delete. You can reorder the
attributes by selecting an attribute and using the up and down arrows as required.
Hint: An easy way to reorder many attributes is to first select the last attribute that you
want in the display (in this case, LineTotal) and click the top arrow, which places the
attribute at the top of the list. Then select the next-to-last attribute (in this case
Quantity) and place it at the top of the list. Continue with all the attributes, from last to
first. Finally, select all the other attributes and delete them.
d. Click OK.
Test the page.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
b.
c.
c.
Right-click the editor for the ShoppingCart page and select Run.
If necessary, in the Confirm Run JSF JSP dialog box, click Yes.
Note: You receive this message because you are running the page directly instead of
running it within the context of the bounded task flow. You do not need to use the ADF
Controller in this case because you are not using any control flows to test this single
page. In most cases, however, you should run pages from a task flow rather than
running them directly.
You also receive several compilation warnings: XML-24521: (Error) Element not
completed: 'view', because you have created several activities in task flows that have
not been completed, such as view activities without corresponding pages. You can
safely ignore these warnings.
The page runs, but does not show any data. ShoppingCart is tied to a specific user;
however, you have not yet told it what user.
Close the browser when you have finished and undeploy the application as described
in step 6(i) of Practice 2-4.
Add to the page an invocation of the application modules init() method that initializes
the application to show shopping cart data for a specific user. The method interrogates the
system user (a hard-coded name is used until security is implemented in a later practice)
and uses that name as the username for the shopping cart. Hint: This involves adding a
method action binding and an invoke action binding to the page definition.
a. Click the Bindings tab in the editor for the ShoppingCart page.
b. Add a Method Action binding to the init() method in the
FODShoppingCartAMDataControl:
d.
4.
1)
2)
In the Insert Item dialog box, select methodAction and click OK.
a.
b.
c.
3)
1)
2)
3)
In the Insert Item dialog box, select invokeAction, and then click OK.
In the Insert invokeAction dialog box:
Enter an ID of invokeInit, select init from the Binds drop-down list, and click
OK.
4)
5)
In the Executables panel, drag the invokeInit executable to the top position, so
that the init() method is invoked before the iterator.
Save your work and run the page again to check that you can see items in the
shopping cart.
You should be able to select any row in the table, and the page should look similar to
the following:
e.
Close your browser when you have finished and undeploy the application as described
in step 6(i) of Practice 2-4.
d.
2.
Add a query component to the ProductSearch page to query for products. The search
results should appear in a table that shows product name, category name, list price, and
description. The user should be able to select a row.
a. The ProductSearch page opens in the editor. Drag FODProductAMDataControl >
BrowseProduct > Named Criteria > SearchByName to the page in the editor and
select Query > ADF Query Panel with Table from the context menu.
In this practice, you use a query component to create a search page, and you test its
functionality.
1. Create the ProductSearch page.
a. Open ShoppingFlow in the visual editor.
b. Double-click the ProductSearch view activity.
c. In the Create JSF Page dialog box, ensure that Create as XML Document is selected,
so that the file that is created can be used as metadata. (This option should be
selected and disabled.)
d. Leave the file name as ProductSearch.jspx.
e. To the Directory path, append \oracle\storefront\ui\pages, and then click OK.
b.
3.
c.
Note that the table does not fill up the page. You must scroll to see all the columns.
You later improve the look of the table in the practice for the lesson titled Achieving the
Required Layout.
Experiment with the functionality of the page.
3)
Enter a percentage sign (%) in the ProductName field and click Search. All of the
products appear.
2)
3)
Resize columns in the table by dragging the lines between the column headers.
Reorder columns in the table by dragging column headers.
4)
5)
1)
Enter Pla in the ProductName search field and click Search. Note that the table
displays products that contain Pla.
7)
Select Does not contain from the operators drop-down list and click Search.
Now the table displays only those products that do not contain the string Pla.
6)
9)
For the Price criterion, select Greater than from the operators drop-down list,
enter a value of $1000 (ListPrice is formatted as currency), and then click Search.
Now the table displays only those products that do not contain the string Pla and
whose list price is more than $1000.
10) When you have finished, close the browser and undeploy the application as
described in step 6(i) of Practice 2-4.
8)
2.
Add a read-only form to the ProductDetails page to display details of the selected product,
including product name, category name, and list price.
a. Drag the Data Control FODProductAMDataControl > BrowseProduct to the visual
editor and select Form > ADF Read-only form from the context menu.
b.
3)
In this practice, you create the ProductDetails page. This page displays the details of the
product that the user selects on the ProductSearch page. Later, in the practices for the lesson
titled Implementing Navigation on Pages, you add a button to the ProductSearch page that
navigates to the ProductDetails page.
1. Create the ProductDetails page on the ShoppingFlow task flow.
a. Open ShoppingFlow from the Application Navigator if it is not already open.
b. Double-click the ProductDetails view activity, or right-click it and select Create Page.
c. Create a .jspx page in the directory where you are creating pages
\oracle\storefront\ui\pages.
Run the page to test it. Run it directly rather than from the task flow because you have not
added navigation yet. The page should look similar to the following, displaying only one
record, which may not be the same as the record shown:
4.
When you have finished, close the browser and undeploy the application as described in
step 6(i) of Practice 2-4.
3.
2.
Create a read-only table on the page to list the suppliers, displaying the supplier ID, name,
status, phone number, and email address. The table should be sortable, and users should
be able to select a row.
a. From the Data Controls panel, drag to the page FODSupplierAMDataControl >
Supplier1 as a Table > ADF Read-only Table.
b.
c.
In this practice, you create the BrowseSuppliers page that enables users to sort the table on any
of its columns. This practice is optional because the steps are similar to what you have done
previously. If you choose not to create the BrowseSuppliers page, you must begin the practices
for the next lesson by opening the starter application.
1. Create the BrowseSuppliers page on ShowSuppliersFlow.
a. From the Application Navigator, open ShowSuppliersFlow.
b. Open the BrowseSuppliers page, being sure to create it in your
\oracle\storefront\ui\pages directory.
b.
Test that you are able to sort columns and select rows.
c.
When you have finished, close the browser and undeploy the application as described
in step 6(i) of Practice 2-4.
3.
c.
2.
Create a .jspx page in the directory where you are creating pages
(\oracle\storefront\ui\pages).
In this practice, you create the ProductCategory page, and then create on it a tree that shows
product categories with their subcategories.
1. Create the ProductCategory page on the unbounded task flow.
a. Open adfc-config.xml from the Application Navigator.
b. You may have to scroll in the diagram to see the existing views, and then either
double-click the ProductCategory view, or right-click it and select Create Page.
b.
In the Edit Tree Binding dialog box, select SubCategory from the Add Rule
down list.
c.
e.
f.
d.
drop-
3.
c.
d.
g.
Note: This shows up at run time as a hierarchical tree with nodes and subnodes
displaying category names and subcategory names. Note that both RootCategoryVO
and BrowseSubCategoryVO are based on the same entity object, ProductCategoryEO.
The queries are differently defined to select those with no parent category for
RootCategoryVO and all categories for BrowseSubCategory. The view link defined to
link the two view objects restricts the second view to display only those subcategories
whose parent category is the root category. This becomes clearer when you run the
page.
The page should look similar to the following:
4.
In the Properties Inspector, set the Text to #{node}. (You can use Expression
Builder and select the expression from JSP Objects.)
b.
c.
Note that you can expand the nodes, but nothing happens when you click the links
other than that the tree is refreshed. You change this behavior in a later practice.
When finished, close the browser and undeploy the application as described in step
6(i) of Practice 2-4.
e.
a.
b.
c.
d.
e.
f.
g.
h.
i.
j.
In this practice, you create pages with input components that use lists of values. Input
components automatically use LOVs when the model specifies that an LOV be used for display
of an attribute.
1. In the data model, review how a list of values was defined for SupplierVO.
2.
You can see that the view accessor limits the view to those rows where the lookup type
is SUPPLIER_STATUS_CODE.
l. Click Cancel to close the window, and then close the EO and VO editors.
In the ManageSupplierFlow task flow, create the SupplierUpdate page, using an LOV for
the SupplierStatus attribute. Place this page in a \supplier subdirectory where you have
been creating pages (\oracle\storefront\ui\pages). The form needs to show only
one record.
a. Open the ManageSupplierFlow task flow from the Application Navigator if it is not
already open.
b. Create the SupplierUpdate page, placing it in a supplier subdirectory
\oracle\storefront\ui\pages\supplier.
k.
Drag the data control FODSupplierAMDataControl > Supplier1 to the page and
create an ADF Form.
d.
Click OK. Note that the Component to Use field for the SupplierStatus attribute is
ADF Select One Choice; this is determined by the setting in the ADF BC model.
Although you can change the setting here, it is better to let the model determine the list
type.
The page should look something like the following:
c.
Test the page by running it directly. The page should look similar to the following with
the list of values dropped down:
f.
When you have finished, close the browser and undeploy the application as described
in step 6(i) of Practice 2-4.
e.
c.
So far all of the text in the user interface is bound to data in the ADF BC model. Soon you begin
to add text that you enter into the application yourself. To make sure that this text is translatable,
you store it in a resource bundle. In this practice, you set up the UI project to use a resource
bundle.
1. Set up the project to use a single Properties Bundle file per project.
a. Right-click the StorefrontUI project in the Application Navigator and select Project
Properties, or just double-click the node to open the Project Properties editor.
b. In the list at the left of the Project Properties editor, select Resource Bundle. Make
sure that the Resource Bundle Type property is set to Properties Bundle and select
the One Bundle Per Project option. If necessary, set the Default Project Bundle Name
to oracle.storefront.ui.StorefrontUIBundle.
Click OK.
Chapter 14
This practice contains some optional steps that are similar to steps already done. If you want to
build the entire application yourself, you can complete the optional steps. However, in the
interest of time, you may want to skip them. If you do so, you must begin the practices for the
next lesson by opening the starter application for that lesson.
So far you have created several pages that are part of task flows, and you have created control
flows between them with outcomes that can be used for navigation. However, you have not
implemented navigation on the pages, so there is no mechanism for moving from one activity to
the next within task flows.
In this set of practices, you implement navigation on pages by creating buttons, links,
breadcrumbs, and a train.
If you successfully completed all sections of the previous practice, including the optional steps,
you can continue working in the same project. However, if you prefer to start with a clean
application that contains everything completed up to the start of this lesson, open
Storefront-14.jws and edit the database information as described in step 4 of Practice 2-4.
In this practice, you create buttons on pages and set the Action property of the buttons to
correspond to a from-outcome of a control flow rule in the task flow. Then when the user
clicks the button, the navigation takes place. You create labels for the buttons as translatable
strings in the Bundle rather than as hard-coded values.
1. The ManageSupplierFlow task flow has a global control flow rule whose from-outcome is
cancel. Add a Cancel button to the page in the task flow to implement this global rule.
Create the label for the button as a translatable string.
a. Open the ManageSupplierFlow task flow by double-clicking it in the Application
Navigator. (The task flows are located under the Web Content > Page Flows > oracle
> storefront > ui > flow node.)
b. Double-click the SupplierUpdate view activity to open the page in the editor.
c. In the Component Palette, ensure that ADF Faces is selected from the drop-down list,
and drag a Button to the page just inside the top of the form in the editor.
(You may find it easier to drag it to the Structure windowexpand af:form and drag
the button just above af:panelFormLayout.)
d.
To define text for the button label and store it in a resource bundle, in the Property
Inspector, click the arrow to the right of the Text property and select Select Text
Resource from the context menu.
(Alternatively, you can right-click the button in the editor or in the Structure window and
select Select Text Resource for > Text from the context menu.)
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
e.
f.
g.
Select the button and in the Property Inspector, click the Action drop-down list and
select cancel.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
4)
2.
Optional step: (If you choose not to create this button, you must begin the practices
for the next lesson by opening the starter application.)
The ManageSupplierFlow task flow has a control flow rule from SupplierUpdate to the Save
task flow return activity whose from-outcome is save. Follow a similar series of steps to
add a Save button just to the right of the Cancel button on the SupplierUpdate page to
implement this navigation. Create the label for the button as a new translatable string and
select the save action. Do not change the default value of the Immediate property for this
button.
h.
This ensures that the cancel control flow is executed when the user clicks the Cancel
button.
To enable users to cancel and leave the form without entering the required fields, set
the Immediate property to true on the Behavior panel of the Property Inspector.
Similarly, in the ShoppingFlow task flow, open the ProductCatalog page. Add a button
above the panelHeader component, and using the Text Resource, label it Search. Set the
Action to search.
4.
Optional step: (If you choose not to create these buttons, you must begin the
practices for the next lesson by opening the starter application.)
Following a similar series of steps, add the following buttons for navigation, optionally using
a text resource for the label of each:
Task Flow
Page
Button Label
Button
Action
ShoppingFlow
search
ShoppingFlow
shop
ShoppingCartFlow ShoppingCart
shop
ShoppingCartFlow ShoppingCart
Checkout (create a
text resource entry)
checkout
3.
c.
The file should look similar to the following (not all of these entries are present if you
skipped any optional steps):
d.
b.
In many cases, you want the user to be able to click some text, such as a product number, to
navigate to another page. In this practice, you create links that implement navigation.
1. The ShoppingFlow task flow has a control flow rule from ProductSearch to
ProductDetails whose from-outcome is detail. You want users to be able to click
the ProductName on the ProductSearch page to drill down to the details about the
products. Convert the ProductName on the ProductSearch page to a link that implements
this navigation. Clicking the link should not select a row.
a. Open the ProductSearch page.
b. Turn off automatic row selection on the table:
1) Select af:table in the Structure window or in the breadcrumbs at the bottom of the
editor.
2) Click Edit on the Property Inspector.
In the Edit Table Columns dialog box, deselect the Row Selection check box, and
then click OK.
Change the ProductName to be a link that calls the ADF method that sets the row and
then navigates to the detail page:
1) In the Structure window, expand the first af:column under af:table.
2) Right-click af:outputText for ProductName in the Structure window and select
Surround With.
3)
c.
In the Surround With dialog box, select ADF Faces > Link and click OK.
4)
In the Property Inspector, remove the value in the Text property of the
af:commandLink and set Action to detail.
If you run the page from the task flow at this point (see step f below for how to do that if
you want to try), the link navigates to the detail page but always displays details for the
first product. The reason for this behavior is that when you disabled row selection you
also disabled row concurrency. Add a method called setCurrentRowWithKey that
sets the row of the Product iterator to whatever the current row is on the page.
1) In the Data Controls panel, expand FODProductAMDataControl >
BrowseProduct > Operations.
d.
3)
e.
3)
4)
2)
3)
4)
5)
If you did not complete the optional steps of defining additional buttons, click the
Back button of your browser, otherwise perform the following actions:
a) On the detail page, click Search to return to the search page to try another
link.
b) On the ProductDetails page, click Shop to return to the ProductCatalog page.
When you have finished, close the browser and undeploy the application as
described in step 6(i) of Practice 2-4.
f.
2)
In the ShoppingFlow task flow, add a drill-down link from the ProductCatalog page to the
ProductDetails page.
a. Open the ProductCatalog page.
b. Select the af:outputText of ProductName in the bottom table.
c.
d.
e.
In the Convert Output Text dialog box, select ADF Faces > Link and click OK.
3.
Coordinating the ProductCatalog and ProductDetails pages is made more complex by the
fact that the two pages use different iterators. The ProductDetails page uses the top-level
BrowseProduct iterator, whereas the ProductCatalog page uses the BrowseProduct1
iterator that is a detail of BrowseCategory > BrowseSubCategory. Therefore, you must use
the setCurrentRowWithKeyValue() method from the BrowseProduct data control to
coordinate the pages.
a. In the Data Controls panel, expand FODProductAMDataControl > BrowseProduct >
Operations.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
2.
c.
d.
e.
4.
b.
In the Attributes section of the Tree Binding Editor, shuttle the ProductId from the
Available Attributes to the Display Attributes, and then click OK.
Note: This adds the attribute to the bindings, but it does not add it to the table on the
page. It simply makes the attribute available to the page.
d. The setCurrentRowWithKeyValue method uses an argument (ND or Named Data)
to tell it which row is current. The argument for setting the current row of Product is
ProductId.
In the Structure window, select bindings > setCurrentRowWithKeyValue > rowKey
and set the NDValue property to #{row.ProductId}. Be sure to tab out of the field or
click in another field so that the value is saved.
c.
e.
Test the page by running it from the ShoppingFlow task flow. (Open the task flow,
right-click the default activity, and select Run.) Remember that the Products table is
not yet coordinated with the Categories and Subcategories tables, so just scroll to the
bottom table and try out the ProductName links.
Click Shop to return to the ProductCatalog page to try different links. (If you did not
define the Shop button in the optional steps, use the browsers Back button to return to
the ProductCatalog page.)
Note: If the Products table at the bottom shows no data, you can test the links after
you coordinate the Products table with the Subcategories table in a later practice.
g. When you have finished, close the browser and undeploy the application as described
in step 6(i) of Practice 2-4.
On the ShowSuppliersFlow task flow, create a task flow call activity to invoke the
ManageSupplierFlow task flow, a control flow case named update from BrowseSuppliers
to ManageSupplierFlow, and a control flow case named done from ManageSupplierFlow to
BrowseSuppliers. You want users to be able to click the SupplierId to be able to update the
supplier. Convert the SupplierId on the BrowseSuppliers page to a link that implements this
navigation. You do not need to disable row selection for this table.
a. Open the ShowSuppliersFlow task flow.
b. From the Application Navigator, drag ManageSupplierFlow to the diagram to create a
task flow call activity.
5.
c.
Create a control flow case from BrowseSuppliers to ManageSupplierFlow and set its
from-outcome to update.
d.
Create a control flow case from ManageSupplierFlow to BrowseSuppliers and set its
from-outcome to done. (It should default to done because that is the outcome of the
task flow return activities in ManageSupplierFlow.)
f.
3)
4)
g.
h.
In the Surround With dialog box, select ADF Faces > Link and click OK.
In the Property Inspector of the af:commandLink:
a) Remove the value in the Text property
b) Set the Action to update
However, the page does not yet commit any updates you may make for the selected
supplier; you implement that in a later practice.
When you have finished, close the browser and undeploy the application as described
in step 6i of Practice 2-4.
e.
f.
3.
4.
Select the first af:commandNavigationItem and use a resource bundle to change its
Text property to Store, or optionally, just enter the text.
You will not be able to test the navigation until after you add the dynamic breadcrumbs
functionality in a later practice. For now, just leave the other two navigation items as they
are.
5.
In this practice, you add breadcrumb navigation to the ProductCatalog page. This application
uses explicitly defined breadcrumbs, rather than those that are tied to the XML Menu Model. In
this exercise, you define the breadcrumbs component and one navigation item. Later, in the
practice for the lesson titled Passing Values Between UI Elements, you add dynamic
navigation items to this breadcrumbs component by using parameters.
1. Open the ProductCatalog page from the ShoppingFlow diagram.
2. Drag a Bread Crumbs component from the Component Palette to the Structure window,
just below the af:form component and above the af:commandButton. It should be the first
component in the form.
b.
c.
d.
e.
f.
Click OK.
Another way to implement navigation is to use a Train component to manage the navigation for
you. This is particularly useful when there is a set navigation path and order. This is the case
with the CheckoutFlow.
In this practice, you define the CheckoutFlow task flow. Because checking out at the end of a
shopping session is a series of steps, you implement this task flow as a train, and you add a
train component to the first page in the train. In the later practice for the lesson titled Ensuring
Reusability, you use a page template for the pages.
1. From the StorefrontUI project, invoke the New Gallery.
2. Select Web Tier > JSF > ADF Task Flow and click OK.
3. In the Create Task Flow dialog box:
a. Enter a File Name of CheckoutFlow.
Create the following three View Activities on CheckoutFlow, and note that because of the
train choice, JDeveloper creates a navigation path as you create the activities:
CheckoutShipping
CheckoutPayment
CheckoutConfirm
5.
b.
Name the other task flow return CancelOrder, and set the name of its outcome in the
Property Inspector to cancel.
c.
d.
6.
4.
7.
8.
When finished, close the browser and undeploy the application as described in step 6(i) of
Practice 2-4.
Establish the context for the shopping cart by calling the init() method defined in the
FODCheckoutAMDataControl application module. Add a reference to the init()
method and execute the method as part of the page load process. This init() method
retrieves the current username (now hard coded, but when security is implemented will be
set programmatically), sets the value in a named WHERE clause, and then reexecutes the
query. The result is that the shopping cart is populated with data from the current user.
To use the init() method, you define a reference for it in the page definition file. Then
you add an invokeAction to the page definition executables. invokeAction executes
when the page is loaded.
a. Open the Page Definition for the CheckoutShipping page (right-click anywhere on
the page and select Go To Page Definition), or click the Bindings tab on the page.
b. Click the Add icon (green plus sign) on the Bindings pane.
c.
2)
e.
2) Click OK.
Now that you have a reference to the init() method, you can add it to the
Executables list:
1) Click Add in the Executables section.
2) Select Generic Bindings > invokeAction and click OK.
3) In the Insert InvokeAction dialog box, set id to invokeInit, and set Binds to init,
and then click OK.
4)
Note: By setting the Refresh property to ifNeeded, the framework refreshes the
executable when it has not been refreshed to this point. For example, when you have
an accessor hierarchy in which a detail is listed first in the page definition, the master
could be refreshed twice (once for the detail and again for the master's iterator). Using
ifNeeded avoids duplicate refreshes.
5) Drag the invokeInit action so that it is first in the list of executables.
9.
Add the ability to navigate to the next page by adding a Train component to the page. The
Train component shows the users relative position in the train. It has train stops (small
boxes) for each of the pages in the train. The current position is highlighted with a slightly
larger box. The Train component can also be used for navigation. The user can click the
previous or next train stop to navigate to that page.
d.
2) Select methodAction.
3) Click OK.
In the Create Action Binding dialog box:
1) Select FODCheckoutAMDataControl. Note that the Operation defaults to
init(). This is because the init() method is the only method in the application
module.
In the page editor for the CheckoutShipping page, drag a Train component from the
Component Palette just inside the top of the form.
b. In the Bind Train dialog box, click OK to accept the default trainModel to bind to.
10. Add a train button bar to the page. A train button bar displays Back and Next buttons to
navigate to the next or previous train stop.
a. Drag a Train Button Bar from the Component Palette to the Structure window just
after the af:train.
b. In the Bind trainButtonBar dialog box, click OK to accept the default trainModel to
bind to.
Note: Ensure that the train button bar appears in the Structure window between the
train and the panel form layout. The Structure window should look like this (if not, drag
components to rearrange them):
11. Add labels for the train stops: Shipping, Billing, and Confirmation. JDeveloper
currently does not provide a way to use a text resource from a resource bundle file, so you
can just enter the text directly.
a. Open the CheckoutFlow task flow.
b. In the Structure pane, expand the view CheckoutShipping node.
c. Right-click the Train Stop and select Insert inside train-stop > Display Name from
context.
d.
a.
e.
a.
b.
c.
d.
e.
f.
However, because you have added the train component and train button bar to only the
first page, you cannot navigate to the other pages from the payment page. You take
care of that problem when you create the real pages.
When finished, close the browser and undeploy the application as described in step
6(i) of Practice 2-4.
Delete the two temporary pages:
1) In the CheckoutFlow task flow, select the CheckoutPayment and
CheckoutConfirm view activities and delete the value in their page property.
2) In the Application Navigator, multiselect the CheckoutConfirm and
CheckoutPayment pages. Right-click and select Delete.
12. Optional step: You may choose to skip this test in the interest of time without
affecting subsequent practices.
Test the train functionality. To see all the train stops, all the train stop view activities must
be associated with pages, so you have to create the other pages. However, because you
are going to delete them after testing the train, for now just create a temporary page for
each with only an output text item on it. Do not add any data binding. You can just create
the pages in the default directory to separate them from the more permanent pages that are
in your \oracle\storefront\ui\pages directory.
d.
Delete the other search control flow rule. The diagram should now look similar to the
following screenshot:
e.
Select one of the detail control flow rules and in the Property Palette, change its
from-activity-id to the wildcard rule by selecting it from the drop-down list.
Delete the other detail control flow rule. The diagram should now look similar to the
following screenshot:
f.
When defining navigation and task flows, you may have noticed that the ShoppingFlow has
several control flows with the same name whose target is the same activity. For example, there
are two control flows named detail that have a target of ProductDetails. In this practice,
you simplify the shopping task flow by defining a global control flow rule, and you also add calls
to other task flows.
1. Simplify the ShoppingFlow task flow by defining a global rule.
a. Open the ShoppingFlow task flow.
b. Drag a Wildcard Control Flow Rule from the Component Palette to the task flow.
c. Select one of the search control flow cases and in the Property Palette, change its
From Activity Id to the wildcard rule by selecting it from the drop-down list.
h.
2.
Select the shop control flow rule and in the Property Palette, change its from-activityid to the wildcard rule by selecting it from the drop-down list.
Rearrange the items on the diagram to look similar to the following screenshot:
a.
g.
Drag a Control Flow Case from the wildcard to CheckoutFlow and name the
outcome checkout.
c.
d.
e.
Drag a Control Flow Case from the wildcard to AddShoppingCart and name the
outcome add.
f.
g.
h.
You later add logic to the application so that there is a difference between displaying
the cart and adding an item to the cart.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
b.
Open the ProductCatalog page and to the right of the Search button, add a button.
1)
Using the resource bundle, set the text property to Show Cart.
2)
3)
Test the navigation with the Show Cart button by running the ProductCatalog
page from the ShoppingFlow task flow.
4)
5)
When you have finished, close the browser and undeploy the application as
described in step 6(i) of Practice 2-4.
i.
Chapter 15
This practice contains some optional steps that are similar to steps already done. If you want to
build the entire application yourself, you can complete the optional steps. However, in the
interest of time, you may want to skip them. If you do so, you must begin the practices for the
next lesson by opening the starter application for that lesson.
In the practices so far, you have chosen the default layout for all the components that you have
used. That is a quick way to check whether your application is working and that data and flow
are handled correctly. This has resulted in pages that are functional, but not very visually
appealing. In this set of practices, you use layout components and techniques to enhance the
appearance of the application, and you implement partial page rendering to coordinate products
with a selected subcategory.
If you successfully completed all sections of the previous practice, including the optional steps,
you can continue working in the same project. However, if you prefer to start with a clean
application that contains everything completed up to the start of this lesson, open
Storefront-15.jws and edit the database information as described in step 4 of Practice 2-4.
a.
b.
c.
d.
e.
ProductCatalog
masterDetail1 table
ProductCatalog
Subcategories table
ProductCatalog
Products table
ProductSearch (optional)
ShoppingCart (optional)
Items table
BrowseSuppliers (optional)
Suppliers table
Apply the same type of stretching to the other two tables on the page: the one for
subcategories and the one for products. However, in the Products table (table2),
stretch the middle column (column3), because it is the one that contains a large
amount of text. To do so, follow these steps:
1) Select the middle column and give it the Id of Description.
2)
f.
g.
Optional: (You may get errors when nondefault values of Id and TestId are not
identical. To avoid this possibility, reset the TestId to its default value.)
3) Select the table and set Column Stretching to column:Description.
Save your work.
Optional step: (If you choose not to complete this step, you must begin the
practices for the next lesson by opening the starter application.)
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
Page Table
Similarly, stretch the table and the last column for all tables on the following pages:
ProductSearch (Search results table)
ShoppingCart (Items table)
BrowseSuppliers (Suppliers table)
a.
b.
c.
2)
3)
2.
In the Property Inspector, change the Text property to Categories. Ensure that
you use a resource bundle.
Similarly, set the Text property for the af:panelHeader BrowseSubCategory1
to Subcategories.
On the ProductCatalog page, two of the tables and panel headers are grouped under an
af:panelGroupLayout component. Enable this component to display scroll bars when the
browser is too small to display all of its contents, and place the third table in the same panel
group layout.
a. In the Structure window, select af:panelGroupLayout.
When you created certain components on your pages, JDeveloper imposed some default
layout. In this practice, you modify some of these default layout components to enhance the
appearance of the pages.
1. Modify headings in the Panel Group Layout components on the ProductCatalog page.
Change the headings to Categories and Subcategories.
In the Property Inspector, select scroll from the Layout drop-down list.
c.
Optional step: (If you choose not to complete this step, you must begin the practices
for the next lesson by opening the starter application.)
Similarly, open ProductSearch page and set the default Panel Group Layout component
to scroll.
3.
b.
In the Surround With dialog box, select ADF Faces > Panel Header and click OK.
In the Property Inspector for the panel header, set the Text property to Products,
optionally using a resource bundle.
f. Save your work.
On the ProductDetails page, place the Product form, which is contained by default in a
panel form layout, into a panel header titled Product Detail. Add a toolbar for the existing
buttons.
a. Open the ProductDetails page.
b. In the Structure window, expand jsp:root > f:view > af:document > af:form.
c. Right-click af:panelFormLayout and select Surround With.
d. In the Surround With dialog box, select ADF Faces > Panel Header and click OK.
e. In the Property Inspector for the panel header, set the Text property to Product
Detail, optionally using the resource bundle.
d.
e.
2.
f.
Drag a Toolbar from the Component Palette to the toolbar facet of the panel header, in
either the Structure window or in the editor.
h.
Drag the existing Search and Shop buttons to the toolbar, in either the Structure
window or in the editor.
i.
Save your work. When you have finished, the page should look similar to this
g.
Optional step: (If you choose not to complete this step, you must begin the practices
for the next lesson by opening the starter application.)
Similarly, on the SupplierUpdate page, put the Supplier form that is contained in a panel
form layout into a panel header. You do not need to change the heading.
Hint: The SupplierUpdate page is in the supplier subdirectory of the
\oracle\storefront\ui\pages directory.
a. Surround the Panel Form Layout with a Panel Header, but do not change the Text
(heading).
b. Add a Toolbar component and move the existing buttons to the toolbar facet of the
panel header.
c. For now, do not change the text of the panel header, because later you add a
conditional text display.
d. Using the Style property group and the Box tab, set the Width of the panel header to
500 pixels.
e.
Save your work. When you have finished, the page should look like this
3.
5.
Optional step: (If you choose not to complete this step, you must begin the practices
for the next lesson by opening the starter application:)
Similarly, on the BrowseSuppliers page, put the Supplier table into a panel header with
the heading Select a Supplier for Update.
a. Surround the Supplier table with a Panel Header.
b. Using the resource bundle, change the Text to Select a Supplier for Update.
c. Save your work.
Optional step: (If you choose not to complete this step, you must begin the practices
for the next lesson by opening the starter application.)
Similarly, on the ShoppingCart page, put the table into a panel header labeled Shopping
Cart.
a. Surround the table with a Panel Header.
b. Use the resource bundle to change the Text to Shopping Cart.
Add a Toolbar component and move the existing buttons to the toolbar facet of the
panel header.
d. Save your work.
Optional step: (If you choose not to complete this step, you must begin the practices
for the next lesson by opening the starter application.)
Similarly, on the CheckoutShipping page, put the panelFormLayout containing the
Shipping form into a panel header titled Shipping Address.
a. Surround the Panel Form Layout with a Panel Header.
b. Use the resource bundle to change the Text to Shipping Address.
c.
6.
c.
d.
Do not move the train or the train button bar into the panel form layout.
Save your work. When you have finished, the Structure window should look like this:
4.
a.
b.
c.
Drag a Panel Group Layout from the Component Palette to the page and set its
Layout property to scroll.
Drag two Panel Headers to the page, one below the other and both within the panel
group layout. You may find it easier to drag the panel headers to the
af:panelGroupLayout in the Structure window.
d.
You have not yet created the last two pages in the CheckoutFlow train. In this practice, you
create those pages, starting with the layout components, and then adding databound
components.
1. Create the CheckoutPayment page. The page should contain a panel group layout with
two panel headers: one that displays the billing address and the other displaying payment
options. The final layout should be something like this:
e.
Now that you have the layout defined, you can add databound components. First, you add
the billing address.
a. Drag the FODCheckoutAMDataControl > ShoppingCart1 > PaymentOption1 >
BillingAddress to the first panel header.
b.
c.
d.
e.
2.
Set the Text of the top panel header to Billing Address and of the other to
Payment Options, optionally using a resource bundle.
3.
Save your work. The page should now look like this:
f.
4.
a.
b.
c.
d.
Drag a second Panel Group Layout to the first one, and set its Layout property to
horizontal and its StyleClass on the Style and Theme tab to AFStretchWidth.
e.
Drag two Panel Headers to the horizontal Panel Group Layout. Set the Text of the first
to Shipping Address, and of the second to Billing Address, optionally using
existing text resources in the resource bundle.
Drag a spacer to the separator facets of each of the two Panel Group Layouts.
Drag another Panel Header to the outermost Panel Group Layout (the one with the
scroll layout) and set its Text to Order Items.
f.
g.
f.
5.
Now that you have defined the layout, you can create databound components on the page.
Create a read-only table of shopping cart items on the Order Items panel header, and readonly forms for shipping address, billing address, and payment options on their respective
panel headers.
a. Drag the FODCheckoutAMDataControl > ShoppingCart1 > PaymentOption1 to the
Payment Options panel header as Form > ADF Read-only Form.
1)
Note
b.
1)
1)
d.
e.
Set the Width of the table to 100% and enable last column stretching.
c.
6. Optional Step: To test your checkout pages, you must add the same train components to
the second and third train stops. In the lesson titled Ensuring Reusability, you define a
page template to use for all these pages, and the train components are on it rather than on
the individual pages. However, for now you temporarily add them to each page for testing.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
e.
f.
g.
h.
i.
j.
Copy the train and train button bar from the CheckoutShipping page to each of the other
two pages in the CheckoutFlow.
a. Open the CheckoutShipping page.
b. In the Structure window, expand jsp:root > f:view > af:document > af:form.
c. Multiselect af:train and af:trainButtonBar.
d. Right-click and select Copy.
DD Direct Debit
IN Invoice
PP PayPal
1. The PaymentTypeCode is a choice list and its default binding gives you the position of the
selected value in the list, not the value. On the CheckoutPayment page, create an attribute
value named PaymentTypeCodeValue for the value of the payment type code.
a. Click the Bindings tab on the CheckoutPayment.jspx page.
b.
c.
d.
e.
f.
1) Because you are going to use partial page rendering for this action, you must reference the
component that triggers the partial page rendering. Set an Id and implement PPR on the
triggering component.
a.
Click the Design tab on the CheckoutPayment.jspx page to go back to the design
view of the page.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
Sometimes there is a need to display or not display attributes depending on specific conditions.
In our example, if the user selects a Credit Card payment type, you do not want to display the
RoutingIdentifier or the InstitutionName because those are used only for checks. If the user
selects a Direct Debit payment type, you do not want to display CardTypeCode or
ExpirationDate, because those are used only for credit cards.
In this practice, you work on the CheckoutPayment page to set the attributes to be visible only
when they are needed, based on the Payment Type. You add Expression Language to the
components that you want to conditionally display, and you use partial page rendering to refresh
only those components, rather than the entire page.
The Payment Type codes are listed below.
CC Credit Card
d.
3.
The first attribute to set a condition on is CardTypeCode. If the payment type code is not
CC (for Credit Card), then do not display this field.
a.
b.
In the list at the left of the Expression Builder, select ADF Bindings > bindings >
PaymentTypeCodeValue > inputValue, which inserts
#{bindings.PaymentTypeCodeValue.inputValue} into the expression. You
then can add the condition to the end of the expression and click OK.
c.
b.
c.
Note: Be sure to select the PaymentTypeCodeValue attribute binding and not the
PaymentTypeCode binding.
a.
6.
7.
Select af:inputText for CheckDigits attribute in either the visual editor or the
Structure window.
b. Repeat steps (4b)(4c) and code are similar.
Set RoutingIdentifier and InstitutionName to be visible only if the value is DD.
Hint: Remember to set the expression for the Visible property and select PaymentType for
the PartialTriggers property for these attributes.
Run CheckoutShipping from the CheckoutFlow task flow and navigate to the
CheckoutPayment page to test your work.
a. Test changing the Payment Type value to see the results. You should see that different
attributes appear depending on the value that you set.
4.
3) Click OK.
Now set ExpireDate to be visible only if the Payment Type Code Value is CC. Define the
Visible and PartialTriggers properties.
a. Select af:inputDate for the ExpireDate attribute in either the visual editor or the
Structure window.
b. Set the Visible attribute (in the Advanced panel) to:
#{bindings.PaymentTypeCodeValue.inputValue eq 'CC'}
When you have finished, close the browser and undeploy the application as described
in step 6(i) of Practice 2-4.
b.
c.
2.
Verify that Row Selection is selected for this table. Use the table Edit icon in the
Property Inspector. (Do not just change the Row Selection property in the property
inspector.)
Set the Products table to be the PPR target that is refreshed when the selected
subcategory changes.
a. Select the Products table (table2).
b. In the Property Inspector, select Edit to set the Partial Triggers property to
SubCategory.
When you added the Products table to the ProductCatalog page, you added it as an
independent table, not as a master-detail table. It is not set to be refreshed when the selection
in the SubCategory table changes. In this practice, you use partial page rendering (PPR) to
refresh the Products table. (This PPR is defined automatically when you add components as
master-detail.)
1. Set the SubCategory table to be the triggering component for PPR.
a. Open the ProductCatalog page and select the af:table within the subcategories
panelHeader.
b. Set Id to SubCategory.
In the Edit Property dialog box, shuttle SubCategory in the Selected pane.
d. Click OK.
3. Test the page.
a. Run the page, either directly or from the task flow.
b. Select Category, then SubCategory and check that the correct products appear.
c. When you have finished, close your browser and undeploy the application as
described in step 6(i) of Practice 2-4.
c.
Chapter 16
Practices Overview
You should also see that the .jspx files for the checkout pages have been converted to
.jsff files.
e.
f.
In this practice, you convert all of your bounded task flows to use page fragments rather than
pages. After you have done this, you no longer can run the task flows independently. You would
need to either call them from an unbounded task flow or use them as regions on a page.
1. Convert CheckoutFlow to use page fragments.
a. Open the CheckoutFlow task flow in the editor.
b. Right-click the diagram and select Convert To Task Flow With Page Fragments.
c. In the Convert To Task Flow With Page Fragments dialog box, click OK. You do not
need to keep a copy of any of the pages.
d. In the warning dialog box, click Yes to continue. You should see that the
use-page-fragments property of the task flow is now set to true.
3.
So that you can use all bounded task flows as regions on a main page, repeat the above
steps to convert all the bounded task flows to use page fragments,
ManageSupplierFlow, ShoppingCartFlow, ShoppingFlow, and
ShowSuppliersFlow. Note that all.jspx files (except for ProductCategory.jspx)
are now converted to .jsff (page fragment) files.
Save your work.
There is only one full page left, which is ProductCategory.jspx. This is a page on the
unbounded task flow. Extract this page into its own bounded task flow named
ProductCategoryFlow, and then convert it to use page fragments as well.
a.
b.
c.
Open adfc-config.xml. Make sure that the views appear in the diagram.
Right-click the ProductCategory view activity and select Extract Task Flow. Click
Yes in the Warning dialog box.
In the Extract Bounded Task Flow dialog box:
1) Enter ProductCategoryFlow as the File Name.
2) Append \oracle\storefront\ui\flow to the Directory path.
d.
3) Click OK.
The task flow opens in the editor. Right-click the ProductCategory view activity and
mark it as the default activity.
e.
Convert ProductCategoryFlow to use page fragments as you did the other task flows.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
2.
When you extract a task flow, JDeveloper creates a task flow call on the original task
flow. Delete the task flow call activity from adfc-config.xml.
g.
f.
In this practice, you create a page template and apply it to the pages in CheckoutFlow. You
previously added the train components and arranged them on each of the checkout pages. This
duplication of effort is not that bad if there are only a few pages. However, if there are many
pages, this duplication becomes a little tedious and possibly error-prone.
To avoid this unnecessary duplication, you now create a template that manages the train
components for each of the pages. The template also contains a Panel Group Layout and a
Panel Header to provide additional layout structure for the checkout pages.
1. Create a new page template named CheckoutPageTemplate, with a content facet and
a required title attribute.
a. In the Application Navigator, right-click the directory where you have been filing pages
and select New.
b. In the New Gallery, select Web Tier > JSF > JSF Page Template.
c. Set the following properties for the new page template:
d.
File Name:
CheckoutPageTemplate.jspx
Directory:
<ProjHome>\public_html\oracle\storefront\ui\
pages\templates
CheckoutPageTemplate
e.
Click OK.
required
To the page template, add the layout and train components that you want to use on all the
checkout pages.
a. Add a Panel Group Layout on af:pageTemplateDef.
1)
2)
If necessary, drag the panel group layout above af:xmlContent in the Structure
window.
b.
c.
d.
2.
f.
g.
Expand the af:panelHeader > Panel Header facets node in the Structure pane.
Add a Toolbar to af:panelHeader > Panel Header facets > toolbar.
h.
2)
3)
i.
Add a Train Button Bar to af:toolbar inside the af:panelHeader toolbar facet
and set the Value property to
#{controllerContext.currentViewPort.taskFlowContext.trainModel}.
j.
1)
2)
e.
3.
Note: If you use the Expression Builder, it displays the code as if it were an error.
It has context for the trainModel, but does not understand .next in the
expression. You can ignore the error.
Save your work. The page template should look similar to the following
3)
4.
Apply the template to the checkout pages. (You cannot use the IDE to apply a template to
an existing page. However, you can add the template-related code to an existing page.)
a. Open CheckoutShipping.jsff.
d.
e.
f.
5.
The template contains the outermost Panel Group Layout (which holds the train, buttons,
and the Panel Header). Therefore, when you apply the template to your page, you must
move the content to the template content facet.
a. Using the Structure window, drag af:panelHeader Shipping Address to the
content facet.
6.
Apply the template to the other pages in the checkout flow, using Billing as the title for the
CheckoutPayment page and Confirmation as the title for the CheckoutConfirm page.
a. Open CheckoutPayment.jsff.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
b.
c.
b.
Repeat the steps above, changing the value of the title attribute to Billing. (The
content area of this page is in the panelGroupLayout.)
Open CheckoutConfirm.jsff.
Repeat the steps above, changing the value of the title attribute to Confirmation.
(The content area of this page is in the outermost panelGroupLayout.)
Save your work.
7.
c.
d.
1.
In the templates subdirectory of your directory for pages, create a new page template
named MainPageTemplate. Define content areas named companyLogo, tab1Content,
tab2Content, and mainContent. Define required attributes called companyName,
tab1Title, and tab2Title.
a. In the Application Navigator, right-click the directory where you have already created a
page template and select New.
b. In the New Gallery, select Web Tier > JSF > JSF Page Template.
c. Set the following properties for the new page template, and then click OK:
File Name
MainPageTemplate.jspx
Directory
<ProjHome>\public_html\oracle\storefront\ui\p
ages\templates
MainPageTemplate
companyLogo
tab1Content
tab2Content
mainContent
Your company is planning several applications that should have a similar look. The main page
should have an image at the top left, with the company name next to it. The lower part of the
page should be divided into two panels. The main flow of the application is to appear in the right
panel, whereas the left panel should have tabs for accessing other functionality that may be
available.
In this practice, you create a page template to be used on the main page of any of the
companys applications. You then create the FODShoppingDashboard page and base it on this
template. The layout of the template should be as follows:
2.
java.lang.String
java.lang.String
java.lang.String
required
required
required
The new template opens in the editor. Add a component with resizable vertical panes, so
that page developers can resize it to fit the size of the image that they add to the top pane.
The component should be one that automatically stretches its children. Stretch it to fit the
browser vertically and horizontally.
a. Drag a Panel Splitter to the page. Ensure that it appears above af:xmlContent in the
Structure window.
1) Set its Orientation to vertical.
2)
3.
companyName
tab1Title
tab2Title
You want the company logo image and the company name to be arranged horizontally in
the top portion of the page. Add a layout component to accomplish that, and add the
company logo and name.
a. In the Structure window, expand af:panelSplitter and Panel Splitter facets.
b. Drag a Panel Form Layout to the first facet and set the following properties:
1)
Set Rows to 1 (so that the components you add are in one horizontal row).
c.
d.
Drag a spacer to the af:panelFormLayout, so that the company name that you add in
the next step is not right up against the logo.
Drag an Output Text component to the af:panelFormLayout.
1) Set its Value to #{attrs.companyName}. (You can use the Expression Builder
and select JSP Objects > attrs > companyName.) Designers of pages that use
this template can supply a value for the companyName attribute.
2) In the Style > Text section of the Property Inspector, set Color to Blue, Size to
xx-large, Italic to italic, and Bold to bold.
e.
4.
Set Width to 500 pixels (so that the components you add are next to one
another, instead of spreading out to fit the browser width).
Below the header section that has the company logo and name, you want two resizable
panels that consume the remainder of the browser area. The left panel should contain two
tabs where page designers can place content, and the right panel should contain the main
content area. Add the layout and components for this area.
a. Drag a Panel Splitter to the second facet of the root af:panelSplitter and set its
Orientation property to horizontal.
b. Expand af:panelSplitter >Panel Splitter facets for the panel splitter that you just
added.
c. Drag a Panel Tabbed component to the first panel splitter facet.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
2)
One detail item (corresponding to a tab) is created by default for the af:panelTabbed
component. Drag a second Show Detail Item to the af:panelTabbed component.
1)
2)
e.
Drag a Facet Ref to the first af:showDetailItem and select tab1Content as the facet
name.
f.
Drag a Facet Ref to the second af:showDetailItem and select tab2Content as the
facet name.
Drag a Facet Ref to the second facet of the af:panelSplitter and select mainContent
as the facet name. This provides a spot for page designers to place the main content of
the application.
Your template should look like the following:
g.
h.
5.
i. Save your work. You must save a page template before you can use it.
On the main unbounded task flow for the application, create the FODShoppingDashboard
page, applying the template that you just created.
a. Open adfc-config.xml.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
d.
6.
Double-click the FODShoppingDashboard view activity to create the page, setting the
following properties:
File Name
FODShoppingDashboard.jspx
Directory
Use Page
Template
MainPageTemplate
Use the attributes of the page template to customize the page for the Storefront application.
Supply values for the attributes of the template. The company name should be Storefront
Demo and the tabs should be labeled Categories and Suppliers. The IDE does not provide
a way to use a resource bundle, so you can enter hard-coded strings in this case.
a. Set the attribute values in FODShoppingDashboard. In the editor, click the
FODShoppingDashboard tab, or reopen that file if you have closed it.
b. In the Structure window, select af:pageTemplate.
c. In the Property Inspector, set the following values:
companyName: Storefront Demo
tab1Title: Categories
tab2Title: Suppliers
b.
d.
2)
In the Insert Image dialog box, click the arrow next to Source, click Edit, and
navigate to the \images subdirectory of your Labs main directory.
3)
4)
In the Image Location Problem warning box, click Yes to copy the image into the
document root of your project.
5)
Back in the Insert Image dialog box, provide a ShortDesc if desired, and then click
OK. You should now see the image on the page.
e. Save your work.
Change the company name to display in red rather than in blue.
a. Open MainPageTemplate.jspx.
b. Expand af:pageTemplateDef > af:panelSplitter - vertical > Panel Splitter facets >
first > af:panelFormLayout - 1.
c. Select af:outputText - #{attrs.companyName}.
d. On the Style > Text section of the Property Inspector, set Color to Red.
7.
e.
f.
Save your work. You must save the changes to a page template for them to be picked
up by pages that use the template.
Open FODShoppingDashboard. If it is already open, click its tab and select View >
Refresh. You should see that the Storefront Demo text is now red.
6)
c.
2.
Add the tab2 content. You should display the ShowSuppliersFlow in this area.
a. From the Application Navigator, drag ShowSuppliersFlow to the tab2Content facet in
the editor.
b. Create the flow as a Region.
b.
4.
Add the main content. You should display the ShoppingFlow in this area.
a. From the Application Navigator, drag ShoppingFlow to the mainContent facet.
b.
c.
d.
e.
f.
g.
h.
i.
j.
Click the Suppliers tab. Click one of the links. You can see that the update supplier
page appears and displays the selected record, but with no way to navigate back to the
browse page (you fix this later).
In the main shopping region, note that you must scroll down to see the other tables on
the page (you fix this shortly). Select a new subcategory and verify that the correct
products appear in the Products table.
Click Show Cart to verify that the cart is displayed correctly.
Click Shop to return to the main shopping region.
Click Search. Enter a search criteria to verify that the search functionality works. Note
that there is no way to return to the main shopping page from this page. You soon fix
this problem.
Click the link on one of the products. The page should now show the product detail.
Click Shop to return to the main shopping page.
Click Show Cart again, and then click Checkout.
Verify that you can navigate through the checkout train, both by using the train and by
using the train buttons.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
3.
Close the browser when you have finished, and undeploy the application as described
in step 6(i) of Practice 2-4.
Optional step: (If you choose not to complete this step, you must begin the practices
for the next lesson by opening the starter application.)
There is no way to return to the main shopping page from the ProductSearch page.
Implement navigation on that page to return to the main shopping task flow. Also add some
layout to the page to improve its appearance: Change the heading of the table to Search
Products and place all components under a root panel header with scrollbars.
a. Open the ProductSearch page fragment.
b. In the existing af:panelHeader, use the resource bundle to change the text from
ProductEO to Search Products.
5.
c.
d.
e.
Shop
Action
shop
f.
Run FODShoppingDashboard again from the unbounded task flow to ensure that the
Shop button on the Product Search page navigates back to the shopping flow (Product
Catalog page).
k.
Chapter 17
Practices Overview
c.
Select the Categories table either in the Structure window or the visual editor (the
default ID of the table is masterDetail1).
In the Property Inspector, click Edit.
2.
a.
b.
Open the Page Definition for the ProductCatalog page (right-click the page and
select Go to Page Definition, or click the Bindings tab).
Add the following parameters to the page definition:
id Value
param_CategoryId
#{pageFlowScope.CategoryId}
param_SubCategoryId
#{pageFlowScope.SubCategoryId}
param_CategoryName
#{pageFlowScope.CategoryName}
param_SubCategoryName
#{pageFlowScope.SubCategoryName}
b.
3.
Leave the page definition file open for the next step.
There is a method named setCurrentCategory() in the FODProductAM application
module. This method takes two arguments: a category ID and a subcategory ID. It
reexecutes the BrowseCategory, BrowseSubcategory, and BrowseProduct view object
queries based on the values that are passed to it.
Edit the bindings for the ProductCatalog page so that this method is executed upon
loading the page. Pass to the method two of the parameters that you have just defined
above.
a. Still in the page definition of the ProductCatalog page, click the Bindings and
Executables tab, then in the Bindings section, click the Create Control Binding green
b.
c.
plus sign
and add a methodAction.
In the Create Action Binding dialog box, select the FODProductAMDataControl Data
Collection, and then confirm that setCurrentCategory appears in the Operation
drop-down list.
In the Create Action Binding dialog box, in the Parameters section, set these values
for the following parameters:
Name Value
categoryId
#{bindings.param_CategoryId}
subCategoryId
#{bindings.param_SubCategoryId}
(You can use Expression Builder; the parameters are shown under ADF Bindings >
bindings.)
The Page Definitions Parameters section should look like the following:
4.
d.
Click OK.
Add an InvokeAction to the Executables.
e.
f.
g.
Make sure that invokeAction is the first executable in the list. This ensures that the
method is executed first when the page is loaded. (If you must move it, drag it to the
top of the list.)
h. Save your work, and leave the page definition file open for the next step.
You have defined parameters that take their values from pageFlowScope variables. But
how do those values get stored in the pageFlowScope variables? In this step, you store
these values.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
The Parameters section of the Create Action Binding Editor should look like the
following:
Repeat this step for BrowseSubCategory1 because you are going to use the
CategoryId that is selected in the SubCategories table to set the
subcategory-related parameters.
On the ProductCatalog page, convert the CategoryName field in the Categories
table to be a link. When a user clicks the link, the page should use setActionListeners
to set the pageFlowScope parameters.
1) Click the Design tab and in the Structure window for the ProductCatalog page,
and expand af:table - masterDetail1.
2)
b.
In the Category and Subcategory tables, convert the category name to a link that
stores the name and ID in pageFlowScope variables. Use a Set Action Listener
operation to store each variable value.
Hint: You must first add the category ID to the page bindings.
a. Add CategoryId to the page bindings for both BrowseCategory1 and
BrowseSubCategory1.
1) Still in the page definition file for ProductCatalog, edit the BrowseCategory1
binding and add CategoryId as a display attribute. Hint: Click the
BrowseCategory1 binding; click Edit; select the rule in the Tree Binding editor;
shuttle the CategoryId from Available to Display Attributes.
Expand the first af:column node, and then click af:outputText for
CategoryName and copy (Ctrl + C) the Value property (to keep its content before
losing it when converting the outputText to a Link).
3)
4)
5)
Select Link, and then click OK in the Confirm Convert dialog box.
Paste into the Text property the value you copied a moment ago. The value
should be #{row.CategoryName}.
6)
Insert two setActionListeners operations inside the Link with the following
properties.
From To
#{row.CategoryId}
#{row.CategoryName}
c.
#{pageFlowScope.CategoryId}
#{pageFlowScope.CategoryName}
Expand the first af:column node and click af:outputText for CategoryName
and copy (Ctrl + C) the Value property.
Right-click af:outputText for CategoryName and select Convert To.
Select Link, and then click OK in the Confirm Convert dialog box.
Paste into the Text property the value that you copied a moment ago. The value
should be #{row.CategoryName}.
Insert two setActionListeners inside the Link with the following properties.
From To
#{row.CategoryId}
#{row.CategoryName}
5.
#{pageFlowScope.SubCategoryId}
#{pageFlowScope.SubCategoryName}
Modify the rendering of the tables so that only a single table appears at a time.
Hint: If both category and subcategory parameters are null, the Categories table
should appear (no links have been clicked to set the parameters). If only the
categoryId parameter is set, the Subcategories table should appear because the
user clicked a link on the Categories table to set the category ID. If both parameters
are set, the Products table should be displayed (both Category and Subcategory links
have been clicked, so both parameters have been set).
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
2)
Select the first af:table (masterDetail1) and, using the Expression Builder, set the
Rendered property so that the table appears if the param_CategoryId and the
param_SubCategoryId are both null. (This means that there were no parameters
set). The EL code is:
#{bindings.param_CategoryId eq null and
bindings.param_SubCategoryId eq null}
b.
Select the second af:table (SubCategory) and set the Rendered property so that
the table appears if the CategoryId parameter is set but the SubCategoryId
parameter is null. (This means that the page set a category, but not a subcategory.)
The EL code is:
#{bindings.param_CategoryId ne null and
bindings.param_SubCategoryId eq null}
c.
Select the third af:table - table2 (Products) and set the Rendered property so
that the table appears if there is a categoryId and a subCategoryId. (This means
that the page has set a Category and subcategory.) The EL code is:
#{bindings.param_CategoryId ne null and
bindings.param_SubCategoryId ne null}
Modify the layout of the ProductCatalog page so that all tables are under a single panel
header whose title changes depending on the table that appears.
a. In the Structure window for the ProductCatalog page, select af:table
SubCategory in the second af:panelHeader and drag it to the first
af:panelHeader (the one currently labeled Categories).
b.
c.
6.
a.
d.
Select af:panelHeader and in the Text property, replace the existing text with:
#{bindings.param_CategoryId eq null ||
bindings.param_SubCategoryId eq null ?
storefrontuiBundle.CATEGORIES : storefrontuiBundle.PRODUCTS}
e. Move the command buttons on the page to a toolbar in the toolbar facet of the panel
7.
header.
1) Expand Panel Header facets.
2) Drag a toolbar to the toolbar facet.
3) Drag the Search and Show Cart buttons to the toolbar.
4) The Structure should now look something like:
Hint: Remember that the parameters get their values from the pageFlowScope variables.
a. On the ProductCatalog page, select the first af:commandNavigationItemthe one
labeled Store.
b. Add four setActionListeners operations with the following properties:
From To
#{null}
#{null}
#{null}
#{null}
#{pageFlowScope.CategoryId}
#{pageFlowScope.CategoryName}
#{pageFlowScope.SubCategoryId}
#{pageFlowScope.SubCategoryName}
Hint: After you add the first setActionListener, you could use the Source tab to copy,
paste, and then modify the code.
2.
Set the second breadcrumb to appear only if the user has clicked a category name in the
Categories table. Label the breadcrumb with the Category name that the user clicked in the
Categories table. Set the second breadcrumb to display the Subcategory table when
a user clicks it.
a. Select the second of the three navigation items in the Structure window.
Expression Builder to set this (ADF Bindings > bindings > param_CategoryName).
Set the Rendered property to
#{bindings.param_CategoryId ne null}.
d.
If a user clicks the second breadcrumb, he or she wants to see SubCategories. You
use the setActionListeners to reset just the SubCategory parameters.
Add two setActionListeners with the following properties:
From To
#{null}
#{null}
#{pageFlowScope.SubCategoryId}
#{pageFlowScope.SubCategoryName}
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
When users click through links in the tables to display either the Subcategories or Products
table, they need a way to navigate back through the chain of tables. This is what the
breadcrumbs on the page enable them to do.
When users click the first breadcrumb, they should return to the top level of the breadcrumb list
to display the Categories table. You have already set the page to use the pageFlowScope
parameters to display the correct section of the page, so in this practice, you just set those
parameters based on which breadcrumb is clicked.
1. For the first breadcrumb, you want the Categories table to appear; therefore, reset all the
parameters to null.
3.
Set the third breadcrumb to appear only if the user has clicked a category name in the
SubCategories table. Label the breadcrumb with the Category name that the user clicked
in the SubCategories table. Set the third breadcrumb to display the Products table
when a user clicks it.
a. Select the last of the three navigation items in the Structure window.
4.
c.
d.
a.
b.
c.
d.
2.
#{pageFlowScope.Action}
True
#{pageFlowScope.ProductId} False
Open ShoppingCartFlow.
Click the Overview tab in the Editor window.
Click the Parameters tab.
Click the Add icon to add the two parameters shown above.
Add a method call to the shopping cart flow that calls the addItemToCart() method of
FODShoppingCartAM. Set the value of its productId argument to
#{pageFlowScope.ProductId}. Navigate to the ShoppingCart view when finished.
a.
b.
c.
In the Edit Action Binding dialog box, set the Value of the productId parameter to
#{pageFlowScope.ProductId}, and then click OK.
d.
Add a Control Flow Case from addItemToCart to ShoppingCart and label it done.
(You can later change this to include a commit function, but for now you simply want to
go to the cart after the method call.)
In the addItemToCart method call, change the fixed-outcome property to done.
e.
Action
ProductId
Required
Add a router named ChooseAction as the default activity for the shopping cart flow. The
router should either display the shopping cart (display control flow case) or add an item
to it (add control flow case), depending on whether pageFlowScope.Action has a value
of Display or Add. The default action should be to display the cart.
a. Add a Router to the flow and name it ChooseAction.
b.
c.
Mark the ChooseAction router as the default activity for the page flow.
Create two Control Flow Cases from ChooseAction: one to addItemToCart named
add, and the other to ShoppingCart named display.
d.
e.
4.
The shopping cart flow is expecting parameters named Action and optionally,
ProductId. Modify the shopping flow to send the correct parameters.
a. Open the ShoppingFlow diagram.
b. Select DisplayShoppingCart. Two parameters have been added to the
DisplayShoppingCart task flow call in the Parameters section of the Property
Inspector. Set a value for the Action parameter as follows:
Name Value
Action
Display
ProductId
3.
In the ShoppingFlow, the same two parameters have been added to the
AddShoppingCart task flow call; select AddShoppingCart and in the parameters
section, set the values as follows:
Name
Value
Action
Add
ProductId
#{requestScope.ProductId}
The ShoppingFlow is now set up to send the Action parameter and, if needed, to
send the ProductId as well.
5.
Finally, you must get the productId from the calling page and put it into the requestScope
variable ProductId. The call to add the item to the cart should be placed on the
ProductDetails page. Hint: There is currently no binding for ProductId.
a. Open the ProductDetails page fragment.
b. Add a button to the toolbar of the panel headers toolbar facet and label it Add Item
to Cart. Set its Action to add.
c.
d.
Return to the Design of the page and add a setActionListener to the Add Item to
Cart button and set the value of From to #{bindings.ProductId.inputValue}
and the value of To #{requestScope.ProductId}.
Hint: Right-click af:commandButton, select Insert inside > ADF Faces > Set
Action Listener and set the From and To values. Make sure to put the correct
c.
6.
SupplierAction
2.
a.
b.
Open ManageSupplierFlow.
Click the task-flow-definition in the Structure window.
c.
d.
Click Add
True
Add a method call to the ManageSupplierFlow task flow to call the CreateInsert operation
for a new supplier and connect it to the SupplierUpdate activity when finished.
a. Open the ManageSupplierFlow task flow.
b. In the Data Controls panel, expand FODSupplierAMDataControl > Supplier1 >
Operations and drag the CreateInsert operation to the task flow diagram to create a
method call activity.
c. Change fixed-outcome of the CreateInsert method call activity to done.
d.
3.
#{pageFlowScope.SupplierAction}
Set up the task flow so that a new supplier is created when a parameter passed to it has a
value of New, or that an existing supplier is updated when the parameter value is Update.
a. Add a Router to the flow and name it ChooseAction.
b.
c.
d.
Right-click the ChooseAction router and mark the activity as the default activity for
the page flow.
Create two Control Flow Cases from ChooseAction: one to SupplierUpdate named
update, and the other to CreateInsert named new.
Add two expressions to the ChooseAction router that evaluate
pageFlowScope.SupplierAction. If the value is New, use the new outcome. If it is
Update, use the update outcome. Hint: The new expression is:
#{pageFlowScope.SupplierAction == 'New'}
Note: You define these expressions in the Cases section under the Common tab of
the Property Inspector.
Name Value
4.
The manage suppliers flow is expecting a parameter named SupplierAction. Modify the
show suppliers flow to send the correct parameter.
a. Open the ShowSuppliersFlow diagram.
b. Add a parameter to the ManageSupplierFlow task flow call activity using the
Parameters section of the Property Inspector. (The parameter should be there by
default because you have set it on the ManageSupplierFlow task flow, so just set its
value in the task flow call activity.)
Name Value
SupplierAction
5.
#{requestScope.SupplierAction}
Set the requestScope variable SupplierAction. The calls to create a new supplier or
update an existing one should be placed on the BrowseSuppliers page.
a. Open the BrowseSuppliers page.
b. Add a toolbar to the panel headers toolbar facet.
c. Add a toolbar button to the toolbar and label it New Supplier. Set its Action to
update.
d.
Add a setActionListener to the New Supplier button that sets the value of
#{requestScope.SupplierAction} to New when the button is clicked.
Set the From property to #{'New'} and the To property to
#{requestScope.SupplierAction}.
e.
f.
Finally, change the panel header text of the SupplierUpdate page to conditionally display
either Update Supplier or New Supplier, depending on the value of the parameter that is
passed.
a. On the SupplierUpdate page, select the panel header.
b. If you are not using resource bundle for text, change the Text to the expression
#{pageFlowScope.SupplierAction == 'New' ? 'New Supplier' :
'Update Supplier'} (all on one line.)
c.
7.
6.
e.
you have finished, close the browser and undeploy the application as described in step 6(i)
of Practice 2-4.
Chapter 18
Practices Overview
The contextual event that you define in the practices for this lesson makes it possible for the
user to click a category in the ProductCategory region at the left of the page, and then display
the appropriate table in the ShoppingFlow region at the right of the page.
The ShoppingFlow region (ProductCatalog page) displays the appropriate table based on
pageFlowScope variables that you defined in the previous set of practices. To be able to set
pageFlowScope variables from outside the task flow, the task flow must be able to receive
values that are set in another region. In this practice, you define input parameters on the
ShoppingFlow task flow as the first step in setting up a contextual event.
1. Define four parameters on the ShoppingFlow task flow: CategoryId, CategoryName,
SubCategoryId, and SubCategoryName. Store them in pageFlowScope variables of
the same name.
a. Select the ShoppingFlow in the Application Navigator.
b. Select the task-flow-definition ShoppingFlow node in the Structure window.
c.
Use the Parameters section of the Property Inspector to create the following input
parameters:
Name Value
CategoryId
CategoryName
SubCategoryId
SubCategoryName
#{pageFlowScope.CategoryId}
#{pageFlowScope.CategoryName}
#{pageFlowScope.SubCategoryId}
#{pageFlowScope.SubCategoryName}
Note that this is just another way to set the pageFlowScope variables in the
ShoppingFlow task flow. The values are set either by clicking links on the
ProductCatalog page, as you defined in the previous set of practices, or they can be
set by receiving values via these input parameters on the task flow. After the values are
received, they have the same effect of setting the correct table to appear and setting
the breadcrumbs.
In the remaining practices in this lesson, you use a contextual event to pass values to
these parameters when a node in the category tree is clicked.
javax.el.ELContext;
javax.el.Expression;
javax.el.ExpressionFactory;
javax.el.MethodExpression;
javax.el.ValueExpression;
import javax.faces.context.FacesContext;
import oracle.adf.model.BindingContext;
import oracle.adf.model.DataControlFrame;
/**
* Provides various utility methods that are handy to
* have around when working with ADF.
*/
public class ADFUtil {
/**
* When a bounded task flow manages a transaction (marked as
* requires-transaction, requires-new-transaction, or
* requires- existing-transaction), then the task flow must
* issue any commits or rollbacks that are needed.
* This is essentially to keep the state of the transaction
* that the task flow understands in synch with the state
* of the transaction in the ADFbc layer.
* Use this method to issue a commit in the middle of a task
* flow while staying in the task flow.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
4.
5.
*/
public static void saveAndContinue() {
Map sessionMap =
(BindingContext)sessionMap.get(BindingContext.CONTEXT_ID);
String currentFrameName =
context.getCurrentDataControlFrame();
DataControlFrame dcFrame =
context.findDataControlFrame(currentFrameName);
dcFrame.commit();
dcFrame.beginTransaction(null);
}
/**
* Programmatic evaluation of EL.
*
* @param el EL to evaluate
* @return Result of the evaluation
*/
public static Object evaluateEL(String el) {
FacesContext facesContext =
FacesContext.getCurrentInstance();
ELContext elContext = facesContext.getELContext();
ExpressionFactory expressionFactory =
facesContext.getApplication().getExpressionFactory();
ValueExpression exp =
expressionFactory.createValueExpression(elContext,
el, Object.class);
return exp.getValue(elContext);
}
/**
* Programmatic invocation of a method that an EL evaluates
* to. The method must not take any parameters.
*
* @param el EL of the method to invoke
* @return Object that the method returns
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
FacesContext.getCurrentInstance().getExternalContext().getSessio
nMap();
BindingContext context =
*/
/**
* Programmatic invocation of a method that an EL evaluates to.
*
* @param el EL of the method to invoke
* @param paramTypes Array of Class defining the types of the
* parameters
* @param params Array of Object defining the values of the
* parametrs
* @return Object that the method returns
*/
public static Object invokeEL(String el,
Class[] paramTypes, Object[] params) {
FacesContext facesContext =
FacesContext.getCurrentInstance();
ELContext elContext = facesContext.getELContext();
ExpressionFactory expressionFactory =
facesContext.getApplication().getExpressionFactory();
MethodExpression exp =
expressionFactory.createMethodExpression(elContext,
el, Object.class, paramTypes);
return exp.invoke(elContext, params);
}
/**
* Sets a value into an EL object. Provides similar
* functionality to
* the <af:setActionListener> tag, except the
* <code>from</code> is
* not an EL. You can get similar behavior by using the
* following...<br>
* <code>setEL(<b>to</b>, evaluateEL(<b>from</b>))</code>
*
* @param el EL object to assign a value
* @param val Value to assign
*/
public static void setEL(String el, Object val) {
FacesContext facesContext =
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
FacesContext.getCurrentInstance();
ELContext elContext = facesContext.getELContext();
ExpressionFactory expressionFactory =
facesContext.getApplication().getExpressionFactory();
ValueExpression exp =
expressionFactory.createValueExpression(elContext,
el, Object.class);
exp.setValue(elContext, val);
}
}
Right-click anywhere in the code editor and select Make to compile the class.
6.
c.
d.
e.
Make it public and use the Constructors from Superclass option. Click OK.
Add private variable definitions for the following:
categoryId, subCategoryId (Number)
categoryName, subCategoryName (String)
At this point, the code should be:
public class FODCategoryBean {
private Number categoryId, subCategoryId;
private String categoryName, subCategoryName;
public FODCategoryBean() {
super();
}
f.
2.
Generate accessors for these variables using either the toolbar button
(on the
visual editor pane) or the menu Source > Generate Accessors. Click the select all
button. Click OK to generate the accessors.
Add a method named onNodeClicked() that returns a bean with values set based on the
values of the node that the user clicked: (You can copy it from onNodeClicked.txt in the
\files subdirectory of the Labs directory.)
/**
* Evaluates the currently selected node in the tree returns a
* bean representing that node.
*
* @return FODCategoryBean with all properties set
*/
public FODCategoryBean onNodeClicked() {
JUCtrlHierNodeBinding node =
(JUCtrlHierNodeBinding)ADFUtil.evaluateEL("#{node}");
Row nodeRow = node.getRow();
JUCtrlHierNodeBinding parentNode = node.getParent();
Row parentRow = parentNode.getRow();
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
When the user clicks a category or subcategory in the tree, you must capture the current values
and store them. These are the values (payload) that you pass to ShoppingFlow and use on the
ProductCatalog page. In this practice, you create a JavaBean to encapsulate the current row
values. A method in this JavaBean becomes the payload method of the contextual event.
1. Create the new Java class.
a. In the Application Navigator, expand Application Sources, right-click the
oracle.storefront.ui package, and select New.
b. In the New Gallery, select Java Class.
setCategoryId(categoryId);
setSubCategoryId(subCategoryId);
setCategoryName(categoryName);
setSubCategoryName(subCategoryName);
return this;
}
3.
JDeveloper prompts you to import the supporting packages. Make sure that you have the
following imports statements:
oracle.jbo.Row;
oracle.jbo.domain.Number;
oracle.jbo.uicli.binding.JUCtrlHierNodeBinding;
oracle.storefront.ui.common.ADFUtil;
Important Note: If you are not prompted for the oracle.jbo.domain.Number
package, add it to the imports manually. Otherwise, the code will use the wrong Number
class and you will get errors when you call it.
4.
2.
c. Click OK to accept the default values on the Confirm Component Rebinding page.
Add an event to the page named FODSelectCategory that will be registered when the user
clicks the node.
a. While still on the ProductCategory page, click the Bindings tab.
b. Expand Bindings in the Structure window.
c. Insert events (an event list) inside onNodeClicked (use the context menu).
The ProductCategory page starts the event sequence. When a user clicks a node in the
Category tree, an event is raised, which is managed by the FODShoppingDashboard page. In
this practice, you set up the ProductCategory page to initiate the event.
1. Call the onNodeClicked() method when the user clicks a node in the tree.
a. Open the ProductCategory page fragment.
b. Drag the FODCategoryBean > onNodeClicked() method from the Data Controls
panel to the af:commandLink, and select Bind Existing Link.
d.
Insert an event inside the event list and set the name property to
FODSelectCategory.
You now have specified that clicking a node at run time in the Category Tree calls the
onNodeClicked() method and raises the FODSelectCategory event.
Sets the requestScope variables to reflect which Category was selected in the tree
ADFUtil.setEL("#{requestScope.refreshLocalArea}",
Boolean.TRUE);
}
JDeveloper prompts you to import the supporting package. Import the following:
oracle.storefront.ui.common.ADFUtil;
4.
As you did with the other bean, compile the class and create a data control from it. The
Data Control panel should now look like this:
3.
2.
b.
c.
c.
2)
3)
4)
to define
In the Consumer Params section, click Add Consumer Parameter
a parameter named category with a value of #{payLoad}. (You can use the
Expression Builder to select Payload Data > payLoad.) Click OK.
1)
e.
Click OK again.
d.
That completes building the event map and defining the producer and consumer methods. Now
you must set ShoppingFlow to be refreshed based on a requestScope parameter and to
accept the other parameters needed by the ProductCatalog page.
The handler method that you defined for the event sets several requestScope variables. In
this practice, you define region parameters to pass these variables into the Shopping region.
The region parameters have the same name as the task flow parameters that you defined in the
first practice for this lesson. So the values come through the event to requestScope variables
and are passed to region parameters. The region parameter values are passed to the task flow
parameters, which in turn set the pageFlowScope variables that the ProductCatalog page uses
to conditionally render tables and breadcrumbs, as you defined in an earlier practice.
1. One of the tasks accomplished by the refreshCategory() method in the
FODShoppingDashboard bean is to set a Boolean requestScope variable named
refreshLocalArea to true. Set a refresh condition in the ShoppingFlow region to make
use of the value of this variable, so that the region is refreshed only if refreshLocalArea
is set to true.
a. Still in the FODShoppingDashboard page definition (the Binding tab of the page),
select Executables > ShoppingFlow1 in the Structure window.
b. Set RefreshCondition to #{requestScope.refreshLocalArea}.
2.
Set region parameter values to the requestScope values that are set by the
refreshCategory() method in the FODShoppingDashboard bean.
a. Click the Parameters tab in the Property Inspector. Note that the task flow binding
parameters are listed.
b. Set the value property of the parameters to the following values.
Name Value
CategoryId
#{requestScope.CategoryId}
CategoryName
SubCategoryId
SubCategoryName
3.
#{requestScope.SubCategoryName}
4.
#{requestScope.CategoryName}
#{requestScope.SubCategoryId}
If you have time: In this practice, you modify the JSF life cycle to print out a message
whenever the user navigates to a new page. In a real application, you could use a similar
modification to call a routine to, for example, perform some cleanup activities.
1. In the oracle.storefront.ui.common package, create a new Java class named
StorefrontPhaseListener.java that implements the PhaseListener interface and
displays a message when the view ID of a page changes.
a. Right-click oracle.storefront.ui.common to invoke the New Gallery, select Java
Class in the General category, and then click OK.
b. In the Create Java Class dialog box, enter a name of StorefrontPhaseListener,
and leaving the default options, click OK.
c. Right-click the editor and select Source > Implement Interface.
d. On the Hierarchy tab of the Implement Interface dialog box, select javax > faces >
event > PhaseListener and click OK.
e.
Add a private String attribute named storedViewId to store the view ID by adding
the following on the line just after the first left brace:
private String storedViewId = null;
f.
Modify the getPhaseId() method to return the PhaseId of whatever life-cycle phase
being executed with the following code:
public PhaseId getPhaseId() {
return PhaseId.ANY_PHASE;
}
g.
Modify the afterPhase() method to store the view ID when the view is first restored:
public void afterPhase(PhaseEvent phaseEvent) {
if (phaseEvent.getPhaseId() == PhaseId.RESTORE_VIEW) {
storedViewId =
phaseEvent.getFacesContext().getViewRoot().getViewId();
}
}
2.
3.
Modify the beforePhase() method so that just before the page is rendered a
message appears if the current view ID is not the same as the stored view ID:
public void beforePhase(PhaseEvent phaseEvent) {
if (phaseEvent.getPhaseId() == PhaseId.RENDER_RESPONSE) {
String viewId =
phaseEvent.getFacesContext().getViewRoot().getViewId();
if (storedViewId != null &&
!viewId.equalsIgnoreCase(storedViewId)) {
System.out.println("Changing pages");
}
storedViewId = null;
}
}
Test the functionality by invoking the application and changing views. Because you have
only one view activity in the application, with all others being part of a region on the same
page, you must add another page to the application to test it.
a. Open adfc-config and add a view activity called Start.
b. Add a control flow case from Start to FODShoppingDashboard whose fromoutcome is start.
c.
Create the Start.jspx page by double-clicking the Start view activity in the editor.
Select the Blank Page option.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
h.
d.
Add a button to the page labeled Start Shopping and set its Action to start.
e.
f.
g.
h.
Chapter 19
The first is Add to Cart, where the user adds items to the cart. So far, the user can add
items but they are not persisted.
The second area is Checkout.
The third area is being able to update, delete, and add Suppliers.
If you successfully completed all sections of the previous practice, you can continue working in
the same project. However, if you prefer to start with a clean application that contains everything
completed up to the start of this lesson, open Storefront-19.jws and edit the database
information as described in step 4 of Practice 2-4.
d.
e.
2.
On the diagram, select the done control flow case and in the property inspector,
change its to-activity-id to Commit.
Add a Control Flow Case labeled done from Commit to ShoppingCart. Set the fromoutcome property to done.
In this practice, you add a commit to the shopping cart functionality to persist items that are
added to the cart.
1. Use the Commit operation of FODShoppingCartAMDataControl to commit items after
adding them to the cart.
a. Open the ShoppingCartFlow.
b. From the Data Controls panel, drag the Commit operation from
FODShoppingCartAMDataControl > Operations to the ShoppingCartFlow page flow.
c. Set the fixed-outcome property to done.
2.
3.
d.
Name
FODCommitDeleteBean
Class
oracle.storefront.ui.bean.FODCommitDeleteBean
Scope request
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
Complete the ShoppingCart page by adding buttons for Update, Delete, and Details; these
buttons should relate to the rows of the table. Add a panel collection around the table to
contain the buttons.
a. Open the ShoppingCart page fragment.
b. Surround the af:table with a Panel Collection.
c.
d.
4.
e.
updateMenu
Update
Action <default>
Disabled
f.
g.
Add a second toolbar button to the toolbar. This time add it from the Component
Palette, or right-click and select insert inside.
Set the following properties on the second toolbar button:
Id
deleteMenu
Delete
Action <default>
ActionListener
#{FODCommitDeleteBean.onDeleteItem}
(Use the Edit option.)
h.
Leave blank
Details
page definition.
Action <default>
The method you added in the managed bean uses a commit binding and a delete binding.
When you added the commit button from the Data Control panel, JDeveloper added the
commit binding for you. Now manually add the delete binding to the page.
a. Click the Bindings tab in the editor of the ShoppingCart page fragment.
b.
c.
d.
FODShoppingCartAMDataControl.ShoppingCart.ShoppingCartItem1.
6.
Use partial page rendering to refresh the table to show the changes when the user clicks
either Update or Delete.
a. Click the Design tab in the editor.
b. Select af:table in ShoppingCart.jsff and using the Edit option, set PartialTriggers
on the table to include up dateMenu and deleteMenu.
5.
8.
9.
c. Remove the value from the Label attribute on the Input Text.
Test the functionality.
a. Run FODShoppingDashboard, add an item to the cart, update a quantity or two,
delete an item by using the Delete button (be sure to leave at least one item in the
cart), and so on. (The only button that you have not yet connected is the details
buttonyou do this next.)
When you update a quantity and click the Update button, you should notice that the
line item total also changes.
b. When you have finished, close the browser and undeploy the application as described
in step 6(i) of Practice 2-4.
Use a pop-up window to display the details of the item when a user clicks the Details
button.
7.
b.
c.
d.
ProductDetails
ContentDelivery
LazyUncached
1)
2)
e.
Id
Ok
Title
#{bindings.ProductName.inputValue}
(use Expression Builder)
f.
a.
b.
When you have finished, close the browser and undeploy the application as described
in step 6(i) of Practice 2-4.
3)
2.
c.
Select the SubmitOrder task flow return and set the End Transaction property to
commit.
d.
Select CancelOrder task flow return and set the End Transaction property to
rollback.
Run the FODShoppingDashboard page to test the checking out steps. When you click
Submit on the Confirmation page, any changes you have made to the shipping and billing
information are committed. In a real SOA-integrated application, this could, for example,
commit an order and start some back-end processing.
On the ManageSuppliers flow, you have already added the functionality to create a new supplier
and to update supplier information, but you have not added the ability to commit the updates
and deletes. In this practice, you implement the ability to add, update, and delete suppliers.
This practice is optional because the steps are similar to what you have done previously.
If you choose not to add CRUD functionality for Suppliers, you must begin the practices
for the next lesson by opening the starter application.
1. Add transaction control to the ManageSupplierFlow task flow as you did with the
ShoppingCartFlow, with the commit and rollback functionality.
a. Open ManageSupplierFlow in the editor.
b. In the Structure window, select task-flow-definition ManageSupplierFlow.
c. In the Property Inspector, click the Behavior tab and set transaction to Always Begin
New Transaction.
d. In the editor, select the Save task flow return and set its End Transaction property to
commit.
e. In the editor, select the Cancel task flow return and set its End Transaction property
to rollback.
f. Save your work.
2. Add the ability to delete a supplier to the BrowseSuppliers page fragment.
a. Open the BrowseSuppliers page fragment in the editor.
b. Check whether the table has row selection enabled by selecting af:table in the
c.
e.
ActionListener
f.
Id
To improve the appearance of the buttons, return to the Design view, and change the
Width of the Panel Header to 500 Pixels.
d.
3.
To ensure that the table is refreshed after the record is removed, use the Edit option,
to set the Partial Triggers property on the table, to the ID of the Delete button.
g.
Chapter 20
In the practices for this lesson, you set up the application to use security. You create users and
roles in an identity store, and you assign permissions to roles. You also create login and error
pages. You then use ADF security to manage access to pages, task flows, and entity objects,
and you programmatically access the security context by using global security expressions and
a security proxy bean.
If you successfully completed all sections of the previous practice, you can continue working in
the same project. However, if you prefer to start with a clean application that contains everything
completed up to the start of this lesson, open Storefront-20.jws and edit the database
information as described in step 4 of Practice 2-4.
2.
Invoke the Configure ADF Security Wizard and configure the application to use ADF
security for both authentication and authorization.
a. With the StorefrontUI project selected in the Application Navigator, from the main
menu, select Application > Secure > Configure ADF Security.
b. On the ADF Security page of the wizard, select the ADF Authentication and
Authorization option, and then click Next.
c. On the Authentication Type page of the wizard, select the Form-Based
Authentication option and the Generate Default Pages check box. Click Next.
d. On the Automatic Policy Grants page of the wizard, select the No Automatic Grants
option, and then click Next.
e. On the Authenticated Welcome page, select Redirect upon successful
authentication, and on the welcome page, select the
/oracle/storefront/ui/pages/FODShoppingDashboard.jspx page. Click
Next.
f. The Summary page of the wizard displays a list of files that will be changed or created.
Click Finish to create the security configuration.
g.
h.
In this practice, you set up the application to use ADF security for both authentication and
authorization.
1. Examine the existing files in the Descriptors node of the Application Resources panel.
Reexamine the files in the Application Resources panel. You can see that the Configure
ADF Security Wizard created a new file, jazn-data.xml.
4.
If you look in the file system, you can compare the modified dates to see which files have
been changed.
a. First, using Windows Explorer, look in the Storefront-20 > .adf > META-INF
subdirectory of your application resource descriptor. You could see that the adfconfig.xml file has just been changed.
b.
c.
Next, look in the Storefront-20 > src > META-INF subdirectory of your application
resource descriptor. You should see that all files except for weblogicapplication.xml have been changed.
Finally, look in the StorefrontUI > public-html > WEB-INF subdirectory of your
application. You can see that web.xml and weblogic.xml have been changed.
(Actually, weblogic.xml is a new file.)
3.
e.
5.
Note that the changed files are the ones that the Summary page of the Configure ADF
Security Wizard reported to be created or changed.
In the JDeveloper Application Resources panel, double-click jazn-data.xml to open it,
and then click the Source tab to examine the entries. It is a newly created file that contains:
The default realm name for the optional XML identity store
The policy store for the Storefront-20 application, consisting of application roles and a
policy. The policy grants permissions on resources (task flows and pages) to the
application roles.
Similarly, using the Source tab, examine:
a. jps-config.xml: Definitions have been added for service providers, service
instances, and the context for Java Platform Security.
b. adf-config.xml: The JaasSecurityContext entry has been added, specifying
that both authentication and authorization are enforced.
Similarly, from the Application Navigator, open web.xml and weblogic.xml (StorefrontUI
> Web Content > WEB-INF):
a. web.xml has added initialization parameters for JpsFilter, along with a definition
for the adfAuthentication servlet, a security constraint, the login configuration
(form-based with the login and error pages), and a security role (valid-users).
b. weblogic.xml is a newly created file that assigns the principal name users to the
valid-users security role.
6.
7.
d.
b.
c.
Click the Users tab and in the Users pane, click Add
to create new users.
In the Add User form, enter the name (such as DRAPHEAL) and the credentials
(welcome1).
d.
Repeat steps b and c for each user; the users appear in the Users list. Instead of
pgamer, you can add your own name if you would prefer to.
Managers in the company must view and update information about suppliers, but they
do not need to delete suppliers and they do not need to access the shopping portal.
Clerks in the company must be able to read, update, and delete supplier information,
but they do not need to access the shopping portal.
Customers must be able to shop and to view the list of suppliers, but do not need to
update or enter new suppliers.
1.
a.
b.
c.
Repeat steps a and b to add the other three roles; the roles appear in the Enterprise
Roles list along with the test-user role that the security configuration created.
a.
b.
c.
d.
3.
manager
sking
clerk
bernst
customer
developer
2.
To each application role, add its corresponding enterprise roles (for example, add
customer to fod_customer).
a. Select fod_manager in the Roles pane.
b. Click the Members tab and select the Add enterprise role from the Add button.
c. Select the manager role and click OK.
d. Repeat steps a, b, and c for each role you created.
e.
5.
4.
c.
In the Select Roles dialog box, select the check boxes for fod_manager, fod_clerk,
and fod_developer, and then click OK.
Note: If all the roles do not appear in the Select Roles dialog box, close jazndata.xml and reopen it. The roles should then appear.
d.
3.
4.
2.
By default, each selected role is assigned with the View Action. Keep this option
selected.
2.
Note: When using Internet Explorer, you may receive an HTTP error instead of seeing
the error page.
Test authorization.
a. Click the browsers Back button.
b. On the login page, enter the username sking, a valid user who is not authorized to
use the shopping application. Enter the password welcome1, and then click Submit.
The FODShoppingDashboard page appears, but the shopping application is not
visible. You see data only when you click the Suppliers tab.
Note: If you encounter an error when you enter the login information after using the
Browsers Back button, rerun the application.
In this practice, you test the authentication and authorization that you have set up.
1. Test authentication by entering incorrect credentials.
a. Open adfc-config in the editor.
b. Right-click the FODShoppingDashboard page and select Run.
Note: If you encounter an error when running the application, undeploy the application
and then terminate the default server. You do this the same way you undeploy an
application, except that you select IntegratedWebLogicServer instead of an application.
Then rerun the application.
c. On the login page, enter a fake username and password, and then click Submit.
d.
e.
f.
g.
Click the Suppliers tab, and then click the SupplierId in one of the rows. The supplier
detail is shown.
When finished, close the browser and undeploy the application as described in step
6(i) of Practice 2-4.
Run the application again and enter credentials for DRAPHEAL, who has access to the
shopping application. The FODShoppingDashboard page should then appear with the
shopping application visible.
Click the Suppliers tab, and then click the SupplierId in one of the rows. You should
receive an error indicating that the authorization check failed, because DRAPHEAL does
not have access to the ManageSupplierFlow task flow.
When finished, close the browser and undeploy the application as described in step
6(i) of Practice 2-4.
c.
c.
In the Edit Security dialog box, enable security on all operations, and then click OK.
d.
1.
f.
Roles
Read
fod_user
Update
Delete
fod_clerk, fod_developer
e.
Click OK.
c.
d.
Click the Suppliers tab. You should note that the Delete button is disabled.
Click New Supplier. You should receive an authorization error.
e.
Close the browser and run the application again, this time logging in as sking, who
has the manager role. Click the Suppliers tab. You should see that the Delete button
is disabled. However, when you click New Supplier, or when you click a supplier ID
link, you should be able to navigate to the New Supplier or the Update Supplier
window.
Close the browser and click the target URL in the Running Log pane to relaunch the
application in your browser.
This time log in as bernst, who has the clerk role, or as pgamer, who has the
developer role. Click the Suppliers tab. You should see that the Delete button is
now enabled. Also, when you click New Supplier, or when you click a supplier ID link,
you should be able to navigate to the New Supplier or the Update Supplier window.
Close the browser and undeploy the application.
f.
g.
h.
In this practice, you test entity object security in the Business Components Browser.
1. Test the implementation of read-only access to the SupplierEO entity object.
a. In the adfc-config task flow diagram, right-click FODShoppingDashboard and select
Run.
b. In the login dialog box, enter the username DRAPHEAL, whose customer role has
read-only access to SupplierEO. Enter the password welcome1 and click Submit.
b.
3.
4.
In this practice, you use the SecurityContext API to retrieve security information
programmatically.
1. In the Application Navigator, in the oracle.fod.storefront.module package,
double-click BaseApplicationModuleImpl.java to open it in the editor.
2. Add a method to retrieve the username from the security context.
a. Add the following code just above the closing right brace:
public String getUserName() {
return
ADFContext.getCurrent().getSecurityContext().getUserName().toUpp
erCase();
}
In the JAAS Security login dialog box, enter DRAPHEAL as Principal and welcome1 as
Credentials, and then click OK.
c.
d.
e.
Select isUserInRole from the Method drop-down list and enter customer as the
Value. Click Execute. You should see the Return value of true.
Change the Value to manager and click Execute. The Return value should be false.
f.
g.
h.
b.
When you tested the Web application and logged in as a customer, clicking the New Supplier
button produced an authorization error, which is not a good situation for a user who may have
no idea what this means. It would be better to prevent the customer from clicking this button. In
this practice, you use Expression Language so that the button does not appear when the
logged-in user does not have permission to run the task flow.
1. You know that customers do not have the view permission for the ManageSupplierFlow
task flow. Set a property on the button that invokes that task flow so that it does not appear
for customers.
a. Open BrowseSuppliers.jsff in the editor.
b. Click the New Supplier button and using the Expression Builder, set the Rendered
property to #{!securityContext.userInRole['fod_customer']}.
2.
b.
Run the application again and log in as a user in one of the other roles, such as
sking. The button should appear now.
Although this works when you know the role that has access to the task flow, you do not
want to have to change the code if other roles are created or if grants for customers should
change. Set the button property so that the button does not appear for any user who does
not have permission to view the task flow.
a. Obtain the complete name of the task flow.
1) Open jazn-data.xml and click the Task Flows tab.
2) Click the Source tab at the bottom of the editor.
3) In the search field, enter ManageSupplier.
4)
b.
c.
4.
Copy (Ctrl + C) the entire task flow name (everything between the <name> and
</name> tags).
Ensure that the button appears if authentication security is not enabled. Instead of using a
global security expression, write a security proxy bean to check the security. Name the
bean FODSecurityBean.
a.
Create a new Java class, accepting default values, named FODSecurityBean in the
oracle.storefront.ui.bean package with the following code: (You can copy the code
from SecurityBean.txt in the \files subdirectory.)
package oracle.storefront.ui.bean;
import oracle.adf.share.ADFContext;
public class FODSecurityBean {
public FODSecurityBean() {
}
public boolean isAuthorizationEnabled() {
3.
return
(ADFContext.getCurrent().getSecurityContext().isAuthorizationEna
bled());
}
}
b.
5)
c.
Name
FODSecurityBean
Class
oracle.storefront.ui.bean.FODSecurityBean
Scope
request
Test the functionality as before, making sure that the button appears for clerks,
managers, or developers, and that it does not appear for customers.
Property Value
d.
e.
Previously you hard coded the username that is used to initialize the shopping cart. In this
practice, you replace the hard-coded name with a call to the method you just added.
1. Modify the TODO item in the base application module code to use the security API.
a. In the editor, open or switch to BaseApplicationModuleImpl.java.
b. Click the pink box in the right margin of the code to go to the TODO item.
c. Replace the hard-coded username with a call to getUserName().
d.
e.
3.
4.
Double-click ShoppingCart1 and click Cancel in the Bind Variables dialog box to
accept the values that were set in the init() method.
The shopping cart for DRAPHEAL should be shown.
2.
Run the application again to ensure that the button appears and that the shopping cart has
items. Notice that no login screen is required anymore.
You can probably see that security should be considered from the beginning, rather than
adding it at the end, so that the UI could be better designed to consider roles and their
access to task flows.
5.
Chapter 21
In this practice, you use the database diagrammer to create a visual representation of the
database schema. You also create a new database component (a table) and create the DDL to
add it to the schema.
This practice is optional and does not affect any of the other practices. You should work on it
only if you have extra time.
If you choose to work on this practice, start with a clean application by opening StorefrontA.jws and editing the database information as described in step 4 of Practice 2-4.
2.
c. Expand the FOD node to view the types of database objects that the schema contains.
Create a new database diagram named FODSchema and put it in the
oracle.fod.storefront.design package.
a.
b.
In the Application Navigator, right-click the StorefrontModel project and select New
from the context menu.
In the New Gallery:
i) Expand the General node if it is not already expanded.
ii) Select Diagrams.
iii) In the Items panel, select Database Diagram.
In this practice, you examine the existing schema objects and use some of them in a new
database diagram.
1. In the Storefront application (the one that you created) in JDeveloper, examine the objects
in the FOD schema.
a. In the Application Navigator, expand the Application Resources section.
b. In the Application Resources section, expand the Connections and Database nodes.
You should see the FOD connection that you created in an earlier practice.
ii)
3.
c.
Use Ctrl-click to multiselect the Orders and Order_Items tables and drag them to the
diagram surface.
c.
In the Specify Location dialog box, change the offline database name to FodDB, and
then click OK to copy the database objects to the new offline database in your project
and to place them on your diagram.
d.
The two tables are depicted on your diagram. Notice that the table icon has two
compartments. The top compartment displays the column names and their data types,
and the bottom compartment displays information about primary and foreign keys. Your
b.
e.
You can modify the column information in the diagram, although you should not modify
any of the table information at this time. To modify the column information, you can
click a column in the Orders table to select it, and then click again. You can modify
the name, data type, and size of the column in the diagram. Alternatively, you can
double-click the table itself to invoke the Edit Table dialog box, where you can make
more detailed modifications to columns and other table information. Do not modify any
columns for this practice.
b.
c.
d.
e.
f.
g.
h.
Ensure that the Component Palette is visible to the right of the diagram. If it is not,
select View > Component Palette.
In the Component Palette, ensure that Database is selected from the drop-down list at
the top. The list below it now displays the components suitable for adding to a schema
diagram.
In the Component Palette, click Table and drag it to the schema diagram.
In the Specify Location dialog box, accept the default location of the FodDB offline
database and click OK.
In the name area at the top of the table icon, enter Shippers.
a.
5)
Similarly, add a Shipper_Name column, with the default values for data type and
size. This is not a mandatory column.
In the list at the left of the Edit Table dialog box, select Primary Key and set the
primary key as follows:
a) Select SHIPPER_ID in the Available Columns list.
6)
7)
2.
b) Click Add
to shuttle SHIPPER_ID to the Selected Columns list.
Click OK. The diagram should look similar to this:
Generate the DDL for adding the new table to the database, but do not actually add the
table.
a. Right-click the SHIPPERS table in the diagram, and from the context menu, select
Synchronize with Database > Generate To > SQL Script. (You can also choose to
generate to FOD, which brings up the same dialog box with different default options
that you can change.)
b. In the Generate SQL from Database Objects Wizard:
1) Click Back until you are on the Specify Source page.
3)
4)
On the Specify Source page, check the location of the objects to be generated (it
should be Source from project), and then click Next.
3)
4)
Select the SQLScript option on the Specify Target page, and click Next.
The Object Picker page should show SHIPPERS in the Selected list. Click Next.
On the Choose Operation page, select the Create option and click Next.
On the SQL Script Options page, change the name of the SQL file to
CreateShippersTable.sql and click Next.
7) Click Finish to generate the script.
When the wizard is complete, the script file opens in the editor. Note the three tabs:
Source, SQL worksheet, and History. Examine the file contents.
Do not run the script, but note that if you select a connection in the upper-right
corner, then you can right-click the script and select Run Script from the context menu,
5)
6)
c.
d.
e.
f.
2)
Chapter 22
In this practice, you create a deployment profile and configure deployment options for the
Storefront application that you have developed. You then configure a data source in the
stand-alone Oracle WebLogic Server, and you configure the application to use a data source.
Finally, you deploy the application to the stand-alone Oracle WebLogic Server, and you test the
deployment.
This practice is optional and does not affect any of the other practices. You should work on it
only if you have extra time.
If you choose to work on this practice, start with the completed application by opening
Storefront-B.jws and editing the database information as described in step 4 of
Practice 2-4.
In this practice, you create a new deployment profile for the application. It should specify a
Java EE Web Context Root of Storefront, and should specify the myWLS connection.
1. The default context root for the application is Storefront2-StorefrontUI-contextroot; because this context root becomes part of the URL to access the application, it is
better to use a shorter one. To set a new context root, you must create or edit a deployment
profile for the StorefrontUI project. Create a new deployment profile called
myStorefrontUI that specifies a context root of Storefront.
a. In the Application Navigator, select the StorefrontUI project, and then select File >
New.
b. In the New Gallery, select General > Deployment Profiles > WAR File.
c. In the Create Deployment Profile dialog box, enter a Deployment Profile Name of
myStorefrontUI and click OK.
d.
2.
In the Edit WAR Deployment Profile Properties dialog box, select the Specify Java EE
Web Context Root option and enter a context root of Storefront.
e. Click OK twice.
Create a deployment profile named myStorefront for the application, specifying that it
should contain the myStorefrontUI WAR file and the JAR file for the StorefrontModel
project.
a. Invoke the Application menu and select Application Properties.
b.
c.
d.
A stand-alone Oracle WebLogic Server has already been created for you and configured to run
ADF applications. In this practice, you use the Oracle WebLogic Server Administration Console
to create a data source that the deployed application can use. You then configure the
application to use a JDBC DataSource connection type rather than the JDBC URL connection
type that it has been using by default.
1. Set up a data source named FODLocal in the basic_domain domain of the stand-alone
Oracle WebLogic Server, setting the JNDI name to jdbc/FODDS. Set other properties so
that it connects to the same schema that you have been using.
a. From the Windows Start menu, select Programs > Oracle Fusion Middleware > User
Projects > MyWLS_domain > Admin Server Console. The console application
deploys and then runs.
Note: If the Administration Server Console does not run, make sure that the WebLogic
Server is running. If it is not running, invoke the same menu except select as the final
item Start Admin Server for WebLogic Server Domain. After the server has started,
you can minimize the startWebLogic command window.
b. Log in to the Administration Server Console with the username of weblogic and the
password of weblogic.
c.
In the Domain Structure menu at the left of the window, expand the Services and
JDBC nodes, and then click the Data Sources node.
d.
e.
FODLocal
JNDI Name
jdbc/FODDS
Database Type
Oracle
Database Driver
Database Name
XE
Host Name
localhost
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
Port
1521
Database User
Name
Password
fusion
On the next page of the wizard, click Test Configuration. If the test is successful, click
Next. (Do not click Finish.)
g. On the next page of the wizard, select the AdminServer check box as a target to
deploy the data source, and then click Finish. You should receive a message that the
changes are activated, and your new data source should be listed.
Configure the application modules to use the data source, rather than the JDBC URL
connection that you have been using.
a. In the JDeveloper Application Navigator, right-click the FODCategoryAM application
module and select Configurations.
2.
b.
c.
3.
Configuration
Name
Connection Type
JDBC DataSource
Datasource Name
Java:comp/env/jdbc/FODDS
d. Click OK twice.
e. Perform steps a through d for all the application modules.
Configure the data bindings to use the data source.
Copyright 2010, Oracle and/or its affiliates. All rights reserved.
f.
b.
3)
Repeat steps 1 and 2 for all five application server data control usages.
a.
Property
Value
Connection Name
myWLS
Password
weblogic
Deploy Password
Checkbox selected
Port
7001
WLS Domain
myWLS_domain
d.
On the last page of the wizard, click Test, and then click Finish if the connection is
successful.
e.
The connection appears in the Application Server Navigator. Expand the myWLS and
deployments nodes so that you can see what is already deployed.
To deploy to an application server from within JDeveloper, you must first create a connection to
it.
1. Create an application server connection to the stand-alone WebLogic Server. Name the
connection myWLS, with a username of weblogic and a password of weblogic. Use a
Port of 7001 and a WLS Domain named base_domain.
a. From the JDeveloper menu, select View > Application Server Navigator.
b. Right-click the Application Servers node and select New Application Server.
c. In the Create Application Server Connection Wizard, enter the following settings,
leaving others at their default values:
The log window displays deployment messages. It may take a few minutes to finish the
deployment; wait until the window displays the message that the deployment is
finished.
b.
In the Application Server Navigator, click Refresh to see the myStorefront deployment.
You have prepared the application and the OracleWebLogic Server for deployment. In this
practice, you use JDeveloper to deploy the application to the application server.
1. Using the deployment profile that you defined in this set of practices, deploy the Storefront
application to the stand-alone WebLogic Server.
a. Invoke the Application menu and select Deploy > myStorefront > to > myWLS.
2.
Ensure that data appears properly, that the New Supplier button is shown on the
BrowseSuppliers page, and that there are items in the shopping cart.
When you have finished, close the browser and undeploy the application as follows:
On the Application Server Navigator, click Refresh
.
Right-click the myStorefront deployment and select Undeploy.
1)
2)
In this practice, you use the WebLogic Server Administration Console to deploy the application.
1. Use JDeveloper to create a deployable EAR file, making note of the directory where the
EAR file is created.
a. From the Application Navigator, invoke the Application menu.
b. Select Deploy > myStorefront > to EAR file.
c. In the log file, note the location of the EAR file.
2. Use the Oracle WebLogic Server Administration Console to deploy the application.
a. Invoke the Administration Console, or switch to it if it is already open.
b. From the Domain Structure menu at the left, select Deployments.
c. In the Deployments panel, click Install.
d. By clicking through the displayed directories, locate the myStorefront.ear file in the
directory where it was created and select it, and then click Next.
Select the Install this deployment as an application option and click Next.
Select the Copy this application onto every target for me option and click Next.
Select the Yes, take me to the deployment's configuration screen option and click
Finish.
h. Review the configuration options, but do not change them. Click Save.
i. Click Deployments on the menu. You should see that the application is deployed.
Test the deployment as you did above.
e.
f.
g.
3.