Oracle® Fusion Middleware Tutorial for Oracle WebCenter Developers 11g Release 1 (11.1.1) E10273-04 |
|
![]() Previous |
![]() Next |
In this lesson, you will learn how to build two types of portlets: a standards-based Java (JSR 168) portlet, which you will build using a wizard in Oracle JDeveloper, and an OmniPortlet, using a step-by-step wizard at runtime.
After you create the portlets, you will add them to the page, then connect the two portlets. By the end of this lesson, you should have a good handle on what's involved with building and testing a standards-based Java (JSR 168) portlet and a PDK-Java portlet (OmniPortlet). You will also be able to "wire" the two portlets so that when you click a link in one portlet, the content in the second portlet is dynamically updated.
Figure 6-1 shows how the portlets section of your page will look.
Figure 6-1 Portlets Section of MyPage.jspx
This lesson contains the following steps:
Step 2: Create the JavaBeans to Store the Standards-Based Portlet Information
Step 3: Create the Business Logic for the Standards-Based Portlet
Step 5: Register the Standards-Based Portlet with Your Application
Step 6: Test the Standards-Based Portlet in Your Application
Step 10: Wire the Standards-Based Portlet and OmniPortlet Together
Both of these portlets use the Tutorial schema that we installed in Chapter 2, "Preparing for the Tutorial," and require that you have a database connection. We created the database connection when we added the Tags service in Chapter 5, "Adding Oracle WebCenter Services to Your Application," so if you did not complete the steps in that chapter, you must follow the steps in "Step 5: Create a Database Connection to the WebCenter Schema" in that chapter before you build the portlets.
Oracle WebCenter Framework enables you to quickly and easily build a standards-based portlet that you can use with a portal or application, such as the one you're currently creating.
Note: The steps to build this portlet rely on the naming convention we've used, so follow the steps carefully. If you do not use the names we've provided, you may not achieve the same results. |
In this step, you will create an application based on the Portlet Producer template, then build a standards-based portlet. Afterward, you will consume the portlet into our Tutorial application. Figure 6-2 shows the portlet at runtime in MyTutorialApplication
.
Figure 6-2 Standards-Based Portlet (JSR 168) at Runtime in MyTutorialApplication
In Oracle JDeveloper, create a new application based on the Portlet Producer Application template (Figure 6-3), then click OK. To do so, choose New from the File menu to display the New Gallery.
In the New Gallery, choose Applications from the Categories list, then choose Portlet Producer Application.
Figure 6-3 Creating a New Portlet Producer Application
In the Create Portlet Producer Application wizard, in the Application Name field, enter MyTutorialPortlet
.
By default, the Directory field should contain the directory where the application will reside (Figure 6-4). You can change the directory location, if you like, but let's leave it as it is for the purposes of the Tutorial.
Figure 6-4 Creating a Portlet Producer Application - Step 1
Click Next.
On the Project Name page of the wizard (Figure 6-5), let's leave the default name: Portlets
, and click Next.
Figure 6-5 Creating a Portlet Producer Application - Step 2
On the last page of the wizard, you can configure the Java settings. You can see that the default package contained in the portlet producer application is portlet
(Figure 6-6). For the purposes of this Tutorial, let's leave the default options and click Finish.
Figure 6-6 Creating a Portlet Producer Application - Step 3
In the Application Navigator, under your new MyTutorialPortlet
application, right-click Portlets, and select New (Figure 6-7).
Figure 6-7 Selecting New from the Context Menu
Click the Current Project Technologies tab.
In the Categories list as shown in Figure 6-8, expand the Web Tier category, and select Portlets.
Figure 6-8 Creating a New Portlet Producer Application
Notice there are two kinds of portlets you can create:
An Oracle PDK-Java portlet. PDK-Java portlets can be consumed by WebCenter applications, Oracle Portal, or some other type of Oracle-specific solution. You build an Oracle PDK-Java portlet using the APIs provided by the PDK. Note that the OmniPortlet producer you will register in Step 7: Register the Preconfigured Portlet Producer is a type of Oracle PDK-Java Portlet
A standards-based Java (JSR 168) Java portlet. Java portlets can be consumed by portals from any vendor that supports the portlet standards. In this Tutorial, we're going to build a standards-based (JSR 168) Java portlet.
Select Standards-based Java Portlet (JSR 168), and click OK.
The JSR 168 Java Portlet wizard displays, which generates a skeleton for the portlet. We will later add our own logic to the portlet. Let's see how this is done.
On the General Portlet Information page, in the Name and Class fields, enter Products
.
Note: The steps to build this portlet rely on the naming convention we've used, so follow the steps carefully. If you do not use the names we've provided, you may not achieve the same results. |
Select Enable inter-portlet communication using Oracle WSRP V2 extensions. Selecting this option enables your portlet to support Oracle WSRP 2.0 extensions, and generates the oracle-portlet.xml
file that is used for WSRP 2.0 features, such as navigation parameters. We will need these parameters later on, when we enable the OmniPortlet and this portlet to communicate with each other. Figure 6-9 shows how the General Portlet Information page should now look.
Figure 6-9 Creating a JSR 168 Java Portlet - General Portlet Information
Click Next.
On the Additional Portlet Information page, we can either leave the defaults or, because we know we are going to show a few details about the products in our database, we can change the display name so anyone using the portlet will know what the portlet contains. Update the fields on this page according to Table 6-1. Figure 6-10 shows the resulting Additional Portlet Information page.
Table 6-1 Name and Attribution Values
Property | Value |
---|---|
Display Name |
Name that will appear in the JDeveloper Component Palette. Because you entered Products as the class name, this field is automatically populated with that name. |
Portlet Title |
Title that will appear on the portlet header. Because you entered Products as the class name, this field is automatically populated with that name. |
Short Title |
Title that will appear on the portlet header on mobile devices. Let's leave the default name, |
Description |
Description of the portlet. This field is relevant only when the portlet is used in an Oracle Portal 10g environment. Enter a description, for example, |
Keywords |
Keywords provide additional information about a page, item, or portlet so that users can locate it during a search. Although keywords are not supported by Oracle WebCenter Suite or Oracle Portal 10g, they are supported by other vendors from whom you may have obtained a deployment environment. Enter |
Figure 6-10 Creating a JSR 168 Java Portlet - Additional Portlet Information
Click Next.
On the Content Types and Portlet Modes page, notice that text/html is the default content type. That means that the portlet will support text encoded with HTML. View and edit are listed as the default portlet modes for text/html
. View is always available as a portlet mode; edit mode provides a page that allows users to personalize the portlet instance.
Notice the Implementation Method area as shown in Figure 6-11. These controls enable you to specify whether you want to generate JSP for the portlet, or use your own custom JSP code.
Figure 6-11 Creating a JSR 168 Portlet - Content Types and Portlet Modes
In this lesson, we'll ask JDeveloper to generate JSPs for us by leaving the default selection.
Click Next.
Although you could click Finish here and produce a basic portlet, let's continue and choose some other options and settings for our portlet.
On the Customization Preferences page, let's leave the default values and click Next (Figure 6-12).
Although we're not going to do anything with this page now, in the future you can use it to add other customization options for the portlet. For example, if your portlet accepted a Zip Code
parameter, you might want to allow users to personalize the Zip Code label. If this were the case, you would use the Add button to make the Zip Code label personalizable.
Figure 6-12 Creating a JSR 168 Java Portlet - Customization Preferences
On the Security Roles page, click Next (Figure 6-13). The Security Roles page is used to specify which of the application's security roles you want to establish for this portlet.
Figure 6-13 Creating a JSR 168 Java Portlet - Security Roles
On the Caching Options page, leave the default option and click Next (Figure 6-14).
The settings on this page enable you to define expiry-based caching for your portlet. You do not need any caching conditions now.
Figure 6-14 Creating a JSR 168 Java Portlet - Caching Options
On the Initialization Parameters page, click Next (Figure 6-15). Our portlet does not require any initialization parameters.
Figure 6-15 Creating a JSR 168 Java Portlet - Initialization Parameters
On the Portlet Navigation Parameters page, let's create a navigation parameter based on the product ID
.
Navigation parameters are a WSRP 2.0 feature. This page enables you to specify external parameters to be consumed by the standards-based portlet, and only displays if you select the Enable inter-portlet communication using Oracle WSRP V2 extensions option on the first page of the wizard.
Click Add.
Double-click the values and update each value to the following:
Name: productId
Label: Product ID
Hint: Enter Product ID
We will use these navigation parameters later on in Step 10: Wire the Standards-Based Portlet and OmniPortlet Together. Figure 6-16 shows the updated Portlet Navigation Parameters page.
Figure 6-16 Creating a JSR 168 Java Portlet - Portlet Navigation Parameters
Click Next.
On the last page of the wizard (Step 9 of 9), click Finish.
After you click Finish, you should be able to locate several newly generated files in the Application Navigator under the Portlets project. The expanded Navigator looks like Figure 6-17.
Figure 6-17 Files Generated for the New Portlet
Under Application Sources, under portlet and portlet.resource, notice two Java classes:
Products.java is invoked by the portlet container. It contains all the methods required by the portlet standards.
ProductsBundle.java contains all the translation strings for the portlet.
Under Web Content, Products, html:
edit.jsp, which contains the information needed to populate the Personalize dialog.
view.jsp, which is invoked when the portlet is sharing the page with other components.
Under Web Content, WEB-INF, three deployment descriptors:
oracle-portlet.xml, which contains information to support Oracle extensions for import/export and inter-portlet communication. It appears because you chose Enable WSRP V2 inter-portlet communication using Oracle extensions on Step 1 of the wizard.
portlet.xml, which specifies all the portlet resources (the information you entered through the JSR 168 Java Portlet Wizard).
web.xml, which specifies the web application resources.
Save all your files. In the next step, we will create a JavaBean to store all the portlet information you just generated.
In this step, you will create the JavaBean to store the information for your standards-based portlet.
In the Application Navigator, right-click the portlet package, and choose New. Figure 6-18 shows the portlet
package in the Application Navigator.
In the New Gallery, click the All Technologies tab.
In the Categories list, under General, choose Java, select Bean from the Items list, then click OK (Figure 6-19).
Figure 6-19 Choosing the JavaBean in the New Gallery
In the Create Bean dialog that displays, enter the following information to set up the new JavaBean (Figure 6-20):
Name: ProductDetailsBean
Package: portlet
Extends: java.lang.Object
This creates a new bean called ProductDetailsBean
in the portlet package.
Click OK. The new JavaBean displays in the Design window (Figure 6-21).
Figure 6-21 ProductDetails JavaBean in the Design View
Figure 6-22 shows the JavaBean in the Structure window. As previously mentioned in Chapter 3, "Creating a WebCenter Application with a Customizable Page," you can use the pushpin in the Structure window to freeze and unfreeze the current view. Ensure that you have selected the ProductDetails Bean
in the Design view, then toggle the pushpin so that you see the ProductDetails Bean
in the Structure window.
Figure 6-22 ProductDetailsBean in the Structure Window
Now that we've set up our JavaBean, let's add the information we need for the portlet. In the Structure window, right-click the ProductDetailsBean, then choose New Field from the context menu (Figure 6-23).
Figure 6-23 Creating a New Field for the ProductDetails Bean
In the Create Field dialog, in the Name field, enter productId
. This name represents the name of the product in our database schema.
Ensure the Type is set to String
.
Ensure the Scope is set to private (Figure 6-24).
Click OK. The new field displays in the Design view of the JavaBean, as shown in Figure 6-25.
Figure 6-25 New Field in the ProductDetailsBean
Now, let's create the other four fields we want to show in our portlet. Follow steps 6 through 10 to create these four fields with the following names:
productName
productPrice
imageURL
categoryDescription
supplierName
The Design view of your JavaBean should now contain the six fields (Figure 6-26).
Figure 6-26 ProductsBean with the Six Fields
Now that we've set up the fields for the JavaBean, let's generate the accessors.
In the Structure window, right-click ProductDetailsBean and choose Generate Accessors from the context menu.
The Generate Accessors dialog displays (Figure 6-27).
Click Select All to select all the fields you created for this bean (Figure 6-28).
Figure 6-28 Generate Accessors DIalog with all Fields Selected
Click OK to generate the accessors for these fields. Oracle JDeveloper generates the code as shown in Example 6-1:
Example 6-1 ProductDetails JavaBean
package portlet; public class ProductDetailsBean { private String productId; private String productName; private String productPrice; private String imageURL; private String categoryDescription; private String supplierName; public ProductDetailsBean() { } public void setProductId(String productId) { this.productId = productId; } public void setProductName(String productName) { this.productName = productName; } public String getProductName() { return productName; } public void setProductPrice(String productPrice) { this.productPrice = productPrice; } public String getProductPrice() { return productPrice; } public void setImageURL(String imageURL) { this.imageURL = imageURL; } public String getImageURL() { return imageURL; } public void setCategoryDescription(String categoryDescription) { this.categoryDescription = categoryDescription; } public String getCategoryDescription() { return categoryDescription; } public void setSupplierName(String supplierName) { this.supplierName = supplierName; } public String getSupplierName() { return supplierName; } }
Create another JavaBean for the portlet called ProductsBean.java
. This bean represents the list of products, which the portlet will display at runtime.
To create the JavaBean right-click the portlet package in the Application Navigator and choose New from the context menu.
In the New Gallery, click the Java category, then click the Bean item to display the Create Bean dialog.
In the Name field, enter ProductsBean
and java.lang.Object
in the Extends field, as shown in Figure 6-29, then click OK.
Replace the code of ProductsBean.java
in the Source view with the code in Example 6-2.
Note: If the formatting of the code in this text does not work, you can open theC:\TutorialContent\Portlets\ProductsBeanJava.txt file and copy and paste the code from there. |
Example 6-2 ProductsBean.java Code
package portlet; import java.util.ArrayList; public class ProductsBean { public static final String DEFAULT_PRODUCT_ID = "12"; private ArrayList<ProductDetailsBean> products = new ArrayList<ProductDetailsBean>(); public ProductsBean() { super(); } public void addProduct(ProductDetailsBean product) { products.add(product); } public ArrayList<ProductDetailsBean> getProducts() { return products; } }
The Source view of the bean should now look like Figure 6-30.
Save all your files.
In the next steps, we'll set up the connection between our JavaBeans and the database schema that contains the data we want to show in our portlet.
After you create the JavaBean to access the data in the database, you create the business logic for the portlet in a Java Class. This class will contain a connection to the database, establish the connection, then query for information using the SQL statement in the class file. When you create a standards-based portlet, you must manually create this class. The database schema you connect to is the one you established in Chapter 2, "Preparing for the Tutorial."
In the Application Navigator, right-click the portlet package, then choose New from the context menu.
In the New Gallery, click Java, then choose Java Class from the Items list (Figure 6-31).
Figure 6-31 Choosing the Java Class Option in the New Gallery
Click OK.
In the Create Java Class dialog, in the Name field, enter the name: ProductsService
, as shown in Figure 6-32.
Leave the rest of the default values in this dialog, as we will overwrite them in the next step, then click OK.
In the ProductsService.java
file that displays, replace all the automatically-generated code with the code shown in Example 6-3. The code assumes that the database where you installed the sample schema is local. In the code, modify the highlighted JDBC connection (jdbc:oracle:thin:@localhost:1521:xe
)to point to your database and Tutorial (fod
) schema
Note: If the formatting of the code in this text does not work, you can open theC:\TutorialContent\Portlets\ProductsServiceJava.txt file and copy and paste the code from there. |
Example 6-3 ProductsService.java Code
package portlet;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class ProductsService {
public ProductsService() {
}
public ProductsBean getProducts() throws ClassNotFoundException {
Connection conn = getConnection();
ProductsBean products = new ProductsBean();
if (conn != null) {
try {
Statement stmt = conn.createStatement();
String query =
"SELECT DISTINCT product_id, product_name name, cost_price price, 'http://localhost:7101/MyTutorialApplication/' || external_url image_url, category_description, supplier_name " +
"FROM category_translations, products_base, suppliers" +
" WHERE products_base.category_id = category_translations.category_id" +
" AND products_base.supplier_id = suppliers.supplier_id " +
" AND cost_price between 25 and 75 " +
" order by product_id";
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
ProductDetailsBean productDetails = new ProductDetailsBean();
productDetails.setProductId(rs.getString(1));
productDetails.setProductName(rs.getString(2));
productDetails.setProductPrice(rs.getString(3));
productDetails.setImageURL(rs.getString(4));
productDetails.setCategoryDescription(rs.getString(5));
productDetails.setSupplierName(rs.getString(6));
products.addProduct(productDetails);
}
conn.close();
} catch (SQLException sqle) {
System.out.println("======== Oracle Fusion Middleware Tutorial for WebCenter Developers ======== ");
System.out.println("Database Connection established successfully but encountered an error while working with the DB:" +
sqle);
System.out.println("============================================================================ ");
} catch (Throwable t) {
System.out.println("======== Oracle Fusion Middleware Tutorial for WebCenter Developers ======== ");
System.out.println("Error while trying to get Product Details: " +
t);
System.out.println("============================================================================ ");
}
}
return products;
}
public static Connection getConnection() throws ClassNotFoundException {
Connection conn = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
conn =
DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "fod",
"fusion");
} catch (SQLException sqle) {
conn = null;
System.out.println("======== Oracle Fusion Middleware Tutorial for WebCenter Developers ======== ");
System.out.println("SQL error while trying to get connection to DB: " +
sqle);
System.out.println("============================================================================ ");
} catch (Throwable t) {
conn = null;
System.out.println("======== Oracle Fusion Middleware Tutorial for WebCenter Developers ======== ");
System.out.println("Error while trying to get the connection to DB: " +
t);
System.out.println("============================================================================ ");
}
return conn;
}
}
Note: In this code, the package names and import statements of theview.jsp , ProductsService , and ProductsBean depend on the name, class name, and package you specified or the portlet. Also, in this code, you must update the connection information to point to the database containing the Tutorial (fod ) schema. If you encounter problems with this portlet, you can check the Messages log below the Visual Editor (the Design view) to verify that the connection information you entered in this code is correct. |
Save the file.
Before we can update our portlet's view.jsp
file to use this Java class, let's return to our portlet code so that it uses the parameter value. This parameter value is the productId
navigation parameter defined for the Products portlet in Figure 6-16.
Click the Products.java tab to bring it into focus. Or, if the file is not open, double-click the name in the Application Navigator.
In the Products.java
file, we must update the ProcessAction()
method in the generated portlet class file to pass the parameter value from the portlet to the Java Bean, so that the appropriate products display depending on the parameter entered.
In the Products.java
file, locate the processAction()
method. Example 6-4 shows the section of the code in the Products.java
file where the method is located.
Example 6-4 End of the Products.java File Containing the processAction() Method
public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException { // Determine which action. String okAction = request.getParameter(OK_ACTION); String applyAction = request.getParameter(APPLY_ACTION); if (okAction != null || applyAction != null) { // Save the preferences. PortletPreferences prefs = request.getPreferences(); String param = request.getParameter(PORTLETTITLE_KEY); prefs.setValues(PORTLETTITLE_KEY, buildValueArray(param)); prefs.store(); if (okAction != null) { response.setPortletMode(PortletMode.VIEW); response.setWindowState(WindowState.NORMAL); } } }
Example 6-4 shows the section we must update. For simplicity, you can replace all the code in the Products.java
file with the code in the C:\TutorialContent\Portlets\ProductsJava.txt
file. Alternatively, Example 6-4 shows the updated section.
Example 6-5 Updating the Final Section of the Products.java file
// Form field names public static final String PARAMETER1 = "productId"; public static final String FORM_PARAMETER1 = "form_Parameter1"; public static final String FORM_SUBMIT = "dosub"; // Portlet Modes public static final String MODE_NAME_PARAM = "mode"; public static final String MODE_VIEW = "view"; public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException { // Determine what kind of action we have by examining the mode parameter boolean viewMode = MODE_VIEW.equals(request.getParameter(MODE_NAME_PARAM)); // Extract the form field parameter and pass it through as a portlet parameter String param1 = request.getParameter(FORM_PARAMETER1); if (param1 == null) { param1 = ProductsBean.DEFAULT_PRODUCT_ID; } if (viewMode) { // Set the new parameter values. These will be intepreted by the // container as navigational parameters as the names match the names of // the declared parameters. response.setRenderParameter(PARAMETER1, param1); } else { // Determine which action. String okAction = request.getParameter(OK_ACTION); String applyAction = request.getParameter(APPLY_ACTION); if (okAction != null || applyAction != null) { // Save the preferences. PortletPreferences prefs = request.getPreferences(); String param = request.getParameter(PORTLETTITLE_KEY); prefs.setValues(PORTLETTITLE_KEY, buildValueArray(param)); prefs.store(); if (okAction != null) { response.setPortletMode(PortletMode.VIEW); response.setWindowState(WindowState.NORMAL); } } } } }
Now that we've updated our portlet and created the Java Class to enable the portlet to communicate with the database, let's update our portlet's view.jsp
file for the portlet to use the Java class.
In the Application Navigator, under Portlets, Web Content, Products, and html, pen the view.jsp
file (Figure 6-33).
Figure 6-33 View.jsp File in the Application Navigator
Click the Source tab to view the code of this page.
Select all the code in the Source view and delete it.
Enter the code in Example 6-6 in the Source view of the view.jsp
:
Note: If the formatting of the code in this text does not work, you can open theC:\TutorialContent\Portlets\ViewJSP.txt file and copy and paste the code from there. |
Example 6-6 View.jsp Code
<%@ page contentType="text/html" pageEncoding="windows-1252" import="javax.portlet.*, java.util.*, portlet.ProductsBean, portlet.ProductDetailsBean, portlet.ProductsService, portlet.Products "%> <%@ taglib uri="http://java.sun.com/portlet" prefix="portlet"%> <!-- Include the Portlet render Response & Request objects --> <portlet:defineObjects/> <% // Get the list of products ProductsBean products = new ProductsService().getProducts(); ArrayList<ProductDetailsBean> productDetails = products.getProducts(); // "Portlet encode" the Action URL if running Portlet mode String actionURL = "view.jsp"; if (renderResponse != null) { actionURL = renderResponse.createActionURL().toString(); } // Extract the current portlet parameter value if running in Portlet mode String param1 = ""; if (renderRequest != null) { param1 = renderRequest.getParameter(Products.PARAMETER1); if (param1 == null) { param1 = ""; } } %> <form method="POST" action="<%= actionURL %>"> <table> <tr> <th>Select</th> <th>Product</th> <th>Product supplied by</th> <th>Our price</th> </tr> <% for (int i = 0; i < productDetails.size(); i++) { ProductDetailsBean productDetail = productDetails.get(i); %> <tr> <td align="center"> <!-- Set the Form parameter name to passed as a render parameter during processAction --> <input type="radio" name="<%= Products.FORM_PARAMETER1 %>" value="<%=productDetail.getProductId()%>" <%= param1.equals(productDetail.getProductId()) ? " checked='checked'" : "" %>/> </td> <td> <%=productDetail.getProductName()%> </td> <td> <%=productDetail.getSupplierName()%> </td> <td align="right"> $<%=productDetail.getProductPrice()%> </td> </tr> <% } %> <tr class="PortletText1"> <td> <input name="<%= Products.FORM_SUBMIT %>" type="submit" class="portlet-form-button" value="Show Details"></input> </td> <td colspan="3"> </td> </tr> </table> <!-- create a hidden parameter to note we're running in "view" mode --> <input type="hidden" name="<%= Products.MODE_NAME_PARAM %>" value="<%= Products.MODE_VIEW %>"/> </form>
Save the view.jsp
.
Now that you have established the connection to the database and set up the portlet to use the new JavaBean and Java Class to get the appropriate product information for the portlet, you are ready to include the portlet in a WAR file. WAR stands for web archive, and it packages all the resources, portlets, and deployment descriptors required to deploy your portlet.
In this lesson, you will learn how to deploy the standards-based portlet to your local Integrated WebLogic Server. When you deploy a portlet, you package it so that it can run on a Java EE server. If you're familiar with Oracle Portal, we're in effect creating a portlet provider, which in the WSRP world is known as a portlet producer.
If it is not running yet, start the Integrated WebLogic Server by choosing Start Server Instance from the Run menu.
Before we deploy the portlet, let's quickly compile and test it. In the Application Navigator, under Web Content then Products, right-click view.jsp and choose Run. The portlet should compile and display in your browser, as shown in Figure 6-34.
Figure 6-34 Testing the Standards-Based Portlet
In the Application Navigator, under Portlets, Web Content, WEB-INF, right-click the web.xml
file, then choose Create WAR Deployment Profile from the context menu (Figure 6-36).
Figure 6-35 Create WAR Deployment Profile Menu Option
In the Create Deployment Profile dialog, name the Deployment Profile Products
, then click OK (Figure 6-36).
Figure 6-36 Create Deployment Profile - WAR File Dialog
On the General tab of the WAR Deployment Profile Properties dialog, look for the Web Application's Context Root setting. Let's change this to a more logical name, so that we can easily reference it later.
Select the Specify J2EE Context Root option, then enter Products
in the field, as shown in Figure 6-37.
Figure 6-37 WAR Deployment Profile Properties -- Setting the Context Root
Click OK to finish updating the properties, then click OK in the Project Properties dialog to finish creating the WAR deployment profile.
Oracle WebCenter includes its own default connection to the Integrated WLS Server. You can see the connection, called IntegratedWLSConnection, in the Resource Palette, under IDE Connections (Figure 6-38).
Figure 6-38 IntegratedWebLogicServer in the Resource Palette
Now, create an EAR file for the Deployment Profile. From the Application menu, choose Deploy, then New Deployment Profile.
In the New Gallery, ensure Deployment Profiles is selected, then choose EAR File from the Items list (Figure 6-39).
Figure 6-39 Creating an EAR File for the Deployment Profile of the Products Portlet
In the Create Deployment Profile -- EAR File dialog, in the Deployment Profile Name field, enter Products
(Figure 6-40), then click OK.
Figure 6-40 Creating a Deployment Profile
Click OK, then click OK again.
Now, we're ready to deploy our standards-based portlet. In the Application Navigator, right-click the Portlets project, and choose Deploy, then Products from the context menu.
In the Deploy Products wizard, on the Deployment Action page, select Deploy to Application Server, then click Next (Figure 6-41).
Figure 6-41 Deployment Action page of the Deploy Products Wizard
On the Select Server page of the Deploy Products wizard, select IntegratedWebLogicServer, then click Next (Figure 6-42).
Figure 6-42 Select Server Page of the Deploy Products Wizard
On the Summary page, ensure that the Application Server listed is the IntegratedWebLogicServer and that the Archive Details shows the Output file pointing to JDEV_USER_HOME
\jdeveloper\mywork\MyTutorialPortlet\Portlets\deploy\Products.war
.
Click Finish.
If the Select deployment type dialog displays, leave the default options and click OK (Figure 6-43).
Verify that the deployment is complete by checking the Deployment - Log below the Visual Editor (the Design view) for the message "Deployment finished."
Let's to go a browser and verify whether the portlet deployment worked. In your browser, enter the URL:
http://localhost:7101/Products
The WSRP Producer Test Page displays as shown in Figure 6-44.
You can choose to use either the WSRP version 1 or version 2 WSDL In general, it's good practice to use more recent versions wherever possible. If the portlet will be consumed by WSRP 1.0 compliant consumers (such as Oracle Portal), you may want to choose WSRP 1.0.
Click WSRP v2 WSDL to view the XML for this WSDL (Figure 6-45).
Figure 6-45 WSDL Describing Your Portlet as a Web Service
The portlet you just deployed has now been exposed as a web service. What appears in the browser is the Web Services Description Language (WSDL) that describes this web service. Now that the portlet is deployed and running, you can add this portlet to any application that can consume portlets. Our next step is to register the producer with our Tutorial application, then add this portlet to MyPage
.
Once we have deployed our portlet, we can register the producer with our Tutorial application and add it to our page.
To register the producer with MyTutorialApplication:
In the Application Navigator, choose MyTutorialApplication from the list to return to our custom WebCenter application (Figure 6-46).
Figure 6-46 MyTutorialApplication in the Application Navigator List
In the Resource Palette, click the folder icon, then choose New Connection and WSRP Producer from the context menu.
On the Name page, ensure Resource Palette is selected, and enter a name for the producer, for example ProductsWSRPProducer
, then click Next (Figure 6-47).
Figure 6-47 Register WSRP Portlet Producer -- Name
On the Connection page, in the WSDL URL field, enter the URL for the WSDL (typically, we use v.2):
http://localhost:7101/Products/portlets/wsrp2?WSDL
Figure 6-48 Register WSRP Portlet Producer -- Connection
Since our Integrated WebLogic Server is installed locally, we do not need a proxy. Click Next to create the connection to the WSRP Producer.
Let's leave the rest of the defaults and finish the wizard. On the Registration Details page, click Finish. You'll see a registration dialog letting you know the registration is being completed.
In the Resource Palette, under IDE Connections, open the WSRP Producer node, then expand the ProductsWSRPProducer node. Figure 6-49 shows the Products portlet here.
Figure 6-49 Products Portlet in the Resource Palette
Now that we've registered the producer with our application, let's add the portlet to the page and test it.
To test the portlet, we'll add it to MyPage.jspx
, run the page, and see if the portlet displays as expected.
In MyTutorialApplication, if MyPage.jspx
is not open, locate the page name in the Application Navigator (under ViewController, Web Content) and double-click it.
In the Structure window, navigate to the second facet, then expand Page Customizable, Panel Group Layout, Layout Customizable, and Panel Customizable, as shown in Figure 6-50. You should see the Show Detail Frame called My Profile. You will add the portlets below this component.
Note: As previously mentioned, you can use the pushpin in the Structure window to freeze the current view. For this step, you should click MyPage in the Design view, then ensure the pushpin is in the "freeze" position (pressed). |
Figure 6-50 Panel Customizable Where You Will Add the Products Portlet
In the Component Palette, choose ADF Faces from the list.
Drag and drop a Panel Group Layout just below the Show Detail Frame called My Profile.
Set the Layout property to horizontal and the StyleClass (located below Style and Theme) to AFStretchWidth
. Figure 6-51 shows the new Panel Group Layout in the Structure Window.
Drag and drop the Products portlet from the Resource Palette onto this Panel Group Layout.
Run the page to see how the portlet looks at runtime. This may take a few moments.
You will notice that selecting the different options and the Show Details button do not yet work, because we have not wired this portlet with another portlet. Let's create a second portlet, then wire it to this portlet. Figure 6-52 shows the Products portlet at runtime.
Figure 6-52 Products Portlet in a Browser Window
For more information about creating standards-based JSR 168 portlets and using them with a WebCenter application, see Part VIII, "Working with Portlets and Portals" in Oracle Fusion Middleware Developer's Guide for Oracle WebCenter.
For this Tutorial, we will use a preconfigured portlet producer, called OmniPortlet, which is predeployed to the Integrated WebLogic Server, also referred to as the Integrated WebLogic Server. Be sure you have followed the steps in Chapter 2, "Preparing for the Tutorial" before you proceed.
To register the preconfigured portlet producer:
Ensure the Integrated WebLogic Server is running.
To find out the URL for the OmniPortlet producer running on the Integrated WebLogic Server, choose WebCenter Preconfigured Server Readme from the Help menu. This Read Me file shows all the information needed to use the portlets that are predeployed to the Integrated WebLogic Server, and the login credentials for the server.
In the Read Me file, under Preconfigured Portlet Producers, then PortalTools Portlet Producers, click OmniPortlet Producer.
In your browser, you should see the OmniPortlet Producer Test Page. Copy the URL from the location bar. The URL should look like this:
http://127.0.0.1:7101/portalTools/omniPortlet/providers/omniPortlet
Entering this URL in your browser displays the OmniPortlet producer test page (Figure 6-53).
Figure 6-53 OmniPortlet Producer Test Page
In the Resource Palette, click the New icon next to the search toolbar, then choose New Connection, and then Oracle PDK-Java Producer (Figure 6-54).
Figure 6-54 Registering an Oracle PDK-Java Producer
On Step 1 of the Register Oracle PDK-Java Portlet Producer wizard, let's enable this portlet producer to be used across all our applications. Select Resource Palette.
In the Name field, enter OmniProducer
(Figure 6-55).
Figure 6-55 Naming the OmniPortlet Producer
Click Next.
Enter this URL for the OmniPortlet Producer Test Page, which you copied earlier in the URL Endpoint field (Figure 6-56).
Figure 6-56 Specifying the Connection Details for the OmniPortlet Producer
Click Next.
On the Registration Details page, click Finish. You should see a message indicating that Oracle JDeveloper is registering your producer.
Because you chose to register the portlet producer in the Resource Palette, your new portlet producer displays in the IDE Connections list of the Resource Palette, as shown in Figure 6-57.
Figure 6-57 OmniProducer in the IDE Connections List
One type of portlet you can use with Oracle WebCenter Framework is OmniPortlet. This portlet is provided out of the box, and is preconfigured on the Integrated WebLogic Server. It lets you quickly create portlets using a variety of default layouts and data sources.
Figure 6-58 shows a sample portlet you can build with OmniPortlet. The portlet displays items stored in a database as images, which are stored locally. After you wire this portlet with the portlet you created in "Step 1: Create a Standards-Based Java (JSR 168) Portlet", a user can click these images in your application to learn more about that item.
Before you can use this OmniPortlet, ensure that you have added the sample schema to your database and that you have started the Integrated WebLogic Server as described in Chapter 2, "Preparing for the Tutorial." Also, ensure that you have registered the OmniPortlet producer, as described in Step 7: Register the Preconfigured Portlet Producer.
In Oracle JDeveloper, ensure MyTutorialApplication is open.
In the Application Navigator, ensure the MyPage.jspx
is in the Design view. If you've closed your application, you can double-click the page name in the Application Navigator.
In the Structure window, locate the horizontal Panel Group Layout where you added the Products portlet.
Note: As previously mentioned, you can use the pushpin in the Structure window to freeze the current view. For this step, you should click MyPage in the Design view, then ensure the pushpin is in the "freeze" position (pressed). |
Figure 6-59 Panel Group Layout Containing the Products Portlet
In the Resource Palette, under IDE Connections, navigate to Oracle PDK-Java Producer, OmniProducer, and OmniPortlet (Figure 6-60).
Figure 6-60 OmniPortlet in the Resource Palette
Drag and drop OmniPortlet onto your page onto the Panel Group Layout. It should display below the existing adfp:portlet in the Structure window. If you see an error message, ensure you have started the Integrated WebLogic Server, then try again.
For more troubleshooting tips on using OmniPortlet, refer to Oracle Fusion Middleware Developer's Guide for Oracle WebCenter.
Set the Height property for the portlet to 230px
.
Now that we've added OmniPortlet to our page, let's customize its contents.
Run your page to the browser and log in as Lisa
/welcome1
.
Figure 6-61 shows the OmniPortlet on MyPage in your browser.
Figure 6-61 Undefined OmniPortlet at Runtime
In this section, we will customize our OmniPortlet to bring in some information from the database schema and the images we added to our application in Chapter 2, "Preparing for the Tutorial."
Since OmniPortlet is a preconfigured portlet, our only steps are to add it to our application, then customize it at runtime. Now that we've placed it on our page and run our page to the browser, let's customize the layout and content of this portlet.
In the upper right corner of the portlet, click the arrow, and choose Customize to launch the OmniPortlet wizard (Figure 6-63).
Figure 6-62 Customize Link for OmniPortlet
On the Data Type page, choose SQL so that we can obtain data from the schema in a database, then click Next. At this point, be sure you've added the schema to your database (as described in Chapter 2, "Preparing for the Tutorial") and the images to your application resources (as described in Chapter 3, "Creating a WebCenter Application with a Customizable Page") otherwise the portlet will not retrieve the sample Tutorial data.
If you're familiar with SQL and your database, you can always use your own sample data, but the ensuing images and steps may not necessarily be accurate for you.
On the Data Source page, we can define our SQL statement and set up the connection to the database where we installed the schema.
In the Statement box, enter the code in Example 6-7. The parameter in the statement will be used when we wire this portlet with the Products portlet we added in Step 5: Register the Standards-Based Portlet with Your Application.
Note: If the formatting of the code in this text does not work, you can open theC:\TutorialContent\Portlets\OmniPortlet_SQL_Statement.txt file and copy and paste the code from there. |
Example 6-7 OmniPortlet SQL Statement
SELECT distinct product_name name , cost_price our_price , cost_price * 1.3 retail_price , cost_price * 0.3 savings , external_url image_url , category_description , supplier_name FROM category_translations, products_base, suppliers WHERE products_base.category_id = category_translations.category_id AND products_base.supplier_id = suppliers.supplier_id AND products_base.product_id = nvl('##Param1##', 0)
Note: In the statement, you'll notice a reference to the localhost. This refers to the OmniPortlet producer you registered; localhost also points to the IP address 127.0.0.1. Notice that you can also click the Test button to see what the statement will return. |
Under Connection, click Edit Connection.
Enter a name for your connection and the connection information for your database. The schema username is fod
and the password is fusion
. For example, if you are using an Oracle XE database locally, the page would look like Figure 6-63.
Figure 6-63 Connection Information for OmniPortlet
Let's make sure the connection information is correct by clicking Test. Figure 6-64 shows a successful test message.
Figure 6-64 Successful Connection Message
Click Close, then click OK to finish creating the connection.
Under Portlet Parameters, set the Default Value for Param1 to 12
. Doing so provides a default value for the parameter in our SQL statement.
Figure 6-65 shows the SQL Source page.
Note: If you do not have theimages folder in your ViewController project as described in Chapter 3, "Creating a WebCenter Application with a Customizable Page," the images referenced in the SQL statement will not display. You can go back and add these now by following Step 2: Add the Resource Files to the Application, but you must run the application to your browser again in order for OmniPortlet to recognize the new folder. |
Click Test next to the Show Bind Variables button to validate the SQL statement and connection.
A pop-up window displays returning a row based on the statement. If you do not see a row returned, validate your SQL statement, connection, and portlet parameter.
Click Next.
On the Filter page, click Next.
On the View page, let's name the portlet, for example Product Information
, by entering the name in the Title field.
We can choose any of the default layouts for this portlet. However, let's check out the HTML layout, which you can use to fine tune the look and feel of your portlet.
Under Layout Style, select HTML, as shown in Figure 6-68, then click Next.
On the Layout page, you'll notice a form for filling in HTML for the template. Here, you can modify the layout of your portlet by updating the Header, Body, and Footer fields. You can use the default layout that OmniPortlet provides, but let's step through creating our own HTML layout.
From the Quick Start list, select Clear Fields, then click Apply. Doing so removes the existing HTML code from the layout template.
In the Repeating Section, enter the HTML in Example 6-8 to create a table that formats the data.
Note: If the formatting of the code in this text does not work, you can open theC:\TutorialContent\Portlets\OmniPortlet_HTML_Layout.txt file and copy and paste the code from there. |
Example 6-8 OmniPortlet HTML Layout Code
<table> <tr> <td> <font class="PortletHeading1">##NAME##</font> <img src="##IMAGE_URL##" title="##NAME## - ##CATEGORY_DESCRIPTION## by ##SUPPLIER_NAME##"></img> </td> <td> <table> <tr class="PortletText2"> <td> Product supplied by <font class="PortletHeading3"> ##SUPPLIER_NAME## </font> </td> </tr> <tr class="PortletText2"> <td> List price: $##RETAIL_PRICE## </td> </tr> <tr class="PortletHeading2"> <td> Our price: $##OUR_PRICE## </td> </tr> <tr class="PortletText2"> <td> You save: $##SAVINGS## </td> </tr> <tr class="PortletText2"> <td> <font class="PortletHeading2">Availability:</font> In Stock. Ships from and sold by <font class="PortletHeading2">FusionOnline.com</font> . Gift-wrap available. </td> </tr> <tr> <td> </td> </tr> </table> </td> </tr> <tr class="PortletText1"> <td colspan="2">Want it delivered Thursday? Order it in the next 22 hours and 45 minutes, and choose One-Day Shipping at checkout.</td> </tr> </table>
The Layout page should now look like Figure 6-69.
Click Finish. Figure 6-70 shows the OmniPortlet in your browser.
Figure 6-70 Completed OmniPortlet at Runtime
Now that we have created our two portlets, let's wire them.
When you added the code for the standards-based portlet called Products
, you also included a parameter called productId
. When you select different options in the Products
portlet, the application will send this parameter to OmniPortlet so that it can display the details of a particular product with that product identification number.
We now must map the two parameters to each other, so that when you choose an option in the Products portlet, the information in OmniPortlet updates accordingly.
To wire the portlets:
In Oracle JDeveloper, ensure MyTutorialApplication is open.
In the Application Navigator, open the page definition file for the MyPage.jspx
page. You can do this by opening the page definition file itself in the Application Navigator, or by right-clicking the page and choosing Go to Page Definition. You created the page definition for MyPage in "Step 3: Add ADF Security Policies to Your Application" in Chapter 4, "Adding Security to Your Application."
In the Structure window, use the pushpin to freeze the current view. Ensure the MyPage Page Definition is selected in the Design view, then, in the Structure window, click the pushpin so that it is in the "freeze" position (pressed).
In the Structure window for the MyPagePageDef.xml (page definition) file, expand executables, expand OmniPortlet1_1 then parameters, then select the portlet variable Param1, as shown in Figure 6-71.
Figure 6-71 OmniPortlet Variable in the Structure Window
While the variable is selected, you should be able to view the properties for it in the Property Inspector.
Set the pageVariable property to Products1_1_productId, as shown in Figure 6-72.
Now we want the detail portlet (OmniPortlet) to refresh whenever the value from the master portlet changes. To do so, we add a Partial Trigger to the detail portlet. Click the MyPage.jspx tab at the top of the Visual Editor to bring it into focus.
Select the OmniPortlet on the page in the Structure window. The portlet is the second instance of adfp:portlet
in the Panel Group Layout, as shown in Figure 6-73.
Figure 6-73 OmniPortlet on MyPage in the Design View
In the Property Inspector for OmniPortlet, under Common, click the arrow next to PartialTriggers, then choose Edit (Figure 6-74).
Figure 6-74 Editing the PartialTriggers Property for OmniPortlet
In the Edit Property: PartialTriggers dialog, the Portlet ID for OmniPortlet (portlet - portlet2
) is automatically selected. Locate the Portlet ID for the Products portlet, which is directly above the OmniPortlet (Figure 6-75).
Figure 6-75 Locating the Portlet ID for the Products Portlet
Select the Portlet ID, in this case portlet - portlet1, and click the right arrow to move it to the Selected list, then click OK (Figure 6-76).
Figure 6-76 Selecting the Portlet ID for the Products Portlet
Now that we've wired the portlet parameters, let's examine how they behave at runtime.
Run MyPage.jspx to your browser and log in as Lisa
/welcome1
. In the next step, we will test how the JSR 168 (Products) portlet and the OmniPortlet interact at runtime.
Let's test the portlets at runtime.
To test the interaction between the portlets:
In the Products portlet, select an option, for example iPod Speakers, then click Show Details.
In the OmniPortlet, notice that the portlet updates to display information about the iPod speakers (Figure 6-77).
Figure 6-77 Testing the Interaction Between the Portlets
For more information about creating portlets and using them with a WebCenter application, see Part VIII, "Working with Portlets and Portals" in Oracle Fusion Middleware Developer's Guide for Oracle WebCenter.
Now that you have created two portlets and added them to your application, let's see how we can change the look and feel of our application using a skin, as well as personalize the application at runtime in Chapter 7, "Changing the Look and Feel of Your Application."