This section describes how to add a portlet that uses the Administration Console's JSP templates, styles, and user input controls. For example, you can add portlets that render your content as one of the following:
A table in the ContentBook
that summarizes the resources you have provided and that enables users to navigate to a specific resource or to invoke actions on the resource from the table. (See Figure 2-5 for an example of a WebLogic Server table.)
A form in the ContentBook
that enables users to monitor or configure resources that you have provided.
Figure 7-1 illustrates the process. The steps in the process, and the results of each are described in Table 7-1. Subsequent sections detail each step in the process.
Figure 7-1 Administration Console Extension Development Overview
Table 7-1 Model MBean Development Tasks and Results
Step | Description | Result |
---|---|---|
Create a text file that contains a name/value pair for each text string that you want to display in your extension. |
One or more |
|
The WebLogic Server JSP tags that render forms and tables assume that Apache Struts is the controller agent. The JSP tags use Java beans that are populated by Struts |
A Struts configuration file, Java beans, and Java classes that implement |
|
WebLogic Server provides JSP templates that you can import into your JSPs. It also provides a JSP tag library to render the same UI controls that the Administration Console uses. |
JSPs that match the Administration Console styles and structure. |
|
5. Create Other Portal Framework Files and Deploy the Extension. |
Create XML files that define a location for your extension. |
A A |
6. Archive and deploy the extension. |
See Chapter 9, "Archiving and Deploying Console Extensions." |
A WAR file that contains your extension. |
Note:
You must precompile JSPs before deploying your extension.Oracle recommends that you define all of the text strings that your JSPs display in a message bundle. For information about creating a message bundle, see Chapter 4, "Creating a Message Bundle."
To use the bundle in your JSPs:
Import the JSTL fmt.tld
tag library:
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
Declare the name of your bundle:
<fmt:setBundle basename="bundle" var="current_bundle" scope="page"/>
where bundle
is the name of your bundle.
When you want the JSP to output a string, use the following JSP tag:
<fmt:message key="property-name" bundle="${current_bundle}"/>
For example:
<fmt:message key="myextension.myTab.introduction" bundle="${current_bundle}"/>
WebLogic Server provides a <wl:form>
JSP tag that can render a variety of HTML input controls, such as text controls, check boxes, and radio controls. You can configure a form to be read-only or to allow user input. Forms that allow user input must include buttons that enable users to post the form data for processing in the business layer.
WebLogic Server provides a <wl:table>
JSP tag that renders data in a tabular format. Each row in the table represents a single entity such as a WebLogic Server instance, an application, or a log message (see Figure 7-2). You can configure table columns to render hypertext links, which enable users to navigate to pages that provide more information about an item in the table. You can also create a table column that contains an HTML check box control. If a user selects a check box for a table row and clicks a submit button, your extension can invoke business logic on behalf of the entire row. For example, you can use a check box to delete an item that a row represents.
Both of these tags use Apache Struts Actions
and ActionForms
to pass data between the business layer and the presentation layer.
Apache Struts supports multiple techniques for instantiating and populating ActionForm
beans (form beans). For example, you can code your own concrete Java bean that contains getter and setter methods for each property in the form. Or you can use the Struts DynaActionForm
bean, which dynamically configures a Java bean to contain the properties that are declared in the Struts configuration file.
If you are using Oracle JSP tags to render a form in the Administration Console, you can use any technique for creating and populating form beans that Struts supports. (The example in Example: How Struts Portlets Display Content uses a DynaActionForm
bean instead of coding a custom Java bean.)
Regardless of the technique that you choose, your Java bean must contain the following property:
handle
, which can be of type com.bea.console.handles.Handle
or a custom Handle
class that you create.
The portal framework uses this property to correlate an ActionForm
bean with the data source that populates the bean, such as an MBean. See Handles for ActionForms and Row Beans.
If you are using Oracle JSP tags to render a table in the Administration Console, you must create two form beans: one bean that represents the rows in the table (called a row bean) and another bean (called a table bean) that contains the collection of row beans. Each property in the row bean is rendered as a table column. For example, in Figure 7-2, each row bean instance contains a name
, state
, health
, and listenPort
property.
To create a row bean, you must create a concrete Java bean that defines each property. You cannot use the Struts DynaActionForm
bean to dynamically contain the properties that are declared in the Struts configuration file.
To create a table bean, you can use any technique for creating and populating form beans that Struts supports. Regardless of the technique that you choose, your table bean must contain the following properties:
content
, which must be of type java.util.Collection
This is the property that you must use to contain the row beans.
handle
, which can be of type com.bea.console.handles.Handle
or a custom Handle
class that you create.
While the portal framework requires you to declare this property for form beans and table beans, its usefulness is limited with table beans. Typically, a table bean is simply a collection of row beans; the row beans expose an underlying data source but the table bean does not. Unless you need to keep track of which Action
class has populated your table bean, you do not need to set the value of this property of the table bean (but you must declare it). See Handles for ActionForms and Row Beans.
If you configure your table to include a column of check boxes, which enables you to invoke a Struts Action
on the selected table row beans, your table bean must also contain the following property:
chosenContents
, which can be an array of any primitive type or an array of com.bea.console.handles.Handle
. For information on how to work with check boxes in a table, see Add Buttons and Check Boxes to Tables.
To uniquely identify an instance of an ActionForm
bean or a row bean and to establish a correlation between the bean and its underlying data source, you can create and use a Handle
object. A Handle
object is a Java object that implements the com.bea.console.handles.Handle
interface.
The Apache Struts controller servlet places Handle
objects in HttpServletRequest
objects, thus making them available to any Struts Action, Beehive Page Flow, or JSP.
The Administration Console uses Handle
objects when linking from a row in a table JSP (see Figure 7-2) to the corresponding configuration JSP. For example, for a ServerMBean
instance named Server-0, the Administration Console populates row bean with data from the Server-0 MBean. The Administration Console passes the JMX object name for Server-0 to a new a Handle
object (of type com.bea.console.handles.JMXHandle
) and sets the Handle
object as the value of the row bean's handle
property (see Figure 7-3). When a user clicks a link in the table JSP, the Struts controller looks in the row bean's handle
property, uses the handle
value to determine which server instance has been selected, and displays the configuration page for the selected server.
If the underlying data source for your ActionForm
beans or row beans is an MBean, you can use the com.bea.console.handles.JMXHandle
object. See JMXHandle in the Administration Console API Reference.
If the underlying data source for your beans is not an MBean, you can create your own Java class that implements the com.bea.console.handles.Handle
interface. See Handle in the Administration Console API Reference.
To render HTML forms and tables and populate them with data, the Administration Console uses JSP tags that load data from Java beans. Most of these beans contain data that a Struts Action
has loaded from a WebLogic Server MBean. To submit user input, the JSP tags forward to Struts Actions
, and most of these Actions
update data in a WebLogic Server MBean.
If you use Administration Console JSP tags, you must create your own Struts ActionForms
and Actions
.
The following sections describe creating Java beans, Struts Actions
, and ActionForms
to use with forms and tables:
For information on Apache Struts, see The Apache Struts Web Application Framework at http://struts.apache.org/
.
To create Struts artifacts that pass data between the business layer and a JSP in the presentation layer:
Create an org.apache.struts.action.Action
class that populates a Java bean (form bean) with data from your business layer.
If your form allows user input, create another Action
class to process the data that users post from the form.
In your Struts configuration file:
Declare the name and the properties of the form bean that your Action
classes will populate and use.
If your form allows user input, you can use the same form bean to populate the form and to return user input to your Action
class that processes data.
Create an Action
mapping that the Struts controller uses to instantiate your form bean and invoke your Action
class that populates the form.
If your form allows user input, create another Action
mapping that the Struts controller uses when users submit the form.
To create Struts Action
classes that handle form data:
Create an org.apache.struts.action.Action
class that populates the form bean. (See Example 7-1.)
The Struts controller passes an empty ActionForm
bean to your Action
class. To populate the bean, implement the following method:
Action.execute(ActionMapping actionMapping, ActionForm actionForm, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
Your implementation should:
Gather data from an underlying source, such as an MBean.
Cast the empty ActionForm
bean as a DynaActionForm
bean.
Invoke the DynaActionForm.set()
method for each property that you defined in the <form-bean>
element, except for the handle
property.
For example, if you defined two properties named name
and totalRx
:
DynaActionForm form = (DynaActionForm) actionForm; form.set("name",namefromMBean); form.set("totalRx",totalRxfromMBean);
To establish a correlation between the form bean and its underlying data source, set the value of the handle
property. (See Handles for ActionForms and Row Beans.)
For example, if your underlying data source is an MBean, use JMXHandle
and set the handle
property to the MBean's ObjectName
:
ObjectName anMBean = new ObjectName("com.bea.medrec:Type=com.bea.medrec.controller. RecordSessionEJBMBean,Name=MedRecEAR"); form.setHandle(new JMXHandle(anMBean));
Put the DynaActionForm
bean into the request object that was also passed to the class:
httpServletRequest.setAttribute("form-bean-name", form);
where form-bean-name
matches the name that you configure for the form bean in the Struts configuration file (see Configure Struts ActionForms and Action Mappings).
Return "success" in the ActionMapping.findForward()
method for the ActionMapping
object that was passed to the Action
class:
return actionMapping.findForward("success");
If your form posts data for processing in the business layer, create another Action
class that processes the form data.
When a user posts data from the form (by clicking an HTML button), the Struts controller passes a populated ActionForm
bean to your Action
class. To process the data, implement the following method:
Action.execute(ActionMapping actionMapping, ActionForm actionForm, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
Your implementation should:
Cast the ActionForm
bean that was passed in the request as a DynaActionForm
bean.
Invoke the DynaActionForm.get()
method for each property that you want to process.
For example, if you want to process the properties named name
, totalRx
, and handle
:
DynaActionForm form = (DynaActionForm) actionForm; String nameValue = (String) form.get(namefromMBean); Integer totalValue = (Integer) form.get(totalRxfromMBean); JMXHandle handle = (JMXHandle) form.get(handle);
Process the data.
For example, if the name
and totalRx
properties represent attributes in a MBean and you want to change the values of the MBean attributes, use the handle
property to get the JMX object name of the MBean instance, and then use JMX APIs to set the MBean attributes to the values that were posted from the form:
ObjectName oName = handle.getObjectName(); MBeanServer.setAttribute(oName, new Attribute(("Name", nameValue)); MBeanServer.setAttribute(oName, new Attribute(("TotalRx", totalValue));
Return "success" in the ActionMapping.findForward()
method for the ActionMapping
object that was passed to the Action
class:
return actionMapping.findForward("success");
Compile the Action classes and save them in a package structure that begins in the root-dir
/WEB-INF/classes
directory.
Example 7-1 is an example org.apache.struts.action.Action
class that accesses a custom MBean and uses it to populate a form bean.
Example 7-1 Example: Action Class that Populates a Form Bean
import javax.management.MBeanServer; import javax.management.ObjectName; import javax.management.MalformedObjectNameException; import javax.naming.InitialContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.DynaActionForm; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; public class MedRecMBeanFormAction extends Action { public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { try { // Establish a local connection to the Runtime MBean Server InitialContext ctx = new InitialContext(); MBeanServer server = (MBeanServer) ctx.lookup("java:comp/env/jmx/runtime"); // Create an ObjectName that corresponds to a custom MBean that // has been registered in the Runtime MBean Server ObjectName anMBean = new ObjectName( "com.bea.medrec:Type=com.bea.medrec.controller. RecordSessionEJBMBean,Name=MedRecEAR"); //Get the value of the custom MBean's "Name" attribute String namefromMBean = (String)server.getAttribute (anMBean, "Name"); // Get the value of the custom MBean's "TotalRx" attribute Integer totalRxfromMBean = (Integer) server.getAttribute (anMBean, "TotalRx"); // Populate the form bean DynaActionForm form = (DynaActionForm) actionForm; form.set("name",namefromMBean); form.set("totalRx",totalRxfromMBean); form.set("handle",(new JMXHandle(anMBean))); // Set the form bean in request. The name of the // form bean must match the "form-bean" name in your // Struts configuration file httpServletRequest.setAttribute("medrecMBeanEJBForm", form); } catch (Exception ex) { ex.printStackTrace(); } return actionMapping.findForward("success"); } }
To create a Struts configuration file that declares your ActionForms
and Action
mappings:
Copy the code from Example 7-2 and paste it into the configuration file for your Struts module.
If you have not already created a configuration file, create a text file in root-dir
/WEB-INF
(see Create a Directory Tree for the Extension). Name the file struts-auto-config-
module
.xml
.
where module
is a name that you have chosen for your Struts module. Consider using the name of your company to avoid possible naming conflicts. You must create your own Struts module; the default Struts module is reserved for Oracle Actions and ActionForms. For information about Struts modules, see the Apache Struts User Guide at http://struts.apache.org/
.
To configure a form bean that Struts will use to transfer data from the business layer to the JSP in the presentation layer, replace the following value in Example 7-2:
form-bean-name
, a unique name that you assign to this instance of a DynaActionForm
bean. Your Action
class will refer to this bean name when it populates the bean and returns it to the Struts controller.
Use a name that reflects the name of the Struts Action
that you will use to populate the bean instance.
To configure an Action
mapping that Struts will use to populate the form bean, serialize the bean, put it into an HTTP request, and forward the request to a JSP, replace the following values in Example 7-2:
action-name
, a unique name that you assign to this Action
mapping. Your .portlet
file will refer to this Action
name.
custom-Action-class
, the fully qualified name of a Java class that you create to populate the form bean. Step 5 describes how to create this class.
form-jsp.jsp
, the name of a JSP that you create to render the form. See Create a Form JSP.
If your form posts data for processing in the business layer, create another <action>
element that specifies a custom class that you will create to process the form data.
For form-bean-name
of this second <action>
element, you can use the same form bean that initially populated the form. If you want to post only a subset of the data for processing, instead of using the same form bean you can configure another one that defines only the properties that you want to process.
Upon success, this additional <action>
element can forward to the Action
mapping that you configured in the previous step. This reloads the JSP with the updated data.
Example 7-2 Template for Struts Configuration File
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "struts-config_1_1.dtd"> <struts-config> <form-beans> <form-bean name="form-bean-name" type="org.apache.struts.action.DynaActionForm"> <form-property name="handle" type="com.bea.console.handles.Handle"/> <!-- insert additional "form-property" elements here --> </form-bean> </form-beans> <action-mappings> <action path="/action-name" type="custom-Action-class" name="form-bean-name" scope="request" validate="false"> <forward name="success" contextRelative="true" path="/ext_jsp/form-jsp.jsp"/> </action> <!-- insert additional "action" elements here --> </action-mappings> <message-resources parameter="global"/> <message-resources parameter="validationmessages" key="VALIDATIONMESSAGES"/> <message-resources parameter="genresources" key="GENRESOURCES"/> <message-resources parameter="global" key="GLOBAL"/> </struts-config>
To create a Java row bean, Struts Action
, and ActionForm
for a JSP that uses the WebLogic Server <wl:table>
JSP tag:
To configure a bean that will function as the row bean, create a standard Java bean that contains one property for each data item that you want to display in the table.
Compile your Java bean and save it in a package structure that begins in the root-dir
/WEB-INF/classes
directory.
To configure a bean that will function as the table bean:
Copy the code from Example 7-2 and paste it into the configuration file for your Struts module.
If you have not already created a configuration file, create a text file in root-dir
/WEB-INF
(see Create a Directory Tree for the Extension). Name the file struts-auto-config-
module
.xml
where module
is a name that you have chosen for your Struts module. Consider using the name of your company to avoid possible naming conflicts. You must create your own Struts module; the default Struts module is reserved for Oracle Actions and ActionForms. For information about Struts modules, see the Apache Struts User Guide at http://struts.apache.org/
.
Replace the following value in Example 7-2:
form-bean-name
, a unique name that you assign to this instance of a DynaActionForm
bean. Your Action
class will refer to this bean name when it populates the bean and returns it to the Struts controller.
Use a name that reflects the name of the Struts Action
that you will use to populate the bean instance.
Add the following property:
<form-property name="contents" type="java.util.Collection"/>
This property will contain the collection of row beans that your Action
class instantiates and populates.
To configure an Action
mapping that Struts will use to populate the row beans and the table bean, serialize the beans, put them into an HTTP request, and forward the request to a JSP, replace the following values in Example 7-2:
action-name
, a unique name that you assign to this Action
mapping. Your .portlet
file will refer to this Action
name.
custom-Action-class
, the fully qualified name of a Java class that you create to populate the row beans and table bean. Step 5 describes how to create this class.
form-jsp.jsp
, the name of a JSP that you create to render the table. See Create a Form JSP.
Create an org.apache.struts.action.Action
class that populates the row beans and table bean. (See Example 7-3.)
To populate the beans, implement the following method:
Action.execute(ActionMapping actionMapping, ActionForm actionForm, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
Your implementation should:
Gather application data from underlying data sources, such as instances of an MBean.
Create instances of your row bean and populate them by invoking their setters for each property in the bean.
Assign all of your row bean instances to an ArrayList
.
Cast the empty ActionForm
bean (table bean) as a DynaActionForm
bean.
Set the table bean's content
property to contain the ArrayList
of row beans:
DynaActionForm table = (DynaActionForm) actionForm; table.set("contents",rowBeanArray);
Put the table bean into the request object that was also passed to the class:
httpServletRequest.setAttribute("table-bean-name", table);
where table-bean-name
is the name that you configured for the table bean in the Struts configuration file (see Example 7-2).
Return "success" in the ActionMapping.findForward()
method for the ActionMapping
object that was passed to the Action
class:
return actionMapping.findForward("success");
Compile the Action
class and save it in a package structure that begins in the root-dir
/WEB-INF/classes
directory.
Example 7-3 Example: Action Class that Populates a Row Bean and a Table Bean
import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.Set; import javax.management.MBeanServer; import javax.management.ObjectName; import javax.management.MalformedObjectNameException; import javax.naming.InitialContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.DynaActionForm; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; public class RetrieveCustomMBeansAction extends Action { public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { try { // Establish a local connection to the Runtime MBean Server InitialContext ctx = new InitialContext(); MBeanServer server = (MBeanServer) ctx.lookup("java:comp/env/jmx/runtime"); // Create a name pattern for all MedRec EJB MBeans ObjectName namepattern = new ObjectName("com.bea.medrec:Type=com.bea.medrec.controller. RecordSessionEJBMBean,*"); // Get all MedRec EJB MBeans for all applications Set objects = server.queryNames(namepattern, null); // Walk through each of these MBeans and get the object name // and the value of its TotalRX attribute Iterator i = objects.iterator(); while (i.hasNext()) { ObjectName anMBean = (ObjectName) i.next(); String identifier = anMBean.toString(); Integer totalRxfromMBean = (Integer) server.getAttribute(anMBean, "TotalRx"); // Instantiate a row bean. MedRecMBeanTableBean row = new MedRecMBeanTableBean(anMBean); // Set the properties of the row bean row.setCanonicalName(anMBean.getCanonicalName()); row.setTotalRxinTableBean(totalRxfromMBean); // Add each row bean to an ArrayList result.add(row); } } catch (Exception ex) { ex.printStackTrace(); } // Instantiate the table bean DynaActionForm form = (DynaActionForm) actionForm; // Set the array of row beans as the value of the table bean's "contents" // property form.set("contents",result); // Set the table bean in request. The name of the // table bean must match the "form-bean" name in your // Struts configuration file httpServletRequest.setAttribute("genericTableForm", form); return actionMapping.findForward("success"); } }
Most portlets in the Administration Console JSPs that are based on the tableBaseLayout_netui
and configBaseLayout_netui
templates.
The following sections describe how to create JSPs that use these templates:
Table 7-2 describes the JSP templates that you can use for your Administration Console extensions. All of the templates are located in the /layouts
directory, which is relative to the WEB-INF
directory of the Administration Console. For more specific information about what a template does, open the JSP file and read the comment toward the beginning of the file.
If these templates do not meet your needs, you can create your own templates and structure the content directly in your JSP.
Table 7-2 Administration Console JSP Templates
Template | Use for... |
---|---|
assistantBaseLayout_netui.jsp |
All standard assistant JSPs in the console. |
assistantFormAndTableLayout_netui.jsp |
All standard assistant JSPs in the console containing a table. |
configBaseLayout_netui.jsp |
All standard configuration form JPSs in the console. |
configBaseLayoutNoTransact.jsp |
All non-transaction configuration form JSPs in the console |
configBaseLayoutWithButtons_netui.jsp |
All standard configuration form JPs in the console with extra buttons in the button bar. |
configIntroLayout_netui.jsp |
Simple pages with text only. |
configNoFieldsLayout_netui.jsp |
All information pages. |
configNoTransactAndTables_netui.jsp |
Pages that contain non-transactional configuration and up to four tables. |
filterAndTableLayout_netui.jsp |
All pages that have a table with filters above it. |
formAndTableLayout_netui.jsp |
Configuration form JSPs that also contain a table. |
formWithButtonsLayout_netui.jsp |
Form pages with a button bar; but they do not participate in Configuration Manager locking. |
fourTablesLayout_netui.jsp |
All table pages with four tables. |
standalone_layout.jsp |
Standalone pages, that is, pages outside the console Portal. |
summarypage.jsp |
All summary pages. |
tableBaseLayout_netui.jsp |
The Administration Console uses this template for all JSPs that render a single table. |
tableBaseMonitoringLayout.jsp |
All single table pages that include table refresh functionality. |
tablePreferencesLayout.jsp |
Deprecated. |
threeTablesLayout_netui.jsp |
All table pages with three tables. |
twoTablesLayout_netui.jsp |
All table pages with two tables. |
twoTablesWithButtonsLayout.jsp |
Pages with two tables and a button bar. |
Before you create a form JSP, create Struts artifacts that pass data between the business layer and the JSP. See Create Struts Artifacts for a Form JSP: Main Steps.
To create a form JSP (see Example 7-4):
Create a JSP and save it in your development directory. Consider creating a subdirectory to contain all of the JSPs in your extension. For example, root-dir
/jsp
, where root-dir
is your development directory. For more information, see Chapter 3, "Setting Up a Development Environment."
Import JSP tag libraries by including the following tags:
<%@ taglib uri="/WEB-INF/console-html.tld" prefix="wl-extension" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://beehive.apache.org/netui/tags-template-1.0" prefix="beehive-template" %>
For information about these tag libraries, see JSP Tag Libraries.
(Optional) If you plan to use <fmt:message>
tags to display localized text, use <fmt:setBundle/>
to specify the name of the message bundle.
This <fmt:setBundle/>
tag enables you to specify the bundle name once, and then refer to this value from <fmt:message>
tags by variable.
Declare the JSP template for configuration pages by creating the following opening tag:
<beehive-template:template templatePage="/layouts/configBaseLayoutNoTransact.jsp">
Do not close the tag yet. All other JSP tags in a form JSP are nested in this template tag.
Note:
If your form modifies attributes of WebLogic Server MBeans, use the configBaseLayout_netui.jsp
template instead. See JSP Tag Libraries.Create a <beehive-template:section name="configAreaIntroduction">
tag. Inside this tag, provide an introductory sentence or paragraph that describes the form. This description is rendered above the form.
Create the following opening tag:
<beehive-template:section name="form">
Do not close the tag yet.
Indicate that the next set of JSP tags output XHTML by creating the following tag:
<html:xhtml/>
Create an opening <wl-extension:template name="/WEB-INF/templates/form.xml">
tag.
This template creates a form that matches Administration Console configuration pages (such as Domains: Configuration: General).
The template also generates a button that submits the form.
Create an opening <wl-extension:form>
and specify values for the following attributes:
action
, (optional) if your form accepts user input, specify the path of a Struts Action
that is invoked when a user submits this form. The Struts module that defines the Action
path is specified in the request.
bundle
, (optional) specify the name of a message bundle that contains localized names of your column headings.
readOnly
, (optional) specify "true" to make this form read-only (for example, if you are displaying read-only monitoring data).
For each property in the form bean that you want to display in the form, create a <wl-extension>
tag corresponding to the type of control that you want to render (see WebLogic Server JSP Tags Reference):
<wl-extension:checkbox>
<wl-extension:chooser-tag>
<wl-extension:hidden>
<wl-extension:password>
<wl-extension:radio>
<wl-extension:select>
<wl-extension:text>
<wl-extension:text-area>
Alternatively, you can use <wl-extension:reflecting-fields>
, which generates an HTML input tag for each property in a form bean. For example, for a bean property that contains a java.lang.String
, the tag generates a text control; for a boolean, it generates a check box. This tag uses the default form bean, which is passed to the JSP in the request.
If your form accepts user input and does not modify the attributes of WebLogic Server MBeans, be sure to include the singlechange="false"
attribute in the <wl-extension>
tags described in the previous step.
This attribute enables users to post form data without starting a WebLogic Server edit session.
To generate text on the page that describes to users the purpose of each control, include the inlineHelpId
attribute in each <wl-extension>
tag in the previous step.
Close the <wl-extension:form>
, <beehive-template:section>
, and <beehive-template:template>
tags.
Example 7-4 Example: Simple Form JSP
<%@ page language="java" %> <%@ taglib uri="/WEB-INF/console-html.tld" prefix="wl-extension" %> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> <%@ taglib uri="http://beehive.apache.org/netui/tags-template-1.0" prefix="beehive-template" %> <fmt:setBundle basename="mycompany" var="current_bundle" scope="page"/> <beehive-template:template templatePage="/layouts/configBaseLayoutNoTransact.jsp"> <beehive-template:section name="configAreaIntroduction"> <fmt:message key="mycompany.myresource.introduction" bundle="${current_bundle}"/> </beehive-template:section> <beehive-template:section name="form"> <html:xhtml/> <wl-extension:template name="/WEB-INF/templates/form.xml"> <wl-extension:form action="/MyCompanyMyResourceUpdated" bundle="core"> <wl-extension:text property="MyResourceName" labelId="mycompany.myresource.name.label" inlineHelpId="mycompany.myresource.name.label.inlinehelp" singlechange="false"/> <wl-extension:select property="MyResourceWidgets" labelId="mycompany.myresource.widgets.label" inlineHelpId="mycompany.myresource.widgets.label.inlinehelp" singlechange="false"> <wl-extension:optionsCollection property="MyResourceAvailableWidgets" label="label" value="value"/> </wl-extension:select> </wl-extension:form> </wl-extension:template> </beehive-template:section> </beehive-template:template>
Before you create a table JSP, create Struts artifacts that pass data between the business layer and the JSP. See Create Struts Artifacts for a Table JSP.
To create a table JSP for monitoring resources (see Example 7-5):
Create a JSP and save it in your development directory. Consider creating a subdirectory to contain all of the JSPs in your extension. For example, root-dir
/ext_jsp
, where root-dir
is your development directory.
Note:
The directory named root-dir/jsp
is reserved. The root directory of your extension must not contain a directory named jsp
.For more information, see Chapter 3, "Setting Up a Development Environment."
Import JSP tag libraries by including the following tags:
<%@ taglib uri="/WEB-INF/console-html.tld" prefix="wl-extension" %> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> <%@ taglib uri="http://beehive.apache.org/netui/tags-template-1.0" prefix="beehive-template" %>
For information about these tag libraries, see JSP Tag Libraries.
(Optional) If you plan to use <fmt:message>
tags to display localized text, use <fmt:setBundle/>
to specify the name of the message bundle.
This <fmt:setBundle/>
tag enables you to specify the bundle name once, and then refer to this value from <fmt:message>
tags by variable.
Declare the JSP template for tables by creating the following opening tag:
<beehive-template:template templatePage="/layouts/tableBaseLayout_netui.jsp">
Do not close the tag yet. All other JSP tags in a table JSP are nested in this template tag.
Create a <beehive-template:section name="configAreaIntroduction">
tag. Inside this tag, provide an introductory sentence or paragraph that describes the table. This description is rendered above the table.
Create the following opening tag:
<beehive-template:section name="table">
Do not close the tag yet.
Create an opening <wl-extensions:table>
tag and specify values for the following minimal attributes:
name
, specify the name of the form bean that you configured for this table.
property
, specify the name of the form-bean property that contains row beans.
bundle
, (optional) specify the name of a message bundle that contains localized names of your column headings.
captionEnabled
, (optional) specify "true" to generate a title above the table.
If you specified "true" for the captionEnabled
attribute, create a <wl-extension:caption>
tag. Inside this tag, provide a caption for the table.
For each property in the row bean that you want to display in the table, create a <wl-extension:column>
tag and specify values for the following attributes:
property
, specify the name of the row bean property
label
, specify a key in your message bundle to display as the column heading
Close the <wl-extension:table>
, <beehive-template:section>
, and <beehive-template:template>
tags.
Example 7-5 Example: Table JSP for Monitoring
<%@ page language="java" %> <%@ taglib uri="/WEB-INF/console-html.tld" prefix="wl-extension" %> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> <%@ taglib uri="http://beehive.apache.org/netui/tags-template-1.0" prefix="beehive-template" %> <fmt:setBundle basename="core" var="current_bundle" scope="page"/> <beehive-template:template templatePage="/layouts/tableBaseLayout_netui.jsp"> <beehive-template:section name="configAreaIntroduction"> <fmt:message key="core.server.servertable.introduction" bundle="${current_bundle}"/> </beehive-template:section> <beehive-template:section name="table"> <wl-extension:table name="extensionForm" property="contents" captionEnabled="true" bundle="core"> <wl-extension:caption> <fmt:message key="server.table.caption" bundle="${current_bundle}"/> </wl-extension:caption> <wl-extension:column property="name" label="server.table.label.name"/> <wl-extension:column property="clusterName" label="server.table.label.cluster"/> <wl-extension:column property="machineName" label="server.table.label.machine"/> </wl-extension:table> </beehive-template:section> </beehive-template:template>
Your table JSP can provide a link from each row to a configuration page or some other related page. The linking mechanism uses a Handle
object to determine which pages are related to a specific table row (see Handles for ActionForms and Row Beans).
You can use any of the following JSP tags to link from a table:
<wl:column-link>
, which requires you to specify the label of the page and portlet instance to which you want to link. The handle causes the portlet to display data related to the specific row that you selected.
<wl:column-dispatch>
, which uses metadata to determine the page and portlet to display. Instead of specifying the page and portlet label, you add a metadata tag to the page declaration and then specify the metadata value in the <wl:column-dispatch>
tag. Using metadata enables you to change page labels without breaking links. The handle is still used to cause the portlet in the page to display data related to the specific row that you selected.
The following sections describe how to create a table column for navigating:
To create and populate a handle
property:
In your row bean, add a property named handle
whose data type is com.bea.console.handles.Handle
:
public com.bea.console.handles.Handle getHandle() { return handle; } public void setHandle(Handle handle) { this.handle = handle; }
In the Struts Action
class that populates the row bean, set the value of the handle
property.
If you populate your row bean from data in an MBean, create a com.bea.console.handles.JMXHandle
object that contains the JMX ObjectName
of the MBean. Then set the JMXHandle
object as the value of the handle
property:
javax.management.ObjectName anMBean = new ObjectName("com.bea.medrec:Type=com.bea.medrec.controller. RecordSessionEJBMBean,Name=MedRecEAR"); row.setHandle(new JMXHandle(anMBean));
If your populate your row bean from some other type of data source, you can create a JMXHandle
object by passing a String
to the constructor instead of an ObjectName
. The String
must contain the following character sequence: Type=
identifier
, where identifier
is something that is meaningful to you:
row.setHandle(new JMXHandle("Type=myDataSource"));
You can also create and set a custom Handle
object. See Handle in the Administration Console API Reference.
Recompile your row bean and Action
class.
To use the <wl:column-link>
tag:
At the top of the table JSP, add the following statement to import the render
tag library into your table JSP:
<%@ taglib uri="render.tld" prefix="render" %>
Oracle provides this tag library in its runtime environment.
In the <wl:table>
tag, add the following attribute:
checkBoxValue="handle"
In the <wl:column>
tag that renders the column from which you want to link, nest the <wl:column-link>
JSP tag:
<wl:column-link portlet="portlet-instanceLabel"> <render:pageUrl pageLabel="page-definitionLabel"/> </wl:column-link>
where:
portlet-instanceLabel
is the label of the portlet instance to which you want to link.
The label is defined in the instanceLabel
attribute of the <netuix:portletInstance>
element, which is in the .book
file for the page that contains the portlet.
page-definitionLabel
is the unique label of the page that contains the instance of the portlet to which you want to link.
The label is defined in the definitionLabel
attribute of the <netuix:page>
element, which is in the page's .book
file.
For example:
<wl:column property="Name" label="medrecMBean.name.label"> <wl:column-link portlet="medrecMonitorTabPortlet"> <render:pageUrl pageLabel="medrecMonitor"/> </wl:column-link> </wl:column>
Note:
The <render:pageUrl/>
tag is a convenience tag for generating a portal framework URL.To use the <wl:column-dispatch>
tag:
In the .book
file that defines the page to which you want to link, find the page's <netuix:page>
element and nest the following element:
<netuix:meta name="perspective-name" content="ObjectType-value"/>
where:
perspective-name
is a name that is meaningful to you. This value must match the value that you specify in the perspective
attribute of the <wl:column-dispatch>
tag. For example, specify myCompany-configuration-page
.
ObjectType-value
is the value of the ObjectType
property in the row bean's Handle
object. See Handle.getObjectType() in the Administration Console API Reference.
For example, assume that you populate your row bean from data in an MBean. You use the MBean's ObjectName
to construct a JMXHandle
object and then set the object as the value of the row bean's handle
property. If the MBean's ObjectName
is "com.mycompany:Name=myApp1,Type=myAppMBean
", then the value of JMXHandle.ObjectType
is myAppMBean
.
For example:
<netuix:meta name="myCompany-configuration-page" content="myAppMBean"/>
In the table JSP, in the <wl:table>
tag, add the following attribute:
checkBoxValue="handle"
In the <wl:column>
tag that renders the column from which you want to link, nest the <wl:column-dispatch>
JSP tag:
<wl:column-dispatch perspective="perspective-name"/>
where:
perspective-name
matches the perspective-name
value that you specified in the .book
file.
For example:
<wl:column property="Name" label="medrecMBean.name.label"> <wl:column-dispatch perspective="myCompany-configuration-page"/> </wl:column-link> </wl:column>
In a table that you create using the <wl:table>
tag, you can use buttons by themselves or in conjunction with a column of check boxes or radio buttons.
When used by themselves, buttons can forward to page UI control. For example, in the WebLogic Server Servers table (see Figure 7-2), users click on a New button to launch the Create a Server assistant.
When used in conjunction with a check box, buttons can process data on behalf of one or more table rows. For example, if each row in your table represents an instance of a custom MBean that provides monitoring data for your application, you can enable users to select a check box for one or more rows and click a button that resets the values in the corresponding MBean instances.
The following sections describe adding check boxes and buttons to tables:
To add buttons to a table:
In the table JSP, add the following attributes to the <wl-extension:table>
tag:
singlechange="false" controlsenabled="true"
The controlsenabled
attribute enables the table to display buttons. The singlechange
attribute enables users to click the button without having to lock the domain's configuration. (See WebLogic Server JSP Tags Reference.)
Immediately after the <wl-extension:table>
opening tag, add the following tags:
<wl:button-bar> <wl:button-bar-button labelid="button-label" pageLabel="page-definitionLabel"/> </wl:button-bar>
where:
button-label
is the text that you want to display on the button or the name of a property that you have defined in the bundle that has been declared in the JSP's <fmt:setBundle>
element.
page-definitionLabel
is the unique label of the page that contains the instance of the portlet to which you want to forward.
The label is defined in the definitionLabel
attribute of the <netuix:page>
element, which is in the page's .book
file.
For example, to link to the Servers table page:
<wl:button-bar> <wl:button-bar-button labelid="Servers" pageLabel="ServerTableBook" /> </wl:button-bar>
To process data on behalf of one or more table rows, use check boxes and a button to post the data to an HTTP request. You must also create a Struts Action
or Page Flow that can retrieve and process the posted data:
To post data to an HTTP request on behalf of one or more table rows:
In your Struts configuration file, add a property named chosenContents
to the definition of the table's ActionForm
bean.
The data type for this property must be either an array of primitive types or of com.bea.console.handles.Handle
.
The <wls:table>
tag adds one element to this array for each check box that is selected when the user submits the table.
For example:
<form-property name="chosenContents" type="[Lcom.bea.console.handles.Handle;"/>
In the table JSP, add the following attributes to the <wl-extension:table>
tag:
singlechange="false"
controlsenabled="true"
showcheckboxes="true"
checkBoxValue="property-name"
where property-name
is the name of a property in the row bean. The data type of this property must match the data type that you have declared for the chosenContents
property.
The <wl:table>
tag adds the value of this row bean to the array in the table bean's chosenContents
property.
If you want the table to render radio buttons, which allow users to select only a single row, add the following attribute:
singlechoice="true"
Immediately after the <wl-extension:table>
opening tag, add the following tags:
<wl:button-bar> <wl:button-bar-button labelid="button-label" portlet="portlet-instanceLabel" pageLabel="page-definitionLabel"/> </wl:button-bar>
where:
button-label
is the text that you want to display on the button or the name of a property that you have defined in the bundle that has been declared in the JSP's <fmt:setBundle>
element.
portlet-instanceLabel
is the label of a portlet instance that contains the Struts Action or Beehive Page Flow that you want to launch when a user clicks the button. The label is defined in the instanceLabel
attribute of the <netuix:portletInstance>
element, which is in the .book
file for the page that contains the portlet.
Instead of immediately launching an Action
or Page Flow, you can specify a portlet that contains a JSP. The JSP can ask users for confirmation before launching an Action
or Page Flow.
page-definitionLabel
is the unique label of the page that contains the instance of the portlet to which you want to forward.
The label is defined in the definitionLabel
attribute of the <netuix:page>
element, which is in the page's .book
file.
To create a Struts Action
that can process the posted data:
Create a portlet that forwards to a Struts Action
. Make sure that the portlet's instanceLabel
matches the value that you specified in step 1c.
For example:
<netuix:portletInstance markupType="Portlet" instanceLabel="medrecMonitor.Tab.Portlet" contentUri="/portlets/medrec_monitor_tab.portlet"/>
For information about creating a portlet, see Define a Portlet.
In your Struts configuration file, define an ActionForm
bean that contains a property named chosenContents
. The data type for this property must be the same data type that you specified in step 1a.
For example:
<form-bean name="processButtonForm" type="org.apache.struts.action.DynaActionForm"> <form-property name="chosenContents" type="[Lcom.bea.console.handles.Handle;"/> </form-bean>
In your Struts configuration file, define a Struts Action mapping that sends the data in the ActionForm
bean to a Java class for processing.
For example:
<action path="/ProcessButtonAction" type="com.bea.medrec.extension.MedrecMBeanButtonAction" name="processButtonForm" scope="request" validate="false"> <forward name="success" contextRelative="true" path="/ext_jsp/button_view.jsp"/> </action>
The following steps describe a table that correlates a table row with an underlying MBean data source and clears the values of attributes in the MBean:
In a table JSP, you configure the <wl-extension:table>
tag to render check boxes. You specify that if a user selects the check box for a row, the value of the row bean's handle
property will ultimately be posted to the request object:
<wl-extension:table showcheckboxes="true" checkBoxValue="handle" ... >
The row bean's handle
property contains a JMXHandle
object, which contains the ObjectName
of the MBean instance that populated the row.
When a user selects a row and clicks a button, the button adds the row bean's JMXHandle
object to an array in the table bean's chosenContents
property. Then it posts the table bean. (See Figure 7-4.)
The Struts controller serializes the table bean (which is a Struts ActionForm
bean) and writes the serialized bean in the HTTP request object. Then it forwards the request to a specified portlet.
The portlet launches a Struts Action
mapping, which does the following:
Creates an ActionForm
bean and populates it with data from the HTTP request.
Invokes an Action
class and makes the ActionForm
bean available to the class.
The Action
class iterates over the form bean's chosenContents
array (which contains instances of JMXHandle
). For each element in the array, the class does the following:
Gets the MBean ObjectName
that is encoded in the JMXHandle
object,
Uses an MBeanServer
to look up the MBean.
Uses an MBeanServer
to invoke an MBean operation that clears an attribute value.
Upon success, the Action
mapping forwards to a JSP.
Figure 7-4 Example: Data Flow from Table to Struts Action
By adding a single attribute to the <wl:table>
tag, you can enable your users to configure which table columns the table displays. The Administration Console persists the preference for each user and for each instance of the portlet that displays the table. If you reuse a table in multiple portlet instances, each user can set a different preference for the table in each portlet instance.
To enable users to configure the set of table columns that your table displays, add the following attribute to your <wl:table>
tag: customize="true"
.
For example:
<wl-extension:table customize="true" ... >
When the Administration Console displays the JSP that contains the table, it renders a "Customize this table" link above the table title. The link causes the table JSP to display a section that contains a chooser control and an Apply or Reset button.
You can add your portlet directly to the desktop, but if you want your portlet to display as a tab or subtab in the ContentBook
, you must define books or pages to contain it. In addition, you must create a netuix-extension.xml
file which specifies where to locate your portlet, books, and pages and which functions as the deployment descriptor for your extension.